chanmap.c
上传用户:shw771010
上传日期:2022-01-05
资源大小:991k
文件大小:11k
源码类别:

Audio

开发平台:

Unix_Linux

  1. /*
  2. ** Copyright (C) 2009 Erik de Castro Lopo <erikd@mega-nerd.com>
  3. **
  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.
  8. **
  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.
  13. **
  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.
  17. */
  18. /*
  19. ** Mostly from "Apple Core Audio Format Specification 1.0":
  20. **
  21. ** http://developer.apple.com/documentation/MusicAudio/Reference/CAFSpec/CAFSpec.pdf
  22. */
  23. #include "sfconfig.h"
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include "sndfile.h"
  28. #include "common.h"
  29. #include "chanmap.h"
  30. static const AIFF_CAF_CHANNEL_MAP zero_chan [] =
  31. { { (0 << 16) | 0, NULL, "Use channel descriptions." },
  32. { (1 << 16) | 0, NULL, "Use channel bitmap." }
  33. } ; /* zero_chan */
  34. static const int one_chan_mono [1] = { SF_CHANNEL_MAP_MONO } ;
  35. static const AIFF_CAF_CHANNEL_MAP one_chan [] =
  36. { { (100 << 16) | 1, one_chan_mono, "mono" }
  37. } ; /* one_chan */
  38. static const int two_channel_stereo [2] = { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT } ;
  39. static const AIFF_CAF_CHANNEL_MAP two_chan [] =
  40. { { (101 << 16) | 2, two_channel_stereo, "stereo (L, R)" },
  41. { (102 << 16) | 2, two_channel_stereo, "stereo headphones (L, R)" },
  42. #if 0
  43. { (103 << 16) | 2, NULL, "matrix stereo (Lt, Rt)" },
  44. { (104 << 16) | 2, NULL, "2 channels (mid, side)" },
  45. { (105 << 16) | 2, NULL, "coincident mic pair" },
  46. { (106 << 16) | 2, NULL, "binaural stereo (L, R)"
  47. }
  48. #endif
  49. } ; /* two_chan */
  50. static const int three_channel_mpeg_30a [3] =
  51. { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_CENTER } ;
  52. static const int three_channel_mpeg_30b [3] =
  53. { SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT } ;
  54. static const int three_channel_itu_21 [3] =
  55. { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_CENTER } ;
  56. static const int three_channel_dvd_4 [3] =
  57. { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_LFE } ;
  58. static const AIFF_CAF_CHANNEL_MAP three_chan [] =
  59. { { (113 << 16) | 3, three_channel_mpeg_30a, "MPEG 3 0 A (L, R, C)" },
  60. { (114 << 16) | 3, three_channel_mpeg_30b, "MPEG 3 0 B (C, L, R)" },
  61. { (131 << 16) | 3, three_channel_itu_21, "ITU 2.1 (L, R, Cs)" },
  62. { (133 << 16) | 3, three_channel_dvd_4, "DVD 4 (L, R, LFE)" }
  63. } ; /* three_chan */
  64. static const int four_channel_ambisonc_b [4] =
  65. { SF_CHANNEL_MAP_AMBISONIC_B_W, SF_CHANNEL_MAP_AMBISONIC_B_X, SF_CHANNEL_MAP_AMBISONIC_B_Y, SF_CHANNEL_MAP_AMBISONIC_B_Z } ;
  66. static const int four_channel_quad [4] =
  67. { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT } ;
  68. static const int four_channel_mpeg_40a [4] =
  69. { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_REAR_CENTER } ;
  70. static const int four_channel_mpeg_40b [4] =
  71. { SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_CENTER } ;
  72. static const int four_channel_itu_23 [4] =
  73. { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT } ;
  74. static const int four_channel_dvd_5 [4] =
  75. { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_LFE, SF_CHANNEL_MAP_REAR_CENTER } ;
  76. static const int four_channel_dvd_10 [4] =
  77. { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_LFE } ;
  78. static const AIFF_CAF_CHANNEL_MAP four_chan [] =
  79. { { (107 << 16) | 4, four_channel_ambisonc_b, "ambisonic B (W,  X, Y, Z)" },
  80. { (108 << 16) | 4, four_channel_quad, "quad (Lfront, Rfront, Lrear, Rrear)" },
  81. { (115 << 16) | 4, four_channel_mpeg_40a, "MPEG 4.0 A (L, R, C, Cs)" },
  82. { (116 << 16) | 4, four_channel_mpeg_40b, "MPEG 4.0 B (C, L, R, Cs)" },
  83. { (132 << 16) | 4, four_channel_itu_23, "ITU 2.3 (L, R, Ls, Rs)" },
  84. { (134 << 16) | 4, four_channel_dvd_5, "DVD 5 (L, R, LFE, Cs)" },
  85. { (136 << 16) | 4, four_channel_dvd_10, "DVD 10 (L, R, C, LFE)" }
  86. } ; /* four_chan */
  87. static const int five_channel_pentagonal [5] =
  88. { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT, SF_CHANNEL_MAP_CENTER } ;
  89. static const int five_channel_mpeg_50_a [5] =
  90. { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT } ;
  91. static const int five_channel_mpeg_50_b [5] =
  92. { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT, SF_CHANNEL_MAP_CENTER } ;
  93. static const int five_channel_mpeg_50_c [5] =
  94. { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT } ;
  95. static const int five_channel_mpeg_50_d [5] =
  96. { SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT } ;
  97. static const int five_channel_dvd_6 [5] =
  98. { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_LFE, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT } ;
  99. static const int five_channel_dvd_11 [5] =
  100. { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_LFE, SF_CHANNEL_MAP_REAR_CENTER } ;
  101. static const int five_channel_dvd_18 [5] =
  102. { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT, SF_CHANNEL_MAP_LFE } ;
  103. static const AIFF_CAF_CHANNEL_MAP five_chan [] =
  104. { { (109 << 16) | 5, five_channel_pentagonal, "pentagonal (L,  R, Lrear, Rrear, C)" },
  105. { (117 << 16) | 5, five_channel_mpeg_50_a, "MPEG 5.0 A (L, R, C, Ls, Rs)" },
  106. { (118 << 16) | 5, five_channel_mpeg_50_b, "MPEG 5.0 B (L, R, Ls, Rs, C)" },
  107. { (119 << 16) | 5, five_channel_mpeg_50_c, "MPEG 5.0 C (L, C, R, Ls, Rs,)" },
  108. { (120 << 16) | 5, five_channel_mpeg_50_d, "MPEG 5.0 D (C, L, R, Ls, Rs)" },
  109. { (135 << 16) | 5, five_channel_dvd_6, "DVD 6 (L, R, LFE, Ls, Rs)" },
  110. { (137 << 16) | 5, five_channel_dvd_11, "DVD 11 (L, R, C, LFE, Cs)" },
  111. { (138 << 16) | 5, five_channel_dvd_18, "DVD 18 (L, R, Ls, Rs, LFE)" }
  112. } ; /* five_chan */
  113. static const int six_channel_mpeg_51_a [6] =
  114. { 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 } ;
  115. static const int six_channel_mpeg_51_b [6] =
  116. { 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 } ;
  117. static const int six_channel_mpeg_51_c [6] =
  118. { 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 } ;
  119. static const int six_channel_mpeg_51_d [6] =
  120. { 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 } ;
  121. static const int six_channel_audio_unit_60 [6] =
  122. { 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 } ;
  123. static const int six_channel_aac_60 [6] =
  124. { 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 } ;
  125. static const AIFF_CAF_CHANNEL_MAP six_chan [] =
  126. { { (110 << 16) | 6, NULL, "hexagonal (L, R, Lr, Rr, C, Rear)" },
  127. { (121 << 16) | 6, six_channel_mpeg_51_a, "MPEG 5.1 A (L, R, C, LFE, Ls, Rs)" },
  128. { (122 << 16) | 6, six_channel_mpeg_51_b, "MPEG 5.1 B (L, R, Ls, Rs, C, LFE)" },
  129. { (123 << 16) | 6, six_channel_mpeg_51_c, "MPEG 5.1 C (L, C, R, Ls, Rs, LFE)" },
  130. { (124 << 16) | 6, six_channel_mpeg_51_d, "MPEG 5.1 D (C, L, R, Ls, Rs, LFE)" },
  131. { (139 << 16) | 6, six_channel_audio_unit_60, "AudioUnit 6.0 (L, R, Ls, Rs, C, Cs)" },
  132. { (141 << 16) | 6, six_channel_aac_60, "AAC 6.0 (C, L, R, Ls, Rs, Cs)" }
  133. } ; /* six_chan */
  134. static const int six_channel_mpeg_61a [7] =
  135. { 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 } ;
  136. static const int six_channel_aac_61 [7] =
  137. { 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 } ;
  138. static const AIFF_CAF_CHANNEL_MAP seven_chan [] =
  139. { { (125 << 16) | 7, six_channel_mpeg_61a, "MPEG 6.1 A (L, R, C, LFE, Ls, Rs, Cs)" },
  140. { (140 << 16) | 7, NULL, "AudioUnit 7.0 (L, R, Ls, Rs, C, Rls, Rrs)" },
  141. { (142 << 16) | 7, six_channel_aac_61, "AAC 6.1 (C, L, R, Ls, Rs, Cs, Lfe)" },
  142. { (143 << 16) | 7, NULL, "AAC 7.0 (C, L, R, Ls, Rs, Rls, Rrs,)" }
  143. } ; /* seven_chan */
  144. static const AIFF_CAF_CHANNEL_MAP eight_chan [] =
  145. { { (111 << 16) | 8, NULL,
  146. // front left, front right, rear left, rear right,
  147. // front center, rear center, side left, side right
  148. "octagonal (Lf, Rf, Lr, Rr, Cf, Cr, Ls, Rs)"
  149. },
  150. { (112 << 16) | 8, NULL,
  151. // left, right, rear left, rear right
  152. // top left, top right, top rear left, top rear right
  153. "cube (L, R, Lrear, Rrear, Ltop, Rtop, Ltoprear, Rtoprear)"
  154. },
  155. { (126 << 16) | 8, NULL, "MPEG 7.1 A (L, R, C, LFE, Ls, Rs, Lc, Rc)" },
  156. { (127 << 16) | 8, NULL, "MPEG 7.1 B (C, Lc, Rc, L, R, Ls, Rs, LFE)" },
  157. { (128 << 16) | 8, NULL, "MPEG 7.1 C (L, R, C, LFE, Ls, R, Rls, Rrs)" },
  158. { (129 << 16) | 8, NULL, "Emagic Default 7.1 (L, R, Ls, Rs, C, LFE, Lc, Rc)" },
  159. { (130 << 16) | 8, NULL,
  160. // (ITU_5_1 plus a matrix encoded stereo mix)
  161. "SMPTE DTV (L, R, C, LFE, Ls, Rs, Lt, Rt)"
  162. },
  163. { (144 << 16) | 8, NULL, "AAC octagonal (C, L, R, Ls, Rs, Rls, Rrs, Cs)" }
  164. } ; /* eight_chan */
  165. #if 0
  166. TMH_10_2_std = (145 << 16) | 16,
  167. // L R C Vhc Lsd Rsd Ls Rs Vhl Vhr Lw Rw Csd Cs LFE1 LFE2
  168. TMH_10_2_full = (146 << 16) | 21,
  169. // TMH_10_2_std plus: Lc Rc HI VI Haptic
  170. #endif
  171. typedef struct
  172. { const AIFF_CAF_CHANNEL_MAP * map ;
  173. int len ;
  174. } MAP_MAP ;
  175. static const MAP_MAP map [] =
  176. { { zero_chan, ARRAY_LEN (zero_chan) },
  177. { one_chan, ARRAY_LEN (one_chan) },
  178. { two_chan, ARRAY_LEN (two_chan) },
  179. { three_chan, ARRAY_LEN (three_chan) },
  180. { four_chan, ARRAY_LEN (four_chan) },
  181. { five_chan, ARRAY_LEN (five_chan) },
  182. { six_chan, ARRAY_LEN (six_chan) },
  183. { seven_chan, ARRAY_LEN (seven_chan) },
  184. { eight_chan, ARRAY_LEN (eight_chan) }
  185. } ; /* map */
  186. int
  187. aiff_caf_find_channel_layout_tag (const int *chan_map, int channels)
  188. { const AIFF_CAF_CHANNEL_MAP * curr_map ;
  189. unsigned k, len ;
  190. if (channels < 1 || channels > ARRAY_LEN (map))
  191. return 0 ;
  192. curr_map = map [channels].map ;
  193. len = map [channels].len ;
  194. for (k = 0 ; k < len ; k++)
  195. if (curr_map [k].channel_map != NULL)
  196. if (memcmp (chan_map, curr_map [k].channel_map, channels * sizeof (chan_map [0])) == 0)
  197. return curr_map [k].channel_layout_tag ;
  198. return 0 ;
  199. } /* aiff_caf_find_channel_layout_tag */
  200. const AIFF_CAF_CHANNEL_MAP *
  201. aiff_caf_of_channel_layout_tag (int tag)
  202. { const AIFF_CAF_CHANNEL_MAP * curr_map ;
  203. unsigned k, len ;
  204. int channels = tag & 0xffff ;
  205. if (channels < 0 || channels > ARRAY_LEN (map))
  206. return NULL ;
  207. curr_map = map [channels].map ;
  208. len = map [channels].len ;
  209. for (k = 0 ; k < len ; k++)
  210. if (curr_map [k].channel_layout_tag == tag)
  211. return curr_map + k ;
  212. return NULL ;
  213. } /* aiff_caf_of_channel_layout_tag */