mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
adjusted modem startup and audio tests
This commit is contained in:
parent
a7ef928d0f
commit
722f1ef785
3 changed files with 151 additions and 114 deletions
|
@ -129,42 +129,47 @@ def get_device_index_from_crc(crc, isInput: bool):
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.warning(f"Audio device {crc} not detected ", devices=detected_devices, isInput=isInput)
|
log.warning(f"Audio device {crc} not detected ", devices=detected_devices, isInput=isInput)
|
||||||
|
return [None, None]
|
||||||
|
|
||||||
import sounddevice as sd
|
|
||||||
|
|
||||||
|
|
||||||
def test_audio_devices(input_id: str, output_id: str) -> list:
|
def test_audio_devices(input_id: str, output_id: str) -> list:
|
||||||
result = [False, False]
|
test_result = [False, False]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
device_index = get_device_index_from_crc(input_id, True)
|
result = get_device_index_from_crc(output_id, True)
|
||||||
if device_index is None:
|
if result is None:
|
||||||
|
# in_dev_index, in_dev_name = None, None
|
||||||
raise ValueError("Invalid input device index.")
|
raise ValueError("Invalid input device index.")
|
||||||
|
else:
|
||||||
|
in_dev_index, in_dev_name = result
|
||||||
sd.check_input_settings(
|
sd.check_input_settings(
|
||||||
device=device_index[0],
|
device=in_dev_index,
|
||||||
channels=1,
|
channels=1,
|
||||||
dtype="int16",
|
dtype="int16",
|
||||||
samplerate=48000,
|
samplerate=48000,
|
||||||
)
|
)
|
||||||
result[0] = True
|
test_result[0] = True
|
||||||
except (sd.PortAudioError, ValueError) as e:
|
except (sd.PortAudioError, ValueError) as e:
|
||||||
print("Input device error:", e)
|
log.warning("Input device error:", e=e)
|
||||||
|
test_result[0] = False
|
||||||
try:
|
try:
|
||||||
device_index = get_device_index_from_crc(output_id, False)
|
result = get_device_index_from_crc(input_id, False)
|
||||||
if device_index is None:
|
if result is None:
|
||||||
|
# out_dev_index, out_dev_name = None, None
|
||||||
raise ValueError("Invalid output device index.")
|
raise ValueError("Invalid output device index.")
|
||||||
|
else:
|
||||||
sd.check_output_settings(
|
out_dev_index, out_dev_name = result
|
||||||
device=device_index[0],
|
sd.check_input_settings(
|
||||||
|
device=out_dev_index,
|
||||||
channels=1,
|
channels=1,
|
||||||
dtype="int16",
|
dtype="int16",
|
||||||
samplerate=48000,
|
samplerate=48000,
|
||||||
)
|
)
|
||||||
result[1] = True
|
test_result[1] = True
|
||||||
except (sd.PortAudioError, ValueError) as e:
|
|
||||||
print("Output device error:", e)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
except (sd.PortAudioError, ValueError) as e:
|
||||||
|
log.warning("Output device error:", e=e)
|
||||||
|
test_result[1] = False
|
||||||
|
|
||||||
|
sd._terminate()
|
||||||
|
sd._initialize()
|
||||||
|
return test_result
|
||||||
|
|
101
modem/modem.py
101
modem/modem.py
|
@ -99,8 +99,6 @@ class RF:
|
||||||
# Make sure our resampler will work
|
# Make sure our resampler will work
|
||||||
assert (self.AUDIO_SAMPLE_RATE_RX / self.MODEM_SAMPLE_RATE) == codec2.api.FDMDV_OS_48 # type: ignore
|
assert (self.AUDIO_SAMPLE_RATE_RX / self.MODEM_SAMPLE_RATE) == codec2.api.FDMDV_OS_48 # type: ignore
|
||||||
|
|
||||||
# init codec2 resampler
|
|
||||||
self.resampler = codec2.resampler()
|
|
||||||
|
|
||||||
self.modem_transmit_queue = MODEM_TRANSMIT_QUEUE
|
self.modem_transmit_queue = MODEM_TRANSMIT_QUEUE
|
||||||
self.modem_received_queue = MODEM_RECEIVED_QUEUE
|
self.modem_received_queue = MODEM_RECEIVED_QUEUE
|
||||||
|
@ -117,11 +115,8 @@ class RF:
|
||||||
|
|
||||||
self.fft_queue = fft_queue
|
self.fft_queue = fft_queue
|
||||||
|
|
||||||
self.init_codec2()
|
self.start_modem()
|
||||||
self.init_audio()
|
|
||||||
self.init_rig_control()
|
|
||||||
self.init_decoders()
|
|
||||||
self.init_data_threads()
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------------------------------
|
||||||
def tci_tx_callback(self) -> None:
|
def tci_tx_callback(self) -> None:
|
||||||
|
@ -138,15 +133,64 @@ class RF:
|
||||||
data_out = self.modoutqueue.popleft()
|
data_out = self.modoutqueue.popleft()
|
||||||
self.tci_module.push_audio(data_out)
|
self.tci_module.push_audio(data_out)
|
||||||
|
|
||||||
def init_audio(self):
|
def start_modem(self):
|
||||||
# --------------------------------------------CREATE PORTAUDIO INSTANCE
|
if not TESTMODE and HamlibParam.hamlib_radiocontrol not in ["tci"]:
|
||||||
if not TESTMODE and not HamlibParam.hamlib_radiocontrol in ["tci"]:
|
self.init_audio()
|
||||||
try:
|
|
||||||
(in_dev_index, in_dev_name) = audio.get_device_index_from_crc(
|
|
||||||
self.audio_input_device, True)
|
|
||||||
(out_dev_index, out_dev_name) = audio.get_device_index_from_crc(
|
|
||||||
self.audio_output_device, False)
|
|
||||||
|
|
||||||
|
elif not TESTMODE:
|
||||||
|
self.init_tci()
|
||||||
|
else:
|
||||||
|
self.init_mkfifo()
|
||||||
|
|
||||||
|
# init codec2 instances
|
||||||
|
self.init_codec2()
|
||||||
|
|
||||||
|
# init rig control
|
||||||
|
self.init_rig_control()
|
||||||
|
|
||||||
|
# init decoders
|
||||||
|
self.init_decoders()
|
||||||
|
|
||||||
|
# init decoding threads
|
||||||
|
self.init_data_threads()
|
||||||
|
atexit.register(self.stream.stop)
|
||||||
|
|
||||||
|
def stop_modem(self):
|
||||||
|
try:
|
||||||
|
# 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
|
||||||
|
# self.stream.stop
|
||||||
|
except Exception:
|
||||||
|
self.log.error("[MDM] Error stopping modem", e=err)
|
||||||
|
|
||||||
|
def init_audio(self):
|
||||||
|
try:
|
||||||
|
self.log.info(f"[MDM] init: get audio devices", input_device=self.audio_input_device,
|
||||||
|
output_device=self.audio_output_device)
|
||||||
|
try:
|
||||||
|
result = audio.get_device_index_from_crc(self.audio_input_device, True)
|
||||||
|
if result is None:
|
||||||
|
raise ValueError("Invalid input device")
|
||||||
|
else:
|
||||||
|
in_dev_index, in_dev_name = result
|
||||||
|
|
||||||
|
result = audio.get_device_index_from_crc(self.audio_output_device, False)
|
||||||
|
if result is None:
|
||||||
|
raise ValueError("Invalid output device")
|
||||||
|
else:
|
||||||
|
out_dev_index, out_dev_name = result
|
||||||
|
|
||||||
|
self.log.info(f"[MDM] init: receiving audio from '{in_dev_name}'")
|
||||||
|
self.log.info(f"[MDM] init: transmiting audio on '{out_dev_name}'")
|
||||||
|
self.log.debug("[MDM] init: starting pyaudio callback and decoding threads")
|
||||||
|
|
||||||
|
# init codec2 resampler
|
||||||
|
self.resampler = codec2.resampler()
|
||||||
|
|
||||||
|
# init audio stream
|
||||||
self.stream = sd.RawStream(
|
self.stream = sd.RawStream(
|
||||||
channels=1,
|
channels=1,
|
||||||
dtype="int16",
|
dtype="int16",
|
||||||
|
@ -155,28 +199,18 @@ class RF:
|
||||||
samplerate=self.AUDIO_SAMPLE_RATE_RX,
|
samplerate=self.AUDIO_SAMPLE_RATE_RX,
|
||||||
blocksize=4800,
|
blocksize=4800,
|
||||||
)
|
)
|
||||||
atexit.register(self.stream.stop)
|
|
||||||
self.log.info("[MDM] init: receiving audio from '%s'" % in_dev_name)
|
|
||||||
self.log.info("[MDM] init: transmiting audio on '%s'" % out_dev_name)
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.log.debug("[MDM] init: starting pyaudio callback")
|
|
||||||
self.stream.start()
|
self.stream.start()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
except Exception as audioerr:
|
except Exception as audioerr:
|
||||||
self.log.error("[MDM] init: starting pyaudio callback failed", e=audioerr)
|
self.log.error("[MDM] init: starting pyaudio callback failed", e=audioerr)
|
||||||
|
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
self.log.error("[MDM] init: can't open audio device. Exit", e=err)
|
self.log.warning("[MDM] init: can't open audio device. Stopping modem", e=err)
|
||||||
self.stream.stop
|
self.stop_modem()
|
||||||
self.stream = lambda: None
|
|
||||||
self.stream.active = False
|
|
||||||
|
|
||||||
# let's stop the modem service
|
def init_tci(self):
|
||||||
self.service_queue.put("stop")
|
|
||||||
# simulate audio class active state for reducing cli output
|
|
||||||
|
|
||||||
|
|
||||||
elif not TESTMODE:
|
|
||||||
# placeholder area for processing audio via TCI
|
# placeholder area for processing audio via TCI
|
||||||
# https://github.com/maksimus1210/TCI
|
# https://github.com/maksimus1210/TCI
|
||||||
self.log.warning("[MDM] [TCI] Not yet fully implemented", ip=TCIParam.ip, port=TCIParam.port)
|
self.log.warning("[MDM] [TCI] Not yet fully implemented", ip=TCIParam.ip, port=TCIParam.port)
|
||||||
|
@ -206,9 +240,7 @@ class RF:
|
||||||
daemon=True,
|
daemon=True,
|
||||||
)
|
)
|
||||||
tci_tx_callback_thread.start()
|
tci_tx_callback_thread.start()
|
||||||
|
def init_mkfifo(self):
|
||||||
else:
|
|
||||||
|
|
||||||
class Object:
|
class Object:
|
||||||
"""An object for simulating audio stream"""
|
"""An object for simulating audio stream"""
|
||||||
active = True
|
active = True
|
||||||
|
@ -237,6 +269,7 @@ class RF:
|
||||||
)
|
)
|
||||||
mkfifo_read_callback_thread.start()
|
mkfifo_read_callback_thread.start()
|
||||||
|
|
||||||
|
|
||||||
def tci_rx_callback(self) -> None:
|
def tci_rx_callback(self) -> None:
|
||||||
"""
|
"""
|
||||||
Callback for TCI RX
|
Callback for TCI RX
|
||||||
|
|
|
@ -27,9 +27,8 @@ class SM:
|
||||||
cmd = self.modem_service.get()
|
cmd = self.modem_service.get()
|
||||||
if cmd in ['start'] and not self.modem:
|
if cmd in ['start'] and not self.modem:
|
||||||
audio_test = audio.test_audio_devices(self.config['AUDIO']['rx'], self.config['AUDIO']['tx'])
|
audio_test = audio.test_audio_devices(self.config['AUDIO']['rx'], self.config['AUDIO']['tx'])
|
||||||
print(self.config['AUDIO']['rx'])
|
|
||||||
print(audio_test)
|
print(audio_test)
|
||||||
if False not in audio_test:
|
if False not in audio_test and None not in audio_test:
|
||||||
self.log.info("starting modem....")
|
self.log.info("starting modem....")
|
||||||
self.modem = modem.RF(self.config, self.modem_events, self.modem_fft, self.modem_service)
|
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)
|
self.data_handler = data_handler.DATA(self.config, self.modem_events)
|
||||||
|
|
Loading…
Reference in a new issue