mirror of
https://github.com/RFnexus/FreeDVInterface.git
synced 2025-12-22 08:17:08 +00:00
Add selecting input / output audio device by name
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
.idea
|
||||||
|
.idea/*
|
||||||
@@ -15,6 +15,7 @@ MODE_DATAC1 = 10
|
|||||||
MODE_DATAC3 = 12
|
MODE_DATAC3 = 12
|
||||||
MODE_DATAC4 = 18
|
MODE_DATAC4 = 18
|
||||||
|
|
||||||
|
|
||||||
class FreeDVData:
|
class FreeDVData:
|
||||||
def __init__(self, mode):
|
def __init__(self, mode):
|
||||||
system = platform.system()
|
system = platform.system()
|
||||||
@@ -250,12 +251,17 @@ class FreeDVInterface(Interface):
|
|||||||
ifconf = Interface.get_config_obj(configuration)
|
ifconf = Interface.get_config_obj(configuration)
|
||||||
self.name = ifconf["name"]
|
self.name = ifconf["name"]
|
||||||
|
|
||||||
|
self.debug = ifconf.get("debug", "false").lower() == "true"
|
||||||
|
|
||||||
# Get configuration parameters
|
# Get configuration parameters
|
||||||
self.input_device = int(ifconf["input_device"]) if "input_device" in ifconf else 0
|
self.input_device_config = ifconf.get("input_device", 0)
|
||||||
self.output_device = int(ifconf["output_device"]) if "output_device" in ifconf else 0
|
self.output_device_config = ifconf.get("output_device", 0)
|
||||||
|
|
||||||
|
self.input_device = self.get_device_index(self.input_device_config, is_input=True)
|
||||||
|
self.output_device = self.get_device_index(self.output_device_config, is_input=False)
|
||||||
|
|
||||||
self.freedv_mode_str = ifconf["freedv_mode"].lower() if "freedv_mode" in ifconf else "datac1"
|
self.freedv_mode_str = ifconf["freedv_mode"].lower() if "freedv_mode" in ifconf else "datac1"
|
||||||
self.tx_volume = float(ifconf.get("tx_volume", 100)) / 100.0
|
self.tx_volume = float(ifconf.get("tx_volume", 100)) / 100.0
|
||||||
self.debug = ifconf.get("debug", "false").lower() == "true"
|
|
||||||
|
|
||||||
# PTT configuration
|
# PTT configuration
|
||||||
self.ptt_type = ifconf.get("ptt_type", "none").lower() # none, serial, hamlib, vox
|
self.ptt_type = ifconf.get("ptt_type", "none").lower() # none, serial, hamlib, vox
|
||||||
@@ -401,12 +407,70 @@ class FreeDVInterface(Interface):
|
|||||||
RNS.log(f"Could not initialize FreeDV interface [{self.name}]: {e}", RNS.LOG_ERROR)
|
RNS.log(f"Could not initialize FreeDV interface [{self.name}]: {e}", RNS.LOG_ERROR)
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
def get_device_index(self, device_config, is_input=True):
|
||||||
|
if isinstance(device_config, int):
|
||||||
|
return device_config
|
||||||
|
|
||||||
|
try:
|
||||||
|
return int(device_config)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
p = pyaudio.PyAudio()
|
||||||
|
device_index = None
|
||||||
|
|
||||||
|
search_name = device_config.lower().strip()
|
||||||
|
|
||||||
|
for i in range(p.get_device_count()):
|
||||||
|
info = p.get_device_info_by_index(i)
|
||||||
|
device_name = info['name'].lower().strip()
|
||||||
|
|
||||||
|
if is_input and info['maxInputChannels'] == 0:
|
||||||
|
continue
|
||||||
|
if not is_input and info['maxOutputChannels'] == 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if device_name == search_name:
|
||||||
|
device_index = i
|
||||||
|
break
|
||||||
|
|
||||||
|
# partial match
|
||||||
|
if search_name in device_name:
|
||||||
|
device_index = i
|
||||||
|
|
||||||
|
p.terminate()
|
||||||
|
|
||||||
|
if device_index is None:
|
||||||
|
RNS.log(f"Could not find audio device '{device_config}' for {'input' if is_input else 'output'}",
|
||||||
|
RNS.LOG_ERROR)
|
||||||
|
RNS.log("Available devices:", RNS.LOG_ERROR)
|
||||||
|
p = pyaudio.PyAudio()
|
||||||
|
for i in range(p.get_device_count()):
|
||||||
|
info = p.get_device_info_by_index(i)
|
||||||
|
if (is_input and info['maxInputChannels'] > 0) or (not is_input and info['maxOutputChannels'] > 0):
|
||||||
|
RNS.log(f" {i}: {info['name']}", RNS.LOG_ERROR)
|
||||||
|
p.terminate()
|
||||||
|
raise ValueError(f"Audio device '{device_config}' not found")
|
||||||
|
|
||||||
|
if self.debug:
|
||||||
|
p = pyaudio.PyAudio()
|
||||||
|
info = p.get_device_info_by_index(device_index)
|
||||||
|
RNS.log(
|
||||||
|
f"Found {'input' if is_input else 'output'} device '{device_config}' at index {device_index}: {info['name']}",
|
||||||
|
RNS.LOG_DEBUG)
|
||||||
|
p.terminate()
|
||||||
|
|
||||||
|
return device_index
|
||||||
|
|
||||||
def init_audio(self):
|
def init_audio(self):
|
||||||
self.p = pyaudio.PyAudio()
|
self.p = pyaudio.PyAudio()
|
||||||
|
|
||||||
if self.debug:
|
if self.debug:
|
||||||
RNS.log(f"Initializing audio for FreeDV [{self.name}]", RNS.LOG_DEBUG)
|
RNS.log(f"Initializing audio for FreeDV [{self.name}]", RNS.LOG_DEBUG)
|
||||||
RNS.log(f"Input device: {self.input_device}, Output device: {self.output_device}", RNS.LOG_DEBUG)
|
input_info = self.p.get_device_info_by_index(self.input_device)
|
||||||
|
output_info = self.p.get_device_info_by_index(self.output_device)
|
||||||
|
RNS.log(f"Input device: {self.input_device} ({input_info['name']})", RNS.LOG_DEBUG)
|
||||||
|
RNS.log(f"Output device: {self.output_device} ({output_info['name']})", RNS.LOG_DEBUG)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Open audio stream
|
# Open audio stream
|
||||||
@@ -857,25 +921,23 @@ if __name__ == "__main__":
|
|||||||
print(f" Sample Rate: {info['defaultSampleRate']}")
|
print(f" Sample Rate: {info['defaultSampleRate']}")
|
||||||
p.terminate()
|
p.terminate()
|
||||||
|
|
||||||
print("\nHamlib radio models")
|
|
||||||
print("-" * 50)
|
|
||||||
try:
|
try:
|
||||||
result = subprocess.run(["rigctl", "--list"], capture_output=True, text=True)
|
result = subprocess.run(["rigctl", "--list"], capture_output=True, text=True)
|
||||||
except:
|
except:
|
||||||
print("rigctl not found - install hamlib for radio control (view README for install instructions)")
|
print("rigctl not found - install hamlib for radio control (view README for install instructions)")
|
||||||
|
|
||||||
print("\nConfiguration example:")
|
print("\nConfiguration examples:")
|
||||||
print("-" * 50)
|
print("-" * 50)
|
||||||
print("""
|
print("""
|
||||||
|
|
||||||
[[FreeDV with IC-7300]]
|
[[FreeDV with IC-7300]]
|
||||||
type = FreeDVInterface
|
type = FreeDVInterface
|
||||||
enabled = yes
|
enabled = yes
|
||||||
input_device = 2
|
input_device = default
|
||||||
output_device = 2
|
output_device = default
|
||||||
freedv_mode = datac1
|
freedv_mode = datac1
|
||||||
ptt_type = hamlib
|
ptt_type = hamlib
|
||||||
hamlib_model = 3073 # run rigctl -l to list devices
|
hamlib_model = 3073 # run rigctl -l to list devices
|
||||||
hamlib_device = /dev/ttyUSB0
|
hamlib_device = /dev/ttyUSB0
|
||||||
hamlib_speed = 19200
|
hamlib_speed = 19200
|
||||||
""")
|
""")
|
||||||
Reference in New Issue
Block a user