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