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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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.
4
5 #include <limits>
6 #include <type_traits>
7
8 #include "base/logging.h"
9 #include "mojo/services/media/common/cpp/linear_transform.h"
10 #include "services/media/audio/platform/generic/output_formatter.h"
11
12 namespace mojo {
13 namespace media {
14 namespace audio {
15
16 // Template to produce destination samples from normalized samples.
17 template <typename DType, typename Enable = void> class DstConverter;
18
19 template <typename DType>
20 class DstConverter<DType,
21 typename std::enable_if<
22 std::is_same<DType, int16_t>::value,
23 void>::type> {
24 public:
25 static inline constexpr DType Convert(int32_t sample) {
26 return static_cast<DType>(sample);
27 }
28 };
29
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
30 template <typename DType>
31 class DstConverter<DType,
32 typename std::enable_if<
33 std::is_same<DType, uint8_t>::value,
34 void>::type> {
35 public:
36 static inline constexpr DType Convert(int32_t sample) {
37 return static_cast<DType>((sample >> 8) + 0x80);
38 }
39 };
40
41 // Template to fill samples with silence based on sample type.
42 template <typename DType, typename Enable = void> class SilenceMaker;
43
44 template <typename DType>
45 class SilenceMaker<DType,
46 typename std::enable_if<
47 std::is_same<DType, int16_t>::value,
48 void>::type> {
49 public:
50 static inline void Fill(void* dest, size_t samples) {
51 ::memset(dest, 0, samples * sizeof(DType));
52 }
53 };
54
55 template <typename DType>
56 class SilenceMaker<DType,
57 typename std::enable_if<
58 std::is_same<DType, uint8_t>::value,
59 void>::type> {
60 public:
61 static inline void Fill(void* dest, size_t samples) {
62 ::memset(dest, 0x80, samples * sizeof(DType));
63 }
64 };
65
66 // A templated class which implements the ProduceOutput and FillWithSilence
67 // methods of OutputFormatter
68 template <typename DType, uint32_t DChCount>
69 class OutputFormatterImpl : public OutputFormatter {
70 public:
71 explicit OutputFormatterImpl(const LpcmMediaTypeDetailsPtr& format)
72 : OutputFormatter(format, sizeof(DType), DChCount) {}
73
74 void ProduceOutput(const int32_t* source,
75 void* dest_void,
76 uint32_t frames) const override {
77 using DC = DstConverter<DType>;
78 DType* dest = static_cast<DType*>(dest_void);
79
80 for (size_t i = 0; i < (static_cast<size_t>(frames) * DChCount); ++i) {
81 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
82 if (val > std::numeric_limits<int16_t>::max()) {
83 dest[i] = DC::Convert(std::numeric_limits<int16_t>::max());
84 } else if (val < std::numeric_limits<int16_t>::min()) {
85 dest[i] = DC::Convert(std::numeric_limits<int16_t>::min());
86 } else {
87 dest[i] = DC::Convert(val);
88 }
89 }
90 }
91
92 void FillWithSilence(void* dest, uint32_t frames) const override {
93 SilenceMaker<DType>::Fill(dest, frames * DChCount);
94 }
95 };
96
97 // Constructor/destructor for the bommon OutputFormatter base class.
jeffbrown 2015/12/01 22:13:30 common
johngro 2016/01/25 18:12:32 Done.
98 OutputFormatter::OutputFormatter(const LpcmMediaTypeDetailsPtr& format,
99 uint32_t bytes_per_sample,
100 uint32_t channels)
101 : format_(format.Clone()),
102 channels_(channels),
103 bytes_per_sample_(bytes_per_sample),
104 bytes_per_frame_(bytes_per_sample * channels) {}
105
106 OutputFormatter::~OutputFormatter() {}
107
108 // Selection routines which will instantiate a particular templatized version of
109 // the output formatter.
110 template <typename DType>
111 static inline OutputFormatterPtr SelectOF(
112 const LpcmMediaTypeDetailsPtr& format) {
113 switch (format->channels) {
114 case 1:
115 return OutputFormatterPtr(new OutputFormatterImpl<DType, 1>(format));
116 case 2:
117 return OutputFormatterPtr(new OutputFormatterImpl<DType, 2>(format));
118 default:
119 LOG(ERROR) << "Unsupported output channels "
120 << format->channels;
121 return nullptr;
122 }
123 }
124
125 OutputFormatterPtr OutputFormatter::Select(
126 const LpcmMediaTypeDetailsPtr& format) {
127 DCHECK(format);
128
129 switch (format->sample_format) {
130 case LpcmSampleFormat::UNSIGNED_8:
131 return SelectOF<uint8_t>(format);
132 case LpcmSampleFormat::SIGNED_16:
133 return SelectOF<int16_t>(format);
134 default:
135 LOG(ERROR) << "Unsupported output sample format "
136 << format->sample_format;
137 return nullptr;
138 }
139 }
140
141 } // namespace audio
142 } // namespace media
143 } // namespace mojo
OLDNEW
« 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