mapping0.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  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.39.2.2 2001/12/18 23:49:16 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 "registry.h"
  24. #include "psy.h"
  25. #include "misc.h"
  26. /* simplistic, wasteful way of doing this (unique lookup for each
  27. mode/submapping); there should be a central repository for
  28. identical lookups. That will require minor work, so I'm putting it
  29. off as low priority.
  30. Why a lookup for each backend in a given mode? Because the
  31. blocksize is set by the mode, and low backend lookups may require
  32. parameters from other areas of the mode/mapping */
  33. extern int analysis_noisy;
  34. typedef struct {
  35. drft_lookup fft_look;
  36. vorbis_info_mode *mode;
  37. vorbis_info_mapping0 *map;
  38. vorbis_look_time **time_look;
  39. vorbis_look_floor **floor_look;
  40. vorbis_look_residue **residue_look;
  41. vorbis_look_psy *psy_look[2];
  42. vorbis_func_time **time_func;
  43. vorbis_func_floor **floor_func;
  44. vorbis_func_residue **residue_func;
  45. int ch;
  46. long lastframe; /* if a different mode is called, we need to
  47. invalidate decay */
  48. } vorbis_look_mapping0;
  49. static vorbis_info_mapping *mapping0_copy_info(vorbis_info_mapping *vm){
  50. vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)vm;
  51. vorbis_info_mapping0 *ret=_ogg_malloc(sizeof(*ret));
  52. memcpy(ret,info,sizeof(*ret));
  53. return(ret);
  54. }
  55. static void mapping0_free_info(vorbis_info_mapping *i){
  56. vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)i;
  57. if(info){
  58. memset(info,0,sizeof(*info));
  59. _ogg_free(info);
  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(*l));
  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(*look));
  96. vorbis_info_mapping0 *info=look->map=(vorbis_info_mapping0 *)m;
  97. look->mode=vm;
  98. look->time_look=_ogg_calloc(info->submaps,sizeof(*look->time_look));
  99. look->floor_look=_ogg_calloc(info->submaps,sizeof(*look->floor_look));
  100. look->residue_look=_ogg_calloc(info->submaps,sizeof(*look->residue_look));
  101. look->time_func=_ogg_calloc(info->submaps,sizeof(*look->time_func));
  102. look->floor_func=_ogg_calloc(info->submaps,sizeof(*look->floor_func));
  103. look->residue_func=_ogg_calloc(info->submaps,sizeof(*look->residue_func));
  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(*look->psy_look[0]));
  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(*look->psy_look[1]));
  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(*look->psy_look[0]));
  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,
  152. oggpack_buffer *opb){
  153. int i;
  154. vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)vm;
  155. /* another 'we meant to do it this way' hack... up to beta 4, we
  156. packed 4 binary zeros here to signify one submapping in use. We
  157. now redefine that to mean four bitflags that indicate use of
  158. deeper features; bit0:submappings, bit1:coupling,
  159. bit2,3:reserved. This is backward compatable with all actual uses
  160. of the beta code. */
  161. if(info->submaps>1){
  162. oggpack_write(opb,1,1);
  163. oggpack_write(opb,info->submaps-1,4);
  164. }else
  165. oggpack_write(opb,0,1);
  166. if(info->coupling_steps>0){
  167. oggpack_write(opb,1,1);
  168. oggpack_write(opb,info->coupling_steps-1,8);
  169. for(i=0;i<info->coupling_steps;i++){
  170. oggpack_write(opb,info->coupling_mag[i],ilog2(vi->channels));
  171. oggpack_write(opb,info->coupling_ang[i],ilog2(vi->channels));
  172. }
  173. }else
  174. oggpack_write(opb,0,1);
  175. oggpack_write(opb,0,2); /* 2,3:reserved */
  176. /* we don't write the channel submappings if we only have one... */
  177. if(info->submaps>1){
  178. for(i=0;i<vi->channels;i++)
  179. oggpack_write(opb,info->chmuxlist[i],4);
  180. }
  181. for(i=0;i<info->submaps;i++){
  182. oggpack_write(opb,info->timesubmap[i],8);
  183. oggpack_write(opb,info->floorsubmap[i],8);
  184. oggpack_write(opb,info->residuesubmap[i],8);
  185. }
  186. }
  187. /* also responsible for range checking */
  188. static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){
  189. int i;
  190. vorbis_info_mapping0 *info=_ogg_calloc(1,sizeof(*info));
  191. codec_setup_info *ci=vi->codec_setup;
  192. memset(info,0,sizeof(*info));
  193. if(oggpack_read(opb,1))
  194. info->submaps=oggpack_read(opb,4)+1;
  195. else
  196. info->submaps=1;
  197. if(oggpack_read(opb,1)){
  198. info->coupling_steps=oggpack_read(opb,8)+1;
  199. for(i=0;i<info->coupling_steps;i++){
  200. int testM=info->coupling_mag[i]=oggpack_read(opb,ilog2(vi->channels));
  201. int testA=info->coupling_ang[i]=oggpack_read(opb,ilog2(vi->channels));
  202. if(testM<0 ||
  203. testA<0 ||
  204. testM==testA ||
  205. testM>=vi->channels ||
  206. testA>=vi->channels) goto err_out;
  207. }
  208. }
  209. if(oggpack_read(opb,2)>0)goto err_out; /* 2,3:reserved */
  210. if(info->submaps>1){
  211. for(i=0;i<vi->channels;i++){
  212. info->chmuxlist[i]=oggpack_read(opb,4);
  213. if(info->chmuxlist[i]>=info->submaps)goto err_out;
  214. }
  215. }
  216. for(i=0;i<info->submaps;i++){
  217. info->timesubmap[i]=oggpack_read(opb,8);
  218. if(info->timesubmap[i]>=ci->times)goto err_out;
  219. info->floorsubmap[i]=oggpack_read(opb,8);
  220. if(info->floorsubmap[i]>=ci->floors)goto err_out;
  221. info->residuesubmap[i]=oggpack_read(opb,8);
  222. if(info->residuesubmap[i]>=ci->residues)goto err_out;
  223. }
  224. return info;
  225. err_out:
  226. mapping0_free_info(info);
  227. return(NULL);
  228. }
  229. #include "os.h"
  230. #include "lpc.h"
  231. #include "lsp.h"
  232. #include "envelope.h"
  233. #include "mdct.h"
  234. #include "psy.h"
  235. #include "scales.h"
  236. /* no time mapping implementation for now */
  237. static long seq=0;
  238. static int mapping0_forward(vorbis_block *vb,vorbis_look_mapping *l){
  239. vorbis_dsp_state *vd=vb->vd;
  240. vorbis_info *vi=vd->vi;
  241. codec_setup_info *ci=vi->codec_setup;
  242. backend_lookup_state *b=vb->vd->backend_state;
  243. bitrate_manager_state *bm=&b->bms;
  244. vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)l;
  245. vorbis_info_mapping0 *info=look->map;
  246. vorbis_info_mode *mode=look->mode;
  247. vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
  248. int n=vb->pcmend;
  249. int i,j;
  250. float *window=b->window[vb->W][vb->lW][vb->nW][mode->windowtype];
  251. int *nonzero=alloca(sizeof(*nonzero)*vi->channels);
  252. float *work=_vorbis_block_alloc(vb,n*sizeof(*work));
  253. float global_ampmax=vbi->ampmax;
  254. float *local_ampmax=alloca(sizeof(*local_ampmax)*vi->channels);
  255. int blocktype=vbi->blocktype;
  256. /* we differentiate between short and long block types to help the
  257. masking engine; the window shapes also matter.
  258. impulse block (a short block in which an impulse occurs)
  259. padding block (a short block that pads between a transitional
  260. long block and an impulse block, or vice versa)
  261. transition block (the wqeird one; a long block with the transition
  262. window; affects bass/midrange response and that must be
  263. accounted for in masking)
  264. long block (run of the mill long block)
  265. */
  266. for(i=0;i<vi->channels;i++){
  267. float scale=4.f/n;
  268. /* the following makes things clearer to *me* anyway */
  269. float *pcm =vb->pcm[i];
  270. float *fft =work;
  271. float *logfft =pcm+n/2;
  272. /*float *res =pcm;
  273. float *mdct =pcm;
  274. float *codedflr=pcm+n/2;
  275. float *logmax =work;
  276. float *logmask =work+n/2;*/
  277. _analysis_output("pcm",seq+i,pcm,n,0,0);
  278. /* window the PCM data */
  279. for(j=0;j<n;j++)
  280. fft[j]=pcm[j]*=window[j];
  281. //_analysis_output("windowed",seq+i,pcm,n,0,0);
  282. /* transform the PCM data */
  283. /* only MDCT right now.... */
  284. mdct_forward(b->transform[vb->W][0],pcm,pcm);
  285. /* FFT yields more accurate tonal estimation (not phase sensitive) */
  286. drft_forward(&look->fft_look,fft);
  287. fft[0]*=scale;
  288. logfft[0]=todB(fft);
  289. local_ampmax[i]=logfft[0];
  290. for(j=1;j<n-1;j+=2){
  291. float temp=scale*FAST_HYPOT(fft[j],fft[j+1]);
  292. temp=logfft[(j+1)>>1]=todB(&temp);
  293. if(temp>local_ampmax[i])local_ampmax[i]=temp;
  294. }
  295. if(local_ampmax[i]>0.f)local_ampmax[i]=0.f;
  296. if(local_ampmax[i]>global_ampmax)global_ampmax=local_ampmax[i];
  297. _analysis_output("fft",seq+i,logfft,n/2,1,0);
  298. }
  299. for(i=0;i<vi->channels;i++){
  300. int submap=info->chmuxlist[i];
  301. /* the following makes things clearer to *me* anyway */
  302. float *mdct =vb->pcm[i];
  303. float *res =mdct;
  304. float *codedflr=mdct+n/2;
  305. float *logfft =mdct+n/2;
  306. float *logmdct =work;
  307. float *logmax =mdct+n/2;
  308. float *logmask =work+n/2;
  309. for(j=0;j<n/2;j++)
  310. logmdct[j]=todB(mdct+j);
  311. _analysis_output("mdct",seq+i,logmdct,n/2,1,0);
  312. /* perform psychoacoustics; do masking */
  313. _vp_compute_mask(look->psy_look[blocktype],
  314. logfft, /* -> logmax */
  315. logmdct,
  316. logmask,
  317. global_ampmax,
  318. local_ampmax[i],
  319. bm->avgnoise);
  320. _analysis_output("mask",seq+i,logmask,n/2,1,0);
  321. /* perform floor encoding */
  322. nonzero[i]=look->floor_func[submap]->
  323. forward(vb,look->floor_look[submap],
  324. mdct,
  325. logmdct,
  326. logmask,
  327. logmax,
  328. codedflr);
  329. _vp_remove_floor(look->psy_look[blocktype],
  330. mdct,
  331. codedflr,
  332. res);
  333. /*for(j=0;j<n/2;j++)
  334. if(fabs(res[j])>1200){
  335. analysis_noisy=1;
  336. fprintf(stderr,"%ld ",seq+i);
  337. }*/
  338. _analysis_output("codedflr",seq+i,codedflr,n/2,1,1);
  339. }
  340. vbi->ampmax=global_ampmax;
  341. /* partition based prequantization and channel coupling */
  342. /* Steps in prequant and coupling:
  343. classify by |mag| across all pcm vectors
  344. down-couple/down-quantize from perfect residue -> quantized vector
  345. do{
  346. encode quantized vector; add encoded values to 'so-far' vector
  347. more? [not yet at bitrate/not yet at target]
  348. yes{
  349. down-couple/down-quantize from perfect-'so-far' ->
  350. quantized vector; when subtracting coupling,
  351. account for +/- out-of-phase component
  352. }no{
  353. break
  354. }
  355. }
  356. done.
  357. quantization in each iteration is done (after circular normalization
  358. in coupling) using a by-iteration quantization granule value.
  359. */
  360. {
  361. float **pcm=vb->pcm;
  362. float **quantized=alloca(sizeof(*quantized)*vi->channels);
  363. float **sofar=alloca(sizeof(*sofar)*vi->channels);
  364. long ***classifications=alloca(sizeof(*classifications)*info->submaps);
  365. float ***qbundle=alloca(sizeof(*qbundle)*info->submaps);
  366. float ***pcmbundle=alloca(sizeof(*pcmbundle)*info->submaps);
  367. float ***sobundle=alloca(sizeof(*sobundle)*info->submaps);
  368. int **zerobundle=alloca(sizeof(*zerobundle)*info->submaps);
  369. int *chbundle=alloca(sizeof(*chbundle)*info->submaps);
  370. int chcounter=0;
  371. /* play a little loose with this abstraction */
  372. int quant_passes=ci->coupling_passes;
  373. for(i=0;i<vi->channels;i++){
  374. quantized[i]=_vorbis_block_alloc(vb,n*sizeof(*sofar[i]));
  375. sofar[i]=quantized[i]+n/2;
  376. memset(sofar[i],0,sizeof(*sofar[i])*n/2);
  377. }
  378. qbundle[0]=alloca(sizeof(*qbundle[0])*vi->channels);
  379. pcmbundle[0]=alloca(sizeof(*pcmbundle[0])*vi->channels);
  380. sobundle[0]=alloca(sizeof(*sobundle[0])*vi->channels);
  381. zerobundle[0]=alloca(sizeof(*zerobundle[0])*vi->channels);
  382. /* initial down-quantized coupling */
  383. if(info->coupling_steps==0){
  384. /* this assumes all or nothing coupling right now. it should pass
  385. through any channels left uncoupled, but it doesn't do that now */
  386. for(i=0;i<vi->channels;i++){
  387. float *lpcm=pcm[i];
  388. float *lqua=quantized[i];
  389. for(j=0;j<n/2;j++)
  390. lqua[j]=lpcm[j];
  391. }
  392. }else{
  393. _vp_quantize_couple(look->psy_look[blocktype],
  394. info,
  395. pcm,
  396. sofar,
  397. quantized,
  398. nonzero,
  399. 0);
  400. }
  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. qbundle[i]=qbundle[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. qbundle[i][ch_in_bundle]=quantized[j];
  416. pcmbundle[i][ch_in_bundle]=pcm[j];
  417. sobundle[i][ch_in_bundle++]=sofar[j];
  418. }
  419. }
  420. chbundle[i]=ch_in_bundle;
  421. chcounter+=ch_in_bundle;
  422. classifications[i]=look->residue_func[i]->
  423. class(vb,look->residue_look[i],pcmbundle[i],zerobundle[i],chbundle[i]);
  424. }
  425. /* actual encoding loop; we pack all the iterations to collect
  426. management data */
  427. for(i=0;i<quant_passes;){
  428. /* perform residue encoding of this pass's quantized residue
  429. vector, according residue mapping */
  430. for(j=0;j<info->submaps;j++){
  431. look->residue_func[j]->
  432. forward(vb,look->residue_look[j],
  433. qbundle[j],sobundle[j],zerobundle[j],chbundle[j],
  434. i,classifications[j],vbi->packet_markers);
  435. }
  436. i++;
  437. if(i<quant_passes){
  438. /* down-couple/down-quantize from perfect-'so-far' ->
  439. new quantized vector */
  440. if(info->coupling_steps==0){
  441. /* this assumes all or nothing coupling right now. it should pass
  442. through any channels left uncoupled, but it doesn't do that now */
  443. int k;
  444. for(k=0;k<vi->channels;k++){
  445. float *lpcm=pcm[k];
  446. float *lsof=sofar[k];
  447. float *lqua=quantized[k];
  448. for(j=0;j<n/2;j++)
  449. lqua[j]=lpcm[j]-lsof[j];
  450. }
  451. }else{
  452. _vp_quantize_couple(look->psy_look[blocktype],
  453. info,
  454. pcm,
  455. sofar,
  456. quantized,
  457. nonzero,
  458. i);
  459. }
  460. }
  461. }
  462. seq+=vi->channels;
  463. }
  464. look->lastframe=vb->sequence;
  465. return(0);
  466. }
  467. static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){
  468. vorbis_dsp_state *vd=vb->vd;
  469. vorbis_info *vi=vd->vi;
  470. codec_setup_info *ci=vi->codec_setup;
  471. backend_lookup_state *b=vd->backend_state;
  472. vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)l;
  473. vorbis_info_mapping0 *info=look->map;
  474. vorbis_info_mode *mode=look->mode;
  475. int i,j;
  476. long n=vb->pcmend=ci->blocksizes[vb->W];
  477. float *window=b->window[vb->W][vb->lW][vb->nW][mode->windowtype];
  478. float **pcmbundle=alloca(sizeof(*pcmbundle)*vi->channels);
  479. int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels);
  480. int *nonzero =alloca(sizeof(*nonzero)*vi->channels);
  481. void **floormemo=alloca(sizeof(*floormemo)*vi->channels);
  482. /* time domain information decode (note that applying the
  483. information would have to happen later; we'll probably add a
  484. function entry to the harness for that later */
  485. /* NOT IMPLEMENTED */
  486. /* recover the spectral envelope; store it in the PCM vector for now */
  487. for(i=0;i<vi->channels;i++){
  488. int submap=info->chmuxlist[i];
  489. floormemo[i]=look->floor_func[submap]->
  490. inverse1(vb,look->floor_look[submap]);
  491. if(floormemo[i])
  492. nonzero[i]=1;
  493. else
  494. nonzero[i]=0;
  495. memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2);
  496. }
  497. /* channel coupling can 'dirty' the nonzero listing */
  498. for(i=0;i<info->coupling_steps;i++){
  499. if(nonzero[info->coupling_mag[i]] ||
  500. nonzero[info->coupling_ang[i]]){
  501. nonzero[info->coupling_mag[i]]=1;
  502. nonzero[info->coupling_ang[i]]=1;
  503. }
  504. }
  505. /* recover the residue into our working vectors */
  506. for(i=0;i<info->submaps;i++){
  507. int ch_in_bundle=0;
  508. for(j=0;j<vi->channels;j++){
  509. if(info->chmuxlist[j]==i){
  510. if(nonzero[j])
  511. zerobundle[ch_in_bundle]=1;
  512. else
  513. zerobundle[ch_in_bundle]=0;
  514. pcmbundle[ch_in_bundle++]=vb->pcm[j];
  515. }
  516. }
  517. look->residue_func[i]->inverse(vb,look->residue_look[i],
  518. pcmbundle,zerobundle,ch_in_bundle);
  519. }
  520. /* channel coupling */
  521. for(i=info->coupling_steps-1;i>=0;i--){
  522. float *pcmM=vb->pcm[info->coupling_mag[i]];
  523. float *pcmA=vb->pcm[info->coupling_ang[i]];
  524. for(j=0;j<n/2;j++){
  525. float mag=pcmM[j];
  526. float ang=pcmA[j];
  527. if(mag>0)
  528. if(ang>0){
  529. pcmM[j]=mag;
  530. pcmA[j]=mag-ang;
  531. }else{
  532. pcmA[j]=mag;
  533. pcmM[j]=mag+ang;
  534. }
  535. else
  536. if(ang>0){
  537. pcmM[j]=mag;
  538. pcmA[j]=mag+ang;
  539. }else{
  540. pcmA[j]=mag;
  541. pcmM[j]=mag-ang;
  542. }
  543. }
  544. }
  545. /* compute and apply spectral envelope */
  546. for(i=0;i<vi->channels;i++){
  547. float *pcm=vb->pcm[i];
  548. int submap=info->chmuxlist[i];
  549. look->floor_func[submap]->
  550. inverse2(vb,look->floor_look[submap],floormemo[i],pcm);
  551. }
  552. /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
  553. /* only MDCT right now.... */
  554. for(i=0;i<vi->channels;i++){
  555. float *pcm=vb->pcm[i];
  556. mdct_backward(b->transform[vb->W][0],pcm,pcm);
  557. }
  558. /* window the data */
  559. for(i=0;i<vi->channels;i++){
  560. float *pcm=vb->pcm[i];
  561. if(nonzero[i])
  562. for(j=0;j<n;j++)
  563. pcm[j]*=window[j];
  564. else
  565. for(j=0;j<n;j++)
  566. pcm[j]=0.f;
  567. }
  568. /* all done! */
  569. return(0);
  570. }
  571. /* export hooks */
  572. vorbis_func_mapping mapping0_exportbundle={
  573. &mapping0_pack,
  574. &mapping0_unpack,
  575. &mapping0_look,
  576. &mapping0_copy_info,
  577. &mapping0_free_info,
  578. &mapping0_free_look,
  579. &mapping0_forward,
  580. &mapping0_inverse
  581. };