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