Home | History | Annotate | Download | only in media
      1 // Copyright (c) 2010 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.
      4 
      5 #include "webkit/glue/media/audio_decoder.h"
      6 
      7 #include <vector>
      8 #include "base/basictypes.h"
      9 #include "base/string_util.h"
     10 #include "base/time.h"
     11 #include "media/filters/audio_file_reader.h"
     12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAudioBus.h"
     13 
     14 using media::AudioFileReader;
     15 using media::InMemoryDataReader;
     16 using std::vector;
     17 using WebKit::WebAudioBus;
     18 
     19 namespace webkit_glue {
     20 
     21 // Decode in-memory audio file data.
     22 bool DecodeAudioFileData(
     23     WebKit::WebAudioBus* destination_bus,
     24     const char* data, size_t data_size, double sample_rate) {
     25   DCHECK(destination_bus);
     26   if (!destination_bus)
     27     return false;
     28 
     29   // Uses the FFmpeg library for audio file reading.
     30   InMemoryDataReader data_reader(data, data_size);
     31   AudioFileReader reader(&data_reader);
     32 
     33   if (!reader.Open())
     34     return false;
     35 
     36   size_t number_of_channels = reader.channels();
     37   double file_sample_rate = reader.sample_rate();
     38   double duration = reader.duration().InSecondsF();
     39   size_t number_of_frames = static_cast<size_t>(reader.number_of_frames());
     40 
     41   // TODO(crogers) : do sample-rate conversion with FFmpeg.
     42   // For now, we're ignoring the requested 'sample_rate' and returning
     43   // the WebAudioBus at the file's sample-rate.
     44   // double destination_sample_rate =
     45   //   (sample_rate != 0.0) ? sample_rate : file_sample_rate;
     46   double destination_sample_rate = file_sample_rate;
     47 
     48   DLOG(INFO) << "Decoding file data -"
     49       << " data: " << data
     50       << " data size: " << data_size
     51       << " duration: " << duration
     52       << " number of frames: " << number_of_frames
     53       << " sample rate: " << file_sample_rate
     54       << " number of channels: " << number_of_channels;
     55 
     56   // Change to destination sample-rate.
     57   number_of_frames = static_cast<size_t>(number_of_frames *
     58       (destination_sample_rate / file_sample_rate));
     59 
     60   // Allocate and configure the output audio channel data.
     61   destination_bus->initialize(number_of_channels,
     62                               number_of_frames,
     63                               destination_sample_rate);
     64 
     65   // Wrap the channel pointers which will receive the decoded PCM audio.
     66   vector<float*> audio_data;
     67   audio_data.reserve(number_of_channels);
     68   for (size_t i = 0; i < number_of_channels; ++i) {
     69     audio_data.push_back(destination_bus->channelData(i));
     70   }
     71 
     72   // Decode the audio file data.
     73   return reader.Read(audio_data, number_of_frames);
     74 }
     75 
     76 }  // namespace webkit_glue
     77