mirror of
https://github.com/thetechprepper/emcomm-tools-os-community.git
synced 2026-09-17 15:41:44 -04:00
fldigi - Initial work to enable PnP support for fldigi. Wrote a custom tool to map between an ALSA device and a PortAudio device.
This commit is contained in:
@@ -2144,7 +2144,7 @@ Operator call sign, if distinct from the station call MYCALL -->
|
|||||||
<!-- type: int; default: SND_IDX_NULL
|
<!-- type: int; default: SND_IDX_NULL
|
||||||
Audio subsystem. Values are as follows:
|
Audio subsystem. Values are as follows:
|
||||||
0: OSS; 1: PortAudio; 2: PulseAudio; 3: File I/O -->
|
0: OSS; 1: PortAudio; 2: PulseAudio; 3: File I/O -->
|
||||||
<AUDIOIO>3</AUDIOIO>
|
<AUDIOIO>1</AUDIOIO>
|
||||||
|
|
||||||
<!-- type: std::string; default: ""
|
<!-- type: std::string; default: ""
|
||||||
OSS device name -->
|
OSS device name -->
|
||||||
@@ -2156,19 +2156,19 @@ For compatibility with older versions -->
|
|||||||
|
|
||||||
<!-- type: std::string; default: ""
|
<!-- type: std::string; default: ""
|
||||||
PortAudio input device name -->
|
PortAudio input device name -->
|
||||||
<PORTINDEVICE>default</PORTINDEVICE>
|
<PORTINDEVICE>{{ET_PORTAUDIO_DEVICE}}</PORTINDEVICE>
|
||||||
|
|
||||||
<!-- type: int; default: -1
|
<!-- type: int; default: -1
|
||||||
PortAudio input device index -->
|
PortAudio input device index -->
|
||||||
<PORTININDEX>19</PORTININDEX>
|
<PORTININDEX>{{ET_PORTAUDIO_INDEX}}</PORTININDEX>
|
||||||
|
|
||||||
<!-- type: std::string; default: ""
|
<!-- type: std::string; default: ""
|
||||||
PortAudio output device name -->
|
PortAudio output device name -->
|
||||||
<PORTOUTDEVICE>default</PORTOUTDEVICE>
|
<PORTOUTDEVICE>{{ET_PORTAUDIO_DEVICE}}</PORTOUTDEVICE>
|
||||||
|
|
||||||
<!-- type: int; default: -1
|
<!-- type: int; default: -1
|
||||||
PortAudio input device index -->
|
PortAudio input device index -->
|
||||||
<PORTOUTINDEX>19</PORTOUTINDEX>
|
<PORTOUTINDEX>{{ET_PORTAUDIO_INDEX}}</PORTOUTINDEX>
|
||||||
|
|
||||||
<!-- type: std::string; default: ""
|
<!-- type: std::string; default: ""
|
||||||
PortAudio alert device name -->
|
PortAudio alert device name -->
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
et-portaudio
|
||||||
|
*.o
|
||||||
|
conf.tmp
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
CC = gcc
|
||||||
|
CFLAGS = -Wall -O2
|
||||||
|
LDFLAGS = -lportaudio -lasound
|
||||||
|
|
||||||
|
TARGET = et-portaudio
|
||||||
|
SRC = main.c
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
$(TARGET): $(SRC)
|
||||||
|
$(CC) $(CFLAGS) -o $(TARGET) $(SRC) $(LDFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(TARGET) *.o
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
# et-portaudio
|
||||||
|
|
||||||
|
A utility program intended for script use to convert a supported
|
||||||
|
EmComm Tools ALSA audio device (i.e. `ET_AUDIO`) to a PulseAudio device.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Returns a JSON object with the PulseAudio device details on success.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./et-portaudio 2>/dev/null
|
||||||
|
{
|
||||||
|
"device": "USB Audio Device: - (hw:1,0)",
|
||||||
|
"index": 6
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If no supported device is found or on error, the utility exits with an
|
||||||
|
exit status of 1.
|
||||||
|
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
``bash
|
||||||
|
make
|
||||||
|
```
|
||||||
Executable
+49
@@ -0,0 +1,49 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Author : Gaston Gonzalez
|
||||||
|
# Date : 1 October 2025
|
||||||
|
# Purpose : Temporary script to fast-fail dynamic fldigi config for PnP
|
||||||
|
#
|
||||||
|
# NOTE:
|
||||||
|
#
|
||||||
|
# THIS IS JUST USED DURING DEVELOPMENT. AN XML PARSER WILL BE USED TO MODIFY
|
||||||
|
# THE FLDIGI CONFIG FOR THE FINAL PNP SOLUTION. SO THAT USER CHANGES CAN STILL
|
||||||
|
# BE PERSISTED.
|
||||||
|
|
||||||
|
CMD=et-portaudio
|
||||||
|
PORT_AUDIO_CONF=conf.tmp
|
||||||
|
FLDIGI_CONF_FILE="${HOME}/.fldigi/fldigi_def.xml"
|
||||||
|
|
||||||
|
# clean up temporary config that may exist
|
||||||
|
[[ -e ${PORT_AUDIO_CONF} ]] && rm ${PORT_AUDIO_CONF}
|
||||||
|
|
||||||
|
[[ ! -e ${CMD} ]] && make
|
||||||
|
./${CMD} 2>/dev/null > ${PORT_AUDIO_CONF}
|
||||||
|
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
echo "No supported ET_AUDIO device found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
DEVICE=$(jq -r -e '.device' ${PORT_AUDIO_CONF})
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
echo "Error getting PulseAudio device name for ET_AUDIO device"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
INDEX=$(jq -r -e '.index' ${PORT_AUDIO_CONF})
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
echo "Error getting PulseAudio device index for ET_AUDIO device"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
et-log "Copying fldigi template..."
|
||||||
|
cp -v ../../overlay/etc/skel/.fldigi/fldigi_def.xml ~/.fldigi/
|
||||||
|
|
||||||
|
et-log "Updating PortAudio devices..."
|
||||||
|
sed -i "s|^<AUDIOIO>.*|<AUDIOIO>1</AUDIOIO>|" ${FLDIGI_CONF_FILE}
|
||||||
|
|
||||||
|
sed -i "s|^<PORTINDEVICE>.*|<PORTINDEVICE>${DEVICE}</PORTINDEVICE>|" ${FLDIGI_CONF_FILE}
|
||||||
|
sed -i "s|^<PORTININDEX>.*|<PORTININDEX>${INDEX}</PORTININDEX>|" ${FLDIGI_CONF_FILE}
|
||||||
|
|
||||||
|
sed -i "s|^<PORTOUTDEVICE>.*|<PORTOUTDEVICE>${DEVICE}</PORTOUTDEVICE>|" ${FLDIGI_CONF_FILE}
|
||||||
|
sed -i "s|^<PORTOUTINDEX>.*|<PORTOUTINDEX>${INDEX}</PORTOUTINDEX>|" ${FLDIGI_CONF_FILE}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Author : Gaston Gonzalez
|
||||||
|
* Date : 1 October 2025
|
||||||
|
* Purpose : Maps an ET_AUDIO ALSA device to a PortAudio device.
|
||||||
|
*
|
||||||
|
* This utility enumerates all ALSA audio devices using PortAudio
|
||||||
|
* to identify a currently plugged-in ET_AUDIO device. If a matching
|
||||||
|
* device is found, it generates a JSON object on STDOUT containing:
|
||||||
|
*
|
||||||
|
* - PortAudio device name
|
||||||
|
* - PortAudio device index
|
||||||
|
*
|
||||||
|
* Exit Status:
|
||||||
|
* 0 - ET_AUDIO device found and JSON output generated successfully
|
||||||
|
* 1 - ET_AUDIO device not found
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "portaudio.h"
|
||||||
|
|
||||||
|
#define PROC_ALSA_PATH_FMT "/proc/asound/card%d/id"
|
||||||
|
|
||||||
|
// Read the ALSA card ID from the /proc filesystem
|
||||||
|
int get_alsa_card_id(int card, char *id_buf, size_t buf_size) {
|
||||||
|
char path[64];
|
||||||
|
snprintf(path, sizeof(path), PROC_ALSA_PATH_FMT, card);
|
||||||
|
FILE *f = fopen(path, "r");
|
||||||
|
if (!f) return -1;
|
||||||
|
if (!fgets(id_buf, buf_size, f)) {
|
||||||
|
fclose(f);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
id_buf[strcspn(id_buf, "\n")] = 0;
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
PaError err;
|
||||||
|
int i, numDevices;
|
||||||
|
const PaDeviceInfo *deviceInfo;
|
||||||
|
const PaHostApiInfo *hostApiInfo;
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
|
err = Pa_Initialize();
|
||||||
|
if (err != paNoError) {
|
||||||
|
fprintf(stderr, "PortAudio error: %s\n", Pa_GetErrorText(err));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
numDevices = Pa_GetDeviceCount();
|
||||||
|
if (numDevices < 0) {
|
||||||
|
fprintf(stderr, "No audio devices found");
|
||||||
|
Pa_Terminate();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < numDevices; i++) {
|
||||||
|
deviceInfo = Pa_GetDeviceInfo(i);
|
||||||
|
hostApiInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
|
||||||
|
|
||||||
|
// Only show ALSA devices
|
||||||
|
if (hostApiInfo && strcmp(hostApiInfo->name, "ALSA") == 0) {
|
||||||
|
int card = -1, device = -1;
|
||||||
|
|
||||||
|
// Extract ALSA card and device (hw:X,Y)
|
||||||
|
if (sscanf(deviceInfo->name, "%*[^()](hw:%d,%d)", &card, &device) == 2) {
|
||||||
|
char card_id[64];
|
||||||
|
if (get_alsa_card_id(card, card_id, sizeof(card_id)) == 0) {
|
||||||
|
|
||||||
|
// Only print if card ID matches ET_AUDIO
|
||||||
|
if (strcmp(card_id, "ET_AUDIO") == 0) {
|
||||||
|
found = 1;
|
||||||
|
printf("{\n");
|
||||||
|
printf(" \"device\": \"%s\",\n", deviceInfo->name);
|
||||||
|
printf(" \"index\": %d\n", i);
|
||||||
|
printf("}\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Pa_Terminate();
|
||||||
|
return found ? 0 : 1;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user