1 // Copyright (c) 2011 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 "webkit/media/audio_decoder.h"
8 #include "base/basictypes.h"
9 #include "base/string_util.h"
10 #include "base/time.h"
11 #include "media/base/limits.h"
12 #include "media/filters/audio_file_reader.h"
13 #include "media/filters/in_memory_url_protocol.h"
14 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebAudioBus.h"
16 using media::AudioFileReader
;
17 using media::InMemoryUrlProtocol
;
19 using WebKit::WebAudioBus
;
21 namespace webkit_media
{
23 // Decode in-memory audio file data.
24 bool DecodeAudioFileData(
25 WebKit::WebAudioBus
* destination_bus
,
26 const char* data
, size_t data_size
, double sample_rate
) {
27 DCHECK(destination_bus
);
31 // Uses the FFmpeg library for audio file reading.
32 InMemoryUrlProtocol
url_protocol(reinterpret_cast<const uint8
*>(data
),
34 AudioFileReader
reader(&url_protocol
);
39 size_t number_of_channels
= reader
.channels();
40 double file_sample_rate
= reader
.sample_rate();
41 double duration
= reader
.duration().InSecondsF();
42 size_t number_of_frames
= static_cast<size_t>(reader
.number_of_frames());
44 // Apply sanity checks to make sure crazy values aren't coming out of
46 if (!number_of_channels
||
47 number_of_channels
> static_cast<size_t>(media::limits::kMaxChannels
) ||
48 file_sample_rate
< media::limits::kMinSampleRate
||
49 file_sample_rate
> media::limits::kMaxSampleRate
)
52 // TODO(crogers) : do sample-rate conversion with FFmpeg.
53 // For now, we're ignoring the requested 'sample_rate' and returning
54 // the WebAudioBus at the file's sample-rate.
55 // double destination_sample_rate =
56 // (sample_rate != 0.0) ? sample_rate : file_sample_rate;
57 double destination_sample_rate
= file_sample_rate
;
59 DLOG(INFO
) << "Decoding file data -"
61 << " data size: " << data_size
62 << " duration: " << duration
63 << " number of frames: " << number_of_frames
64 << " sample rate: " << file_sample_rate
65 << " number of channels: " << number_of_channels
;
67 // Change to destination sample-rate.
68 number_of_frames
= static_cast<size_t>(number_of_frames
*
69 (destination_sample_rate
/ file_sample_rate
));
71 // Allocate and configure the output audio channel data.
72 destination_bus
->initialize(number_of_channels
,
74 destination_sample_rate
);
76 // Wrap the channel pointers which will receive the decoded PCM audio.
77 vector
<float*> audio_data
;
78 audio_data
.reserve(number_of_channels
);
79 for (size_t i
= 0; i
< number_of_channels
; ++i
) {
80 audio_data
.push_back(destination_bus
->channelData(i
));
83 // Decode the audio file data.
84 return reader
.Read(audio_data
, number_of_frames
);
87 } // namespace webkit_media