From 7531f5df20b31322d7e898cf8a39d85ca9fb40b0 Mon Sep 17 00:00:00 2001 From: Stefan Schlosser Date: Thu, 14 Nov 2024 02:36:20 +0100 Subject: [PATCH] oss: cleanup and unification Audio and record initializations are unified by providing helper functions for opening the audio device and for setting the device parameters. The ioctl calls are properly checked for errors and log an appropriate error message. The init fails if the requested parameters are not supported by the device, i.e. 44.1kHz 16bit stereo for playback. This provides consistent behavior with all the other audio backends. --- core/audio/audiobackend_oss.cpp | 117 +++++++++++++++++++++----------- 1 file changed, 76 insertions(+), 41 deletions(-) diff --git a/core/audio/audiobackend_oss.cpp b/core/audio/audiobackend_oss.cpp index b9f81c601..f724dcea8 100644 --- a/core/audio/audiobackend_oss.cpp +++ b/core/audio/audiobackend_oss.cpp @@ -10,29 +10,87 @@ class OSSAudioBackend : public AudioBackend int audioFD = -1; int recordFD = -1; + static int openDevice(int flags) + { + const char* path = "/dev/dsp"; + int fd = open(path, flags); + + if (fd < 0) + ERROR_LOG(AUDIO, "OSS: open(%s) failed: %s", path, strerror(errno)); + + return fd; + } + + static bool setRate(int fd, int rate) + { + int tmp = rate; + + if (ioctl(fd, SNDCTL_DSP_SPEED, &tmp) < 0) + { + ERROR_LOG(AUDIO, "OSS: ioctl(SNDCTL_DSP_SPEED) failed: %s", strerror(errno)); + return false; + } + + if (tmp != rate) + { + ERROR_LOG(AUDIO, "OSS: sample rate unsupported: %d => %d", rate, tmp); + return false; + } + + return true; + } + + static bool setChannels(int fd, int channels) + { + int tmp = channels; + + if (ioctl(fd, SNDCTL_DSP_CHANNELS, &tmp) < 0) + { + ERROR_LOG(AUDIO, "OSS: ioctl(SNDCTL_DSP_CHANNELS) failed: %s", strerror(errno)); + return false; + } + + if (tmp != channels) + { + ERROR_LOG(AUDIO, "OSS: channels unsupported: %d => %d", channels, tmp); + return false; + } + + return true; + } + + static bool setFormat(int fd, int format) + { + int tmp = format; + + if (ioctl(fd, SNDCTL_DSP_SETFMT, &tmp) < 0) + { + ERROR_LOG(AUDIO, "OSS: ioctl(SNDCTL_DSP_SETFMT) failed: %s", strerror(errno)); + return false; + } + + if (tmp != format) + { + ERROR_LOG(AUDIO, "OSS: sample format unsupported: %#.8x => %#.8x", format, tmp); + return false; + } + + return true; + } + public: OSSAudioBackend() : AudioBackend("oss", "Open Sound System") {} bool init() override { - audioFD = open("/dev/dsp", O_WRONLY); - if (audioFD < 0) + audioFD = openDevice(O_WRONLY); + + if (audioFD < 0 || !setRate(audioFD, 44100) || !setChannels(audioFD, 2) || !setFormat(audioFD, AFMT_S16_LE)) { - WARN_LOG(AUDIO, "Couldn't open /dev/dsp."); + term(); return false; } - INFO_LOG(AUDIO, "sound enabled, dsp opened for write"); - int tmp=44100; - int err_ret; - err_ret=ioctl(audioFD,SNDCTL_DSP_SPEED,&tmp); - INFO_LOG(AUDIO, "set Frequency to %i, return %i (rate=%i)", 44100, err_ret, tmp); - int channels=2; - err_ret=ioctl(audioFD, SNDCTL_DSP_CHANNELS, &channels); - INFO_LOG(AUDIO, "set dsp to stereo (%i => %i)", channels, err_ret); - int format=AFMT_S16_LE; - err_ret=ioctl(audioFD, SNDCTL_DSP_SETFMT, &format); - INFO_LOG(AUDIO, "set dsp to %s audio (%i/%i => %i)", "16bits signed", AFMT_S16_LE, format, err_ret); return true; } @@ -54,34 +112,11 @@ class OSSAudioBackend : public AudioBackend bool initRecord(u32 sampling_freq) override { - recordFD = open("/dev/dsp", O_RDONLY); - if (recordFD < 0) - { - INFO_LOG(AUDIO, "OSS: can't open default audio capture device"); - return false; - } - int tmp = AFMT_S16_NE; // Native 16 bits - if (ioctl(recordFD, SNDCTL_DSP_SETFMT, &tmp) == -1 || tmp != AFMT_S16_NE) - { - INFO_LOG(AUDIO, "OSS: can't set sample format"); - close(recordFD); - recordFD = -1; - return false; - } - tmp = 1; - if (ioctl(recordFD, SNDCTL_DSP_CHANNELS, &tmp) == -1) - { - INFO_LOG(AUDIO, "OSS: can't set channel count"); - close(recordFD); - recordFD = -1; - return false; - } - tmp = sampling_freq; - if (ioctl(recordFD, SNDCTL_DSP_SPEED, &tmp) == -1) + recordFD = openDevice(O_RDONLY); + + if (recordFD < 0 || !setRate(recordFD, sampling_freq) || !setChannels(recordFD, 1) || !setFormat(recordFD, AFMT_S16_NE /* Native 16 bits */ )) { - INFO_LOG(AUDIO, "OSS: can't set sample rate"); - close(recordFD); - recordFD = -1; + termRecord(); return false; }