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 { |
+ 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; |
+ |
+ 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 |