output/oss: replace the AudioFormat field with 3 raw OSS integers

This simplifies Reopen().
This commit is contained in:
Max Kellermann 2021-08-05 15:55:20 +02:00
parent d42342e0ba
commit dee5d1b87b

View File

@ -62,16 +62,10 @@ class OssOutput final : AudioOutput {
const char *device;
/**
* The current input audio format. This is needed to reopen
* the device after cancel().
* The effective audio format settings of the OSS device.
* This is needed by Reopen() after Cancel().
*/
AudioFormat audio_format;
/**
* The current OSS audio format. This is needed to reopen the
* device after cancel().
*/
int oss_format;
int effective_channels, effective_speed, effective_samplesize;
static constexpr unsigned oss_flags = FLAG_ENABLE_DISABLE;
@ -279,14 +273,17 @@ OssIoctlExact(FileDescriptor fd, unsigned long request, int requested_value,
* Throws on error.
*/
static void
oss_setup_channels(FileDescriptor fd, AudioFormat &audio_format)
oss_setup_channels(FileDescriptor fd, AudioFormat &audio_format,
int &effective_channels)
{
const char *const msg = "Failed to set channel count";
int channels = audio_format.channels;
if (oss_try_ioctl_r(fd, SNDCTL_DSP_CHANNELS, &channels, msg) &&
audio_valid_channel_count(channels)) {
audio_format.channels = channels;
effective_channels = audio_format.channels;
if (oss_try_ioctl_r(fd, SNDCTL_DSP_CHANNELS,
&effective_channels, msg) &&
audio_valid_channel_count(effective_channels)) {
audio_format.channels = effective_channels;
return;
}
@ -295,10 +292,11 @@ oss_setup_channels(FileDescriptor fd, AudioFormat &audio_format)
/* don't try that again */
continue;
channels = i;
if (oss_try_ioctl_r(fd, SNDCTL_DSP_CHANNELS, &channels, msg) &&
audio_valid_channel_count(channels)) {
audio_format.channels = channels;
effective_channels = i;
if (oss_try_ioctl_r(fd, SNDCTL_DSP_CHANNELS,
&effective_channels, msg) &&
audio_valid_channel_count(effective_channels)) {
audio_format.channels = effective_channels;
return;
}
}
@ -313,26 +311,27 @@ oss_setup_channels(FileDescriptor fd, AudioFormat &audio_format)
* Throws on error.
*/
static void
oss_setup_sample_rate(FileDescriptor fd, AudioFormat &audio_format)
oss_setup_sample_rate(FileDescriptor fd, AudioFormat &audio_format,
int &effective_speed)
{
const char *const msg = "Failed to set sample rate";
int sample_rate = audio_format.sample_rate;
if (oss_try_ioctl_r(fd, SNDCTL_DSP_SPEED, &sample_rate, msg) &&
audio_valid_sample_rate(sample_rate)) {
audio_format.sample_rate = sample_rate;
effective_speed = audio_format.sample_rate;
if (oss_try_ioctl_r(fd, SNDCTL_DSP_SPEED, &effective_speed, msg) &&
audio_valid_sample_rate(effective_speed)) {
audio_format.sample_rate = effective_speed;
return;
}
static constexpr int sample_rates[] = { 48000, 44100, 0 };
for (unsigned i = 0; sample_rates[i] != 0; ++i) {
sample_rate = sample_rates[i];
if (sample_rate == (int)audio_format.sample_rate)
effective_speed = sample_rates[i];
if (effective_speed == (int)audio_format.sample_rate)
continue;
if (oss_try_ioctl_r(fd, SNDCTL_DSP_SPEED, &sample_rate, msg) &&
audio_valid_sample_rate(sample_rate)) {
audio_format.sample_rate = sample_rate;
if (oss_try_ioctl_r(fd, SNDCTL_DSP_SPEED, &effective_speed, msg) &&
audio_valid_sample_rate(effective_speed)) {
audio_format.sample_rate = effective_speed;
return;
}
}
@ -518,9 +517,10 @@ oss_setup_sample_format(FileDescriptor fd, AudioFormat &audio_format,
inline void
OssOutput::Setup(AudioFormat &_audio_format)
{
oss_setup_channels(fd, _audio_format);
oss_setup_sample_rate(fd, _audio_format);
oss_setup_sample_format(fd, _audio_format, &oss_format, pcm_export);
oss_setup_channels(fd, _audio_format, effective_channels);
oss_setup_sample_rate(fd, _audio_format, effective_speed);
oss_setup_sample_format(fd, _audio_format, &effective_samplesize,
pcm_export);
}
/**
@ -534,11 +534,11 @@ try {
if (!fd.Open(device, O_WRONLY))
throw FormatErrno("Error opening OSS device \"%s\"", device);
OssIoctlExact(fd, SNDCTL_DSP_CHANNELS, audio_format.channels,
OssIoctlExact(fd, SNDCTL_DSP_CHANNELS, effective_channels,
"Failed to set channel count");
OssIoctlExact(fd, SNDCTL_DSP_SPEED, audio_format.sample_rate,
OssIoctlExact(fd, SNDCTL_DSP_SPEED, effective_speed,
"Failed to set sample rate");
OssIoctlExact(fd, SNDCTL_DSP_SAMPLESIZE, oss_format,
OssIoctlExact(fd, SNDCTL_DSP_SAMPLESIZE, effective_samplesize,
"Failed to set sample format");
} catch (...) {
DoClose();
@ -552,8 +552,6 @@ try {
throw FormatErrno("Error opening OSS device \"%s\"", device);
Setup(_audio_format);
audio_format = _audio_format;
} catch (...) {
DoClose();
throw;