diff --git a/daemon/src/media/audio/audiobuffer.cpp b/daemon/src/media/audio/audiobuffer.cpp index 40d11e108726cfc83af074516fb4358fd690444d..5310536e9e0682cc06bd1cb07f34f8a4519f804b 100644 --- a/daemon/src/media/audio/audiobuffer.cpp +++ b/daemon/src/media/audio/audiobuffer.cpp @@ -214,6 +214,26 @@ void AudioBuffer::deinterleave(const std::vector<ring::AudioSample>& in, AudioFo deinterleave(in.data(), in.size()/format.nb_channels, format.nb_channels); } +void AudioBuffer::convertFloatPlanarToSigned16(uint8_t** extended_data, size_t frame_num, unsigned nb_channels) +{ + if (extended_data == nullptr) + return; + + // Resize buffer + setChannelNum(nb_channels); + resize(frame_num); + + for (unsigned j = 0, c = channels(); j < c; j++){ + float* inputChannel = (float*)extended_data[j]; + for (unsigned i=0, f=frames(); i < f; i++){ + float inputChannelVal = *inputChannel++; + // avoid saturation: limit val between -1 and 1 + inputChannelVal = std::max(-1.0f, std::min(inputChannelVal, 1.0f)); + samples_[j][i] = (int16_t) (inputChannelVal * 32768.0f); + } + } +} + size_t AudioBuffer::mix(const AudioBuffer& other, bool up /* = true */) { const bool upmix = up && (other.samples_.size() < samples_.size()); diff --git a/daemon/src/media/audio/audiobuffer.h b/daemon/src/media/audio/audiobuffer.h index 3d22eb9e4778862284fae8e22fc78bfb006571cd..fffd5c2c7e3deebda5f45c7c32853812865efb72 100644 --- a/daemon/src/media/audio/audiobuffer.h +++ b/daemon/src/media/audio/audiobuffer.h @@ -288,6 +288,12 @@ class AudioBuffer { */ void deinterleave(const std::vector<ring::AudioSample>& in, AudioFormat format); + /** + * convert float planar data to signed 16 + */ + void convertFloatPlanarToSigned16(uint8_t** extended_data, size_t frame_num, unsigned nb_channels = 1); + + /** * In-place gain transformation. * diff --git a/daemon/src/media/media_decoder.cpp b/daemon/src/media/media_decoder.cpp index 4a14fef7885303e6ff74f660e3d356533d4ce536..2b8a517da7e6ba42e0db7e21e6128bb4141fdee6 100644 --- a/daemon/src/media/media_decoder.cpp +++ b/daemon/src/media/media_decoder.cpp @@ -432,8 +432,13 @@ void MediaDecoder::writeToRingBuffer(AVFrame* decoded_frame, ring::AudioBuffer out(decoded_frame->nb_samples, decoderFormat); - out.deinterleave(reinterpret_cast<const ring::AudioSample*>(decoded_frame->data[0]), - decoded_frame->nb_samples, decoderCtx_->channels); + if ( decoderCtx_->sample_fmt == AV_SAMPLE_FMT_FLTP ) { + out.convertFloatPlanarToSigned16(decoded_frame->extended_data, + decoded_frame->nb_samples, decoderCtx_->channels); + } else if ( decoderCtx_->sample_fmt == AV_SAMPLE_FMT_S16 ) { + out.deinterleave(reinterpret_cast<const ring::AudioSample*>(decoded_frame->data[0]), + decoded_frame->nb_samples, decoderCtx_->channels); + } if ((unsigned)decoded_frame->sample_rate != outFormat.sample_rate) { if (!resampler_) { RING_DBG("Creating audio resampler");