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