A webapp which can send beqcatalogue filters to a DSP device
Project description
ezbeq
A simple web browser for beqcatalogue which integrates with minidsp-rs for local remote control of a minidsp or HTP-1.
Table of Contents
- Setup
- Scripts (bin/)
- How the app is structured
- Running the app
- Configuration
- Starting ezbeq on bootup
- Verifying MiniDSP Response
Setup
Windows / MacOS
Python is required so use an appropriate package manager to install it.
chocolatey is a convenient choice for Windows homebrew is the equivalent for MacOS
Linux
Use your distro package manager to install python.
Installation
ezbeq uses Poetry for dependency management.
$ pip install poetry
$ git clone https://github.com/3ll3d00d/ezbeq
$ cd ezbeq
$ poetry install
Example is provided for rpi users
$ ssh pi@myrpi
$ sudo apt install python3 python3-venv python3-pip libyaml-dev
$ pip install poetry
$ git clone https://github.com/3ll3d00d/ezbeq
$ cd ezbeq
$ poetry install
Docker
The official ezBEQ docker image is published at https://github.com/3ll3d00d/ezbeq-docker. See that project's README for setup instructions, example compose files, and USB device configuration.
Running in Docker
Set EZBEQ_ACCESS_LOG_STDOUT=1 in your container environment to echo every HTTP request to stdout so it appears in docker compose logs. This is independent of accessLogging: in ezbeq.yml (which controls the access log file).
Example Config Files
See examples
| Type | File |
|---|---|
| Camilla DSP | for CamillaDSP v3 |
| J River Media Center | ezbeq_mc.yml |
| Minidsp 2x4HD | ezbeq_md.yml, using multiple devices or with custom slot names |
| Minidsp 4x10 | ezbeq_4x10.yml |
| Minidsp 10x10 | without use of XO, with or using a custom mapping across input, output and xo |
| Minidsp DDRC-24 | ezbeq_ddrc24.yml |
| Minidsp DDRC-88 | ezbeq_ddrc88.yml |
| Minidsp HTx | ezbeq_htx.yml |
| Minidsp SHD | ezbeq_shd.yml |
| Monolith HTP-1 | ezbeq_htp1.yml |
| Q-Sys | ezbeq_qsys.yml |
| Multiple, different devices | ezbeq_multi.yml |
Using with a Minidsp
Install minidsp-rs as per the provided instructions
Using with a Monolith HTP-1
See the configuration section below
Upgrade
$ cd ezbeq
$ git pull
$ poetry install
then restart the app
Scripts (bin/)
| Script | Purpose |
|---|---|
bin/run-server |
Start the server with real hardware |
bin/run-server-stub |
Start with a simulated device — no hardware needed |
bin/run-ui-dev |
Hot-reload UI dev mode (Vite + Python backend) |
bin/run-tests |
Run pytest suite + smoke test |
bin/smoke-test |
HTTP smoke test against a running server |
How the app is structured
ezbeq is a single Python server (Twisted) that does two things:
- Serves the REST API —
/api/...routes handled by Flask - Serves the React UI — pre-built static files from
ezbeq/ui/
The UI source lives in ui/ and is built with Vite /
Yarn. Running yarn build compiles it into
ezbeq/ui/, which the Python server then picks up automatically. The Docker
image ships with the UI pre-built.
Running the app
$ cd ezbeq
$ bin/run-server
Then open http://localhost:8080 in your browser.
Note:
bin/run-serverrequires theminidspbinary in your PATH. Install it from minidsp-rs releases. To run without hardware, see Stub mode below.
Stub mode — no hardware required
Simulates a MiniDSP 2x4HD in memory. No minidsp binary or physical device
needed. Builds the UI automatically if it hasn't been built yet.
$ bin/run-server-stub
Then open http://localhost:8080.
Frontend hot-reload (UI development)
For iterating on the React UI without rebuilding after every change:
$ bin/run-ui-dev
This starts two processes and wires them together:
| Process | URL | Purpose |
|---|---|---|
| Python backend (stub) | http://localhost:8080 | API + WebSocket |
| Vite dev server | http://localhost:5174 | UI with hot-reload |
Open http://localhost:5174 in your browser. Edits to files under ui/src/
are reflected instantly. The Python backend does not hot-reload; restart the
script when you change backend code.
Requires Node + Yarn. Node is available via homebrew (
brew install node). Yarn is activated viacorepack enable yarn.
Running the tests
$ bin/run-tests
This runs the pytest suite followed by an HTTP smoke test that starts a stub server, makes real HTTP requests, and checks the responses.
Smoke test
bin/smoke-test can also be run standalone — useful for checking a server
that is already running:
$ bin/smoke-test # start a temporary stub server, run checks, stop
$ bin/smoke-test --port 9999 # same, but on a custom port
$ bin/smoke-test --no-start # check a server already running on port 8080
Configuration
See $HOME/.ezbeq/ezbeq.yml
The only intended option for override is the port option which sets the port the UI and API is accessible on. This defaults to 8080.
Using a custom catalogue
If catalogueUrl is added to the configuration, e.g.
catalogueUrl: http://localhost:9999
ezbeq will instead load the catalogue from http://localhost:9999/database.json
This provides the ability to run ezbeq against a custom, or locally provided, catalogue.
Configuring Devices
The devices section contains a list of supported device, the format varies by the type of device and each item is a named device with the name subsequently appearing the UI (if multiple devices are listed)
Minidsp
Default values are shown, the only required value is the type field
minidsp:
cmdTimeout: 10
exe: minidsp
ignoreRetcode: false
options: ''
slotChangeDelay: false
type: minidsp
- cmdTime: default timeout in seconds for a command sent to minidsp-rs to complete
- exe: location of the minidsp-rs executable
- ignoreRetcode: if true, errors generated by minidsp-rs will be ignored (for debugging/local testing only)
- options: additional command line switches to pass to minidsp-rs (refer to minidsp-rs docs for details)
- type: minidsp
- slotChangeDelay: if true, the command to change the slot is always sent to minidsp-rs as a separate command. If a positive integer or float, it represents an additional delay (in seconds) that will separate each command.
By default, it is assumed the Minidsp 2x4HD is in use. To use a different model, specify via the device_type option. For example:
minidsp:
cmdTimeout: 10
exe: minidsp
ignoreRetcode: false
options: ''
type: minidsp
device_type: 4x10
In order for the ezbeq ui to update when the device status is updated outside of ezbeq (e.g. using minidsp remote control), additional configuration is required to enable the minidsp rs websocket interface
This requires 2 optional additional values in the configuration
wsDeviceId: 0
wsIp: 127.0.0.1:5380
wsIp is the address of the [http_server] from /etc/minidsp/config.toml
wsDeviceId is the device id provided by minidsp probe, in this example 2 device ids (0 and 1) are available
$ minidsp probe
Found 2x4HD with serial 911111 at ws://localhost/devices/0/ws [hw_id: 10, dsp_version: 100]
Found 2x4HD with serial 911112 at ws://localhost/devices/1/ws [hw_id: 10, dsp_version: 100]
Using, and controlling, multiple devices independently is supported but does require use of the options key in order
to direct commands to the right device. Precise configuration of this option depends on the minidsp-rs setup so is out
of scope of this readme. Typical configuration would involve use of the --tcp option combined with changes to
minidsp.toml as mentioned in the minidsp-rs docs.
For reference, a community provided example configuration guide can be found via avs
Naming Slots
By default, the slots are numbered 1-4 as per the minidsp console.
To override, extend the device configuration with the slotNames key as illustrated
in this example. It is not necessary to list every slot, just those that require an explicit
name.
Minidsp Variants
Device support largely tracks minidsp-rs device support.
BEQ MV adjustments are applied to input peq channels only.
2x4HD
set device_type: 24HD
BEQ filters are written to both input channels.
Flex
configure as per 2x4HD
add slotChangeDelay: true to workaround issues with slow slot changing. If it remains unstable, use
slotChangeDelay: 1.5 (or some other number, experiment to find the smallest value that enables a reliable experience).
Dirac mode (PEQ on output) is only supported at present via a custom configuration.
DDRC-24
set device_type: DDRC24
BEQ filters are written to all output channels.
DDRC-88
set device_type: DDRC88
BEQ filters are written to output channel 3 by default.
Add the sw_channels config key to override this, provide a list of channel indexes (0 based) to which the filters
should be written. For example to write to the last two output channels:
device_type: DDRC88
sw_channels:
- 6
- 7
HTx
set device_type: HTx
If using minidsp-rs 0.1.12
-
BEQ filters are written to output channel 3 by default.
-
Add the
sw_channelsconfig key to override this, provide a list of channel indexes (0 based) to which the filters should be written. For example to write to the last two output channels:device_type: HTx sw_channels:
- 6
- 7
If using a build of minidsp-rs that contains this PR:
-
BEQ filters are written to input channel 3 by default.
-
Add the
channelsconfig key to override this, provide a list of channel indexes (0 based) to which the filters should be written. For example to write to the last two input channels:device_type: HTx channels:
- 6
- 7
4x10
set device_type: 4x10
The limited biquad capacity (5 per channel) means that filters are split across input and output channels and there is no capacity for user filters.
10x10
set device_type: 10x10
The limited biquad capacity (6 per channel) means that filters are split across input and output channels and the last 2 biquads per output channel are left under user control.
To avoid this, use the crossover biquads to hold the remaining beq biquads. This leaves the output PEQ untouched. Set
use_xo to one of the following values to activate this mode:
- all : apply beq to both crossover groups
- 0 (or true) : apply beq to crossover group 0
- 1 : apply beq to crossover group 1
SHD
set device_type: SHD
BEQ filters are written to all output channels.
8x12 CDSP
set device_type: 8x12CDSP
BEQ filters are written to all 6 input channels.
Custom Layouts
This is intended for advanced users only and requires a detailed understanding of the target device's capabilities and configuration.
This option allows for bespoke mapping of beq filters to biquad slots. This requires the user to specify
- the capabilities of the device (channel counts, biquad slots per channel)
- the biquad slots the beq filters should be written to.
10 slots must be reserved for BEQ filters. These slots can be allocated via any combination of input, xo and output but there must be exactly 10 slots allocated.
The main characteristics of the custom layout are defined in the descriptor section of the config. The descriptor is made up of the following keys:
- name: a name for the device, this is only used for display purposes in the UI
- fs: the sample rate at which the device is configured to operate, this is dictated the minidsp plugin.
- routes: must contain 3 entries (input, crossover, output)
- each entry in routes must contain the following keys:
- name: must be input, crossover or output
- biquads: the number of biquads per channel
- channels: a list of channel indexes (0 based) that are part of this route
- slots: a list of slot indexes (0 based) that are allocated to beq filters in this route, these slots will be used in order so the first slot in the list will be used for BEQ filter 0, the second for BEQ filter 1 and so on.
- groups: specified by the crossover route only, all known minidsp devices that support crossover filters have 2 groups.
Only the channels/biquads specified in the descriptor are addressable via the minidsp command loader screen in the UI. In practical terms, this means if a channel is not included in the BEQ config (e.g. you only write to 1 input channel), the command loader will not be able to address the missing channel(s).
Some example configurations are shown below.
- 2x4HD physical device with BEQ filters applied to the 1st input channel only.
accessLogging: false
debugLogging: true
devices:
dsp1:
cmdTimeout: 10
exe: minidsp
options: ''
type: minidsp
descriptor:
name: 2x4
fs: 96000
routes:
- name: input
biquads: 10
channels: [0]
slots: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- name: crossover
biquads: 4
channels: [0, 1, 2, 3]
slots: []
groups: [0, 1]
- name: output
biquads: 10
channels: [0, 1, 2, 3]
slots: []
port: 8080
- 2x4HD physical device with the BEQ filters applied to the 1st 4 slots of both input channels and the 1st 6 slots of every output channel.
accessLogging: false
debugLogging: true
devices:
dsp1:
cmdTimeout: 10
exe: minidsp
options: ''
type: minidsp
descriptor:
name: 2x4
fs: 96000
routes:
- name: input
biquads: 10
channels: [0]
slots: [0, 1, 2, 3]
- name: crossover
biquads: 4
channels: [0, 1, 2, 3]
slots: []
groups: [0, 1]
- name: output
biquads: 10
channels: [0, 1, 2, 3]
slots: [0, 1, 2, 3, 4, 5]
port: 8080
Monolith HTP1
htp1:
ip: 192.168.1.181
channels:
- sub1
autoclear: true
BEQ filters are loaded into the bottom 10 slots of the specified channels only.
- ip: ip address of the HTP1
- channels: list of channels to apply filters to (sub1, sub2 and sub3 are the standard subwoofer channels in the HTP1)
- autoclear: if set to true, BEQ filters will be reset on power state or input change
JRiver Media Center
Media Network must be enabled
jriver:
address: 192.168.1.181:52199
auth:
user: foo
pass: thisismypass
secure: true
channels:
- SW
- C9
- C10
block: 2
- address: the ip and port on which the Media Center media network is listening
- auth is optional, leave this out if MCWS is not secured
- secure is optional, leave this out if SSL is not used
- supported channels are L R C SW SL SR RL RR and C9 upto C32 (if more than 8 channel output is used)
- block is 1 or 2 and refers to the dsp slots Parametric Equalizer and Parametric Equalizer 2 respectively
This information is not validated, it is left to the user to configure the output format on the zone to match the supplied configuration.
Q-Sys
Q-Sys Designer is supported via the QRC protocol
qsys:
ip: 192.168.1.181
port: 1710
timeout_secs: 2
components:
- beq
content_info:
- beq_movie_info:
text.1: title
text.2: genres
text.3: audio_types
text.4: mv_adjust
text.5: overview
text.6: images[0]
text.7: images[1]
type: qsys
Configuration of the audio pipeline in Q-Sys Designer is left as an exercise for the user.
2 alternative implementations are possible.
One uses a IIR Custom Filter component which must be connected to component which provides a text field.
This can be implemented using either a Text Controller or a Custom Control.
This component allows for a mapping of a text field control key to a CatalogueEntry field name.
Two fields have special treatment:
- filters: will be set in a format that can be linked to a IIR Custom Filter and feeds it with the required biquad coefficients.
- images: there can be a variable number of images so each individual image can be specified in a separate field
The alternative approach uses a Parametric Equaliser component which should be configured with:
- at least 10 bands
- q factor
The component name should be supplied in the configuration above.
Note that this format does not support variable Q shelf filters.
CamillaDSP
CamillaDSP v3 is supported via its websocket api which means CamillaDSP must be started with additional options:
-pto specify the port-ato specify the listen address (required if ezbeq runs on a different host to camilladsp)
camilla:
ip: 192.168.1.181
port: 1710
timeout_secs: 2
channels:
- 4
- 7
type: camilladsp
- ip: the ip on which camilladsp is listening
- port: the port on which camilladsp is listening
- channels: a list of channel numbers to which BEQ filters will be appended
On load, the camilladsp configuration will be updated as follows:
- each filter will be added to the
Filterssection in IIR format using one of the Peaking, HighShelf or LowShelf filter types. Filter names will be BEQ_0 to BEQ_9, the number corresponds to the filter index in the loaded BEQ filter. If a filter with the same name already exists, it will be overwritten with the new settings. This means that if you load a different BEQ filter, the existing filters will be updated rather than new filters being added. - each filter will be appended to the Pipeline for the specified
channel, an entry of type
Filterwill be added if not already present for that channel
Note that if the named filter (BEQ_0 for example) is already present in the camilladsp configuration, only the filter parameters will be updated on load or remove. i.e. this enables the user to define where to put the filters in the pipeline rather than always appending to the end of the pipeline.
On unload, the camilladsp configuration will be updated as follows:
- the filters will reset to 0 gain filters in the
Filterssection
User controlled master volume adjustments are supported using the Volume filter if that filter has been configured in the pipeline.
BEQ specific input gain adjustments are supported via the use of a Gain filter which is inserted into the pipeline ahead of the BEQ filters themselves.
Starting ezbeq on bootup
This is optional but recommended, it ensures the app starts automatically whenever the rpi boots up and makes sure it restarts automatically if it ever crashes.
We will achieve this by creating and enabling a systemd service.
- Create a file ezbeq.service in the appropriate location for your distro (e.g.
/etc/systemd/system/for debian)::
[Unit]
Description=ezbeq
After=network.target
[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi
ExecStart=/home/pi/python/ezbeq/bin/ezbeq
Restart=always
RestartSec=1
[Install]
WantedBy=multi-user.target
- enable the service and start it up::
$ sudo systemctl enable ezbeq.service
$ sudo service ezbeq start
$ sudo journalctl -u ezbeq.service
-- Logs begin at Sat 2019-08-17 12:17:02 BST, end at Sun 2019-08-18 21:58:43 BST. --
Aug 18 21:58:36 swoop systemd[1]: Started ezbeq.
- reboot and repeat step 2 to verify the recorder has automatically started
Verifying MiniDSP Response
As noted in the setup guide, minidsp devices do not provide any mechanism to read the currently loaded DSP configuration. This means it is impossible to see exactly how the DSP is configured, it's only possible to measure the resulting response.
From an ezbeq perspective, there are 2 ways to do this
Quick & Crude
- Clear filters
- Open the levels tab
- Start playback of a scene that is known to have content boosted by the beq filter (use the beqcatalogue heatmap to find one)
- Make note of the displayed levels
- Load the filter
- Restart playback of the same scene
- Compare the reported levels
The measured output level should be increased with the filter in place.
Slower but Accurate
- Clear filters
- Switch to USB input
- Connect the minidsp dsp to a PC running REW, configure REW to use the minidsp as both input and output device
- Measure a full bandwidth (2-20000 Hz) sweep (call this A)
- Load a filter (switch connection to the ezbeq host if necessary)
- Measure a full bandwidth (2-20000 Hz) sweep (call this B)
- Use the trace arithmetic
A / Bfunction ( call the result C), the result should look like the inverse of the BEQ filter (i.e. it will go into negative values, it shows the supposed rolloff in the original source that is to be corrected by the BEQ filter) - With C selected, open the EQ window, select your minidsp device as the dsp type and manually input the individual filters in the loaded BEQ
- The predicted response should now be a flat line (i.e. the beq filter has "corrected" this back to flat)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ezbeq-2.8.0a0.tar.gz.
File metadata
- Download URL: ezbeq-2.8.0a0.tar.gz
- Upload date:
- Size: 666.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4e4918eeb05a7e6b670dd828e4f153861eb998249fe32a92521d6d231ed4bbfd
|
|
| MD5 |
be71c622987a1da4ebfd0901b1da2f22
|
|
| BLAKE2b-256 |
6535fa79ec490c8512a07a52250e322c5077a69d24d756fea6fba77a5b421037
|
Provenance
The following attestation bundles were made for ezbeq-2.8.0a0.tar.gz:
Publisher:
create-app.yaml on 3ll3d00d/ezbeq
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ezbeq-2.8.0a0.tar.gz -
Subject digest:
4e4918eeb05a7e6b670dd828e4f153861eb998249fe32a92521d6d231ed4bbfd - Sigstore transparency entry: 1367826855
- Sigstore integration time:
-
Permalink:
3ll3d00d/ezbeq@2edb02c26e8b37b96acd28d0c8b9ebeb2830e0b5 -
Branch / Tag:
refs/tags/2.8.0a0 - Owner: https://github.com/3ll3d00d
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
create-app.yaml@2edb02c26e8b37b96acd28d0c8b9ebeb2830e0b5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ezbeq-2.8.0a0-py3-none-any.whl.
File metadata
- Download URL: ezbeq-2.8.0a0-py3-none-any.whl
- Upload date:
- Size: 674.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ba523a771b1370d15c08879c65073d9e8ea68d5d6d22cfc9c4973e653b7b9984
|
|
| MD5 |
5c60902f17f07835149b0f455331f3c4
|
|
| BLAKE2b-256 |
72ea4e27e18e408433a3e8de4a07f599a9c328e59c65372b9f49f813a19cb834
|
Provenance
The following attestation bundles were made for ezbeq-2.8.0a0-py3-none-any.whl:
Publisher:
create-app.yaml on 3ll3d00d/ezbeq
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ezbeq-2.8.0a0-py3-none-any.whl -
Subject digest:
ba523a771b1370d15c08879c65073d9e8ea68d5d6d22cfc9c4973e653b7b9984 - Sigstore transparency entry: 1367826862
- Sigstore integration time:
-
Permalink:
3ll3d00d/ezbeq@2edb02c26e8b37b96acd28d0c8b9ebeb2830e0b5 -
Branch / Tag:
refs/tags/2.8.0a0 - Owner: https://github.com/3ll3d00d
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
create-app.yaml@2edb02c26e8b37b96acd28d0c8b9ebeb2830e0b5 -
Trigger Event:
push
-
Statement type: