summaryrefslogtreecommitdiffstats
path: root/media/audio
diff options
context:
space:
mode:
authordalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-20 01:59:39 +0000
committerdalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-20 01:59:39 +0000
commita9721dd681919183d4a9c9062475e6c21a7a339a (patch)
tree8deb998359ca3133b5da2c9259b36d5f37f9e8d0 /media/audio
parent185fd4761b276f12d7dc0e6d90f547a9c6570055 (diff)
downloadchromium_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.cc50
-rw-r--r--media/audio/null_audio_sink.h15
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_;