downmix.c
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:8k
源码类别:

DVD

开发平台:

Unix_Linux

  1. /*
  2.  *
  3.  *  downmix.c
  4.  *    
  5.  * Copyright (C) Aaron Holtzman - Sept 1999
  6.  *
  7.  * Originally based on code by Yuqing Deng.
  8.  *
  9.  *  This file is part of ac3dec, a free Dolby AC-3 stream decoder.
  10.  *
  11.  *  ac3dec is free software; you can redistribute it and/or modify
  12.  *  it under the terms of the GNU General Public License as published by
  13.  *  the Free Software Foundation; either version 2, or (at your option)
  14.  *  any later version.
  15.  *   
  16.  *  ac3dec is distributed in the hope that it will be useful,
  17.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  *  GNU General Public License for more details.
  20.  *   
  21.  *  You should have received a copy of the GNU General Public License
  22.  *  along with GNU Make; see the file COPYING.  If not, write to
  23.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  24.  *
  25.  *
  26.  */
  27. #include <stdlib.h>
  28. #include <stdio.h>
  29. #include <math.h>
  30. #include "ac3.h"
  31. #include "decode.h"
  32. #include "downmix.h"
  33. #include "debug.h"
  34. //Pre-scaled downmix coefficients
  35. static float cmixlev_lut[4] = { 0.2928, 0.2468, 0.2071, 0.2468 };
  36. static float smixlev_lut[4] = { 0.2928, 0.2071, 0.0   , 0.2071 };
  37. /* Downmix into _two_ channels...other downmix modes aren't implemented
  38.  * to reduce complexity. Realistically, there aren't many machines around
  39.  * with > 2 channel output anyways */
  40. void downmix(bsi_t* bsi, stream_samples_t* stream_sample)
  41. {
  42. int j;
  43. float right_tmp;
  44. float left_tmp;
  45. float clev,slev;
  46. float *centre = 0, *left = 0, *right = 0, *left_sur = 0, *right_sur = 0;
  47. if(bsi->acmod > 7)
  48. dprintf("(downmix) invalid acmod numbern"); 
  49. //There are two main cases, with or without Dolby Surround
  50. if(global_prefs.use_dolby_surround)
  51. {
  52. switch(bsi->acmod)
  53. {
  54. // 3/2
  55. case 7:
  56. left      = stream_sample->channel[0];
  57. centre    = stream_sample->channel[1];
  58. right     = stream_sample->channel[2];
  59. left_sur  = stream_sample->channel[3];
  60. right_sur = stream_sample->channel[4];
  61. for (j = 0; j < 256; j++) 
  62. {
  63. right_tmp = 0.2265 * *left_sur++ + 0.2265 * *right_sur++;
  64. left_tmp  = -1 * right_tmp;
  65. right_tmp += 0.3204 * *right++ + 0.2265 * *centre;
  66. left_tmp  += 0.3204 * *left++  + 0.2265 * *centre++;
  67. stream_sample->channel[1][j] = right_tmp;
  68. stream_sample->channel[0][j] = left_tmp;
  69. }
  70. break;
  71. // 2/2
  72. case 6:
  73. left      = stream_sample->channel[0];
  74. right     = stream_sample->channel[1];
  75. left_sur  = stream_sample->channel[2];
  76. right_sur = stream_sample->channel[3];
  77. for (j = 0; j < 256; j++) 
  78. {
  79. right_tmp = 0.2265 * *left_sur++ + 0.2265 * *right_sur++;
  80. left_tmp  = -1 * right_tmp;
  81. right_tmp += 0.3204 * *right++;
  82. left_tmp  += 0.3204 * *left++ ;
  83. stream_sample->channel[1][j] = right_tmp;
  84. stream_sample->channel[0][j] = left_tmp;
  85. }
  86. break;
  87. // 3/1
  88. case 5:
  89. left      = stream_sample->channel[0];
  90. centre    = stream_sample->channel[1];
  91. right     = stream_sample->channel[2];
  92. //Mono surround
  93. right_sur = stream_sample->channel[3];
  94. for (j = 0; j < 256; j++) 
  95. {
  96. right_tmp =  0.2265 * *right_sur++;
  97. left_tmp  = -1 * right_tmp;
  98. right_tmp += 0.3204 * *right++ + 0.2265 * *centre;
  99. left_tmp  += 0.3204 * *left++  + 0.2265 * *centre++;
  100. stream_sample->channel[1][j] = right_tmp;
  101. stream_sample->channel[0][j] = left_tmp;
  102. }
  103. break;
  104. // 2/1
  105. case 4:
  106. left      = stream_sample->channel[0];
  107. right     = stream_sample->channel[1];
  108. //Mono surround
  109. right_sur = stream_sample->channel[2];
  110. for (j = 0; j < 256; j++) 
  111. {
  112. right_tmp =  0.2265 * *right_sur++;
  113. left_tmp  = -1 * right_tmp;
  114. right_tmp += 0.3204 * *right++; 
  115. left_tmp  += 0.3204 * *left++;
  116. stream_sample->channel[1][j] = right_tmp;
  117. stream_sample->channel[0][j] = left_tmp;
  118. }
  119. break;
  120. // 3/0
  121. case 3:
  122. left      = stream_sample->channel[0];
  123. centre    = stream_sample->channel[1];
  124. right     = stream_sample->channel[2];
  125. for (j = 0; j < 256; j++) 
  126. {
  127. right_tmp = 0.3204 * *right++ + 0.2265 * *centre;
  128. left_tmp  = 0.3204 * *left++  + 0.2265 * *centre++;
  129. stream_sample->channel[1][j] = right_tmp;
  130. stream_sample->channel[0][j] = left_tmp;
  131. }
  132. break;
  133. // 2/0
  134. case 2:
  135. //Do nothing!
  136. break;
  137. // 1/0
  138. case 1:
  139. //Mono program!
  140. right = stream_sample->channel[0];
  141. for (j = 0; j < 256; j++) 
  142. {
  143. right_tmp = 0.7071 * *right++;
  144. stream_sample->channel[1][j] = right_tmp;
  145. stream_sample->channel[0][j] = right_tmp;
  146. }
  147. break;
  148. // 1+1
  149. case 0:
  150. //Dual mono, output selected by user
  151. right = stream_sample->channel[global_prefs.dual_mono_channel_select];
  152. for (j = 0; j < 256; j++) 
  153. {
  154. right_tmp = 0.7071 * *right++;
  155. stream_sample->channel[1][j] = right_tmp;
  156. stream_sample->channel[0][j] = right_tmp;
  157. }
  158. break;
  159. }
  160. }
  161. else
  162. {
  163. //Non-Dolby surround downmixes
  164. switch(bsi->acmod)
  165. {
  166. // 3/2
  167. case 7:
  168. left      = stream_sample->channel[0];
  169. centre    = stream_sample->channel[1];
  170. right     = stream_sample->channel[2];
  171. left_sur  = stream_sample->channel[3];
  172. right_sur = stream_sample->channel[4];
  173. clev = cmixlev_lut[bsi->cmixlev];
  174. slev = smixlev_lut[bsi->surmixlev];
  175. for (j = 0; j < 256; j++) 
  176. {
  177. right_tmp= 0.4142 * *right++ + clev * *centre   + slev * *right_sur++;
  178. left_tmp = 0.4142 * *left++  + clev * *centre++ + slev * *left_sur++;
  179. stream_sample->channel[1][j] = right_tmp;
  180. stream_sample->channel[0][j] = left_tmp;
  181. }
  182. break;
  183. // 2/2
  184. case 6:
  185. left      = stream_sample->channel[0];
  186. right     = stream_sample->channel[1];
  187. left_sur  = stream_sample->channel[2];
  188. right_sur = stream_sample->channel[3];
  189. slev = smixlev_lut[bsi->surmixlev];
  190. for (j = 0; j < 256; j++) 
  191. {
  192. right_tmp= 0.4142 * *right++ + slev * *right_sur++;
  193. left_tmp = 0.4142 * *left++  + slev * *left_sur++;
  194. stream_sample->channel[1][j] = right_tmp;
  195. stream_sample->channel[0][j] = left_tmp;
  196. }
  197. // 3/1
  198. case 5:
  199. left      = stream_sample->channel[0];
  200. centre    = stream_sample->channel[1];
  201. right     = stream_sample->channel[2];
  202. //Mono surround
  203. right_sur = stream_sample->channel[3];
  204. clev = cmixlev_lut[bsi->cmixlev];
  205. slev = smixlev_lut[bsi->surmixlev];
  206. for (j = 0; j < 256; j++) 
  207. {
  208. right_tmp= 0.4142 * *right++ + clev * *centre   + slev * *right_sur;
  209. left_tmp = 0.4142 * *left++  + clev * *centre++ + slev * *right_sur++;
  210. stream_sample->channel[1][j] = right_tmp;
  211. stream_sample->channel[0][j] = left_tmp;
  212. }
  213. break;
  214. // 2/1
  215. case 4:
  216. left      = stream_sample->channel[0];
  217. right     = stream_sample->channel[1];
  218. //Mono surround
  219. right_sur = stream_sample->channel[2];
  220. slev = smixlev_lut[bsi->surmixlev];
  221. for (j = 0; j < 256; j++) 
  222. {
  223. right_tmp= 0.4142 * *right++ + slev * *right_sur;
  224. left_tmp = 0.4142 * *left++  + slev * *right_sur++;
  225. stream_sample->channel[1][j] = right_tmp;
  226. stream_sample->channel[0][j] = left_tmp;
  227. }
  228. // 3/0
  229. case 3:
  230. left      = stream_sample->channel[0];
  231. centre    = stream_sample->channel[1];
  232. right     = stream_sample->channel[2];
  233. clev = cmixlev_lut[bsi->cmixlev];
  234. for (j = 0; j < 256; j++) 
  235. {
  236. right_tmp= 0.4142 * *right++ + clev * *centre;   
  237. left_tmp = 0.4142 * *left++  + clev * *centre++; 
  238. stream_sample->channel[1][j] = right_tmp;
  239. stream_sample->channel[0][j] = left_tmp;
  240. }
  241. break;
  242. case 2:
  243. //Do nothing!
  244. break;
  245. // 1/0
  246. case 1:
  247. //Mono program!
  248. right = stream_sample->channel[0];
  249. for (j = 0; j < 256; j++) 
  250. {
  251. right_tmp = 0.7071 * *right++;
  252. stream_sample->channel[1][j] = right_tmp;
  253. stream_sample->channel[0][j] = right_tmp;
  254. }
  255. break;
  256. // 1+1
  257. case 0:
  258. //Dual mono, output selected by user
  259. right = stream_sample->channel[global_prefs.dual_mono_channel_select];
  260. for (j = 0; j < 256; j++) 
  261. {
  262. right_tmp = 0.7071 * *right++;
  263. stream_sample->channel[1][j] = right_tmp;
  264. stream_sample->channel[0][j] = right_tmp;
  265. }
  266. break;
  267. }
  268. }
  269. }