mapping0.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. /********************************************************************
  2. * *
  3. * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
  4. * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
  5. * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  6. * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
  7. * *
  8. * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
  9. * by the XIPHOPHORUS Company http://www.xiph.org/ *
  10. * *
  11. ********************************************************************
  12. function: channel mapping 0 implementation
  13. last mod: $Id: mapping0.c,v 1.33.2.6 2001/08/13 00:20:10 xiphmont Exp $
  14. ********************************************************************/
  15. #include <stdlib.h>
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <math.h>
  19. #include <ogg/ogg.h>
  20. #include "vorbis/codec.h"
  21. #include "codec_internal.h"
  22. #include "codebook.h"
  23. #include "bitbuffer.h"
  24. #include "registry.h"
  25. #include "psy.h"
  26. #include "misc.h"
  27. /* simplistic, wasteful way of doing this (unique lookup for each
  28. mode/submapping); there should be a central repository for
  29. identical lookups. That will require minor work, so I'm putting it
  30. off as low priority.
  31. Why a lookup for each backend in a given mode? Because the
  32. blocksize is set by the mode, and low backend lookups may require
  33. parameters from other areas of the mode/mapping */
  34. extern int analysis_noisy;
  35. typedef struct {
  36. drft_lookup fft_look;
  37. vorbis_info_mode *mode;
  38. vorbis_info_mapping0 *map;
  39. vorbis_look_time **time_look;
  40. vorbis_look_floor **floor_look;
  41. vorbis_look_residue **residue_look;
  42. vorbis_look_psy *psy_look[2];
  43. vorbis_func_time **time_func;
  44. vorbis_func_floor **floor_func;
  45. vorbis_func_residue **residue_func;
  46. int ch;
  47. long lastframe; /* if a different mode is called, we need to
  48. invalidate decay */
  49. } vorbis_look_mapping0;
  50. static vorbis_info_mapping *mapping0_copy_info(vorbis_info_mapping *vm){
  51. vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)vm;
  52. vorbis_info_mapping0 *ret=_ogg_malloc(sizeof(vorbis_info_mapping0));
  53. memcpy(ret,info,sizeof(vorbis_info_mapping0));
  54. return(ret);
  55. }
  56. static void mapping0_free_info(vorbis_info_mapping *i){
  57. if(i){
  58. memset(i,0,sizeof(vorbis_info_mapping0));
  59. _ogg_free(i);
  60. }
  61. }
  62. static void mapping0_free_look(vorbis_look_mapping *look){
  63. int i;
  64. vorbis_look_mapping0 *l=(vorbis_look_mapping0 *)look;
  65. if(l){
  66. drft_clear(&l->fft_look);
  67. for(i=0;i<l->map->submaps;i++){
  68. l->time_func[i]->free_look(l->time_look[i]);
  69. l->floor_func[i]->free_look(l->floor_look[i]);
  70. l->residue_func[i]->free_look(l->residue_look[i]);
  71. }
  72. if(l->psy_look[1] && l->psy_look[1]!=l->psy_look[0]){
  73. _vp_psy_clear(l->psy_look[1]);
  74. _ogg_free(l->psy_look[1]);
  75. }
  76. if(l->psy_look[0]){
  77. _vp_psy_clear(l->psy_look[0]);
  78. _ogg_free(l->psy_look[0]);
  79. }
  80. _ogg_free(l->time_func);
  81. _ogg_free(l->floor_func);
  82. _ogg_free(l->residue_func);
  83. _ogg_free(l->time_look);
  84. _ogg_free(l->floor_look);
  85. _ogg_free(l->residue_look);
  86. memset(l,0,sizeof(vorbis_look_mapping0));
  87. _ogg_free(l);
  88. }
  89. }
  90. static vorbis_look_mapping *mapping0_look(vorbis_dsp_state *vd,vorbis_info_mode *vm,
  91. vorbis_info_mapping *m){
  92. int i;
  93. vorbis_info *vi=vd->vi;
  94. codec_setup_info *ci=vi->codec_setup;
  95. vorbis_look_mapping0 *look=_ogg_calloc(1,sizeof(vorbis_look_mapping0));
  96. vorbis_info_mapping0 *info=look->map=(vorbis_info_mapping0 *)m;
  97. look->mode=vm;
  98. look->time_look=_ogg_calloc(info->submaps,sizeof(vorbis_look_time *));
  99. look->floor_look=_ogg_calloc(info->submaps,sizeof(vorbis_look_floor *));
  100. look->residue_look=_ogg_calloc(info->submaps,sizeof(vorbis_look_residue *));
  101. look->time_func=_ogg_calloc(info->submaps,sizeof(vorbis_func_time *));
  102. look->floor_func=_ogg_calloc(info->submaps,sizeof(vorbis_func_floor *));
  103. look->residue_func=_ogg_calloc(info->submaps,sizeof(vorbis_func_residue *));
  104. for(i=0;i<info->submaps;i++){
  105. int timenum=info->timesubmap[i];
  106. int floornum=info->floorsubmap[i];
  107. int resnum=info->residuesubmap[i];
  108. look->time_func[i]=_time_P[ci->time_type[timenum]];
  109. look->time_look[i]=look->time_func[i]->
  110. look(vd,vm,ci->time_param[timenum]);
  111. look->floor_func[i]=_floor_P[ci->floor_type[floornum]];
  112. look->floor_look[i]=look->floor_func[i]->
  113. look(vd,vm,ci->floor_param[floornum]);
  114. look->residue_func[i]=_residue_P[ci->residue_type[resnum]];
  115. look->residue_look[i]=look->residue_func[i]->
  116. look(vd,vm,ci->residue_param[resnum]);
  117. }
  118. if(ci->psys && vd->analysisp){
  119. if(info->psy[0] != info->psy[1]){
  120. int psynum=info->psy[0];
  121. look->psy_look[0]=_ogg_calloc(1,sizeof(vorbis_look_psy));
  122. _vp_psy_init(look->psy_look[0],ci->psy_param[psynum],
  123. ci->psy_g_param,
  124. ci->blocksizes[vm->blockflag]/2,vi->rate);
  125. psynum=info->psy[1];
  126. look->psy_look[1]=_ogg_calloc(1,sizeof(vorbis_look_psy));
  127. _vp_psy_init(look->psy_look[1],ci->psy_param[psynum],
  128. ci->psy_g_param,
  129. ci->blocksizes[vm->blockflag]/2,vi->rate);
  130. }else{
  131. int psynum=info->psy[0];
  132. look->psy_look[0]=_ogg_calloc(1,sizeof(vorbis_look_psy));
  133. look->psy_look[1]=look->psy_look[0];
  134. _vp_psy_init(look->psy_look[0],ci->psy_param[psynum],
  135. ci->psy_g_param,
  136. ci->blocksizes[vm->blockflag]/2,vi->rate);
  137. }
  138. }
  139. look->ch=vi->channels;
  140. if(vd->analysisp)drft_init(&look->fft_look,ci->blocksizes[vm->blockflag]);
  141. return(look);
  142. }
  143. static int ilog2(unsigned int v){
  144. int ret=0;
  145. while(v>1){
  146. ret++;
  147. v>>=1;
  148. }
  149. return(ret);
  150. }
  151. static void mapping0_pack(vorbis_info *vi,vorbis_info_mapping *vm,oggpack_buffer *opb){
  152. int i;
  153. vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)vm;
  154. /* another 'we meant to do it this way' hack... up to beta 4, we
  155. packed 4 binary zeros here to signify one submapping in use. We
  156. now redefine that to mean four bitflags that indicate use of
  157. deeper features; bit0:submappings, bit1:coupling,
  158. bit2,3:reserved. This is backward compatable with all actual uses
  159. of the beta code. */
  160. if(info->submaps>1){
  161. oggpack_write(opb,1,1);
  162. oggpack_write(opb,info->submaps-1,4);
  163. }else
  164. oggpack_write(opb,0,1);
  165. if(info->coupling_steps>0){
  166. oggpack_write(opb,1,1);
  167. oggpack_write(opb,info->coupling_steps-1,8);
  168. for(i=0;i<info->coupling_steps;i++){
  169. oggpack_write(opb,info->coupling_mag[i],ilog2(vi->channels));
  170. oggpack_write(opb,info->coupling_ang[i],ilog2(vi->channels));
  171. }
  172. }else
  173. oggpack_write(opb,0,1);
  174. oggpack_write(opb,0,2); /* 2,3:reserved */
  175. /* we don't write the channel submappings if we only have one... */
  176. if(info->submaps>1){
  177. for(i=0;i<vi->channels;i++)
  178. oggpack_write(opb,info->chmuxlist[i],4);
  179. }
  180. for(i=0;i<info->submaps;i++){
  181. oggpack_write(opb,info->timesubmap[i],8);
  182. oggpack_write(opb,info->floorsubmap[i],8);
  183. oggpack_write(opb,info->residuesubmap[i],8);
  184. }
  185. }
  186. /* also responsible for range checking */
  187. static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){
  188. int i;
  189. vorbis_info_mapping0 *info=_ogg_calloc(1,sizeof(vorbis_info_mapping0));
  190. codec_setup_info *ci=vi->codec_setup;
  191. memset(info,0,sizeof(vorbis_info_mapping0));
  192. if(oggpack_read(opb,1))
  193. info->submaps=oggpack_read(opb,4)+1;
  194. else
  195. info->submaps=1;
  196. if(oggpack_read(opb,1)){
  197. info->coupling_steps=oggpack_read(opb,8)+1;
  198. for(i=0;i<info->coupling_steps;i++){
  199. int testM=info->coupling_mag[i]=oggpack_read(opb,ilog2(vi->channels));
  200. int testA=info->coupling_ang[i]=oggpack_read(opb,ilog2(vi->channels));
  201. if(testM<0 ||
  202. testA<0 ||
  203. testM==testA ||
  204. testM>=vi->channels ||
  205. testA>=vi->channels) goto err_out;
  206. }
  207. }
  208. if(oggpack_read(opb,2)>0)goto err_out; /* 2,3:reserved */
  209. if(info->submaps>1){
  210. for(i=0;i<vi->channels;i++){
  211. info->chmuxlist[i]=oggpack_read(opb,4);
  212. if(info->chmuxlist[i]>=info->submaps)goto err_out;
  213. }
  214. }
  215. for(i=0;i<info->submaps;i++){
  216. info->timesubmap[i]=oggpack_read(opb,8);
  217. if(info->timesubmap[i]>=ci->times)goto err_out;
  218. info->floorsubmap[i]=oggpack_read(opb,8);
  219. if(info->floorsubmap[i]>=ci->floors)goto err_out;
  220. info->residuesubmap[i]=oggpack_read(opb,8);
  221. if(info->residuesubmap[i]>=ci->residues)goto err_out;
  222. }
  223. return info;
  224. err_out:
  225. mapping0_free_info(info);
  226. return(NULL);
  227. }
  228. #include "os.h"
  229. #include "lpc.h"
  230. #include "lsp.h"
  231. #include "envelope.h"
  232. #include "mdct.h"
  233. #include "psy.h"
  234. #include "scales.h"
  235. /* no time mapping implementation for now */
  236. static long seq=0;
  237. static int mapping0_forward(vorbis_block *vb,vorbis_look_mapping *l){
  238. vorbis_dsp_state *vd=vb->vd;
  239. vorbis_info *vi=vd->vi;
  240. codec_setup_info *ci=vi->codec_setup;
  241. backend_lookup_state *b=vb->vd->backend_state;
  242. vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)l;
  243. vorbis_info_mapping0 *info=look->map;
  244. vorbis_info_mode *mode=look->mode;
  245. vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
  246. int n=vb->pcmend;
  247. int i,j;
  248. float *window=b->window[vb->W][vb->lW][vb->nW][mode->windowtype];
  249. int *nonzero=alloca(sizeof(int)*vi->channels);
  250. float *work=_vorbis_block_alloc(vb,n*sizeof(float));
  251. float global_ampmax=vbi->ampmax;
  252. float *local_ampmax=alloca(sizeof(float)*vi->channels);
  253. int blocktype;
  254. /* we differentiate between short and long block types to help the
  255. masking engine; the window shapes also matter.
  256. impulse block (a short block in which an impulse occurs)
  257. padding block (a short block that pads between a transitional
  258. long block and an impulse block, or vice versa)
  259. transition block (the wqeird one; a long block with the transition
  260. window; affects bass/midrange response and that must be
  261. accounted for in masking)
  262. long block (run of the mill long block)
  263. */
  264. if(vb->W){
  265. if(!vb->lW || !vb->nW)
  266. blocktype=BLOCKTYPE_TRANSITION;
  267. else
  268. blocktype=BLOCKTYPE_LONG;
  269. }else{
  270. /* right now we're missing the infrastructure to distingush the
  271. two short types */
  272. blocktype=BLOCKTYPE_IMPULSE;
  273. }
  274. for(i=0;i<vi->channels;i++){
  275. float scale=4.f/n;
  276. /* the following makes things clearer to *me* anyway */
  277. float *pcm =vb->pcm[i];
  278. float *fft =work;
  279. float *logfft =pcm+n/2;
  280. /*float *res =pcm;
  281. float *mdct =pcm;
  282. float *codedflr=pcm+n/2;
  283. float *logmax =work;
  284. float *logmask =work+n/2;*/
  285. /* window the PCM data */
  286. for(j=0;j<n;j++)
  287. fft[j]=pcm[j]*=window[j];
  288. /* transform the PCM data */
  289. /* only MDCT right now.... */
  290. mdct_forward(b->transform[vb->W][0],pcm,pcm);
  291. /* FFT yields more accurate tonal estimation (not phase sensitive) */
  292. drft_forward(&look->fft_look,fft);
  293. fft[0]*=scale;
  294. logfft[0]=todB(fft);
  295. local_ampmax[i]=logfft[0];
  296. for(j=1;j<n-1;j+=2){
  297. float temp=scale*FAST_HYPOT(fft[j],fft[j+1]);
  298. temp=logfft[(j+1)>>1]=todB(&temp);
  299. if(temp>local_ampmax[i])local_ampmax[i]=temp;
  300. }
  301. if(local_ampmax[i]>global_ampmax)global_ampmax=local_ampmax[i];
  302. _analysis_output("fft",seq+i,logfft,n/2,1,0);
  303. }
  304. for(i=0;i<vi->channels;i++){
  305. int submap=info->chmuxlist[i];
  306. /* the following makes things clearer to *me* anyway */
  307. float *mdct =vb->pcm[i];
  308. float *res =mdct;
  309. float *codedflr=mdct+n/2;
  310. float *logfft =mdct+n/2;
  311. float *logmdct =work;
  312. float *logmax =mdct+n/2;
  313. float *logmask =work+n/2;
  314. for(j=0;j<n/2;j++)
  315. logmdct[j]=todB(mdct+j);
  316. _analysis_output("mdct",seq+i,logmdct,n/2,1,0);
  317. /* perform psychoacoustics; do masking */
  318. _vp_compute_mask(look->psy_look[blocktype],
  319. b->psy_g_look,
  320. i,
  321. logfft, /* -> logmax */
  322. logmdct,
  323. logmask,
  324. global_ampmax,
  325. local_ampmax[i],
  326. ci->blocksizes[vb->lW]/2);
  327. _analysis_output("mask",seq+i,logmask,n/2,1,0);
  328. /* perform floor encoding */
  329. nonzero[i]=look->floor_func[submap]->
  330. forward(vb,look->floor_look[submap],
  331. mdct,
  332. logmdct,
  333. logmask,
  334. logmax,
  335. codedflr);
  336. _analysis_output("mdct2",seq+i,mdct,n/2,1,1);
  337. _vp_remove_floor(look->psy_look[blocktype],
  338. b->psy_g_look,
  339. logmdct,
  340. mdct,
  341. codedflr,
  342. res,
  343. local_ampmax[i]);
  344. for(j=0;j<n/2;j++)
  345. if(fabs(res[j])>1200){
  346. analysis_noisy=1;
  347. fprintf(stderr,"%ld ",seq+i);
  348. }
  349. _analysis_output("res",seq+i,res,n/2,1,0);
  350. _analysis_output("codedflr",seq+i,codedflr,n/2,1,1);
  351. }
  352. vbi->ampmax=global_ampmax;
  353. /* partition based prequantization and channel coupling */
  354. /* Steps in prequant and coupling:
  355. down-couple/down-quantize from perfect residue -> quantized vector
  356. classify by this first quantized vector
  357. do{
  358. encode quantized vector; add encoded values to 'so-far' vector
  359. more? [not yet at bitrate/not yet at target]
  360. yes{
  361. down-couple/down-quantize from perfect-'so-far' ->
  362. quantized vector; when subtracting coupling,
  363. account for +/- out-of-phase component
  364. }no{
  365. break
  366. }
  367. }
  368. done.
  369. quantization in each iteration is done (after circular normalization
  370. in coupling) using a by-iteration quantization granule value.
  371. */
  372. {
  373. float **pcm=vb->pcm;
  374. float **quantized=alloca(sizeof(float*)*vi->channels);
  375. float **sofar=alloca(sizeof(float*)*vi->channels);
  376. long ***classifications=alloca(sizeof(long**)*info->submaps);
  377. float ***pcmbundle=alloca(sizeof(float **)*info->submaps);
  378. float ***sobundle=alloca(sizeof(float **)*info->submaps);
  379. int **zerobundle=alloca(sizeof(int *)*info->submaps);
  380. int *chbundle=alloca(sizeof(int)*info->submaps);
  381. int chcounter=0;
  382. /* play a little loose with this abstraction */
  383. int quant_passes=look->psy_look[blocktype]->vi->coupling_passes;
  384. int stopflag=0;
  385. for(i=0;i<vi->channels;i++){
  386. quantized[i]=pcm[i]+n/2;
  387. sofar[i]=_vorbis_block_alloc(vb,n/2*sizeof(float));
  388. memset(sofar[i],0,sizeof(float)*n/2);
  389. }
  390. pcmbundle[0]=alloca(sizeof(float *)*vi->channels);
  391. sobundle[0]=alloca(sizeof(float *)*vi->channels);
  392. zerobundle[0]=alloca(sizeof(int)*vi->channels);
  393. /* initial down-quantized coupling */
  394. _vp_quantize_couple(look->psy_look[blocktype],
  395. info,
  396. pcm,
  397. sofar,
  398. quantized,
  399. nonzero,
  400. 0);
  401. for(i=0;i<vi->channels;i++)
  402. _analysis_output("quant",seq+i,quantized[i],n/2,1,0);
  403. /* classify, by submap */
  404. for(i=0;i<info->submaps;i++){
  405. int ch_in_bundle=0;
  406. pcmbundle[i]=pcmbundle[0]+chcounter;
  407. sobundle[i]=sobundle[0]+chcounter;
  408. zerobundle[i]=zerobundle[0]+chcounter;
  409. for(j=0;j<vi->channels;j++){
  410. if(info->chmuxlist[j]==i){
  411. if(nonzero[j])
  412. zerobundle[i][ch_in_bundle]=1;
  413. else
  414. zerobundle[i][ch_in_bundle]=0;
  415. pcmbundle[i][ch_in_bundle]=quantized[j];
  416. sobundle[i][ch_in_bundle++]=sofar[j];
  417. }
  418. }
  419. chbundle[i]=ch_in_bundle;
  420. chcounter+=ch_in_bundle;
  421. classifications[i]=look->residue_func[i]->
  422. class(vb,look->residue_look[i],pcmbundle[i],zerobundle[i],chbundle[i]);
  423. }
  424. /* actual encoding loop */
  425. for(i=0;!stopflag;){
  426. /* perform residue encoding of this pass's quantized residue
  427. vector, according residue mapping */
  428. for(j=0;j<info->submaps;j++)
  429. look->residue_func[j]->
  430. forward(vb,look->residue_look[j],
  431. pcmbundle[j],sobundle[j],zerobundle[j],chbundle[j],
  432. i,classifications[j]);
  433. i++;
  434. /* bitrate management decision hook; the following if() is where
  435. we tell progressive encoding to halt, right now it just
  436. avoids falling off the edge */
  437. if(i>=quant_passes /* || yadda yadda */)stopflag=1;
  438. if(!stopflag){
  439. /* down-couple/down-quantize from perfect-'so-far' ->
  440. new quantized vector */
  441. _vp_quantize_couple(look->psy_look[blocktype],
  442. info,
  443. pcm,
  444. sofar,
  445. quantized,
  446. nonzero,
  447. i);
  448. }
  449. /* steady as she goes */
  450. }
  451. seq+=vi->channels;
  452. }
  453. look->lastframe=vb->sequence;
  454. return(0);
  455. }
  456. static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){
  457. vorbis_dsp_state *vd=vb->vd;
  458. vorbis_info *vi=vd->vi;
  459. codec_setup_info *ci=vi->codec_setup;
  460. backend_lookup_state *b=vd->backend_state;
  461. vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)l;
  462. vorbis_info_mapping0 *info=look->map;
  463. vorbis_info_mode *mode=look->mode;
  464. int i,j;
  465. long n=vb->pcmend=ci->blocksizes[vb->W];
  466. float *window=b->window[vb->W][vb->lW][vb->nW][mode->windowtype];
  467. float **pcmbundle=alloca(sizeof(float *)*vi->channels);
  468. int *zerobundle=alloca(sizeof(int)*vi->channels);
  469. int *nonzero =alloca(sizeof(int)*vi->channels);
  470. void **floormemo=alloca(sizeof(void *)*vi->channels);
  471. /* time domain information decode (note that applying the
  472. information would have to happen later; we'll probably add a
  473. function entry to the harness for that later */
  474. /* NOT IMPLEMENTED */
  475. /* recover the spectral envelope; store it in the PCM vector for now */
  476. for(i=0;i<vi->channels;i++){
  477. int submap=info->chmuxlist[i];
  478. floormemo[i]=look->floor_func[submap]->
  479. inverse1(vb,look->floor_look[submap]);
  480. if(floormemo[i])
  481. nonzero[i]=1;
  482. else
  483. nonzero[i]=0;
  484. memset(vb->pcm[i],0,sizeof(float)*n/2);
  485. }
  486. /* channel coupling can 'dirty' the nonzero listing */
  487. for(i=0;i<info->coupling_steps;i++){
  488. if(nonzero[info->coupling_mag[i]] ||
  489. nonzero[info->coupling_ang[i]]){
  490. nonzero[info->coupling_mag[i]]=1;
  491. nonzero[info->coupling_ang[i]]=1;
  492. }
  493. }
  494. /* recover the residue into our working vectors */
  495. for(i=0;i<info->submaps;i++){
  496. int ch_in_bundle=0;
  497. for(j=0;j<vi->channels;j++){
  498. if(info->chmuxlist[j]==i){
  499. if(nonzero[j])
  500. zerobundle[ch_in_bundle]=1;
  501. else
  502. zerobundle[ch_in_bundle]=0;
  503. pcmbundle[ch_in_bundle++]=vb->pcm[j];
  504. }
  505. }
  506. look->residue_func[i]->inverse(vb,look->residue_look[i],
  507. pcmbundle,zerobundle,ch_in_bundle);
  508. }
  509. /* channel coupling */
  510. for(i=info->coupling_steps-1;i>=0;i--){
  511. float *pcmM=vb->pcm[info->coupling_mag[i]];
  512. float *pcmA=vb->pcm[info->coupling_ang[i]];
  513. for(j=0;j<n/2;j++){
  514. float mag=pcmM[j];
  515. float ang=pcmA[j];
  516. if(mag>0)
  517. if(ang>0){
  518. pcmM[j]=mag;
  519. pcmA[j]=mag-ang;
  520. }else{
  521. pcmA[j]=mag;
  522. pcmM[j]=mag+ang;
  523. }
  524. else
  525. if(ang>0){
  526. pcmM[j]=mag;
  527. pcmA[j]=mag+ang;
  528. }else{
  529. pcmA[j]=mag;
  530. pcmM[j]=mag-ang;
  531. }
  532. }
  533. }
  534. /* compute and apply spectral envelope */
  535. for(i=0;i<vi->channels;i++){
  536. float *pcm=vb->pcm[i];
  537. int submap=info->chmuxlist[i];
  538. look->floor_func[submap]->
  539. inverse2(vb,look->floor_look[submap],floormemo[i],pcm);
  540. }
  541. /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
  542. /* only MDCT right now.... */
  543. for(i=0;i<vi->channels;i++){
  544. float *pcm=vb->pcm[i];
  545. _analysis_output("out",seq+i,pcm,n/2,1,1);
  546. mdct_backward(b->transform[vb->W][0],pcm,pcm);
  547. }
  548. /* window the data */
  549. for(i=0;i<vi->channels;i++){
  550. float *pcm=vb->pcm[i];
  551. if(nonzero[i])
  552. for(j=0;j<n;j++)
  553. pcm[j]*=window[j];
  554. else
  555. for(j=0;j<n;j++)
  556. pcm[j]=0.f;
  557. _analysis_output("final",seq++,pcm,n,0,0);
  558. }
  559. /* now apply the decoded post-window time information */
  560. /* NOT IMPLEMENTED */
  561. /* all done! */
  562. return(0);
  563. }
  564. /* export hooks */
  565. vorbis_func_mapping mapping0_exportbundle={
  566. &mapping0_pack,
  567. &mapping0_unpack,
  568. &mapping0_look,
  569. &mapping0_copy_info,
  570. &mapping0_free_info,
  571. &mapping0_free_look,
  572. &mapping0_forward,
  573. &mapping0_inverse
  574. };