From 75b04cba9433614bd3cff1c9cfb2026e10fc6d21 Mon Sep 17 00:00:00 2001 From: HEnquist Date: Sat, 28 Nov 2020 23:07:23 +0100 Subject: [PATCH 1/4] Changes for camilladsp 0.5 --- camilladsp/camilladsp.py | 49 ++++++++++++++++++++++++++++++++++++++-- setup.py | 2 +- tests/test_camillaws.py | 18 +++++++++++++++ 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/camilladsp/camilladsp.py b/camilladsp/camilladsp.py index 02118ce..f1a3b9d 100644 --- a/camilladsp/camilladsp.py +++ b/camilladsp/camilladsp.py @@ -4,7 +4,7 @@ import math from threading import Lock -VERSION = (0, 4, 1) +VERSION = (0, 5, 0) STANDARD_RATES = [ 8000, @@ -48,7 +48,7 @@ def __init__(self, host, port): def _query(self, command, arg=None): if self._ws is not None: - if arg: + if arg is not None: query = json.dumps({command: arg}) else: query = json.dumps(command) @@ -152,6 +152,51 @@ def get_signal_range_dB(self): range_dB = -1000 return range_dB + def get_capture_signal_rms(self): + """ + Get capture signal level rms in dB. Full scale is 0 dB. + """ + sigrms = self._query("GetCaptureSignalRms") + sigrms = [float(val) for val in sigrms] + return sigrms + + def get_playback_signal_rms(self): + """ + Get playback signal level rms in dB. Full scale is 0 dB. + """ + sigrms = self._query("GetPlaybackSignalRms") + sigrms = [float(val) for val in sigrms] + return sigrms + + def get_capture_signal_peak(self): + """ + Get capture signal level peak in dB. Full scale is 0 dB. + """ + sigpeak = self._query("GetCaptureSignalPeak") + sigpeak = [float(val) for val in sigpeak] + return sigpeak + + def get_playback_signal_peak(self): + """ + Get playback signal level peak in dB. Full scale is 0 dB. + """ + sigpeak = self._query("GetPlaybackSignalPeak") + sigpeak = [float(val) for val in sigpeak] + return sigpeak + + def get_volume(self): + """ + Get current volume setting in dB. + """ + vol = self._query("GetVolume") + return float(vol) + + def set_volume(self, value): + """ + Set volume in dB. + """ + self._query("SetVolume", arg=value) + def get_capture_rate_raw(self): """ Get current capture rate, raw value. diff --git a/setup.py b/setup.py index 80c9ba2..3118dad 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="camilladsp", - version="0.4.1", + version="0.5.0", author="Henrik Enquist", author_email="henrik.enquist@gmail.com", description="A library for comminucating with CamillaDSP", diff --git a/tests/test_camillaws.py b/tests/test_camillaws.py index b5b819b..1c0abb6 100644 --- a/tests/test_camillaws.py +++ b/tests/test_camillaws.py @@ -13,6 +13,7 @@ def __init__(self): '"GetState"': json.dumps({"GetState": {"result": "Ok", "value": "IDLE"}}), '"GetVersion"': json.dumps({"GetVersion": {"result": "Ok", "value": "0.3.2"}}), '"GetSignalRange"': json.dumps({"GetSignalRange": {"result": "Ok", "value": "0.2"}}), + '"GetCaptureSignalRms"': json.dumps({"GetCaptureSignalRms": {"result": "Ok", "value": [0.1, 0.2]}}), '"GetCaptureRate"': json.dumps({"GetCaptureRate": {"result": "Ok", "value": "88250"}}), '"GetErrorValue"': json.dumps({"GetErrorValue": {"result": "Error", "value": "badstuff"}}), '"GetError"': json.dumps({"GetError": {"result": "Error"}}), @@ -94,6 +95,10 @@ def test_signal_range(camilla_mockws): camilla_mockws.connect() assert camilla_mockws.get_signal_range() == 0.2 +def test_signal_rms(camilla_mockws): + camilla_mockws.connect() + assert camilla_mockws.get_capture_signal_rms() == [0.1, 0.2] + def test_signal_range_dB(camilla_mockws): camilla_mockws.connect() assert camilla_mockws.get_signal_range_dB() == -20 @@ -168,6 +173,19 @@ def test_queries(camilla_mockquery): camilla_mockquery._query.assert_called_with('GetBufferLevel') camilla_mockquery.get_clipped_samples() camilla_mockquery._query.assert_called_with('GetClippedSamples') + camilla_mockquery.get_volume() + camilla_mockquery._query.assert_called_with('GetVolume') + camilla_mockquery.set_volume(-25.0) + camilla_mockquery._query.assert_called_with('SetVolume', arg=-25.0) + camilla_mockquery.get_capture_signal_rms() + camilla_mockquery._query.assert_called_with('GetCaptureSignalRms') + camilla_mockquery.get_capture_signal_peak() + camilla_mockquery._query.assert_called_with('GetCaptureSignalPeak') + camilla_mockquery.get_playback_signal_rms() + camilla_mockquery._query.assert_called_with('GetPlaybackSignalRms') + camilla_mockquery.get_playback_signal_peak() + camilla_mockquery._query.assert_called_with('GetPlaybackSignalPeak') + def test_queries_adv(camilla_mockquery_yaml): camilla_mockquery_yaml.read_config_file("some/path") From 9357ddcc237fabdc57a51453bfffc9ddddfeb023 Mon Sep 17 00:00:00 2001 From: HEnquist Date: Sun, 29 Nov 2020 20:02:39 +0100 Subject: [PATCH 2/4] Update readme with new commands --- README.md | 6 ++++++ camilladsp/camilladsp.py | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d420996..9fac4f7 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,12 @@ The CamillaConnection class provides the following methods: |`get_state()` | Get current processing state. Returns one of "RUNNING", "PAUSED" or "INACTIVE".| |`get_signal_range()` | Get current signal range.| |`get_signal_range_dB()` | Get current signal range in dB.| +|`get_capture_signal_rms()` | Get capture signal level rms in dB. Full scale is 0 dB. Returns a list with one element per channel.| +|`get_playback_signal_rms()` | Get playback signal level rms in dB. Full scale is 0 dB. Returns a list with one element per channel.| +|`get_capture_signal_peak()` | Get capture signal level peak in dB. Full scale is 0 dB. Returns a list with one element per channel.| +|`get_playback_signal_peak()` | Get playback signal level peak in dB. Full scale is 0 dB. Returns a list with one element per channel.| +|`get_volume()` | Get current volume setting in dB.| +|`set_volume(value)` | Set volume in dB.| |`get_capture_rate_raw()` | Get current capture rate, raw value.| |`get_capture_rate()` | Get current capture rate. Returns the nearest common value.| |`get_update_interval()` | Get current update interval in ms.| diff --git a/camilladsp/camilladsp.py b/camilladsp/camilladsp.py index f1a3b9d..cdcb6a5 100644 --- a/camilladsp/camilladsp.py +++ b/camilladsp/camilladsp.py @@ -154,7 +154,7 @@ def get_signal_range_dB(self): def get_capture_signal_rms(self): """ - Get capture signal level rms in dB. Full scale is 0 dB. + Get capture signal level rms in dB. Full scale is 0 dB. Returns a list with one element per channel. """ sigrms = self._query("GetCaptureSignalRms") sigrms = [float(val) for val in sigrms] @@ -162,7 +162,7 @@ def get_capture_signal_rms(self): def get_playback_signal_rms(self): """ - Get playback signal level rms in dB. Full scale is 0 dB. + Get playback signal level rms in dB. Full scale is 0 dB. Returns a list with one element per channel. """ sigrms = self._query("GetPlaybackSignalRms") sigrms = [float(val) for val in sigrms] @@ -170,7 +170,7 @@ def get_playback_signal_rms(self): def get_capture_signal_peak(self): """ - Get capture signal level peak in dB. Full scale is 0 dB. + Get capture signal level peak in dB. Full scale is 0 dB. Returns a list with one element per channel. """ sigpeak = self._query("GetCaptureSignalPeak") sigpeak = [float(val) for val in sigpeak] @@ -178,7 +178,7 @@ def get_capture_signal_peak(self): def get_playback_signal_peak(self): """ - Get playback signal level peak in dB. Full scale is 0 dB. + Get playback signal level peak in dB. Full scale is 0 dB. Returns a list with one element per channel. """ sigpeak = self._query("GetPlaybackSignalPeak") sigpeak = [float(val) for val in sigpeak] From 8e15a396af519316133211cb5dab72165f6edbba Mon Sep 17 00:00:00 2001 From: HEnquist Date: Sun, 29 Nov 2020 23:08:29 +0100 Subject: [PATCH 3/4] Fix typos --- README.md | 2 +- camilladsp/camilladsp.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9fac4f7..b2c497e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # pyCamillaDSP Companion Python library for CamillaDSP. -Works with CamillaDSP version 0.4.0 and up. +Works with CamillaDSP version 0.5.0 and up. Download the library, either by `git clone` or by downloading a zip file of the code. Then unpack the files, go to the folder containing the `setup.py` file and run: ```sh diff --git a/camilladsp/camilladsp.py b/camilladsp/camilladsp.py index cdcb6a5..08a90f8 100644 --- a/camilladsp/camilladsp.py +++ b/camilladsp/camilladsp.py @@ -195,7 +195,7 @@ def set_volume(self, value): """ Set volume in dB. """ - self._query("SetVolume", arg=value) + self._query("SetVolume", arg=float(value)) def get_capture_rate_raw(self): """ From d3b83bf15dd3a9021b3eceff50ce80bc4c3eb0f4 Mon Sep 17 00:00:00 2001 From: HEnquist Date: Wed, 9 Dec 2020 22:35:16 +0100 Subject: [PATCH 4/4] Update readme, add more examples --- README.md | 60 +++++++++++++++++++++++-------- examples/read_rms/read_rms.py | 22 ++++++++++++ examples/set_volume/set_volume.py | 24 +++++++++++++ 3 files changed, 91 insertions(+), 15 deletions(-) create mode 100644 examples/read_rms/read_rms.py create mode 100644 examples/set_volume/set_volume.py diff --git a/README.md b/README.md index b2c497e..a494636 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,9 @@ except IOError as e: ## Methods -The CamillaConnection class provides the following methods: +The CamillaConnection class provides the following methods + +### Basics | Method | Description | |----------|---------------| @@ -88,21 +90,13 @@ The CamillaConnection class provides the following methods: |`get_version()` | Read CamillaDSP version, returns a tuple with 3 elements| |`get_library_version()` | Read pyCamillaDSP version, returns a tuple with 3 elements| |`get_state()` | Get current processing state. Returns one of "RUNNING", "PAUSED" or "INACTIVE".| -|`get_signal_range()` | Get current signal range.| -|`get_signal_range_dB()` | Get current signal range in dB.| -|`get_capture_signal_rms()` | Get capture signal level rms in dB. Full scale is 0 dB. Returns a list with one element per channel.| -|`get_playback_signal_rms()` | Get playback signal level rms in dB. Full scale is 0 dB. Returns a list with one element per channel.| -|`get_capture_signal_peak()` | Get capture signal level peak in dB. Full scale is 0 dB. Returns a list with one element per channel.| -|`get_playback_signal_peak()` | Get playback signal level peak in dB. Full scale is 0 dB. Returns a list with one element per channel.| -|`get_volume()` | Get current volume setting in dB.| -|`set_volume(value)` | Set volume in dB.| -|`get_capture_rate_raw()` | Get current capture rate, raw value.| -|`get_capture_rate()` | Get current capture rate. Returns the nearest common value.| -|`get_update_interval()` | Get current update interval in ms.| -|`set_update_interval(value)` | Set current update interval in ms.| -|`get_rate_adjust()` | Get current value for rate adjust.| |`stop()` | Stop processing and wait for new config if wait mode is active, else exit. | |`exit()` | Stop processing and exit.| + + +### Config handling +| Method | Description | +|----------|---------------| |`reload()` | Reload config from disk.| |`get_config_name()` | Get path to current config file.| |`set_config_name(value)` | Set path to config file.| @@ -114,10 +108,46 @@ The CamillaConnection class provides the following methods: |`read_config_file(path)` | Read a config file from `path`. Returns the loaded config with all optional fields filled with defaults. Raises a CamillaError on errors.| |`read_config(config)` | Read a config from yaml string and return the contents as an obect, with defaults filled out with their default values.| +### Reading status +| Method | Description | +|----------|---------------| +|`get_signal_range()` | Get current signal range.| +|`get_signal_range_dB()` | Get current signal range in dB.| +|`get_capture_signal_rms()` | Get capture signal level rms in dB. Full scale is 0 dB. Returns a list with one element per channel.| +|`get_playback_signal_rms()` | Get playback signal level rms in dB. Full scale is 0 dB. Returns a list with one element per channel.| +|`get_capture_signal_peak()` | Get capture signal level peak in dB. Full scale is 0 dB. Returns a list with one element per channel.| +|`get_playback_signal_peak()` | Get playback signal level peak in dB. Full scale is 0 dB. Returns a list with one element per channel.| +|`get_capture_rate_raw()` | Get current capture rate, raw value.| +|`get_capture_rate()` | Get current capture rate. Returns the nearest common value.| +|`get_update_interval()` | Get current update interval in ms.| +|`set_update_interval(value)` | Set current update interval in ms.| +|`get_rate_adjust()` | Get current value for rate adjust.| +|`get_buffer_level()` | Get current buffer level of the playback device.| +|`get_clipped_samples()` | Get number of clipped samples since the config was loaded.| + +### Volume control +| Method | Description | +|----------|---------------| +|`get_volume()` | Get current volume setting in dB.| +|`set_volume(value)` | Set volume in dB.| # Included examples: -play_wav: Play a wav file. This example reads a configuration from a file, updates the capture device fto point at a given .wav file, and sends this modified config to CamillaDSP. +## read_rms +Read the playback signal level continuously and print in the terminal, until stopped by Ctrl+c. +```sh +python read_rms.py 1234 +``` + +## set_volume +Set the volume control to a new value. First argument is websocket port, second is new volume in dB. +For this to work, CamillaDSP must be running a configuration that has Volume filters in the pipeline for every channel. +```sh +python set_volume.py 1234 -12.3 +``` + +## play_wav +Play a wav file. This example reads a configuration from a file, updates the capture device fto point at a given .wav file, and sends this modified config to CamillaDSP. Usage example: ```sh python play_wav.py 1234 /path/to/wavtest.yml /path/to/music.wav diff --git a/examples/read_rms/read_rms.py b/examples/read_rms/read_rms.py new file mode 100644 index 0000000..d7d5a4e --- /dev/null +++ b/examples/read_rms/read_rms.py @@ -0,0 +1,22 @@ +# play wav +from camilladsp import CamillaConnection +import sys +import time + +try: + port = int(sys.argv[1]) +except: + print("Usage: start CamillaDSP with the socketserver enabled:") + print("> camilladsp -p4321 yourconfig.yml") + print("Then read the signal level") + print("> python read_rms.py 4321") + sys.exit() + +cdsp = CamillaConnection("127.0.0.1", port) +cdsp.connect() + +print("Reading playback signal RMS, press Ctrl+c to stop") +while True: + print(cdsp.get_playback_signal_rms()) + time.sleep(1) + diff --git a/examples/set_volume/set_volume.py b/examples/set_volume/set_volume.py new file mode 100644 index 0000000..4e39e95 --- /dev/null +++ b/examples/set_volume/set_volume.py @@ -0,0 +1,24 @@ +# play wav +from camilladsp import CamillaConnection +import sys +import time + +try: + port = int(sys.argv[1]) + new_vol = float(sys.argv[2]) +except: + print("Usage: Make sure that your pipeline includes Volume filters for each channel.") + print("Then start CamillaDSP with the websocket server enabled:") + print("> camilladsp -p4321 yourconfig.yml") + print("Then set the volume") + print("> python read_rms.py 4321 -12.3") + sys.exit() + +cdsp = CamillaConnection("127.0.0.1", port) +cdsp.connect() + +current_vol = cdsp.get_volume() +print(f"Current volume: {current_vol} dB") +print(f"Changing volume to: {new_vol} dB") +cdsp.set_volume(new_vol) +