direwolf icon indicating copy to clipboard operation
direwolf copied to clipboard

macOS: Unable to specify audio device with non-ascii characters

Open martinhpedersen opened this issue 1 year ago • 3 comments

When running macOS with Norwegian locale, the Core Audio audio device is named using the unicode character ø: MacBook Pro-høyttalere (translates to Macbook Pro-speakers).

When attempting to specify this as the output device, ø appears to be stripped from the string. This makes direwolf unusable with the built-in soundcard on macOS with Norwegian locale. I imagine this is a problem with other locales as well, as many use non-ascii characters.

My direwolf.conf (encoded using UTF-8):

ADEVICE  "MacBook Pro-mikrofon"  "MacBook Pro-høyttalere"

Direwolf output:

Dire Wolf DEVELOPMENT version 1.7 E (Aug 28 2022)
Includes optional support for:  hamlib dns-sd
Warning: Could not open 'symbols-new.txt'.
The "new" OVERLAID character information will not be available.

Reading config file /Users/martinhpedersen/direwolf.conf
Audio input device for receive: MacBook Pro-mikrofon  (channel 0)
Audio out device for transmit: MacBook Pro-høyttalere  (channel 0)
Number of devices = 2
--------------------------------------- device #0
[ Default Input ]
Name        = "MacBook Pro-mikrofon"
Host API    = Core Audio
Max inputs  = 1
Max outputs = 0
--------------------------------------- device #1
[ Default Output ]
Name        = "MacBook Pro-høyttalere"
Host API    = Core Audio
Max inputs  = 0
Max outputs = 2
Requested Output Audio Device not found MacBook Pro-hyttalere.
Pointless to continue without audio device.

martinhpedersen avatar Aug 28 '22 20:08 martinhpedersen

I'm guessing pa_devNN is the offending function. It skips bytes outside the ASCII range 0x20-0x7E.

https://github.com/wb2osz/direwolf/blob/fe6cba2b0dfa1f0f6d95bed20301baf1d727a566/src/audio_portaudio.c#L216-L218

martinhpedersen avatar Aug 28 '22 20:08 martinhpedersen

I attempted to simply remove the 0x20-0x7E range test, and at least on my laptop it resolves the issue:

diff --git a/src/audio_portaudio.c b/src/audio_portaudio.c
index 6d53f6a..19a4e74 100644
--- a/src/audio_portaudio.c
+++ b/src/audio_portaudio.c
@@ -213,7 +213,7 @@ static int pa_devNN(char *deviceStr, char *_devName, size_t length, int *_devNo)
 	while(*cPtr) {
 		cVal = *cPtr++;
 		if(cVal == ':')  break;
-		if(((cVal >= ' ') && (cVal <= '~')) && (count < length)) {
+		if(count < length) {
 			_devName[count++] = cVal;
 		}
 

What's the reason behind skipping bytes outside this ASCII subset?

Reading through the various PortAudio threads, it looks like they decided to start using UTF-8 strings back in 2014. If so, maybe this needs to be transcoded and/or changed to test for a valid UTF-8 string instead? I'm not sure which encoding direwolf prefers internally (if any).

martinhpedersen avatar Sep 18 '22 20:09 martinhpedersen

I'd be happy to send this patch in as a PR if anyone think it's a good enough solution.

martinhpedersen avatar Sep 18 '22 20:09 martinhpedersen

Thanks for identifying the problem and finding a solution. No need to generate a pull request for a single line change. That's just making more work for everyone.

I did not write this. The Mac-specific part was submitted by someone else and I never looked at it very carefully.

It seems to me that the test for buffer full is off by one.

As written, count could reach length. There would be no room for the nul terminator. I think the test should be against length minus 1.

if(count < length - 1) {

If the source string is truncated, the result would be nul terminated.

wb2osz avatar Sep 25 '22 21:09 wb2osz

Fix has been pushed to repository in dev branch.

wb2osz avatar Sep 25 '22 21:09 wb2osz

Works like a charm 🎉

Reading config file /Users/martinhpedersen/direwolf.conf
Audio input device for receive: MacBook Pro-mikrofon  (channel 0)
Audio out device for transmit: MacBook Pro-høyttalere  (channel 0)

martinhpedersen avatar Oct 14 '22 05:10 martinhpedersen