diff --git a/gui/src/store/audioStore.js b/gui/src/store/audioStore.js index 29ae3f02..78b6f556 100644 --- a/gui/src/store/audioStore.js +++ b/gui/src/store/audioStore.js @@ -17,6 +17,8 @@ export const useAudioStore = defineStore("audioStore", () => { function getInputDevices() { var html = ""; + if (inputDevices.value.length > 0){ + for (var key in inputDevices.value) { let selected = ""; @@ -35,20 +37,25 @@ export const useAudioStore = defineStore("audioStore", () => { html += ``; } return html; + } } function getOutputDevices() { var html = ""; - for (var key in outputDevices.value) { - let selected = ""; - if (outputDevices.value[key]["id"] == settings.tx_audio) { - selected = "selected"; - } else { - selected = ""; - } - html += ``; + + if (outputDevices.value.length > 0){ + for (var key in outputDevices.value) { + + let selected = ""; + if (outputDevices.value[key]["id"] == settings.tx_audio) { + selected = "selected"; + } else { + selected = ""; + } + html += ``; + } + return html; } - return html; } return { diff --git a/modem/audio.py b/modem/audio.py index ec06b26e..d7fdbbb1 100644 --- a/modem/audio.py +++ b/modem/audio.py @@ -110,18 +110,59 @@ def fetch_audio_devices(input_devices, output_devices): # index of the device within the list # returns (id, name) def get_device_index_from_crc(crc, isInput: bool): - in_devices = [] - out_devices = [] + try: + in_devices = [] + out_devices = [] - fetch_audio_devices(in_devices, out_devices) + fetch_audio_devices(in_devices, out_devices) - if isInput: - detected_devices = in_devices - else: - detected_devices = out_devices + if isInput: + detected_devices = in_devices + else: + detected_devices = out_devices - for i, dev in enumerate(detected_devices): - if dev['id'] == crc: - return (i, dev['name']) + for i, dev in enumerate(detected_devices): + if dev['id'] == crc: + return (i, dev['name']) - raise Exception(f"Input: {isInput} | Audio device {crc} not detected | Devices: {detected_devices}") + except Exception as e: + log.warning(f"Audio device {crc} not detected ", devices=detected_devices, isInput=isInput) + + +import sounddevice as sd + + +def test_audio_devices(input_id: str, output_id: str) -> list: + result = [False, False] + + try: + device_index = get_device_index_from_crc(input_id, True) + if device_index is None: + raise ValueError("Invalid input device index.") + + sd.check_input_settings( + device=device_index[0], + channels=1, + dtype="int16", + samplerate=48000, + ) + result[0] = True + except (sd.PortAudioError, ValueError) as e: + print("Input device error:", e) + + try: + device_index = get_device_index_from_crc(output_id, False) + if device_index is None: + raise ValueError("Invalid output device index.") + + sd.check_output_settings( + device=device_index[0], + channels=1, + dtype="int16", + samplerate=48000, + ) + result[1] = True + except (sd.PortAudioError, ValueError) as e: + print("Output device error:", e) + + return result diff --git a/modem/modem.py b/modem/modem.py index 71ba82bd..06359f2d 100644 --- a/modem/modem.py +++ b/modem/modem.py @@ -161,18 +161,20 @@ class RF: try: self.log.debug("[MDM] init: starting pyaudio callback") - # self.audio_stream.start_stream( self.stream.start() except Exception as audioerr: self.log.error("[MDM] init: starting pyaudio callback failed", e=audioerr) except Exception as err: self.log.error("[MDM] init: can't open audio device. Exit", e=err) + self.stream.stop + self.stream = lambda: None + self.stream.active = False + # let's stop the modem service self.service_queue.put("stop") # simulate audio class active state for reducing cli output - self.stream = lambda: None - self.stream.active = False + elif not TESTMODE: # placeholder area for processing audio via TCI diff --git a/modem/service_manager.py b/modem/service_manager.py index 52273878..661125fd 100644 --- a/modem/service_manager.py +++ b/modem/service_manager.py @@ -2,6 +2,7 @@ import threading import data_handler import modem import structlog +import audio class SM: def __init__(self, app): @@ -15,6 +16,7 @@ class SM: self.modem_fft = app.modem_fft self.modem_service = app.modem_service + runner_thread = threading.Thread( target=self.runner, name="runner thread", daemon=True ) @@ -24,13 +26,20 @@ class SM: while True: cmd = self.modem_service.get() if cmd in ['start'] and not self.modem: - self.log.info("starting modem....") - self.modem = modem.RF(self.config, self.modem_events, self.modem_fft, self.modem_service) - self.data_handler = data_handler.DATA(self.config, self.modem_events) + audio_test = audio.test_audio_devices(self.config['AUDIO']['rx'], self.config['AUDIO']['tx']) + print(self.config['AUDIO']['rx']) + print(audio_test) + if False not in audio_test: + self.log.info("starting modem....") + self.modem = modem.RF(self.config, self.modem_events, self.modem_fft, self.modem_service) + self.data_handler = data_handler.DATA(self.config, self.modem_events) + else: + self.log.warning("starting modem failed", input_test=audio_test[0], output_test=audio_test[1]) + else: - print("--------------------------------------") - self.log.info("stopping modem....") - del self.modem - del self.data_handler - self.modem = False - self.data_handler = False + print("--------------------------------------") + self.log.info("stopping modem....") + del self.modem + del self.data_handler + self.modem = False + self.data_handler = False