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