Skip to content
Extraits de code Groupes Projets
Valider 93ad15ef rédigé par Thomas Goyne's avatar Thomas Goyne
Parcourir les fichiers

Reuse the decoding buffer in the audio converters

parent b9c75d87
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -28,6 +28,8 @@ namespace { ...@@ -28,6 +28,8 @@ namespace {
template<class Target> template<class Target>
class BitdepthConvertAudioProvider final : public AudioProviderWrapper { class BitdepthConvertAudioProvider final : public AudioProviderWrapper {
int src_bytes_per_sample; int src_bytes_per_sample;
mutable std::vector<uint8_t> src_buf;
public: public:
BitdepthConvertAudioProvider(std::unique_ptr<AudioProvider> src) : AudioProviderWrapper(std::move(src)) { BitdepthConvertAudioProvider(std::unique_ptr<AudioProvider> src) : AudioProviderWrapper(std::move(src)) {
if (bytes_per_sample > 8) if (bytes_per_sample > 8)
...@@ -38,7 +40,7 @@ public: ...@@ -38,7 +40,7 @@ public:
} }
void FillBuffer(void *buf, int64_t start, int64_t count) const override { void FillBuffer(void *buf, int64_t start, int64_t count) const override {
std::vector<uint8_t> src_buf(count * src_bytes_per_sample * channels); src_buf.resize(count * src_bytes_per_sample * channels);
source->GetAudio(src_buf.data(), start, count); source->GetAudio(src_buf.data(), start, count);
auto dest = static_cast<int16_t*>(buf); auto dest = static_cast<int16_t*>(buf);
...@@ -70,6 +72,8 @@ public: ...@@ -70,6 +72,8 @@ public:
/// Floating point -> 16 bit signed machine-endian audio converter /// Floating point -> 16 bit signed machine-endian audio converter
template<class Source, class Target> template<class Source, class Target>
class FloatConvertAudioProvider final : public AudioProviderWrapper { class FloatConvertAudioProvider final : public AudioProviderWrapper {
mutable std::vector<Source> src_buf;
public: public:
FloatConvertAudioProvider(std::unique_ptr<AudioProvider> src) : AudioProviderWrapper(std::move(src)) { FloatConvertAudioProvider(std::unique_ptr<AudioProvider> src) : AudioProviderWrapper(std::move(src)) {
bytes_per_sample = sizeof(Target); bytes_per_sample = sizeof(Target);
...@@ -77,10 +81,10 @@ public: ...@@ -77,10 +81,10 @@ public:
} }
void FillBuffer(void *buf, int64_t start, int64_t count) const override { void FillBuffer(void *buf, int64_t start, int64_t count) const override {
std::vector<Source> src_buf(count * channels); src_buf.resize(count * channels);
source->GetAudio(&src_buf[0], start, count); source->GetAudio(&src_buf[0], start, count);
auto dest = reinterpret_cast<Target*>(buf); auto dest = static_cast<Target*>(buf);
for (size_t i = 0; i < static_cast<size_t>(count * channels); ++i) { for (size_t i = 0; i < static_cast<size_t>(count * channels); ++i) {
Source expanded; Source expanded;
...@@ -102,23 +106,19 @@ public: ...@@ -102,23 +106,19 @@ public:
/// Non-mono 16-bit signed machine-endian -> mono 16-bit signed machine endian converter /// Non-mono 16-bit signed machine-endian -> mono 16-bit signed machine endian converter
class DownmixAudioProvider final : public AudioProviderWrapper { class DownmixAudioProvider final : public AudioProviderWrapper {
int src_channels; int src_channels;
mutable std::vector<int16_t> src_buf;
public: public:
DownmixAudioProvider(std::unique_ptr<AudioProvider> src) : AudioProviderWrapper(std::move(src)) { DownmixAudioProvider(std::unique_ptr<AudioProvider> src) : AudioProviderWrapper(std::move(src)) {
if (bytes_per_sample != 2)
throw InternalError("DownmixAudioProvider requires 16-bit input");
if (channels == 1)
throw InternalError("DownmixAudioProvider requires multi-channel input");
src_channels = channels; src_channels = channels;
channels = 1; channels = 1;
} }
void FillBuffer(void *buf, int64_t start, int64_t count) const override { void FillBuffer(void *buf, int64_t start, int64_t count) const override {
if (count == 0) return; src_buf.resize(count * src_channels);
std::vector<int16_t> src_buf(count * src_channels);
source->GetAudio(&src_buf[0], start, count); source->GetAudio(&src_buf[0], start, count);
int16_t *dst = reinterpret_cast<int16_t*>(buf); auto dst = static_cast<int16_t*>(buf);
// Just average the channels together // Just average the channels together
while (count-- > 0) { while (count-- > 0) {
int sum = 0; int sum = 0;
...@@ -129,24 +129,17 @@ public: ...@@ -129,24 +129,17 @@ public:
} }
}; };
/// Sample doubler with linear interpolation for the agi::make_unique<samples> /// Sample doubler with linear interpolation for the samples provider
/// Requires 16-bit mono input /// Requires 16-bit mono input
class SampleDoublingAudioProvider final : public AudioProviderWrapper { class SampleDoublingAudioProvider final : public AudioProviderWrapper {
public: public:
SampleDoublingAudioProvider(std::unique_ptr<AudioProvider> src) : AudioProviderWrapper(std::move(src)) { SampleDoublingAudioProvider(std::unique_ptr<AudioProvider> src) : AudioProviderWrapper(std::move(src)) {
if (source->GetBytesPerSample() != 2)
throw InternalError("UpsampleAudioProvider requires 16-bit input");
if (source->GetChannels() != 1)
throw InternalError("UpsampleAudioProvider requires mono input");
sample_rate *= 2; sample_rate *= 2;
num_samples *= 2; num_samples *= 2;
decoded_samples = decoded_samples * 2; decoded_samples = decoded_samples * 2;
} }
void FillBuffer(void *buf, int64_t start, int64_t count) const override { void FillBuffer(void *buf, int64_t start, int64_t count) const override {
if (count == 0) return;
bool not_end = start + count < num_samples; bool not_end = start + count < num_samples;
int64_t src_count = count / 2; int64_t src_count = count / 2;
source->GetAudio(buf, start / 2, src_count + not_end); source->GetAudio(buf, start / 2, src_count + not_end);
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter