summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorkylep@chromium.org <kylep@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-10 21:04:44 +0000
committerkylep@chromium.org <kylep@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-10 21:04:44 +0000
commit4cdbad1fd0f03fc0db25955acacab5e0d9e8f5c4 (patch)
tree9e4fae5c2e250c1c31ce78c17eedd73b08588f75 /media
parent78f69a4f9f08d5e983639d5648386cfe0657110e (diff)
downloadchromium_src-4cdbad1fd0f03fc0db25955acacab5e0d9e8f5c4.zip
chromium_src-4cdbad1fd0f03fc0db25955acacab5e0d9e8f5c4.tar.gz
chromium_src-4cdbad1fd0f03fc0db25955acacab5e0d9e8f5c4.tar.bz2
Modify OLA to use window size in seconds instead of bytes.
BUG=16011 TEST=none Review URL: http://codereview.chromium.org/157001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20416 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/filters/audio_renderer_algorithm_base.cc14
-rw-r--r--media/filters/audio_renderer_algorithm_base.h5
-rw-r--r--media/filters/audio_renderer_algorithm_ola.cc34
-rw-r--r--media/filters/audio_renderer_algorithm_ola.h3
-rw-r--r--media/tools/wav_ola_test.cc22
5 files changed, 59 insertions, 19 deletions
diff --git a/media/filters/audio_renderer_algorithm_base.cc b/media/filters/audio_renderer_algorithm_base.cc
index 013c716..ef6c0ec 100644
--- a/media/filters/audio_renderer_algorithm_base.cc
+++ b/media/filters/audio_renderer_algorithm_base.cc
@@ -15,6 +15,7 @@ const size_t kDefaultMaxQueueSizeInBytes = 65536;
AudioRendererAlgorithmBase::AudioRendererAlgorithmBase()
: channels_(0),
+ sample_rate_(0),
sample_bytes_(0),
playback_rate_(0.0f) {
}
@@ -22,15 +23,22 @@ AudioRendererAlgorithmBase::AudioRendererAlgorithmBase()
AudioRendererAlgorithmBase::~AudioRendererAlgorithmBase() {}
void AudioRendererAlgorithmBase::Initialize(int channels,
+ int sample_rate,
int sample_bits,
float initial_playback_rate,
RequestReadCallback* callback) {
DCHECK_GT(channels, 0);
+ DCHECK_LE(channels, 6) << "We only support <=6 channel audio.";
+ DCHECK_GT(sample_rate, 0);
+ DCHECK_LE(sample_rate, 256000)
+ << "We only support sample rates at or below 256000Hz.";
DCHECK_GT(sample_bits, 0);
- DCHECK(callback);
+ DCHECK_LE(sample_bits, 32) << "We only support 8, 16, 32 bit audio.";
DCHECK_EQ(sample_bits % 8, 0) << "We only support 8, 16, 32 bit audio.";
+ DCHECK(callback);
channels_ = channels;
+ sample_rate_ = sample_rate;
sample_bytes_ = sample_bits / 8;
request_read_callback_.reset(callback);
@@ -88,6 +96,10 @@ int AudioRendererAlgorithmBase::channels() {
return channels_;
}
+int AudioRendererAlgorithmBase::sample_rate() {
+ return sample_rate_;
+}
+
int AudioRendererAlgorithmBase::sample_bytes() {
return sample_bytes_;
}
diff --git a/media/filters/audio_renderer_algorithm_base.h b/media/filters/audio_renderer_algorithm_base.h
index d817e3d..3fc8fde 100644
--- a/media/filters/audio_renderer_algorithm_base.h
+++ b/media/filters/audio_renderer_algorithm_base.h
@@ -45,6 +45,7 @@ class AudioRendererAlgorithmBase {
// Checks validity of audio parameters and takes ownership of |callback|.
virtual void Initialize(int channels,
+ int sample_rate,
int sample_bits,
float initial_playback_rate,
RequestReadCallback* callback);
@@ -82,12 +83,16 @@ class AudioRendererAlgorithmBase {
// Number of audio channels.
virtual int channels();
+ // Sample rate in hertz.
+ virtual int sample_rate();
+
// Number of bytes per sample per channel.
virtual int sample_bytes();
private:
// Audio properties.
int channels_;
+ int sample_rate_;
int sample_bytes_;
// Used by algorithm to scale output.
diff --git a/media/filters/audio_renderer_algorithm_ola.cc b/media/filters/audio_renderer_algorithm_ola.cc
index da2992d..b32b27a 100644
--- a/media/filters/audio_renderer_algorithm_ola.cc
+++ b/media/filters/audio_renderer_algorithm_ola.cc
@@ -11,13 +11,14 @@
namespace media {
-// Default window size in bytes.
-// TODO(kylep): base the window size in seconds, not bytes.
-const size_t kDefaultWindowSize = 4096;
+// Default window and crossfade lengths in seconds.
+const double kDefaultWindowLength = 0.08;
+const double kDefaultCrossfadeLength = 0.008;
AudioRendererAlgorithmOLA::AudioRendererAlgorithmOLA()
: input_step_(0),
- output_step_(0) {
+ output_step_(0),
+ window_size_(0) {
}
AudioRendererAlgorithmOLA::~AudioRendererAlgorithmOLA() {
@@ -47,7 +48,7 @@ size_t AudioRendererAlgorithmOLA::FillBuffer(DataBuffer* buffer_out) {
// on the UI side or in set_playback_rate().
while (dest_remaining >= output_step_ + crossfade_size_) {
// If we don't have enough data to completely finish this loop, quit.
- if (QueueSize() < kDefaultWindowSize)
+ if (QueueSize() < window_size_)
break;
// Copy bulk of data to output (including some to crossfade to the next
@@ -89,7 +90,7 @@ size_t AudioRendererAlgorithmOLA::FillBuffer(DataBuffer* buffer_out) {
// Advance pointers again.
AdvanceInputPosition(crossfade_size);
- dest += crossfade_size;
+ dest += crossfade_size_;
}
return dest_written;
}
@@ -97,21 +98,32 @@ size_t AudioRendererAlgorithmOLA::FillBuffer(DataBuffer* buffer_out) {
void AudioRendererAlgorithmOLA::set_playback_rate(float new_rate) {
AudioRendererAlgorithmBase::set_playback_rate(new_rate);
+ // Calculate the window size from our default length and our audio properties.
+ // Precision is not an issue because we will round this to a sample boundary.
+ // This will not overflow because each parameter is checked in Initialize().
+ window_size_ = static_cast<size_t>(sample_rate()
+ * sample_bytes()
+ * channels()
+ * kDefaultWindowLength);
+
// Adjusting step sizes to accomodate requested playback rate.
if (playback_rate() > 1.0f) {
- input_step_ = kDefaultWindowSize;
+ input_step_ = window_size_;
output_step_ = static_cast<size_t>(ceil(
- static_cast<float>(kDefaultWindowSize / playback_rate())));
+ static_cast<float>(window_size_ / playback_rate())));
} else {
input_step_ = static_cast<size_t>(ceil(
- static_cast<float>(kDefaultWindowSize * playback_rate())));
- output_step_ = kDefaultWindowSize;
+ static_cast<float>(window_size_ * playback_rate())));
+ output_step_ = window_size_;
}
AlignToSampleBoundary(&input_step_);
AlignToSampleBoundary(&output_step_);
// Calculate length for crossfading.
- crossfade_size_ = kDefaultWindowSize / 10;
+ crossfade_size_ = static_cast<size_t>(sample_rate()
+ * sample_bytes()
+ * channels()
+ * kDefaultCrossfadeLength);
AlignToSampleBoundary(&crossfade_size_);
// To keep true to playback rate, modify the steps.
diff --git a/media/filters/audio_renderer_algorithm_ola.h b/media/filters/audio_renderer_algorithm_ola.h
index 006400c..da5cbe4 100644
--- a/media/filters/audio_renderer_algorithm_ola.h
+++ b/media/filters/audio_renderer_algorithm_ola.h
@@ -48,6 +48,9 @@ class AudioRendererAlgorithmOLA : public AudioRendererAlgorithmBase {
// Length for crossfade in bytes.
size_t crossfade_size_;
+ // Window size, in bytes (calculated from audio properties).
+ size_t window_size_;
+
DISALLOW_COPY_AND_ASSIGN(AudioRendererAlgorithmOLA);
};
diff --git a/media/tools/wav_ola_test.cc b/media/tools/wav_ola_test.cc
index 9676861..5835bf2 100644
--- a/media/tools/wav_ola_test.cc
+++ b/media/tools/wav_ola_test.cc
@@ -23,7 +23,7 @@ using file_util::ScopedFILE;
using media::AudioRendererAlgorithmOLA;
using media::DataBuffer;
-const size_t kDefaultWindowSize = 4096;
+const double kDefaultWindowLength = 0.08;
struct WavHeader {
int32 riff;
@@ -42,15 +42,16 @@ struct WavHeader {
// Dummy class to feed data to OLA algorithm. Necessary to create callback.
class Dummy {
public:
- Dummy(FILE* in, AudioRendererAlgorithmOLA* ola)
+ Dummy(FILE* in, AudioRendererAlgorithmOLA* ola, size_t window_size)
: input_(in),
- ola_(ola) {
+ ola_(ola),
+ window_size_(window_size) {
}
void ReadDataForAlg() {
scoped_refptr<DataBuffer> b(new DataBuffer());
- uint8* buf = b->GetWritableData(kDefaultWindowSize);
- if (fread(buf, 1, kDefaultWindowSize, input_) > 0) {
+ uint8* buf = b->GetWritableData(window_size_);
+ if (fread(buf, 1, window_size_, input_) > 0) {
ola_->EnqueueBuffer(b.get());
}
}
@@ -58,6 +59,7 @@ class Dummy {
private:
FILE* input_;
AudioRendererAlgorithmOLA* ola_;
+ size_t window_size_;
DISALLOW_COPY_AND_ASSIGN(Dummy);
};
@@ -104,11 +106,17 @@ int main(int argc, const char** argv) {
return 1;
}
+ size_t window_size = static_cast<size_t>(wav.sample_rate
+ * (wav.bit_rate / 8)
+ * wav.channels
+ * kDefaultWindowLength);
+
// Instantiate dummy class and callback to feed data to |ola|.
- Dummy guy(input.get(), &ola);
+ Dummy guy(input.get(), &ola, window_size);
AudioRendererAlgorithmOLA::RequestReadCallback* cb =
NewCallback(&guy, &Dummy::ReadDataForAlg);
ola.Initialize(wav.channels,
+ wav.sample_rate,
wav.bit_rate,
static_cast<float>(playback_rate),
cb);
@@ -129,7 +137,7 @@ int main(int argc, const char** argv) {
// Create buffer to be filled by |ola|.
scoped_refptr<DataBuffer> buffer(new DataBuffer());
- uint8* buf = buffer->GetWritableData(kDefaultWindowSize);
+ uint8* buf = buffer->GetWritableData(window_size);
// Keep track of bytes written to disk and bytes copied to |b|.
size_t bytes_written = 0;