12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// MSVC++ requires this to be set before any other includes to get M_PI.
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define _USE_MATH_DEFINES
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <cmath>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/audio_hash.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/audio_bus.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace media {
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AudioHash::AudioHash()
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : audio_hash_(),
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sample_count_(0) {
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AudioHash::~AudioHash() {}
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AudioHash::Update(const AudioBus* audio_bus, int frames) {
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Use uint32 to ensure overflow is a defined operation.
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (uint32 ch = 0; ch < static_cast<uint32>(audio_bus->channels()); ++ch) {
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const float* channel = audio_bus->channel(ch);
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (uint32 i = 0; i < static_cast<uint32>(frames); ++i) {
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const uint32 kSampleIndex = sample_count_ + i;
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const uint32 kHashIndex =
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          (kSampleIndex * (ch + 1)) % arraysize(audio_hash_);
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Mix in a sine wave with the result so we ensure that sequences of empty
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // buffers don't result in an empty hash.
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (ch == 0) {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        audio_hash_[kHashIndex] +=
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            channel[i] + sin(2.0 * M_PI * M_PI * kSampleIndex);
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        audio_hash_[kHashIndex] += channel[i];
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sample_count_ += static_cast<uint32>(frames);
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string AudioHash::ToString() const {
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string result;
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < arraysize(audio_hash_); ++i)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    result += base::StringPrintf("%.2f,", audio_hash_[i]);
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return result;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}  // namespace media
54