{"id":13430326,"url":"https://github.com/marcoevang/camilladsp-setrate","last_synced_at":"2025-03-16T05:30:41.855Z","repository":{"id":193033802,"uuid":"687351537","full_name":"marcoevang/camilladsp-setrate","owner":"marcoevang","description":"Automatic sample rate switcher for CamillaDSP","archived":false,"fork":false,"pushed_at":"2024-08-07T09:05:56.000Z","size":242,"stargazers_count":8,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-10-27T08:39:32.352Z","etag":null,"topics":["alsa","camilladsp","usb-gadget","websocket"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marcoevang.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-05T07:21:52.000Z","updated_at":"2024-09-24T02:03:00.000Z","dependencies_parsed_at":"2023-09-23T01:59:15.708Z","dependency_job_id":"e08b0fac-31d6-4727-bc8b-4162f0c808ff","html_url":"https://github.com/marcoevang/camilladsp-setrate","commit_stats":null,"previous_names":["marcoevang/camilladsp-setrate"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcoevang%2Fcamilladsp-setrate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcoevang%2Fcamilladsp-setrate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcoevang%2Fcamilladsp-setrate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcoevang%2Fcamilladsp-setrate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcoevang","download_url":"https://codeload.github.com/marcoevang/camilladsp-setrate/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243830912,"owners_count":20354848,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alsa","camilladsp","usb-gadget","websocket"],"created_at":"2024-07-31T02:00:52.249Z","updated_at":"2025-03-16T05:30:41.544Z","avatar_url":"https://github.com/marcoevang.png","language":"C","funding_links":[],"categories":["C"],"sub_categories":[],"readme":"# **camilladsp-setrate  version 2.2.1**\n\n## Automatic sample rate switcher for [CamillaDSP](https://github.com/HEnquist/camilladsp)\n\nThis tool provides two useful services:\n\n1. **Automatic updating of the sample rate when that of the audio stream being captured changes.**\n\n*CamillaDSP* works at a fixed sample rate. However, sample rate may change during a session, e.g. when listening to a playlist. In this case, if the incoming sample rate does not match the one *CamillaDSP* is using for processing,  playback will not be correct.  \n\n***camilladsp-setrate*** solves this problem by changing *CamillaDSP*'s configuration on-the-fly to match the sample rate of the captured audio.  \n\nThis tool may also allow resampling to a fixed playback rate and upsampling by a fixed factor. Details are provided below in the \"Running\" section (see `--capture` flag and `--uppsampling` option).  \n\n2. **Automatic reloading of a valid configuration whenever the playback device becomes available.**    \n\n*CamillaDSP* as it must be, stops working when the playback device is no longer available. This happens, for example, when your DAC is switched off or you switch to another input. Unfortunately, *CamillaDSP* remains blocked even when the playback device becomes available again. \n\n***camilladsp-setrate*** reloads a valid configuration as soon as the playback device reappears, thus unlocking _CamillaDSP_.   \n\n## Foreword\n\nIn order for ***camilladsp-setrate*** to work the audio capture device must provide the necessary information about the sample rate change. ***camilladsp-setrate*** is designed to work with a *USB gadget* capture device, which is one of the few that fulfils this requirement.  \nThe term *USB Gadget* refers to a device that uses a USB port and its control hardware to act as a peripheral (the term 'gadget' here is to be understood as 'peripheral'). This type of device was chosen for this project because it is available for cheap on certain types of Raspberry Pi boards after proper software configuration (on this subject, see this [thread](https://www.audiosciencereview.com/forum/index.php?threads/using-a-raspberry-pi-as-equaliser-in-between-an-usb-source-ipad-and-usb-dac.25414/) and this [guide](https://www.diyaudio.com/community/threads/linux-usb-audio-gadget-rpi4-otg.342070/post-7240169)).\n\nIt is not excluded, however, that this tool may work with other capture devices, but it is necessary to check carefully that all requirements are met. Feel free to do your own experiments.\n\n## Context\nI have tested **_camilladsp-setrate_**  on my Raspberry Pi 4 with its USB-C port configured in gadget mode for audio capture. I expect it may also work on other boards supporting *USB gadget* mode, such as Raspberry Pi Zero, Raspberry Pi 3A+, Raspberry Pi CM4 and BeagleBones.  \n\nThis project was developed on DietPi 64-bit. It should also work on other Debian-based Linux distributions and arguably on other Linux flavors as well.   The software is coded in C language with use of the *alsa* and *libwebsockets* C API's.\n\nThe DSP unlocking functionality has only been tested with USB playback devices.\n\n## Requirements\n\n- Linux operating system\n- C language development environment\n- Alsa sound system\n- Alsa C library\n- Libwebsockets C library\n- [*CamillaDSP*](https://github.com/HEnquist/camilladsp) up and running\n- A capture device providing information about sample rate change\n\nFor ***camilladsp-setrate*** to work, \u003cins\u003ethe capture device driver must feature an *alsa control* function informing when the sample rate changes and what its value is\u003c/ins\u003e. You can check if your capture device meets this requirement by issuing the following command:\n\n`amixer -D \u003cyour device\u003e controls`\n\nIf the device driver sports the required *alsa control*, the above command should list a control whose name contains the word *'rate'* (or something like that). In any case, please check the documentation of your device.\n\nFor example, in the case of a *USB gadget*, the command:\n\n`amixer -D hw:UAC2Gadget controls`\n\nproduces this output:\n\n`numid=2,iface=MIXER,name='PCM Capture Switch'`  \n`numid=3,iface=MIXER,name='PCM Capture Volume'`  \n`numid=1,iface=PCM,name='Capture Pitch 1000000'`  \n`numid=4,iface=PCM,name='Capture Rate'`  \n\nNOTE that since the *USB gadget* device acts as a peripheral, it must be connected to a USB device that acts as a host. Thus, \u003cins\u003eyour audio source must be equipped with a host USB port \u003c/ins\u003e (usually a female USB Type A).\n\n## How it works\n\nTo achieve sample rate switching ***camilladsp-setrate*** subscribes to alsa events, reads the value of the sample rate when it changes, reads the current configuration of *CamillaDSP* and overwrites the *samplerate* and/or *capture_samplerate* parameters. To this end, some commands of the [CamillaDSP websocket interface]( https://github.com/HEnquist/camilladsp/blob/master/websocket.md) are issued. The command `GetConfig` provides the current configuration; if the current configuration is not valid, the `GetPreviousConfig` command is issued. Then the _samplerate_ and/or *capture_samplerate* values in the current configuration of *CamillaDSP* are replaced with the new ones. The _chunksize_ parameter value is as well updated as a function of the sample rate, calculating the value suggested in the section \"Devices\" of the [*CamillaDSP* home page](https://github.com/HEnquist/camilladsp).  Finally, the updated configuration is flushed to the DSP with the command `SetConfig.`\n\nTo achieve DSP unlocking when the playback device reappears, ***camilladsp-setrate*** goes through the same procedure described above for sample rate. In this case, however, the procedure is initiated by a signal sent by the operating system to the _**camilladsp-setrate**_ process when the playback device is detected. This is obtained by means of an `udev rule` (see the `88-DAC.rules` file).\n\n## Building\n\n1. Install *git*, the C development environment and the required libraries:\n\n```\nsudo apt update  \nsudo apt install git build-essential libasound2-dev libwebsockets-dev\n```\n\n2. Clone the *git* repository and move to the home of the project:\n```\ngit clone https://github.com/marcoevang/camilladsp-setrate\ncd camilladsp-setrate\n```\n3. Build the executable file:\n\n```\nmake\n```\nInstructions for installing the required packages are valid on debian-based Linux distributions. On other Linux flavors (e.g. Fedora) the package manager might differ, and the name of the libraries might also differ slightly.   \n\nIf you use this tool on a Raspberry Pi 4 64-bit OS, you can probably directly use the ***camilladsp-setrate*** executable file provided under the *bin* folder of this repository. In that case, skip steps 1. and 3., complete the Install phase and then check if the provided executable file works.  \n\n## Installing\n\n1. Copy the executable file to `/usr/local/bin`:\n\n```\nmake install\n```\nIf the executable file is already running, stop it before issuing *make install*.\n\n2. Edit the file `camilladsp-setrate.service` and replace the values of the parameters _User_ and _Group_ with yours. You might want to make other changes, e.g. the options on the command line of the _ExecStart_ parameter (see below for a description of command options and flags).\n\n3. Copy the file `camilladsp-setrate.service` to the system services folder and enable that service:\n\n```\nsudo cp camilladsp-setrate.service /etc/systemd/system\nsudo systemctl enable camilladsp-setrate\n```\n4. Make sure the user that runs the service (e.g. dietpi in the example .service file) is a member of the *audio* group, otherwise the started process cannot access the audio devices. If it is not, add it to the *audio* group:\n\n```\nsudo usermod -a \u003cuser running the camilladsp-setrate service\u003e -G audio\n```\n\n   Example:\n\n```\nsudo usermod -a dietpi -G audio\n```\n\n\n5. Edit the file `85-DAC.rules` and replace the values of the parameters `ID_VENDOR_ID` and `ID_MODEL_ID` with those of your USB DAC.\n   You can obtain those values with the following command :\n\n```\nusb-devices\n```\n(_Vendor_ corresponds to `ID_VENDOR_ID` and _ProdID_ corresponds to `ID_MODEL_ID`)  \n\n6. Copy the file `85-DAC.rules` to the `udev` rules folder:\n\n```\nsudo cp 85-DAC.rules /etc/udev/rules.d\n```\n7. Reboot the system:\n\n```\nsudo shutdown -r now\n```\n## Running\nUSAGE: \n\n```\n  camilladsp-setrate [FLAGS] [OPTIONS]\n```\nFLAGS:\n\n- `-c, --capture`          Update *capture_samplerate* instead of *samplerate*\n- `-t, --timestamp`      Causes a timestamp to be prepended to log messages\n- `-s, --syslog`            Redirect log messages to _syslog_ (if this flag is omitted, messages are sent to standard error)\n- `-v, --version`          Print software version\n- `-h, --help`                Print help\n\nOPTIONS:\n\n- `-d, --device \u003ccapture device\u003e`    Set alsa capture device [default: hw:UAC2Gadget]\n- `-a, --address \u003caddress\u003e       `                Set server IP address [default: localhost]\n- `-p, --port \u003cport\u003e`                            Set server IP port [default: 1234]\n- `-u, --upsampling \u003cfactor\u003e`            Set upsampling factor [default: 1]\n- `-l, --loglevel \u003clog level\u003e`          Set log level [values: err, warn, user, notice, off. Default: err]\n\n\n\nAll options require an argument. If an option is omitted, the default value is applied. \n\nArguments must not be specified for flags.\n\nThe `--capture` flag and `--upsampling` options change the way ***camilladsp-setrate*** processes the *samplerate*, *chunksize* and *capture_samplerate* parameters, as follows:\n\n- [ ] if `--capture` and `--upsampling` are both omitted, *samplerate* is set to that of the audio being captured and *chunksize* is updated as a function of *samplerate*. The *capture_samplerate* parameter is left unchanged.  \n\n  \u003cins\u003eIn this case resampling shall be disabled and *capture_samplerate* shall not be set in the configuration file\u003c/ins\u003e.\n\n- [ ] if `--capture` is used, *capture_samplerate* is set to that of the audio being captured. The *samplerate* and *chunksize* parameters are left unchanged. This flag should be used to achieve resampling of the captured audio to the fixed playback rate set by the *samplerate* parameter in the configuration file.  \n\n  \u003cins\u003eIn this case resampling shall be enabled in the configuration file\u003c/ins\u003e.\n\n- [ ] If `--upsampling` is used, *capture_samplerate* is set to that of the audio being captured and *samplerate* is set equal to the input rate multiplied by the specified upsampling factor (the latter must be positive). The *chunksize* parameter is as well updated as a function of *samplerate*. This option should be used to obtain in playback upsampled audio by a constant factor. For example, this flag can be used to instruct CamillaDSP to perform 2X or 4X oversampling regardless of the sample rate of the incoming audio. Make sure your playback device supports the resulting upsampled rate. \n\n  \u003cins\u003eIn this case resampling shall be enabled in the configuration file\u003c/ins\u003e.\n\nNote that `--capture` and `--upsampling` cannot be used at the same time.\n\nIf the `--device` option is used, the name of the capture device shall be given in the format required by the`arecord`command. \n\nThe `--loglevel` option sets the following logging levels: \n\n- [ ] ​    `err`: only errors are logged\n- [ ] ​    `warn`: errors and warnings are logged\n\n- [ ] ​    `user`: errors, warnings and key events are logged, such as sample rate change\n- [ ] ​    `notice`: errors, warnings, key events and debugging information are logged.\n\n***camilladsp-setrate*** should start as a service at boot time. To this end, the `camilladsp-setrate.service` file is provided. You can edit that file to set the desired options.  \nAfter modifications to the service file you have to make the `udev` daemon reload the rules:\n\n```\nsudo systemctl daemon-reload\nsudo systemctl restart camilladsp-setrate\n```\nor reboot the system.\n\nI strongly recommend not running ***camilladsp-setrate*** as *super-user*.\n\n## Final notes\n- This tool is useful if the audio player and *CamillaDSP* run on distinct computers. In case they run on the same computer, I recommend using the [alsa_cdsp](https://github.com/scripple/alsa_cdsp) plugin instead to get automatic sample rate switching.\n- Starting with version 2.0.0 the sample rate change process is driven by a finite-state machine whose diagram is provided under the *doc* folder.  You can find tons of information about this technique on the Internet (start [here](https://www.spiceworks.com/tech/tech-general/articles/what-is-fsm/) and [here](https://broken-bytes.medium.com/using-state-machines-in-software-development-b784f6d37b34))  \n- Starting with version 2.1.0 the flags `--err`, `--warn`, `--user` and `--notice` have been removed as unnecessary. The `--loglevel` option can be used instead.\n\n\n- Capture devices other than *USB gadgets* may not provide the necessary information on sample rate change.\n- If using a capture device other than the *USB gadget*, you may need to change the `ALSA_CONTROL_NAME` constant value in the `setrate.h` file according to the name of the alsa control.\n- ***camilladsp-setrate*** can handle *CamillaDSP* configuration files of a maximum size of about 16 KBytes. If the size of your configuration file is larger than this, you need to increase the size of the message buffer by updating the `MAX_PAYLOAD_SIZE` constant value in the `setrate.h` file.\n\n\n- ***camilladsp-setrate***  works with all released versions of CamillaDSP.\n- Comments in the source code will, hopefully, help to understand the what and the how.  \n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcoevang%2Fcamilladsp-setrate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcoevang%2Fcamilladsp-setrate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcoevang%2Fcamilladsp-setrate/lists"}