Index: media/audio/audio_util.cc |
=================================================================== |
--- media/audio/audio_util.cc (revision 68541) |
+++ media/audio/audio_util.cc (working copy) |
@@ -158,4 +158,50 @@ |
return false; |
} |
+bool DeinterleaveAudioChannel(void* source, |
+ float* destination, |
+ AVSampleFormat sample_fmt, |
+ size_t number_of_channels, |
+ unsigned channel_index, |
+ unsigned number_of_frames) { |
+ switch (sample_fmt) { |
+ case AV_SAMPLE_FMT_S16: |
+ { |
+ int16* source16 = static_cast<int16*>(source) + channel_index; |
+ const float kScale = 1.0f / 32768.0f; |
+ for (unsigned i = 0; i < number_of_frames; ++i) { |
+ destination[i] = kScale * *source16; |
+ source16 += number_of_channels; |
+ } |
+ return true; |
+ } |
+ |
+ case AV_SAMPLE_FMT_S32: |
+ { |
+ int32* source32 = static_cast<int32*>(source) + channel_index; |
+ const float kScale = 1.0f / (1L << 31); |
+ for (unsigned i = 0; i < number_of_frames; ++i) { |
+ destination[i] = kScale * *source32; |
+ source32 += number_of_channels; |
+ } |
+ return true; |
+ } |
+ |
+ case AV_SAMPLE_FMT_U8: |
+ { |
+ uint8* source8 = static_cast<uint8*>(source) + channel_index; |
+ const float kScale = 1.0f / 128.0f; |
+ for (unsigned i = 0; i < number_of_frames; ++i) { |
+ destination[i] = kScale * static_cast<int>(*source8 + 128); |
+ source8 += number_of_channels; |
+ } |
+ return true; |
+ } |
+ |
+ default: |
+ break; |
+ } |
+ return false; |
+} |
+ |
} // namespace media |