audio_converter.h revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// AudioConverter is a complete mixing, resampling, buffering, and channel 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// mixing solution for converting data from one set of AudioParameters to 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// another. 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// For efficiency, pieces are only invoked when necessary; i.e., 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - The resampler is only used if sample rates differ. 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - The FIFO is only used if buffer sizes differ. 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - The channel mixer is only used if channel layouts differ. 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Additionally, since resampling is the most expensive operation, input mixing 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// and channel down mixing are done prior to resampling. Likewise, channel up 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// mixing is performed after resampling. 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef MEDIA_BASE_AUDIO_CONVERTER_H_ 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MEDIA_BASE_AUDIO_CONVERTER_H_ 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <list> 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/callback.h" 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/audio/audio_parameters.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/media_export.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace media { 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AudioBus; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AudioPullFifo; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ChannelMixer; 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MultiChannelResampler; 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Converts audio data between two AudioParameters formats. Sample usage: 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// AudioParameters input(...), output(...); 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// AudioConverter ac(input, output); 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// scoped_ptr<AudioBus> output_audio_bus = AudioBus::Create(output); 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ac.AddInput(<AudioConverter::InputCallback* 1>); 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ac.AddInput(<AudioConverter::InputCallback* 2>); 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ac.Convert(output_audio_bus.get()); 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Convert() will ask for input audio data from each InputCallback and convert 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the data into the provided AudioBus. 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MEDIA_EXPORT AudioConverter { 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Interface for inputs into the converter. Each InputCallback is added or 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // removed from Convert() processing via AddInput() and RemoveInput(). 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class MEDIA_EXPORT InputCallback { 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Method for providing more data into the converter. Expects |audio_bus| 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to be completely filled with data upon return; zero padded if not enough 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // frames are available to satisfy the request. The return value is the 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // volume level of the provided audio data. If a volume level of zero is 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // returned no further processing will be done on the provided data, else 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the volume level will be used to scale the provided audio data. 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual double ProvideInput(AudioBus* audio_bus, 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta buffer_delay) = 0; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~InputCallback() {} 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Constructs an AudioConverter for converting between the given input and 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // output parameters. Specifying |disable_fifo| means all InputCallbacks are 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // capable of handling arbitrary buffer size requests; i.e. one call might ask 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // for 10 frames of data (indicated by the size of AudioBus provided) and the 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // next might ask for 20. In synthetic testing, disabling the FIFO yields a 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ~20% speed up for common cases. 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AudioConverter(const AudioParameters& input_params, 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const AudioParameters& output_params, 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool disable_fifo); 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~AudioConverter(); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Converts audio from all inputs into the |dest|. |dest| must be sized for 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // data matching the output AudioParameters provided during construction. If 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // an |initial_delay| is specified, it will be propagated to each input. 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Convert(AudioBus* dest); 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void ConvertWithDelay(const base::TimeDelta& initial_delay, AudioBus* dest); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Adds or removes an input from the converter. RemoveInput() will call 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Reset() if no inputs remain after the specified input is removed. 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void AddInput(InputCallback* input); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void RemoveInput(InputCallback* input); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Flushes all buffered data. 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Reset(); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Provides input to the MultiChannelResampler. Called by the resampler when 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // more data is necessary. 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ProvideInput(int resampler_frame_delay, AudioBus* audio_bus); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Provides input to the AudioPullFifo. Called by the fifo when more data is 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // necessary. 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SourceCallback(int fifo_frame_delay, AudioBus* audio_bus); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set of inputs for Convert(). 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef std::list<InputCallback*> InputCallbackSet; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InputCallbackSet transform_inputs_; 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Used to buffer data between the client and the output device in cases where 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the client buffer size is not the same as the output device buffer size. 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AudioPullFifo> audio_fifo_; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Handles resampling. 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<MultiChannelResampler> resampler_; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Handles channel transforms. |unmixed_audio_| is a temporary destination 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // for audio data before it goes into the channel mixer. 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ChannelMixer> channel_mixer_; 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AudioBus> unmixed_audio_; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Temporary AudioBus destination for mixing inputs. 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AudioBus> mixer_input_audio_bus_; 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Since resampling is expensive, figure out if we should downmix channels 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // before resampling. 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool downmix_early_; 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Used to calculate buffer delay information for InputCallbacks. 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta input_frame_duration_; 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta output_frame_duration_; 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::TimeDelta initial_delay_; 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int resampler_frame_delay_; 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Number of channels of input audio data. Set during construction via the 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // value from the input AudioParameters class. Preserved to recreate internal 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // AudioBus structures on demand in response to varying frame size requests. 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int input_channel_count_; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AudioConverter); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace media 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // MEDIA_BASE_AUDIO_CONVERTER_H_ 139