AudioResampler.h (3910B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 4 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef DOM_MEDIA_DRIFTCONTROL_AUDIORESAMPLER_H_ 7 #define DOM_MEDIA_DRIFTCONTROL_AUDIORESAMPLER_H_ 8 9 #include "AudioChunkList.h" 10 #include "AudioSegment.h" 11 #include "DynamicResampler.h" 12 13 namespace mozilla { 14 15 /** 16 * Audio Resampler is a resampler able to change the input rate and channels 17 * count on the fly. The API is simple and it is based in AudioSegment in order 18 * to be used MTG. Memory allocations, for input and output buffers, will happen 19 * in the constructor, when channel count changes and if the amount of input 20 * data outgrows the input buffer. The memory is recycled in order to avoid 21 * reallocations. It also supports prebuffering of silence. It consists of 22 * DynamicResampler and AudioChunkList so please read their documentation if you 23 * are interested in more details. 24 * 25 * The output buffer is preallocated and returned in the form of AudioSegment. 26 * The intention is to be used directly in a MediaTrack. Since an AudioChunk 27 * must no be "shared" in order to be written, the AudioSegment returned by 28 * resampler method must be cleaned up in order to be able for the `AudioChunk`s 29 * that it consists of to be reused. For `MediaTrack::mSegment` this happens 30 * every ~50ms (look at MediaTrack::AdvanceTimeVaryingValuesToCurrentTime). Thus 31 * memory capacity of 100ms has been preallocated for internal input and output 32 * buffering. Note that the amount of memory used for input buffering may 33 * increase if needed. 34 */ 35 class AudioResampler final { 36 public: 37 AudioResampler(uint32_t aInRate, uint32_t aOutRate, 38 uint32_t aInputPreBufferFrameCount, 39 const PrincipalHandle& aPrincipalHandle); 40 41 /** 42 * Append input data into the resampler internal buffer. Copy/move of the 43 * memory is taking place. Also, the channel count will change according to 44 * the channel count of the chunks. 45 */ 46 void AppendInput(const AudioSegment& aInSegment); 47 /** 48 * Get the number of frames that the internal input buffer can hold. 49 */ 50 uint32_t InputCapacityFrames() const; 51 /** 52 * Get the number of frames that can be read from the internal input buffer 53 * before it becomes empty. 54 */ 55 uint32_t InputReadableFrames() const; 56 57 /* 58 * Reguest `aOutFrames` of audio in the output sample rate. The internal 59 * buffered input is used. If the input buffer does not have enough data to 60 * reach `aOutFrames` frames, the input buffer is padded with enough silence 61 * to allow the requested frames to be resampled and returned, and the 62 * pre-buffer is reset so that the next call will be treated as the first. 63 * 64 * On first call, prepends the internal buffer with silence so that after 65 * resampling aOutFrames frames of data, the internal buffer holds input 66 * data as close as possible to the configured pre-buffer size. 67 */ 68 AudioSegment Resample(uint32_t aOutFrames, bool* aHasUnderrun); 69 70 /* 71 * Updates the input rate that will be used by the resampler. 72 */ 73 void UpdateInRate(uint32_t aInRate) { 74 Update(aInRate, mResampler.GetChannels()); 75 } 76 77 /** 78 * Set the number of frames that should be used for input pre-buffering. 79 */ 80 void SetInputPreBufferFrameCount(uint32_t aInputPreBufferFrameCount) { 81 mResampler.SetInputPreBufferFrameCount(aInputPreBufferFrameCount); 82 } 83 84 private: 85 void UpdateChannels(uint32_t aChannels) { 86 Update(mResampler.GetInRate(), aChannels); 87 } 88 void Update(uint32_t aInRate, uint32_t aChannels); 89 90 private: 91 DynamicResampler mResampler; 92 AudioChunkList mOutputChunks; 93 bool mIsSampleFormatSet = false; 94 }; 95 96 } // namespace mozilla 97 98 #endif // DOM_MEDIA_DRIFTCONTROL_AUDIORESAMPLER_H_