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.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef MEDIA_AUDIO_VIRTUAL_AUDIO_INPUT_STREAM_H_
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MEDIA_AUDIO_VIRTUAL_AUDIO_INPUT_STREAM_H_
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <map>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <set>
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/gtest_prod_util.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/synchronization/lock.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/threading/thread_checker.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/audio/audio_io.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/audio/audio_parameters.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/audio/fake_audio_consumer.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/audio_converter.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base {
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class SingleThreadTaskRunner;
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace media {
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class LoopbackAudioConverter;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class VirtualAudioOutputStream;
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// VirtualAudioInputStream converts and mixes audio from attached
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// VirtualAudioOutputStreams into a single stream. It will continuously render
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// audio until this VirtualAudioInputStream is stopped and closed.
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MEDIA_EXPORT VirtualAudioInputStream : public AudioInputStream {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Callback invoked just after VirtualAudioInputStream is closed.
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef base::Callback<void(VirtualAudioInputStream* vais)>
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AfterCloseCallback;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Construct a target for audio loopback which mixes multiple data streams
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // into a single stream having the given |params|.  |worker_task_runner| is
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // the task runner on which AudioInputCallback methods are called and may or
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // may not be the single thread that invokes the AudioInputStream methods.
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  VirtualAudioInputStream(
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const AudioParameters& params,
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner,
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const AfterCloseCallback& after_close_cb);
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~VirtualAudioInputStream();
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // AudioInputStream:
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool Open() OVERRIDE;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Start(AudioInputCallback* callback) OVERRIDE;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Stop() OVERRIDE;
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Close() OVERRIDE;
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual double GetMaxVolume() OVERRIDE;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetVolume(double volume) OVERRIDE;
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual double GetVolume() OVERRIDE;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetAutomaticGainControl(bool enabled) OVERRIDE;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool GetAutomaticGainControl() OVERRIDE;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Attaches a VirtualAudioOutputStream to be used as input. This
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // VirtualAudioInputStream must outlive all attached streams, so any attached
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // stream must be closed (which causes a detach) before
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // VirtualAudioInputStream is destroyed.
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddOutputStream(VirtualAudioOutputStream* stream,
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               const AudioParameters& output_params);
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Detaches a VirtualAudioOutputStream and removes it as input.
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void RemoveOutputStream(VirtualAudioOutputStream* stream,
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const AudioParameters& output_params);
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class VirtualAudioInputStreamTest;
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef std::map<AudioParameters, LoopbackAudioConverter*> AudioConvertersMap;
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Pulls audio data from all attached VirtualAudioOutputStreams, mixes and
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // converts the streams into one, and pushes the result to |callback_|.
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Invoked on the worker thread.
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void PumpAudio(AudioBus* audio_bus);
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner_;
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AfterCloseCallback after_close_cb_;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AudioInputCallback* callback_;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Non-const for testing.
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<uint8[]> buffer_;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AudioParameters params_;
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Guards concurrent access to the converter network: converters_, mixer_, and
92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // num_attached_output_streams_.
93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::Lock converter_network_lock_;
94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // AudioConverters associated with the attached VirtualAudioOutputStreams,
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // partitioned by common AudioParameters.
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AudioConvertersMap converters_;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // AudioConverter that takes all the audio converters and mixes them into one
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // final audio stream.
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AudioConverter mixer_;
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Number of currently attached VirtualAudioOutputStreams.
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int num_attached_output_streams_;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Handles callback timing for consumption of audio data.
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeAudioConsumer fake_consumer_;
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::ThreadChecker thread_checker_;
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(VirtualAudioInputStream);
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace media
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // MEDIA_AUDIO_VIRTUAL_AUDIO_INPUT_STREAM_H_
117