pcm/Export: add CalcOutputSampleRate(), CalcInputSampleRate()
Prepare for DSD sample rate fixups.
This commit is contained in:
parent
142fdc8d86
commit
c143adba91
|
@ -469,7 +469,6 @@ static void
|
||||||
AlsaSetup(AlsaOutput *ad, AudioFormat &audio_format,
|
AlsaSetup(AlsaOutput *ad, AudioFormat &audio_format,
|
||||||
PcmExport::Params ¶ms)
|
PcmExport::Params ¶ms)
|
||||||
{
|
{
|
||||||
unsigned int sample_rate = audio_format.sample_rate;
|
|
||||||
unsigned int channels = audio_format.channels;
|
unsigned int channels = audio_format.channels;
|
||||||
int err;
|
int err;
|
||||||
unsigned retry = MPD_ALSA_RETRY_NR;
|
unsigned retry = MPD_ALSA_RETRY_NR;
|
||||||
|
@ -513,18 +512,23 @@ configure_hw:
|
||||||
|
|
||||||
audio_format.channels = (int8_t)channels;
|
audio_format.channels = (int8_t)channels;
|
||||||
|
|
||||||
|
const unsigned requested_sample_rate =
|
||||||
|
params.CalcOutputSampleRate(audio_format.sample_rate);
|
||||||
|
unsigned output_sample_rate = requested_sample_rate;
|
||||||
|
|
||||||
err = snd_pcm_hw_params_set_rate_near(ad->pcm, hwparams,
|
err = snd_pcm_hw_params_set_rate_near(ad->pcm, hwparams,
|
||||||
&sample_rate, nullptr);
|
&output_sample_rate, nullptr);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
throw FormatRuntimeError("Failed to configure sample rate %u Hz: %s",
|
throw FormatRuntimeError("Failed to configure sample rate %u Hz: %s",
|
||||||
audio_format.sample_rate,
|
requested_sample_rate,
|
||||||
snd_strerror(-err));
|
snd_strerror(-err));
|
||||||
|
|
||||||
if (sample_rate == 0)
|
if (output_sample_rate == 0)
|
||||||
throw FormatRuntimeError("Failed to configure sample rate %u Hz",
|
throw FormatRuntimeError("Failed to configure sample rate %u Hz",
|
||||||
audio_format.sample_rate);
|
audio_format.sample_rate);
|
||||||
|
|
||||||
audio_format.sample_rate = sample_rate;
|
if (output_sample_rate != requested_sample_rate)
|
||||||
|
audio_format.sample_rate = params.CalcInputSampleRate(output_sample_rate);
|
||||||
|
|
||||||
snd_pcm_uframes_t buffer_size_min, buffer_size_max;
|
snd_pcm_uframes_t buffer_size_min, buffer_size_max;
|
||||||
snd_pcm_hw_params_get_buffer_size_min(hwparams, &buffer_size_min);
|
snd_pcm_hw_params_get_buffer_size_min(hwparams, &buffer_size_min);
|
||||||
|
|
|
@ -98,6 +98,18 @@ PcmExport::GetFrameSize(const AudioFormat &audio_format) const
|
||||||
return audio_format.GetFrameSize();
|
return audio_format.GetFrameSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
PcmExport::Params::CalcOutputSampleRate(unsigned sample_rate) const
|
||||||
|
{
|
||||||
|
return sample_rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
PcmExport::Params::CalcInputSampleRate(unsigned sample_rate) const
|
||||||
|
{
|
||||||
|
return sample_rate;
|
||||||
|
}
|
||||||
|
|
||||||
ConstBuffer<void>
|
ConstBuffer<void>
|
||||||
PcmExport::Export(ConstBuffer<void> data)
|
PcmExport::Export(ConstBuffer<void> data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,6 +41,21 @@ struct PcmExport {
|
||||||
bool shift8 = false;
|
bool shift8 = false;
|
||||||
bool pack24 = false;
|
bool pack24 = false;
|
||||||
bool reverse_endian = false;
|
bool reverse_endian = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the output sample rate, given a specific input
|
||||||
|
* sample rate. Usually, both are the same; however, with
|
||||||
|
* DSD_U32, four input bytes (= 4 * 8 bits) are combined to
|
||||||
|
* one output word (32 bits), dividing the sample rate by 4.
|
||||||
|
*/
|
||||||
|
gcc_pure
|
||||||
|
unsigned CalcOutputSampleRate(unsigned input_sample_rate) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The inverse of CalcOutputSampleRate().
|
||||||
|
*/
|
||||||
|
gcc_pure
|
||||||
|
unsigned CalcInputSampleRate(unsigned output_sample_rate) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -35,6 +35,9 @@ PcmExportTest::TestShift8()
|
||||||
PcmExport::Params params;
|
PcmExport::Params params;
|
||||||
params.shift8 = true;
|
params.shift8 = true;
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(params.CalcOutputSampleRate(42u), 42u);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(params.CalcInputSampleRate(42u), 42u);
|
||||||
|
|
||||||
PcmExport e;
|
PcmExport e;
|
||||||
e.Open(SampleFormat::S24_P32, 2, params);
|
e.Open(SampleFormat::S24_P32, 2, params);
|
||||||
|
|
||||||
|
@ -71,6 +74,9 @@ PcmExportTest::TestPack24()
|
||||||
PcmExport::Params params;
|
PcmExport::Params params;
|
||||||
params.pack24 = true;
|
params.pack24 = true;
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(params.CalcOutputSampleRate(42u), 42u);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(params.CalcInputSampleRate(42u), 42u);
|
||||||
|
|
||||||
PcmExport e;
|
PcmExport e;
|
||||||
e.Open(SampleFormat::S24_P32, 2, params);
|
e.Open(SampleFormat::S24_P32, 2, params);
|
||||||
|
|
||||||
|
@ -97,6 +103,9 @@ PcmExportTest::TestReverseEndian()
|
||||||
PcmExport::Params params;
|
PcmExport::Params params;
|
||||||
params.reverse_endian = true;
|
params.reverse_endian = true;
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(params.CalcOutputSampleRate(42u), 42u);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(params.CalcInputSampleRate(42u), 42u);
|
||||||
|
|
||||||
PcmExport e;
|
PcmExport e;
|
||||||
e.Open(SampleFormat::S8, 2, params);
|
e.Open(SampleFormat::S8, 2, params);
|
||||||
|
|
||||||
|
@ -192,6 +201,9 @@ TestAlsaChannelOrder51()
|
||||||
PcmExport::Params params;
|
PcmExport::Params params;
|
||||||
params.alsa_channel_order = true;
|
params.alsa_channel_order = true;
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(params.CalcOutputSampleRate(42u), 42u);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(params.CalcInputSampleRate(42u), 42u);
|
||||||
|
|
||||||
PcmExport e;
|
PcmExport e;
|
||||||
e.Open(F, 6, params);
|
e.Open(F, 6, params);
|
||||||
|
|
||||||
|
@ -219,6 +231,9 @@ TestAlsaChannelOrder71()
|
||||||
PcmExport::Params params;
|
PcmExport::Params params;
|
||||||
params.alsa_channel_order = true;
|
params.alsa_channel_order = true;
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(params.CalcOutputSampleRate(42u), 42u);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(params.CalcInputSampleRate(42u), 42u);
|
||||||
|
|
||||||
PcmExport e;
|
PcmExport e;
|
||||||
e.Open(F, 8, params);
|
e.Open(F, 8, params);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue