Chromium Code Reviews| Index: services/media/framework/lpcm_util.cc |
| diff --git a/services/media/framework/lpcm_util.cc b/services/media/framework/lpcm_util.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c2121a4fe017dd69e8f1c22e82f78e0535bbe1ac |
| --- /dev/null |
| +++ b/services/media/framework/lpcm_util.cc |
| @@ -0,0 +1,127 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "base/logging.h" |
| +#include "services/media/framework/lpcm_util.h" |
| +#include "services/media/framework/ostream.h" |
| + |
| +namespace mojo { |
| +namespace media { |
| + |
| +LpcmUtil* LpcmUtil::Create(const LpcmStreamType& stream_type) { |
| + switch (stream_type.sample_format()) { |
| + case LpcmStreamType::SampleFormat::kUnsigned8: |
| + case LpcmStreamType::SampleFormat::kAny: |
| + return new LpcmUtilImpl<uint8_t>(stream_type); |
| + case LpcmStreamType::SampleFormat::kSigned16: |
| + return new LpcmUtilImpl<int16_t>(stream_type); |
| + case LpcmStreamType::SampleFormat::kSigned24In32: |
| + return new LpcmUtilImpl<int32_t>(stream_type); |
| + case LpcmStreamType::SampleFormat::kFloat: |
| + return new LpcmUtilImpl<float>(stream_type); |
| + default: |
| + NOTREACHED() |
| + << "unsupported sample format " << stream_type.sample_format(); |
| + return nullptr; |
| + } |
| +} |
| + |
| +template<typename T> |
| +LpcmUtilImpl<T>::LpcmUtilImpl(const LpcmStreamType& stream_type) : |
| + stream_type_(stream_type) {} |
| + |
| +template<typename T> |
| +LpcmUtilImpl<T>::~LpcmUtilImpl() {} |
| + |
| +template<typename T> |
| +void LpcmUtilImpl<T>::Silence(void* buffer, uint64_t frame_count) const { |
|
johngro
2016/01/25 18:55:43
for the cases of filling a non-float, signed buffe
dalesat
2016/01/25 23:29:37
Done.
|
| + T* sample = reinterpret_cast<T*>(buffer); |
| + for ( |
| + uint64_t sample_countdown = frame_count * stream_type_.channels(); |
| + sample_countdown != 0; |
| + --sample_countdown) { |
| + *sample = 0; |
| + sample++; |
| + } |
| +} |
| + |
| +template<> |
| +void LpcmUtilImpl<uint8_t>::Silence(void* buffer, uint64_t frame_count) const { |
| + uint8_t* sample = reinterpret_cast<uint8_t*>(buffer); |
| + for ( |
| + uint64_t sample_countdown = frame_count * stream_type_.channels(); |
| + sample_countdown != 0; |
| + --sample_countdown) { |
| + *sample = 0x80; |
| + sample++; |
| + } |
| +} |
| + |
| +template<typename T> |
| +void LpcmUtilImpl<T>::Copy(void* in, void* out, uint64_t frame_count) const { |
| + std::memcpy(out, in, stream_type_.min_buffer_size(frame_count)); |
| +} |
| + |
| +template<typename T> |
| +void LpcmUtilImpl<T>::Mix(void* in, void* out, uint64_t frame_count) const { |
| + T* in_sample = reinterpret_cast<T*>(in); |
| + T* out_sample = reinterpret_cast<T*>(out); |
| + for ( |
| + uint64_t sample_countdown = frame_count * stream_type_.channels(); |
| + sample_countdown != 0; |
| + --sample_countdown) { |
| + *out_sample += *in_sample; // TODO(dalesat): Limit. |
| + out_sample++; |
| + in_sample++; |
| + } |
| +} |
| + |
| +template<> |
| +void LpcmUtilImpl<uint8_t>::Mix(void* in, void* out, uint64_t frame_count) |
| + const { |
| + uint8_t* in_sample = reinterpret_cast<uint8_t*>(in); |
| + uint8_t* out_sample = reinterpret_cast<uint8_t*>(out); |
| + for ( |
| + uint64_t sample_countdown = frame_count * stream_type_.channels(); |
| + sample_countdown != 0; |
| + --sample_countdown) { |
| + *out_sample = uint8_t(uint16_t(*out_sample) + uint16_t(*in_sample) - 0x80); |
| + // TODO(dalesat): Limit. |
| + out_sample++; |
| + in_sample++; |
| + } |
| +} |
| + |
| +template<typename T> |
| +void LpcmUtilImpl<T>::Interleave( |
| + void* in, |
| + uint64_t in_byte_count, |
| + void* out, |
| + uint64_t frame_count) const { |
| + DCHECK(in); |
| + DCHECK(in_byte_count); |
| + DCHECK(out); |
| + DCHECK(frame_count); |
| + |
| + uint32_t channels = stream_type_.channels(); |
| + uint64_t in_channel_stride = in_byte_count / channels; |
|
johngro
2016/01/25 18:55:43
see comment in header re: in_byte_count. That sai
dalesat
2016/01/25 23:29:37
Done.
|
| + |
| + uint8_t* in_channel = reinterpret_cast<uint8_t*>(in); |
| + uint8_t* out_channel = reinterpret_cast<uint8_t*>(out); |
| + |
| + for (uint32_t channel = channels; channel != 0; --channel) { |
| + T* in_sample = reinterpret_cast<T*>(in_channel); |
| + T* out_sample = reinterpret_cast<T*>(out_channel); |
| + for (uint64_t frame = frame_count; frame != 0; --frame) { |
| + *out_sample = *in_sample; |
| + ++in_sample; |
| + out_sample += channels; |
| + } |
| + in_channel += in_channel_stride; |
| + out_channel += stream_type_.sample_size(); |
| + } |
| +} |
| + |
| +} // namespace media |
| +} // namespace mojo |