1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 // 5 // AudioConverter is a complete mixing, resampling, buffering, and channel 6 // mixing solution for converting data from one set of AudioParameters to 7 // another. 8 // 9 // For efficiency, pieces are only invoked when necessary; i.e., 10 // - The resampler is only used if sample rates differ. 11 // - The FIFO is only used if buffer sizes differ. 12 // - The channel mixer is only used if channel layouts differ. 13 // 14 // Additionally, since resampling is the most expensive operation, input mixing 15 // and channel down mixing are done prior to resampling. Likewise, channel up 16 // mixing is performed after resampling. 17 18 #ifndef MEDIA_BASE_AUDIO_CONVERTER_H_ 19 #define MEDIA_BASE_AUDIO_CONVERTER_H_ 20 21 #include <list> 22 #include <memory> 23 24 #include "base/callback.h" 25 #include "base/macros.h" 26 #include "base/time/time.h" 27 #include "media/base/audio_parameters.h" 28 #include "media/base/media_export.h" 29 30 namespace media { 31 32 class AudioBus; 33 class AudioPullFifo; 34 class ChannelMixer; 35 class MultiChannelResampler; 36 37 // Converts audio data between two AudioParameters formats. Sample usage: 38 // AudioParameters input(...), output(...); 39 // AudioConverter ac(input, output); 40 // std::unique_ptr<AudioBus> output_audio_bus = AudioBus::Create(output); 41 // ac.AddInput(<AudioConverter::InputCallback* 1>); 42 // ac.AddInput(<AudioConverter::InputCallback* 2>); 43 // ac.Convert(output_audio_bus.get()); 44 // 45 // Convert() will ask for input audio data from each InputCallback and convert 46 // the data into the provided AudioBus. 47 class MEDIA_EXPORT AudioConverter { 48 public: 49 // Interface for inputs into the converter. Each InputCallback is added or 50 // removed from Convert() processing via AddInput() and RemoveInput(). 51 class MEDIA_EXPORT InputCallback { 52 public: 53 // Method for providing more data into the converter. Expects |audio_bus| 54 // to be completely filled with data upon return; zero padded if not enough 55 // frames are available to satisfy the request. The return value is the 56 // volume level of the provided audio data. If a volume level of zero is 57 // returned no further processing will be done on the provided data, else 58 // the volume level will be used to scale the provided audio data. 59 // |frames_delayed| is given in terms of the input sample rate. 60 virtual double ProvideInput(AudioBus* audio_bus, 61 uint32_t frames_delayed) = 0; 62 63 protected: ~InputCallback()64 virtual ~InputCallback() {} 65 }; 66 67 // Constructs an AudioConverter for converting between the given input and 68 // output parameters. Specifying |disable_fifo| means all InputCallbacks are 69 // capable of handling arbitrary buffer size requests; i.e. one call might ask 70 // for 10 frames of data (indicated by the size of AudioBus provided) and the 71 // next might ask for 20. In synthetic testing, disabling the FIFO yields a 72 // ~20% speed up for common cases. 73 AudioConverter(const AudioParameters& input_params, 74 const AudioParameters& output_params, 75 bool disable_fifo); 76 ~AudioConverter(); 77 78 // Converts audio from all inputs into the |dest|. If |frames_delayed| is 79 // specified, it will be propagated to each input. Count of frames must be 80 // given in terms of the output sample rate. 81 void Convert(AudioBus* dest); 82 void ConvertWithDelay(uint32_t frames_delayed, AudioBus* dest); 83 84 // Adds or removes an input from the converter. RemoveInput() will call 85 // Reset() if no inputs remain after the specified input is removed. 86 void AddInput(InputCallback* input); 87 void RemoveInput(InputCallback* input); 88 89 // Flushes all buffered data. 90 void Reset(); 91 92 // The maximum size in frames that guarantees we will only make a single call 93 // to each input's ProvideInput for more data. 94 int ChunkSize() const; 95 96 // See SincResampler::PrimeWithSilence. 97 void PrimeWithSilence(); 98 99 // Maximum number of frames requested via InputCallback::ProvideInput, when 100 // trying to convert |output_frames_requested| at a time. 101 // Returns |output_frames_requested| when we are not resampling, and a 102 // multiple of the request size when we are. 103 int GetMaxInputFramesRequested(int output_frames_requested); 104 empty()105 bool empty() const { return transform_inputs_.empty(); } 106 107 private: 108 // Provides input to the MultiChannelResampler. Called by the resampler when 109 // more data is necessary. 110 void ProvideInput(int resampler_frame_delay, AudioBus* audio_bus); 111 112 // Provides input to the AudioPullFifo. Called by the fifo when more data is 113 // necessary. 114 void SourceCallback(int fifo_frame_delay, AudioBus* audio_bus); 115 116 // (Re)creates the temporary |unmixed_audio_| buffer if necessary. 117 void CreateUnmixedAudioIfNecessary(int frames); 118 119 // Set of inputs for Convert(). 120 typedef std::list<InputCallback*> InputCallbackSet; 121 InputCallbackSet transform_inputs_; 122 123 // Used to buffer data between the client and the output device in cases where 124 // the client buffer size is not the same as the output device buffer size. 125 std::unique_ptr<AudioPullFifo> audio_fifo_; 126 int chunk_size_; 127 128 // Handles resampling. 129 std::unique_ptr<MultiChannelResampler> resampler_; 130 131 // Handles channel transforms. |unmixed_audio_| is a temporary destination 132 // for audio data before it goes into the channel mixer. 133 std::unique_ptr<ChannelMixer> channel_mixer_; 134 std::unique_ptr<AudioBus> unmixed_audio_; 135 136 // Temporary AudioBus destination for mixing inputs. 137 std::unique_ptr<AudioBus> mixer_input_audio_bus_; 138 139 // Since resampling is expensive, figure out if we should downmix channels 140 // before resampling. 141 bool downmix_early_; 142 143 // Used to calculate buffer delay information for InputCallbacks. 144 uint32_t initial_frames_delayed_; 145 uint32_t resampler_frames_delayed_; 146 const double io_sample_rate_ratio_; 147 148 // Number of channels of input audio data. Set during construction via the 149 // value from the input AudioParameters class. Preserved to recreate internal 150 // AudioBus structures on demand in response to varying frame size requests. 151 const int input_channel_count_; 152 153 DISALLOW_COPY_AND_ASSIGN(AudioConverter); 154 }; 155 156 } // namespace media 157 158 #endif // MEDIA_BASE_AUDIO_CONVERTER_H_ 159