2 ** Copyright (C) 2009-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU Lesser General Public License as published by
6 ** the Free Software Foundation; either version 2.1 of the License, or
7 ** (at your option) any later version.
9 ** This program is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ** GNU Lesser General Public License for more details.
14 ** You should have received a copy of the GNU Lesser General Public License
15 ** along with this program; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 ** Mostly from "Apple Core Audio Format Specification 1.0":
22 ** http://developer.apple.com/documentation/MusicAudio/Reference/CAFSpec/CAFSpec.pdf
36 static const AIFF_CAF_CHANNEL_MAP zero_chan
[] =
37 { { (0 << 16) | 0, NULL
, "Use channel descriptions." },
38 { (1 << 16) | 0, NULL
, "Use channel bitmap." }
42 static const int one_chan_mono
[1] = { SF_CHANNEL_MAP_MONO
} ;
44 static const AIFF_CAF_CHANNEL_MAP one_chan
[] =
45 { { (100 << 16) | 1, one_chan_mono
, "mono" }
49 static const int two_channel_stereo
[2] = { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
} ;
51 static const AIFF_CAF_CHANNEL_MAP two_chan
[] =
52 { { (101 << 16) | 2, two_channel_stereo
, "stereo (L, R)" },
53 { (102 << 16) | 2, two_channel_stereo
, "stereo headphones (L, R)" },
55 { (103 << 16) | 2, NULL
, "matrix stereo (Lt, Rt)" },
56 { (104 << 16) | 2, NULL
, "2 channels (mid, side)" },
57 { (105 << 16) | 2, NULL
, "coincident mic pair" },
58 { (106 << 16) | 2, NULL
, "binaural stereo (L, R)"
64 static const int three_channel_mpeg_30a
[3] =
65 { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_CENTER
} ;
66 static const int three_channel_mpeg_30b
[3] =
67 { SF_CHANNEL_MAP_CENTER
, SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
} ;
68 static const int three_channel_itu_21
[3] =
69 { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_REAR_CENTER
} ;
70 static const int three_channel_dvd_4
[3] =
71 { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_LFE
} ;
73 static const AIFF_CAF_CHANNEL_MAP three_chan
[] =
74 { { (113 << 16) | 3, three_channel_mpeg_30a
, "MPEG 3 0 A (L, R, C)" },
75 { (114 << 16) | 3, three_channel_mpeg_30b
, "MPEG 3 0 B (C, L, R)" },
76 { (131 << 16) | 3, three_channel_itu_21
, "ITU 2.1 (L, R, Cs)" },
77 { (133 << 16) | 3, three_channel_dvd_4
, "DVD 4 (L, R, LFE)" }
81 static const int four_channel_ambisonc_b
[4] =
82 { SF_CHANNEL_MAP_AMBISONIC_B_W
, SF_CHANNEL_MAP_AMBISONIC_B_X
, SF_CHANNEL_MAP_AMBISONIC_B_Y
, SF_CHANNEL_MAP_AMBISONIC_B_Z
} ;
83 static const int four_channel_quad
[4] =
84 { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_REAR_LEFT
, SF_CHANNEL_MAP_REAR_RIGHT
} ;
85 static const int four_channel_mpeg_40a
[4] =
86 { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_CENTER
, SF_CHANNEL_MAP_REAR_CENTER
} ;
87 static const int four_channel_mpeg_40b
[4] =
88 { SF_CHANNEL_MAP_CENTER
, SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_REAR_CENTER
} ;
89 static const int four_channel_itu_23
[4] =
90 { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_REAR_LEFT
, SF_CHANNEL_MAP_REAR_RIGHT
} ;
91 static const int four_channel_dvd_5
[4] =
92 { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_LFE
, SF_CHANNEL_MAP_REAR_CENTER
} ;
93 static const int four_channel_dvd_10
[4] =
94 { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_CENTER
, SF_CHANNEL_MAP_LFE
} ;
96 static const AIFF_CAF_CHANNEL_MAP four_chan
[] =
97 { { (107 << 16) | 4, four_channel_ambisonc_b
, "ambisonic B (W, X, Y, Z)" },
98 { (108 << 16) | 4, four_channel_quad
, "quad (Lfront, Rfront, Lrear, Rrear)" },
99 { (115 << 16) | 4, four_channel_mpeg_40a
, "MPEG 4.0 A (L, R, C, Cs)" },
100 { (116 << 16) | 4, four_channel_mpeg_40b
, "MPEG 4.0 B (C, L, R, Cs)" },
101 { (132 << 16) | 4, four_channel_itu_23
, "ITU 2.3 (L, R, Ls, Rs)" },
102 { (134 << 16) | 4, four_channel_dvd_5
, "DVD 5 (L, R, LFE, Cs)" },
103 { (136 << 16) | 4, four_channel_dvd_10
, "DVD 10 (L, R, C, LFE)" }
107 static const int five_channel_pentagonal
[5] =
108 { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_REAR_LEFT
, SF_CHANNEL_MAP_REAR_RIGHT
, SF_CHANNEL_MAP_CENTER
} ;
109 static const int five_channel_mpeg_50_a
[5] =
110 { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_CENTER
, SF_CHANNEL_MAP_REAR_LEFT
, SF_CHANNEL_MAP_REAR_RIGHT
} ;
111 static const int five_channel_mpeg_50_b
[5] =
112 { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_REAR_LEFT
, SF_CHANNEL_MAP_REAR_RIGHT
, SF_CHANNEL_MAP_CENTER
} ;
113 static const int five_channel_mpeg_50_c
[5] =
114 { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_CENTER
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_REAR_LEFT
, SF_CHANNEL_MAP_REAR_RIGHT
} ;
115 static const int five_channel_mpeg_50_d
[5] =
116 { SF_CHANNEL_MAP_CENTER
, SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_REAR_LEFT
, SF_CHANNEL_MAP_REAR_RIGHT
} ;
117 static const int five_channel_dvd_6
[5] =
118 { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_LFE
, SF_CHANNEL_MAP_REAR_LEFT
, SF_CHANNEL_MAP_REAR_RIGHT
} ;
119 static const int five_channel_dvd_11
[5] =
120 { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_CENTER
, SF_CHANNEL_MAP_LFE
, SF_CHANNEL_MAP_REAR_CENTER
} ;
121 static const int five_channel_dvd_18
[5] =
122 { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_REAR_LEFT
, SF_CHANNEL_MAP_REAR_RIGHT
, SF_CHANNEL_MAP_LFE
} ;
124 static const AIFF_CAF_CHANNEL_MAP five_chan
[] =
125 { { (109 << 16) | 5, five_channel_pentagonal
, "pentagonal (L, R, Lrear, Rrear, C)" },
126 { (117 << 16) | 5, five_channel_mpeg_50_a
, "MPEG 5.0 A (L, R, C, Ls, Rs)" },
127 { (118 << 16) | 5, five_channel_mpeg_50_b
, "MPEG 5.0 B (L, R, Ls, Rs, C)" },
128 { (119 << 16) | 5, five_channel_mpeg_50_c
, "MPEG 5.0 C (L, C, R, Ls, Rs,)" },
129 { (120 << 16) | 5, five_channel_mpeg_50_d
, "MPEG 5.0 D (C, L, R, Ls, Rs)" },
130 { (135 << 16) | 5, five_channel_dvd_6
, "DVD 6 (L, R, LFE, Ls, Rs)" },
131 { (137 << 16) | 5, five_channel_dvd_11
, "DVD 11 (L, R, C, LFE, Cs)" },
132 { (138 << 16) | 5, five_channel_dvd_18
, "DVD 18 (L, R, Ls, Rs, LFE)" }
136 static const int six_channel_mpeg_51_a
[6] =
137 { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_CENTER
, SF_CHANNEL_MAP_LFE
, SF_CHANNEL_MAP_REAR_LEFT
, SF_CHANNEL_MAP_REAR_RIGHT
} ;
138 static const int six_channel_mpeg_51_b
[6] =
139 { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_REAR_LEFT
, SF_CHANNEL_MAP_REAR_RIGHT
, SF_CHANNEL_MAP_CENTER
, SF_CHANNEL_MAP_LFE
} ;
140 static const int six_channel_mpeg_51_c
[6] =
141 { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_CENTER
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_REAR_LEFT
, SF_CHANNEL_MAP_REAR_RIGHT
, SF_CHANNEL_MAP_LFE
} ;
142 static const int six_channel_mpeg_51_d
[6] =
143 { SF_CHANNEL_MAP_CENTER
, SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_REAR_LEFT
, SF_CHANNEL_MAP_REAR_RIGHT
, SF_CHANNEL_MAP_LFE
} ;
144 static const int six_channel_audio_unit_60
[6] =
145 { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_REAR_LEFT
, SF_CHANNEL_MAP_REAR_RIGHT
, SF_CHANNEL_MAP_CENTER
, SF_CHANNEL_MAP_REAR_CENTER
} ;
146 static const int six_channel_aac_60
[6] =
147 { SF_CHANNEL_MAP_CENTER
, SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_REAR_LEFT
, SF_CHANNEL_MAP_REAR_RIGHT
, SF_CHANNEL_MAP_REAR_CENTER
} ;
149 static const AIFF_CAF_CHANNEL_MAP six_chan
[] =
150 { { (110 << 16) | 6, NULL
, "hexagonal (L, R, Lr, Rr, C, Rear)" },
151 { (121 << 16) | 6, six_channel_mpeg_51_a
, "MPEG 5.1 A (L, R, C, LFE, Ls, Rs)" },
152 { (122 << 16) | 6, six_channel_mpeg_51_b
, "MPEG 5.1 B (L, R, Ls, Rs, C, LFE)" },
153 { (123 << 16) | 6, six_channel_mpeg_51_c
, "MPEG 5.1 C (L, C, R, Ls, Rs, LFE)" },
154 { (124 << 16) | 6, six_channel_mpeg_51_d
, "MPEG 5.1 D (C, L, R, Ls, Rs, LFE)" },
155 { (139 << 16) | 6, six_channel_audio_unit_60
, "AudioUnit 6.0 (L, R, Ls, Rs, C, Cs)" },
156 { (141 << 16) | 6, six_channel_aac_60
, "AAC 6.0 (C, L, R, Ls, Rs, Cs)" }
160 static const int six_channel_mpeg_61a
[7] =
161 { SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_CENTER
, SF_CHANNEL_MAP_LFE
, SF_CHANNEL_MAP_REAR_LEFT
, SF_CHANNEL_MAP_REAR_RIGHT
, SF_CHANNEL_MAP_REAR_CENTER
} ;
162 static const int six_channel_aac_61
[7] =
163 { SF_CHANNEL_MAP_CENTER
, SF_CHANNEL_MAP_LEFT
, SF_CHANNEL_MAP_RIGHT
, SF_CHANNEL_MAP_REAR_LEFT
, SF_CHANNEL_MAP_REAR_RIGHT
, SF_CHANNEL_MAP_REAR_CENTER
, SF_CHANNEL_MAP_LFE
} ;
165 static const AIFF_CAF_CHANNEL_MAP seven_chan
[] =
166 { { (125 << 16) | 7, six_channel_mpeg_61a
, "MPEG 6.1 A (L, R, C, LFE, Ls, Rs, Cs)" },
167 { (140 << 16) | 7, NULL
, "AudioUnit 7.0 (L, R, Ls, Rs, C, Rls, Rrs)" },
168 { (142 << 16) | 7, six_channel_aac_61
, "AAC 6.1 (C, L, R, Ls, Rs, Cs, Lfe)" },
169 { (143 << 16) | 7, NULL
, "AAC 7.0 (C, L, R, Ls, Rs, Rls, Rrs,)" }
173 static const AIFF_CAF_CHANNEL_MAP eight_chan
[] =
174 { { (111 << 16) | 8, NULL
,
175 // front left, front right, rear left, rear right,
176 // front center, rear center, side left, side right
177 "octagonal (Lf, Rf, Lr, Rr, Cf, Cr, Ls, Rs)"
179 { (112 << 16) | 8, NULL
,
180 // left, right, rear left, rear right
181 // top left, top right, top rear left, top rear right
182 "cube (L, R, Lrear, Rrear, Ltop, Rtop, Ltoprear, Rtoprear)"
184 { (126 << 16) | 8, NULL
, "MPEG 7.1 A (L, R, C, LFE, Ls, Rs, Lc, Rc)" },
185 { (127 << 16) | 8, NULL
, "MPEG 7.1 B (C, Lc, Rc, L, R, Ls, Rs, LFE)" },
186 { (128 << 16) | 8, NULL
, "MPEG 7.1 C (L, R, C, LFE, Ls, R, Rls, Rrs)" },
187 { (129 << 16) | 8, NULL
, "Emagic Default 7.1 (L, R, Ls, Rs, C, LFE, Lc, Rc)" },
188 { (130 << 16) | 8, NULL
,
189 // (ITU_5_1 plus a matrix encoded stereo mix)
190 "SMPTE DTV (L, R, C, LFE, Ls, Rs, Lt, Rt)"
192 { (144 << 16) | 8, NULL
, "AAC octagonal (C, L, R, Ls, Rs, Rls, Rrs, Cs)" }
199 TMH_10_2_std
= (145 << 16) | 16,
200 // L R C Vhc Lsd Rsd Ls Rs Vhl Vhr Lw Rw Csd Cs LFE1 LFE2
202 TMH_10_2_full
= (146 << 16) | 21,
203 // TMH_10_2_std plus: Lc Rc HI VI Haptic
209 { const AIFF_CAF_CHANNEL_MAP
* map
;
213 static const MAP_MAP map
[] =
214 { { zero_chan
, ARRAY_LEN (zero_chan
) },
215 { one_chan
, ARRAY_LEN (one_chan
) },
216 { two_chan
, ARRAY_LEN (two_chan
) },
217 { three_chan
, ARRAY_LEN (three_chan
) },
218 { four_chan
, ARRAY_LEN (four_chan
) },
219 { five_chan
, ARRAY_LEN (five_chan
) },
220 { six_chan
, ARRAY_LEN (six_chan
) },
221 { seven_chan
, ARRAY_LEN (seven_chan
) },
222 { eight_chan
, ARRAY_LEN (eight_chan
) }
227 aiff_caf_find_channel_layout_tag (const int *chan_map
, int channels
)
228 { const AIFF_CAF_CHANNEL_MAP
* curr_map
;
231 if (channels
< 1 || channels
> ARRAY_LEN (map
))
234 curr_map
= map
[channels
].map
;
235 len
= map
[channels
].len
;
237 for (k
= 0 ; k
< len
; k
++)
238 if (curr_map
[k
].channel_map
!= NULL
)
239 if (memcmp (chan_map
, curr_map
[k
].channel_map
, channels
* sizeof (chan_map
[0])) == 0)
240 return curr_map
[k
].channel_layout_tag
;
243 } /* aiff_caf_find_channel_layout_tag */
245 const AIFF_CAF_CHANNEL_MAP
*
246 aiff_caf_of_channel_layout_tag (int tag
)
247 { const AIFF_CAF_CHANNEL_MAP
* curr_map
;
249 int channels
= tag
& 0xffff ;
251 if (channels
< 0 || channels
> ARRAY_LEN (map
))
254 curr_map
= map
[channels
].map
;
255 len
= map
[channels
].len
;
257 for (k
= 0 ; k
< len
; k
++)
258 if (curr_map
[k
].channel_layout_tag
== tag
)
259 return curr_map
+ k
;
262 } /* aiff_caf_of_channel_layout_tag */