Commit 3a666702 authored by Max Kellermann's avatar Max Kellermann

pcm/PcmConvert: add AudioFormat parameters

Don't use src_format. In the middle of Convert(), the current AudioFormat has already been modified, it's now something in between src_format and dest_format. This simplifies keeping track of what remains to be done.
parent 3c0c9396
...@@ -63,10 +63,6 @@ PcmConvert::Open(AudioFormat _src_format, AudioFormat _dest_format, ...@@ -63,10 +63,6 @@ PcmConvert::Open(AudioFormat _src_format, AudioFormat _dest_format,
src_format = _src_format; src_format = _src_format;
dest_format = _dest_format; dest_format = _dest_format;
is_dsd = src_format.format == SampleFormat::DSD;
if (is_dsd)
src_format.format = SampleFormat::FLOAT;
return true; return true;
} }
...@@ -83,7 +79,7 @@ PcmConvert::Close() ...@@ -83,7 +79,7 @@ PcmConvert::Close()
} }
inline ConstBuffer<int16_t> inline ConstBuffer<int16_t>
PcmConvert::Convert16(ConstBuffer<void> src, Error &error) PcmConvert::Convert16(ConstBuffer<void> src, AudioFormat format, Error &error)
{ {
const int16_t *buf; const int16_t *buf;
size_t len; size_t len;
...@@ -91,34 +87,34 @@ PcmConvert::Convert16(ConstBuffer<void> src, Error &error) ...@@ -91,34 +87,34 @@ PcmConvert::Convert16(ConstBuffer<void> src, Error &error)
assert(dest_format.format == SampleFormat::S16); assert(dest_format.format == SampleFormat::S16);
buf = pcm_convert_to_16(format_buffer, dither, buf = pcm_convert_to_16(format_buffer, dither,
src_format.format, format.format,
src.data, src.size, src.data, src.size,
&len); &len);
if (buf == nullptr) { if (buf == nullptr) {
error.Format(pcm_convert_domain, error.Format(pcm_convert_domain,
"Conversion from %s to 16 bit is not implemented", "Conversion from %s to 16 bit is not implemented",
sample_format_to_string(src_format.format)); sample_format_to_string(format.format));
return nullptr; return nullptr;
} }
if (src_format.channels != dest_format.channels) { if (format.channels != dest_format.channels) {
buf = pcm_convert_channels_16(channels_buffer, buf = pcm_convert_channels_16(channels_buffer,
dest_format.channels, dest_format.channels,
src_format.channels, format.channels,
buf, len, &len); buf, len, &len);
if (buf == nullptr) { if (buf == nullptr) {
error.Format(pcm_convert_domain, error.Format(pcm_convert_domain,
"Conversion from %u to %u channels " "Conversion from %u to %u channels "
"is not implemented", "is not implemented",
src_format.channels, format.channels,
dest_format.channels); dest_format.channels);
return nullptr; return nullptr;
} }
} }
if (src_format.sample_rate != dest_format.sample_rate) { if (format.sample_rate != dest_format.sample_rate) {
buf = resampler.Resample16(dest_format.channels, buf = resampler.Resample16(dest_format.channels,
src_format.sample_rate, buf, len, format.sample_rate, buf, len,
dest_format.sample_rate, &len, dest_format.sample_rate, &len,
error); error);
if (buf == nullptr) if (buf == nullptr)
...@@ -129,7 +125,7 @@ PcmConvert::Convert16(ConstBuffer<void> src, Error &error) ...@@ -129,7 +125,7 @@ PcmConvert::Convert16(ConstBuffer<void> src, Error &error)
} }
inline ConstBuffer<int32_t> inline ConstBuffer<int32_t>
PcmConvert::Convert24(ConstBuffer<void> src, Error &error) PcmConvert::Convert24(ConstBuffer<void> src, AudioFormat format, Error &error)
{ {
const int32_t *buf; const int32_t *buf;
size_t len; size_t len;
...@@ -137,33 +133,33 @@ PcmConvert::Convert24(ConstBuffer<void> src, Error &error) ...@@ -137,33 +133,33 @@ PcmConvert::Convert24(ConstBuffer<void> src, Error &error)
assert(dest_format.format == SampleFormat::S24_P32); assert(dest_format.format == SampleFormat::S24_P32);
buf = pcm_convert_to_24(format_buffer, buf = pcm_convert_to_24(format_buffer,
src_format.format, format.format,
src.data, src.size, &len); src.data, src.size, &len);
if (buf == nullptr) { if (buf == nullptr) {
error.Format(pcm_convert_domain, error.Format(pcm_convert_domain,
"Conversion from %s to 24 bit is not implemented", "Conversion from %s to 24 bit is not implemented",
sample_format_to_string(src_format.format)); sample_format_to_string(format.format));
return nullptr; return nullptr;
} }
if (src_format.channels != dest_format.channels) { if (format.channels != dest_format.channels) {
buf = pcm_convert_channels_24(channels_buffer, buf = pcm_convert_channels_24(channels_buffer,
dest_format.channels, dest_format.channels,
src_format.channels, format.channels,
buf, len, &len); buf, len, &len);
if (buf == nullptr) { if (buf == nullptr) {
error.Format(pcm_convert_domain, error.Format(pcm_convert_domain,
"Conversion from %u to %u channels " "Conversion from %u to %u channels "
"is not implemented", "is not implemented",
src_format.channels, format.channels,
dest_format.channels); dest_format.channels);
return nullptr; return nullptr;
} }
} }
if (src_format.sample_rate != dest_format.sample_rate) { if (format.sample_rate != dest_format.sample_rate) {
buf = resampler.Resample24(dest_format.channels, buf = resampler.Resample24(dest_format.channels,
src_format.sample_rate, buf, len, format.sample_rate, buf, len,
dest_format.sample_rate, &len, dest_format.sample_rate, &len,
error); error);
if (buf == nullptr) if (buf == nullptr)
...@@ -174,7 +170,7 @@ PcmConvert::Convert24(ConstBuffer<void> src, Error &error) ...@@ -174,7 +170,7 @@ PcmConvert::Convert24(ConstBuffer<void> src, Error &error)
} }
inline ConstBuffer<int32_t> inline ConstBuffer<int32_t>
PcmConvert::Convert32(ConstBuffer<void> src, Error &error) PcmConvert::Convert32(ConstBuffer<void> src, AudioFormat format, Error &error)
{ {
const int32_t *buf; const int32_t *buf;
size_t len; size_t len;
...@@ -182,33 +178,33 @@ PcmConvert::Convert32(ConstBuffer<void> src, Error &error) ...@@ -182,33 +178,33 @@ PcmConvert::Convert32(ConstBuffer<void> src, Error &error)
assert(dest_format.format == SampleFormat::S32); assert(dest_format.format == SampleFormat::S32);
buf = pcm_convert_to_32(format_buffer, buf = pcm_convert_to_32(format_buffer,
src_format.format, format.format,
src.data, src.size, &len); src.data, src.size, &len);
if (buf == nullptr) { if (buf == nullptr) {
error.Format(pcm_convert_domain, error.Format(pcm_convert_domain,
"Conversion from %s to 32 bit is not implemented", "Conversion from %s to 32 bit is not implemented",
sample_format_to_string(src_format.format)); sample_format_to_string(format.format));
return nullptr; return nullptr;
} }
if (src_format.channels != dest_format.channels) { if (format.channels != dest_format.channels) {
buf = pcm_convert_channels_32(channels_buffer, buf = pcm_convert_channels_32(channels_buffer,
dest_format.channels, dest_format.channels,
src_format.channels, format.channels,
buf, len, &len); buf, len, &len);
if (buf == nullptr) { if (buf == nullptr) {
error.Format(pcm_convert_domain, error.Format(pcm_convert_domain,
"Conversion from %u to %u channels " "Conversion from %u to %u channels "
"is not implemented", "is not implemented",
src_format.channels, format.channels,
dest_format.channels); dest_format.channels);
return nullptr; return nullptr;
} }
} }
if (src_format.sample_rate != dest_format.sample_rate) { if (format.sample_rate != dest_format.sample_rate) {
buf = resampler.Resample32(dest_format.channels, buf = resampler.Resample32(dest_format.channels,
src_format.sample_rate, buf, len, format.sample_rate, buf, len,
dest_format.sample_rate, &len, dest_format.sample_rate, &len,
error); error);
if (buf == nullptr) if (buf == nullptr)
...@@ -219,7 +215,8 @@ PcmConvert::Convert32(ConstBuffer<void> src, Error &error) ...@@ -219,7 +215,8 @@ PcmConvert::Convert32(ConstBuffer<void> src, Error &error)
} }
inline ConstBuffer<float> inline ConstBuffer<float>
PcmConvert::ConvertFloat(ConstBuffer<void> src, Error &error) PcmConvert::ConvertFloat(ConstBuffer<void> src, AudioFormat format,
Error &error)
{ {
assert(dest_format.format == SampleFormat::FLOAT); assert(dest_format.format == SampleFormat::FLOAT);
...@@ -227,27 +224,27 @@ PcmConvert::ConvertFloat(ConstBuffer<void> src, Error &error) ...@@ -227,27 +224,27 @@ PcmConvert::ConvertFloat(ConstBuffer<void> src, Error &error)
size_t size; size_t size;
const float *buffer = pcm_convert_to_float(format_buffer, const float *buffer = pcm_convert_to_float(format_buffer,
src_format.format, format.format,
src.data, src.size, &size); src.data, src.size, &size);
if (buffer == nullptr) { if (buffer == nullptr) {
error.Format(pcm_convert_domain, error.Format(pcm_convert_domain,
"Conversion from %s to float is not implemented", "Conversion from %s to float is not implemented",
sample_format_to_string(src_format.format)); sample_format_to_string(format.format));
return nullptr; return nullptr;
} }
/* convert channels */ /* convert channels */
if (src_format.channels != dest_format.channels) { if (format.channels != dest_format.channels) {
buffer = pcm_convert_channels_float(channels_buffer, buffer = pcm_convert_channels_float(channels_buffer,
dest_format.channels, dest_format.channels,
src_format.channels, format.channels,
buffer, size, &size); buffer, size, &size);
if (buffer == nullptr) { if (buffer == nullptr) {
error.Format(pcm_convert_domain, error.Format(pcm_convert_domain,
"Conversion from %u to %u channels " "Conversion from %u to %u channels "
"is not implemented", "is not implemented",
src_format.channels, format.channels,
dest_format.channels); dest_format.channels);
return nullptr; return nullptr;
} }
...@@ -256,9 +253,9 @@ PcmConvert::ConvertFloat(ConstBuffer<void> src, Error &error) ...@@ -256,9 +253,9 @@ PcmConvert::ConvertFloat(ConstBuffer<void> src, Error &error)
/* resample with float, because this is the best format for /* resample with float, because this is the best format for
libsamplerate */ libsamplerate */
if (src_format.sample_rate != dest_format.sample_rate) { if (format.sample_rate != dest_format.sample_rate) {
buffer = resampler.ResampleFloat(dest_format.channels, buffer = resampler.ResampleFloat(dest_format.channels,
src_format.sample_rate, format.sample_rate,
buffer, size, buffer, size,
dest_format.sample_rate, dest_format.sample_rate,
&size, error); &size, error);
...@@ -275,10 +272,11 @@ PcmConvert::Convert(const void *src, size_t src_size, ...@@ -275,10 +272,11 @@ PcmConvert::Convert(const void *src, size_t src_size,
Error &error) Error &error)
{ {
ConstBuffer<void> buffer(src, src_size); ConstBuffer<void> buffer(src, src_size);
AudioFormat format = src_format;
if (is_dsd) { if (format.format == SampleFormat::DSD) {
auto s = ConstBuffer<uint8_t>::FromVoid(buffer); auto s = ConstBuffer<uint8_t>::FromVoid(buffer);
auto d = dsd.ToFloat(src_format.channels, auto d = dsd.ToFloat(format.channels,
false, s); false, s);
if (d.IsNull()) { if (d.IsNull()) {
error.Set(pcm_convert_domain, error.Set(pcm_convert_domain,
...@@ -287,23 +285,24 @@ PcmConvert::Convert(const void *src, size_t src_size, ...@@ -287,23 +285,24 @@ PcmConvert::Convert(const void *src, size_t src_size,
} }
buffer = d.ToVoid(); buffer = d.ToVoid();
format.format = SampleFormat::FLOAT;
} }
switch (dest_format.format) { switch (dest_format.format) {
case SampleFormat::S16: case SampleFormat::S16:
buffer = Convert16(buffer, error).ToVoid(); buffer = Convert16(buffer, format, error).ToVoid();
break; break;
case SampleFormat::S24_P32: case SampleFormat::S24_P32:
buffer = Convert24(buffer, error).ToVoid(); buffer = Convert24(buffer, format, error).ToVoid();
break; break;
case SampleFormat::S32: case SampleFormat::S32:
buffer = Convert32(buffer, error).ToVoid(); buffer = Convert32(buffer, format, error).ToVoid();
break; break;
case SampleFormat::FLOAT: case SampleFormat::FLOAT:
buffer = ConvertFloat(buffer, error).ToVoid(); buffer = ConvertFloat(buffer, format, error).ToVoid();
break; break;
default: default:
......
...@@ -52,13 +52,6 @@ class PcmConvert { ...@@ -52,13 +52,6 @@ class PcmConvert {
AudioFormat src_format, dest_format; AudioFormat src_format, dest_format;
/**
* Do we get DSD source data? Then this flag is true and
* src_format.format is set to SampleFormat::FLOAT, because
* the #PcmDsd class will convert it to floating point.
*/
bool is_dsd;
public: public:
PcmConvert(); PcmConvert();
~PcmConvert(); ~PcmConvert();
...@@ -92,10 +85,18 @@ public: ...@@ -92,10 +85,18 @@ public:
Error &error); Error &error);
private: private:
ConstBuffer<int16_t> Convert16(ConstBuffer<void> src, Error &error); ConstBuffer<int16_t> Convert16(ConstBuffer<void> src,
ConstBuffer<int32_t> Convert24(ConstBuffer<void> src, Error &error); AudioFormat format,
ConstBuffer<int32_t> Convert32(ConstBuffer<void> src, Error &error); Error &error);
ConstBuffer<float> ConvertFloat(ConstBuffer<void> src, Error &error); ConstBuffer<int32_t> Convert24(ConstBuffer<void> src,
AudioFormat format,
Error &error);
ConstBuffer<int32_t> Convert32(ConstBuffer<void> src,
AudioFormat format,
Error &error);
ConstBuffer<float> ConvertFloat(ConstBuffer<void> src,
AudioFormat format,
Error &error);
}; };
extern const Domain pcm_convert_domain; extern const Domain pcm_convert_domain;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment