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