This source file includes following definitions.
- AddInput
- RemoveInput
- ProvideInput
- fake_consumer_
- Open
- Start
- Stop
- AddOutputStream
- RemoveOutputStream
- PumpAudio
- Close
- GetMaxVolume
- SetVolume
- GetVolume
- SetAutomaticGainControl
- GetAutomaticGainControl
#include "media/audio/virtual_audio_input_stream.h"
#include <algorithm>
#include <utility>
#include "base/bind.h"
#include "base/single_thread_task_runner.h"
#include "media/audio/virtual_audio_output_stream.h"
namespace media {
class LoopbackAudioConverter : public AudioConverter::InputCallback {
public:
LoopbackAudioConverter(const AudioParameters& input_params,
const AudioParameters& output_params)
: audio_converter_(input_params, output_params, false) {}
virtual ~LoopbackAudioConverter() {}
void AddInput(AudioConverter::InputCallback* input) {
audio_converter_.AddInput(input);
}
void RemoveInput(AudioConverter::InputCallback* input) {
audio_converter_.RemoveInput(input);
}
private:
virtual double ProvideInput(AudioBus* audio_bus,
base::TimeDelta buffer_delay) OVERRIDE {
audio_converter_.Convert(audio_bus);
return 1.0;
}
AudioConverter audio_converter_;
DISALLOW_COPY_AND_ASSIGN(LoopbackAudioConverter);
};
VirtualAudioInputStream::VirtualAudioInputStream(
const AudioParameters& params,
const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner,
const AfterCloseCallback& after_close_cb)
: worker_task_runner_(worker_task_runner),
after_close_cb_(after_close_cb),
callback_(NULL),
buffer_(new uint8[params.GetBytesPerBuffer()]),
params_(params),
mixer_(params_, params_, false),
num_attached_output_streams_(0),
fake_consumer_(worker_task_runner_, params_) {
DCHECK(params_.IsValid());
DCHECK(worker_task_runner_.get());
thread_checker_.DetachFromThread();
}
VirtualAudioInputStream::~VirtualAudioInputStream() {
DCHECK(!callback_);
DCHECK_EQ(0, num_attached_output_streams_);
for (AudioConvertersMap::iterator it = converters_.begin();
it != converters_.end(); ++it) {
delete it->second;
}
}
bool VirtualAudioInputStream::Open() {
DCHECK(thread_checker_.CalledOnValidThread());
memset(buffer_.get(), 0, params_.GetBytesPerBuffer());
return true;
}
void VirtualAudioInputStream::Start(AudioInputCallback* callback) {
DCHECK(thread_checker_.CalledOnValidThread());
callback_ = callback;
fake_consumer_.Start(base::Bind(
&VirtualAudioInputStream::PumpAudio, base::Unretained(this)));
}
void VirtualAudioInputStream::Stop() {
DCHECK(thread_checker_.CalledOnValidThread());
fake_consumer_.Stop();
callback_ = NULL;
}
void VirtualAudioInputStream::AddOutputStream(
VirtualAudioOutputStream* stream, const AudioParameters& output_params) {
DCHECK(thread_checker_.CalledOnValidThread());
base::AutoLock scoped_lock(converter_network_lock_);
AudioConvertersMap::iterator converter = converters_.find(output_params);
if (converter == converters_.end()) {
std::pair<AudioConvertersMap::iterator, bool> result = converters_.insert(
std::make_pair(output_params,
new LoopbackAudioConverter(output_params, params_)));
converter = result.first;
mixer_.AddInput(converter->second);
}
converter->second->AddInput(stream);
++num_attached_output_streams_;
}
void VirtualAudioInputStream::RemoveOutputStream(
VirtualAudioOutputStream* stream, const AudioParameters& output_params) {
DCHECK(thread_checker_.CalledOnValidThread());
base::AutoLock scoped_lock(converter_network_lock_);
DCHECK(converters_.find(output_params) != converters_.end());
converters_[output_params]->RemoveInput(stream);
--num_attached_output_streams_;
DCHECK_LE(0, num_attached_output_streams_);
}
void VirtualAudioInputStream::PumpAudio(AudioBus* audio_bus) {
DCHECK(worker_task_runner_->BelongsToCurrentThread());
{
base::AutoLock scoped_lock(converter_network_lock_);
mixer_.Convert(audio_bus);
}
audio_bus->ToInterleaved(params_.frames_per_buffer(),
params_.bits_per_sample() / 8,
buffer_.get());
callback_->OnData(this,
buffer_.get(),
params_.GetBytesPerBuffer(),
params_.GetBytesPerBuffer(),
1.0);
}
void VirtualAudioInputStream::Close() {
DCHECK(thread_checker_.CalledOnValidThread());
Stop();
if (!after_close_cb_.is_null()) {
const AfterCloseCallback cb = after_close_cb_;
after_close_cb_.Reset();
cb.Run(this);
}
}
double VirtualAudioInputStream::GetMaxVolume() {
return 1.0;
}
void VirtualAudioInputStream::SetVolume(double volume) {}
double VirtualAudioInputStream::GetVolume() {
return 1.0;
}
void VirtualAudioInputStream::SetAutomaticGainControl(bool enabled) {}
bool VirtualAudioInputStream::GetAutomaticGainControl() {
return false;
}
}