15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/speech/audio_buffer.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioChunk::AudioChunk(int bytes_per_sample)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : bytes_per_sample_(bytes_per_sample) {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioChunk::AudioChunk(const uint8* data, size_t length, int bytes_per_sample)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : data_string_(reinterpret_cast<const char*>(data), length),
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bytes_per_sample_(bytes_per_sample) {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(length % bytes_per_sample, 0U);
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AudioChunk::IsEmpty() const {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return data_string_.empty();
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t AudioChunk::NumSamples() const {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return data_string_.size() / bytes_per_sample_;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const std::string& AudioChunk::AsString() const {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return data_string_;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int16 AudioChunk::GetSample16(size_t index) const {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(index < (data_string_.size() / sizeof(int16)));
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SamplesData16()[index];
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int16* AudioChunk::SamplesData16() const {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return reinterpret_cast<const int16*>(data_string_.data());
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioBuffer::AudioBuffer(int bytes_per_sample)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : bytes_per_sample_(bytes_per_sample) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(bytes_per_sample == 1 ||
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         bytes_per_sample == 2 ||
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         bytes_per_sample == 4);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioBuffer::~AudioBuffer() {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Clear();
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioBuffer::Enqueue(const uint8* data, size_t length) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chunks_.push_back(new AudioChunk(data, length, bytes_per_sample_));
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<AudioChunk> AudioBuffer::DequeueSingleChunk() {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!chunks_.empty());
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<AudioChunk> chunk(chunks_.front());
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chunks_.pop_front();
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return chunk;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<AudioChunk> AudioBuffer::DequeueAll() {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<AudioChunk> chunk(new AudioChunk(bytes_per_sample_));
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t resulting_length = 0;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChunksContainer::const_iterator it;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In order to improve performance, calulate in advance the total length
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and then copy the chunks.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (it = chunks_.begin(); it != chunks_.end(); ++it) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resulting_length += (*it)->data_string_.length();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chunk->data_string_.reserve(resulting_length);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (it = chunks_.begin(); it != chunks_.end(); ++it) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    chunk->data_string_.append((*it)->data_string_);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Clear();
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return chunk;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioBuffer::Clear() {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chunks_.clear();
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AudioBuffer::IsEmpty() const {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return chunks_.empty();
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
92