blob: 188952c7c634dcfd26cf39bf9676cb2f4b4ba07f [file] [log] [blame]
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/filters/reference_audio_renderer.h"
#include <math.h>
#include "base/logging.h"
#include "media/base/filter_host.h"
#include "media/audio/audio_manager.h"
namespace media {
// This is an arbitrary number, ~184ms in a 44.1kHz stream, assuming a playback
// rate of 1.0.
static const size_t kSamplesPerBuffer = 8 * 1024;
ReferenceAudioRenderer::ReferenceAudioRenderer()
: AudioRendererBase(),
stream_(NULL),
bytes_per_second_(0) {
}
ReferenceAudioRenderer::~ReferenceAudioRenderer() {
// Close down the audio device.
if (stream_) {
stream_->Stop();
stream_->Close();
}
}
void ReferenceAudioRenderer::SetPlaybackRate(float rate) {
// TODO(fbarchard): limit rate to reasonable values
AudioRendererBase::SetPlaybackRate(rate);
static bool started = false;
if (rate > 0.0f && !started && stream_)
stream_->Start(this);
}
void ReferenceAudioRenderer::SetVolume(float volume) {
if (stream_)
stream_->SetVolume(volume);
}
uint32 ReferenceAudioRenderer::OnMoreData(
AudioOutputStream* stream, uint8* dest, uint32 len,
AudioBuffersState buffers_state) {
// TODO(scherkus): handle end of stream.
if (!stream_)
return 0;
// TODO(fbarchard): Waveout_output_win.h should handle zero length buffers
// without clicking.
uint32 pending_bytes = static_cast<uint32>(ceil(buffers_state.total_bytes() *
GetPlaybackRate()));
base::TimeDelta delay = base::TimeDelta::FromMicroseconds(
base::Time::kMicrosecondsPerSecond * pending_bytes /
bytes_per_second_);
bool buffers_empty = buffers_state.pending_bytes == 0;
return FillBuffer(dest, len, delay, buffers_empty);
}
void ReferenceAudioRenderer::OnClose(AudioOutputStream* stream) {
// TODO(scherkus): implement OnClose.
NOTIMPLEMENTED();
}
void ReferenceAudioRenderer::OnError(AudioOutputStream* stream, int code) {
// TODO(scherkus): implement OnError.
NOTIMPLEMENTED();
}
bool ReferenceAudioRenderer::OnInitialize(int bits_per_channel,
ChannelLayout channel_layout,
int sample_rate) {
AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, channel_layout,
sample_rate, bits_per_channel, kSamplesPerBuffer);
bytes_per_second_ = params.GetBytesPerSecond();
// Create our audio stream.
stream_ = AudioManager::GetAudioManager()->MakeAudioOutputStream(params);
if (!stream_)
return false;
if (!stream_->Open()) {
stream_->Close();
stream_ = NULL;
}
return true;
}
void ReferenceAudioRenderer::OnStop() {
if (stream_)
stream_->Stop();
}
} // namespace media