1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "MediaInfo.h"
8
9 namespace mozilla {
10
11 typedef AudioConfig::ChannelLayout ChannelLayout;
12
13 /**
14 * AudioConfig::ChannelLayout
15 */
16
17 /*
18 SMPTE channel layout (also known as wave order)
19 DUAL-MONO L R
20 DUAL-MONO-LFE L R LFE
21 MONO M
22 MONO-LFE M LFE
23 STEREO L R
24 STEREO-LFE L R LFE
25 3F L R C
26 3F-LFE L R C LFE
27 2F1 L R S
28 2F1-LFE L R LFE S
29 3F1 L R C S
30 3F1-LFE L R C LFE S
31 2F2 L R LS RS
32 2F2-LFE L R LFE LS RS
33 3F2 L R C LS RS
34 3F2-LFE L R C LFE LS RS
35 3F3R-LFE L R C LFE BC LS RS
36 3F4-LFE L R C LFE Rls Rrs LS RS
37 */
38
39 void
UpdateChannelMap()40 AudioConfig::ChannelLayout::UpdateChannelMap()
41 {
42 mChannelMap = 0;
43 mValid = mChannels.Length() <= MAX_AUDIO_CHANNELS;
44 for (size_t i = 0; i < mChannels.Length() && i <= MAX_AUDIO_CHANNELS; i++) {
45 uint32_t mask = 1 << mChannels[i];
46 if (mChannels[i] == CHANNEL_INVALID || (mChannelMap & mask)) {
47 mValid = false;
48 }
49 mChannelMap |= mask;
50 }
51 }
52
53 /* static */ const AudioConfig::Channel*
SMPTEDefault(uint32_t aChannels) const54 AudioConfig::ChannelLayout::SMPTEDefault(uint32_t aChannels) const
55 {
56 switch (aChannels) {
57 case 1: // MONO
58 {
59 static const Channel config[] = { CHANNEL_MONO };
60 return config;
61 }
62 case 2: // STEREO
63 {
64 static const Channel config[] = { CHANNEL_LEFT, CHANNEL_RIGHT };
65 return config;
66 }
67 case 3: // 3F
68 {
69 static const Channel config[] = { CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_CENTER };
70 return config;
71 }
72 case 4: // 2F2
73 {
74 static const Channel config[] = { CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_LS, CHANNEL_RS };
75 return config;
76 }
77 case 5: // 3F2
78 {
79 static const Channel config[] = { CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_CENTER, CHANNEL_LS, CHANNEL_RS };
80 return config;
81 }
82 case 6: // 3F2-LFE
83 {
84 static const Channel config[] = { CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_CENTER, CHANNEL_LFE, CHANNEL_LS, CHANNEL_RS };
85 return config;
86 }
87 case 7: // 3F3R-LFE
88 {
89 static const Channel config[] = { CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_CENTER, CHANNEL_LFE, CHANNEL_RCENTER, CHANNEL_LS, CHANNEL_RS };
90 return config;
91 }
92 case 8: // 3F4-LFE
93 {
94 static const Channel config[] = { CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_CENTER, CHANNEL_LFE, CHANNEL_RLS, CHANNEL_RRS, CHANNEL_LS, CHANNEL_RS };
95 return config;
96 }
97 default:
98 return nullptr;
99 }
100 }
101
102 bool
MappingTable(const ChannelLayout & aOther,uint8_t * aMap) const103 AudioConfig::ChannelLayout::MappingTable(const ChannelLayout& aOther,
104 uint8_t* aMap) const
105 {
106 if (!IsValid() || !aOther.IsValid() ||
107 Map() != aOther.Map()) {
108 return false;
109 }
110 if (!aMap) {
111 return true;
112 }
113 for (uint32_t i = 0; i < Count(); i++) {
114 for (uint32_t j = 0; j < Count(); j++) {
115 if (aOther[j] == mChannels[i]) {
116 aMap[j] = i;
117 break;
118 }
119 }
120 }
121 return true;
122 }
123
124 /**
125 * AudioConfig::ChannelConfig
126 */
127
128 /* static */ const char*
FormatToString(AudioConfig::SampleFormat aFormat)129 AudioConfig::FormatToString(AudioConfig::SampleFormat aFormat)
130 {
131 switch (aFormat) {
132 case FORMAT_U8: return "unsigned 8 bit";
133 case FORMAT_S16: return "signed 16 bit";
134 case FORMAT_S24: return "signed 24 bit MSB";
135 case FORMAT_S24LSB: return "signed 24 bit LSB";
136 case FORMAT_S32: return "signed 32 bit";
137 case FORMAT_FLT: return "32 bit floating point";
138 case FORMAT_NONE: return "none";
139 default: return "unknown";
140 }
141 }
142 /* static */ uint32_t
SampleSize(AudioConfig::SampleFormat aFormat)143 AudioConfig::SampleSize(AudioConfig::SampleFormat aFormat)
144 {
145 switch (aFormat) {
146 case FORMAT_U8: return 1;
147 case FORMAT_S16: return 2;
148 case FORMAT_S24: MOZ_FALLTHROUGH;
149 case FORMAT_S24LSB: MOZ_FALLTHROUGH;
150 case FORMAT_S32: MOZ_FALLTHROUGH;
151 case FORMAT_FLT: return 4;
152 case FORMAT_NONE:
153 default: return 0;
154 }
155 }
156
157 /* static */ uint32_t
FormatToBits(AudioConfig::SampleFormat aFormat)158 AudioConfig::FormatToBits(AudioConfig::SampleFormat aFormat)
159 {
160 switch (aFormat) {
161 case FORMAT_U8: return 8;
162 case FORMAT_S16: return 16;
163 case FORMAT_S24LSB: MOZ_FALLTHROUGH;
164 case FORMAT_S24: return 24;
165 case FORMAT_S32: MOZ_FALLTHROUGH;
166 case FORMAT_FLT: return 32;
167 case FORMAT_NONE: MOZ_FALLTHROUGH;
168 default: return 0;
169 }
170 }
171
AudioConfig(const ChannelLayout & aChannelLayout,uint32_t aRate,AudioConfig::SampleFormat aFormat,bool aInterleaved)172 AudioConfig::AudioConfig(const ChannelLayout& aChannelLayout, uint32_t aRate,
173 AudioConfig::SampleFormat aFormat, bool aInterleaved)
174 : mChannelLayout(aChannelLayout)
175 , mChannels(aChannelLayout.Count())
176 , mRate(aRate)
177 , mFormat(aFormat)
178 , mInterleaved(aInterleaved)
179 {}
180
AudioConfig(uint32_t aChannels,uint32_t aRate,AudioConfig::SampleFormat aFormat,bool aInterleaved)181 AudioConfig::AudioConfig(uint32_t aChannels, uint32_t aRate,
182 AudioConfig::SampleFormat aFormat, bool aInterleaved)
183 : mChannelLayout(aChannels)
184 , mChannels(aChannels)
185 , mRate(aRate)
186 , mFormat(aFormat)
187 , mInterleaved(aInterleaved)
188 {}
189
190 } // namespace mozilla
191