Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(186)

Unified Diff: services/media/audio/platform/generic/output_formatter.cc

Issue 1471813002: Mix to an intermediate buffer. (Closed) Base URL: https://github.com/domokit/mojo.git@change7
Patch Set: rebase on top of samples_per_frame -> channels patchset Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: services/media/audio/platform/generic/output_formatter.cc
diff --git a/services/media/audio/platform/generic/output_formatter.cc b/services/media/audio/platform/generic/output_formatter.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8c26c8396132d75bb5bb0b9779f63222228ece33
--- /dev/null
+++ b/services/media/audio/platform/generic/output_formatter.cc
@@ -0,0 +1,143 @@
+// Copyright 2015 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 <limits>
+#include <type_traits>
+
+#include "base/logging.h"
+#include "mojo/services/media/common/cpp/linear_transform.h"
+#include "services/media/audio/platform/generic/output_formatter.h"
+
+namespace mojo {
+namespace media {
+namespace audio {
+
+// Template to produce destination samples from normalized samples.
+template <typename DType, typename Enable = void> class DstConverter;
+
+template <typename DType>
+class DstConverter<DType,
+ typename std::enable_if<
+ std::is_same<DType, int16_t>::value,
+ void>::type> {
+ public:
+ static inline constexpr DType Convert(int32_t sample) {
+ return static_cast<DType>(sample);
+ }
+};
+
dalesat 2016/01/24 19:07:39 Can we just define a template function and special
johngro 2016/01/25 18:12:32 Its been a while, but this can fail in some cases
+template <typename DType>
+class DstConverter<DType,
+ typename std::enable_if<
+ std::is_same<DType, uint8_t>::value,
+ void>::type> {
+ public:
+ static inline constexpr DType Convert(int32_t sample) {
+ return static_cast<DType>((sample >> 8) + 0x80);
+ }
+};
+
+// Template to fill samples with silence based on sample type.
+template <typename DType, typename Enable = void> class SilenceMaker;
+
+template <typename DType>
+class SilenceMaker<DType,
+ typename std::enable_if<
+ std::is_same<DType, int16_t>::value,
+ void>::type> {
+ public:
+ static inline void Fill(void* dest, size_t samples) {
+ ::memset(dest, 0, samples * sizeof(DType));
+ }
+};
+
+template <typename DType>
+class SilenceMaker<DType,
+ typename std::enable_if<
+ std::is_same<DType, uint8_t>::value,
+ void>::type> {
+ public:
+ static inline void Fill(void* dest, size_t samples) {
+ ::memset(dest, 0x80, samples * sizeof(DType));
+ }
+};
+
+// A templated class which implements the ProduceOutput and FillWithSilence
+// methods of OutputFormatter
+template <typename DType, uint32_t DChCount>
+class OutputFormatterImpl : public OutputFormatter {
+ public:
+ explicit OutputFormatterImpl(const LpcmMediaTypeDetailsPtr& format)
+ : OutputFormatter(format, sizeof(DType), DChCount) {}
+
+ void ProduceOutput(const int32_t* source,
+ void* dest_void,
+ uint32_t frames) const override {
+ using DC = DstConverter<DType>;
+ DType* dest = static_cast<DType*>(dest_void);
+
+ for (size_t i = 0; i < (static_cast<size_t>(frames) * DChCount); ++i) {
+ register int32_t val = source[i];
jeffbrown 2015/12/01 22:13:30 Does the register keyword even do anything these d
johngro 2016/01/25 18:12:32 probably not, but it does not hurt either. It has
+ if (val > std::numeric_limits<int16_t>::max()) {
+ dest[i] = DC::Convert(std::numeric_limits<int16_t>::max());
+ } else if (val < std::numeric_limits<int16_t>::min()) {
+ dest[i] = DC::Convert(std::numeric_limits<int16_t>::min());
+ } else {
+ dest[i] = DC::Convert(val);
+ }
+ }
+ }
+
+ void FillWithSilence(void* dest, uint32_t frames) const override {
+ SilenceMaker<DType>::Fill(dest, frames * DChCount);
+ }
+};
+
+// Constructor/destructor for the bommon OutputFormatter base class.
jeffbrown 2015/12/01 22:13:30 common
johngro 2016/01/25 18:12:32 Done.
+OutputFormatter::OutputFormatter(const LpcmMediaTypeDetailsPtr& format,
+ uint32_t bytes_per_sample,
+ uint32_t channels)
+ : format_(format.Clone()),
+ channels_(channels),
+ bytes_per_sample_(bytes_per_sample),
+ bytes_per_frame_(bytes_per_sample * channels) {}
+
+OutputFormatter::~OutputFormatter() {}
+
+// Selection routines which will instantiate a particular templatized version of
+// the output formatter.
+template <typename DType>
+static inline OutputFormatterPtr SelectOF(
+ const LpcmMediaTypeDetailsPtr& format) {
+ switch (format->channels) {
+ case 1:
+ return OutputFormatterPtr(new OutputFormatterImpl<DType, 1>(format));
+ case 2:
+ return OutputFormatterPtr(new OutputFormatterImpl<DType, 2>(format));
+ default:
+ LOG(ERROR) << "Unsupported output channels "
+ << format->channels;
+ return nullptr;
+ }
+}
+
+OutputFormatterPtr OutputFormatter::Select(
+ const LpcmMediaTypeDetailsPtr& format) {
+ DCHECK(format);
+
+ switch (format->sample_format) {
+ case LpcmSampleFormat::UNSIGNED_8:
+ return SelectOF<uint8_t>(format);
+ case LpcmSampleFormat::SIGNED_16:
+ return SelectOF<int16_t>(format);
+ default:
+ LOG(ERROR) << "Unsupported output sample format "
+ << format->sample_format;
+ return nullptr;
+ }
+}
+
+} // namespace audio
+} // namespace media
+} // namespace mojo
« no previous file with comments | « services/media/audio/platform/generic/output_formatter.h ('k') | services/media/audio/platform/generic/standard_output_base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698