diff options
author | dalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-20 01:59:39 +0000 |
---|---|---|
committer | dalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-20 01:59:39 +0000 |
commit | a9721dd681919183d4a9c9062475e6c21a7a339a (patch) | |
tree | 8deb998359ca3133b5da2c9259b36d5f37f9e8d0 /media/audio | |
parent | 185fd4761b276f12d7dc0e6d90f547a9c6570055 (diff) | |
download | chromium_src-a9721dd681919183d4a9c9062475e6c21a7a339a.zip chromium_src-a9721dd681919183d4a9c9062475e6c21a7a339a.tar.gz chromium_src-a9721dd681919183d4a9c9062475e6c21a7a339a.tar.bz2 |
Introduce AudioHash for fuzzy audio matching.
The old MD5 approach is too strict due to differences in floating
point implementations on each platform. AudioHash provides a simple
algorithm for ensuring signals are within roughly -40 dBFS.
BUG=168204
TEST=media_unittests on Linux && Win.
Review URL: https://chromiumcodereview.appspot.com/12925002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@189197 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio')
-rw-r--r-- | media/audio/null_audio_sink.cc | 50 | ||||
-rw-r--r-- | media/audio/null_audio_sink.h | 15 |
2 files changed, 12 insertions, 53 deletions
diff --git a/media/audio/null_audio_sink.cc b/media/audio/null_audio_sink.cc index 8fee966..5c4f67a 100644 --- a/media/audio/null_audio_sink.cc +++ b/media/audio/null_audio_sink.cc @@ -6,9 +6,8 @@ #include "base/bind.h" #include "base/message_loop_proxy.h" -#include "base/stringprintf.h" -#include "base/sys_byteorder.h" #include "media/audio/fake_audio_consumer.h" +#include "media/base/audio_hash.h" namespace media { @@ -17,8 +16,6 @@ NullAudioSink::NullAudioSink( : initialized_(false), playing_(false), callback_(NULL), - hash_audio_for_testing_(false), - channels_(0), message_loop_(message_loop) { } @@ -27,16 +24,7 @@ NullAudioSink::~NullAudioSink() {} void NullAudioSink::Initialize(const AudioParameters& params, RenderCallback* callback) { DCHECK(!initialized_); - fake_consumer_.reset(new FakeAudioConsumer(message_loop_, params)); - - if (hash_audio_for_testing_) { - channels_ = params.channels(); - md5_channel_contexts_.reset(new base::MD5Context[params.channels()]); - for (int i = 0; i < params.channels(); i++) - base::MD5Init(&md5_channel_contexts_[i]); - } - callback_ = callback; initialized_ = true; } @@ -85,47 +73,19 @@ void NullAudioSink::CallRender(AudioBus* audio_bus) { DCHECK(message_loop_->BelongsToCurrentThread()); int frames_received = callback_->Render(audio_bus, 0); - if (!hash_audio_for_testing_ || frames_received <= 0) + if (!audio_hash_ || frames_received <= 0) return; - DCHECK_EQ(sizeof(float), sizeof(uint32)); - int channels = audio_bus->channels(); - for (int channel_idx = 0; channel_idx < channels; ++channel_idx) { - float* channel = audio_bus->channel(channel_idx); - for (int frame_idx = 0; frame_idx < frames_received; frame_idx++) { - // Convert float to uint32 w/o conversion loss. - uint32 frame = base::ByteSwapToLE32(bit_cast<uint32>(channel[frame_idx])); - base::MD5Update(&md5_channel_contexts_[channel_idx], base::StringPiece( - reinterpret_cast<char*>(&frame), sizeof(frame))); - } - } + audio_hash_->Update(audio_bus, frames_received); } void NullAudioSink::StartAudioHashForTesting() { DCHECK(!initialized_); - hash_audio_for_testing_ = true; + audio_hash_.reset(new AudioHash()); } std::string NullAudioSink::GetAudioHashForTesting() { - DCHECK(hash_audio_for_testing_); - - base::MD5Digest digest; - if (channels_ == 0) { - // If initialize failed or was never called, ensure we return an empty hash. - base::MD5Context context; - base::MD5Init(&context); - base::MD5Final(&digest, &context); - } else { - // Hash all channels into the first channel. - for (int i = 1; i < channels_; i++) { - base::MD5Final(&digest, &md5_channel_contexts_[i]); - base::MD5Update(&md5_channel_contexts_[0], base::StringPiece( - reinterpret_cast<char*>(&digest), sizeof(base::MD5Digest))); - } - base::MD5Final(&digest, &md5_channel_contexts_[0]); - } - - return base::MD5DigestToBase16(digest); + return audio_hash_ ? audio_hash_->ToString() : ""; } } // namespace media diff --git a/media/audio/null_audio_sink.h b/media/audio/null_audio_sink.h index 9fb7237..37022b7 100644 --- a/media/audio/null_audio_sink.h +++ b/media/audio/null_audio_sink.h @@ -5,7 +5,8 @@ #ifndef MEDIA_AUDIO_NULL_AUDIO_SINK_H_ #define MEDIA_AUDIO_NULL_AUDIO_SINK_H_ -#include "base/md5.h" +#include <string> + #include "base/memory/scoped_ptr.h" #include "media/base/audio_renderer_sink.h" @@ -15,6 +16,7 @@ class MessageLoopProxy; namespace media { class AudioBus; +class AudioHash; class FakeAudioConsumer; class MEDIA_EXPORT NullAudioSink @@ -31,11 +33,10 @@ class MEDIA_EXPORT NullAudioSink virtual void Play() OVERRIDE; virtual bool SetVolume(double volume) OVERRIDE; - // Enables audio frame hashing and reinitializes the MD5 context. Must be - // called prior to Initialize(). + // Enables audio frame hashing. Must be called prior to Initialize(). void StartAudioHashForTesting(); - // Returns the MD5 hash of all audio frames seen since the last reset. + // Returns the hash of all audio frames seen since construction. std::string GetAudioHashForTesting(); protected: @@ -49,10 +50,8 @@ class MEDIA_EXPORT NullAudioSink bool playing_; RenderCallback* callback_; - // Controls whether or not a running MD5 hash is computed for audio frames. - bool hash_audio_for_testing_; - int channels_; - scoped_array<base::MD5Context> md5_channel_contexts_; + // Controls whether or not a running hash is computed for audio frames. + scoped_ptr<AudioHash> audio_hash_; scoped_refptr<base::MessageLoopProxy> message_loop_; scoped_ptr<FakeAudioConsumer> fake_consumer_; |