[refactor] More post-NSS WebCrypto cleanups (utility functions).
[chromium-blink-merge.git] / content / browser / speech / audio_encoder.cc
blobf7846390fa643710ca47a8cb56b92da0b05829ac
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/speech/audio_encoder.h"
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "content/browser/speech/audio_buffer.h"
12 namespace content {
14 namespace {
16 const char* const kContentTypeFLAC = "audio/x-flac; rate=";
17 const int kFLACCompressionLevel = 0; // 0 for speed
19 FLAC__StreamEncoderWriteStatus WriteCallback(
20 const FLAC__StreamEncoder* encoder,
21 const FLAC__byte buffer[],
22 size_t bytes,
23 unsigned samples,
24 unsigned current_frame,
25 void* client_data) {
26 AudioBuffer* encoded_audio_buffer = static_cast<AudioBuffer*>(client_data);
27 encoded_audio_buffer->Enqueue(buffer, bytes);
28 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
31 } // namespace
33 AudioEncoder::AudioEncoder(int sampling_rate, int bits_per_sample)
34 : encoded_audio_buffer_(1), /* Byte granularity of encoded samples. */
35 encoder_(FLAC__stream_encoder_new()),
36 is_encoder_initialized_(false) {
37 FLAC__stream_encoder_set_channels(encoder_, 1);
38 FLAC__stream_encoder_set_bits_per_sample(encoder_, bits_per_sample);
39 FLAC__stream_encoder_set_sample_rate(encoder_, sampling_rate);
40 FLAC__stream_encoder_set_compression_level(encoder_, kFLACCompressionLevel);
42 // Initializing the encoder will cause sync bytes to be written to
43 // its output stream, so we wait until the first call to Encode()
44 // before doing so.
47 AudioEncoder::~AudioEncoder() {
48 FLAC__stream_encoder_delete(encoder_);
51 void AudioEncoder::Encode(const AudioChunk& raw_audio) {
52 DCHECK_EQ(raw_audio.bytes_per_sample(), 2);
53 if (!is_encoder_initialized_) {
54 const FLAC__StreamEncoderInitStatus encoder_status =
55 FLAC__stream_encoder_init_stream(encoder_, WriteCallback, NULL, NULL,
56 NULL, &encoded_audio_buffer_);
57 DCHECK_EQ(encoder_status, FLAC__STREAM_ENCODER_INIT_STATUS_OK);
58 is_encoder_initialized_ = true;
61 // FLAC encoder wants samples as int32s.
62 const int num_samples = raw_audio.NumSamples();
63 scoped_ptr<FLAC__int32[]> flac_samples(new FLAC__int32[num_samples]);
64 FLAC__int32* flac_samples_ptr = flac_samples.get();
65 for (int i = 0; i < num_samples; ++i)
66 flac_samples_ptr[i] = static_cast<FLAC__int32>(raw_audio.GetSample16(i));
68 FLAC__stream_encoder_process(encoder_, &flac_samples_ptr, num_samples);
71 void AudioEncoder::Flush() {
72 FLAC__stream_encoder_finish(encoder_);
75 scoped_refptr<AudioChunk> AudioEncoder::GetEncodedDataAndClear() {
76 return encoded_audio_buffer_.DequeueAll();
79 std::string AudioEncoder::GetMimeType() {
80 return std::string(kContentTypeFLAC) +
81 base::IntToString(FLAC__stream_encoder_get_sample_rate(encoder_));
84 int AudioEncoder::GetBitsPerSample() {
85 return FLAC__stream_encoder_get_bits_per_sample(encoder_);
88 } // namespace content