aboutsummaryrefslogtreecommitdiffstats
path: root/Tremolo/mapping0.c
diff options
context:
space:
mode:
Diffstat (limited to 'Tremolo/mapping0.c')
-rw-r--r--Tremolo/mapping0.c241
1 files changed, 241 insertions, 0 deletions
diff --git a/Tremolo/mapping0.c b/Tremolo/mapping0.c
new file mode 100644
index 0000000..f3e4c96
--- /dev/null
+++ b/Tremolo/mapping0.c
@@ -0,0 +1,241 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
+ * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: channel mapping 0 implementation
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "ogg.h"
+#include "os.h"
+#include "ivorbiscodec.h"
+#include "mdct.h"
+#include "codec_internal.h"
+#include "codebook.h"
+#include "misc.h"
+
+void mapping_clear_info(vorbis_info_mapping *info){
+ if(info){
+ if(info->chmuxlist)_ogg_free(info->chmuxlist);
+ if(info->submaplist)_ogg_free(info->submaplist);
+ if(info->coupling)_ogg_free(info->coupling);
+ memset(info,0,sizeof(*info));
+ }
+}
+
+static int ilog(unsigned int v){
+ int ret=0;
+ if(v)--v;
+ while(v){
+ ret++;
+ v>>=1;
+ }
+ return(ret);
+}
+
+/* also responsible for range checking */
+int mapping_info_unpack(vorbis_info_mapping *info,vorbis_info *vi,
+ oggpack_buffer *opb){
+ int i;
+ codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
+ memset(info,0,sizeof(*info));
+
+ if(oggpack_read(opb,1))
+ info->submaps=oggpack_read(opb,4)+1;
+ else
+ info->submaps=1;
+
+ if(oggpack_read(opb,1)){
+ info->coupling_steps=oggpack_read(opb,8)+1;
+ info->coupling=
+ _ogg_malloc(info->coupling_steps*sizeof(*info->coupling));
+
+ for(i=0;i<info->coupling_steps;i++){
+ int testM=info->coupling[i].mag=(unsigned char)(oggpack_read(opb,ilog(vi->channels)));
+ int testA=info->coupling[i].ang=(unsigned char)(oggpack_read(opb,ilog(vi->channels)));
+
+ if(testM<0 ||
+ testA<0 ||
+ testM==testA ||
+ testM>=vi->channels ||
+ testA>=vi->channels) goto err_out;
+ }
+
+ }
+
+ if(oggpack_read(opb,2)>0)goto err_out; /* 2,3:reserved */
+
+ if(info->submaps>1){
+ info->chmuxlist=_ogg_malloc(sizeof(*info->chmuxlist)*vi->channels);
+ for(i=0;i<vi->channels;i++){
+ info->chmuxlist[i]=(unsigned char)(oggpack_read(opb,4));
+ if(info->chmuxlist[i]>=info->submaps)goto err_out;
+ }
+ }
+
+ info->submaplist=_ogg_malloc(sizeof(*info->submaplist)*info->submaps);
+ for(i=0;i<info->submaps;i++){
+ int temp=oggpack_read(opb,8);
+ info->submaplist[i].floor=(char)oggpack_read(opb,8);
+ if(info->submaplist[i].floor>=ci->floors)goto err_out;
+ info->submaplist[i].residue=(char)oggpack_read(opb,8);
+ if(info->submaplist[i].residue>=ci->residues)goto err_out;
+ }
+
+ return 0;
+
+ err_out:
+ mapping_clear_info(info);
+ return -1;
+}
+
+int mapping_inverse(vorbis_dsp_state *vd,vorbis_info_mapping *info){
+ vorbis_info *vi=vd->vi;
+ codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
+
+ int i,j;
+ long n=ci->blocksizes[vd->W];
+
+ ogg_int32_t **pcmbundle=
+ alloca(sizeof(*pcmbundle)*vi->channels);
+ int *zerobundle=
+ alloca(sizeof(*zerobundle)*vi->channels);
+ int *nonzero=
+ alloca(sizeof(*nonzero)*vi->channels);
+ ogg_int32_t **floormemo=
+ alloca(sizeof(*floormemo)*vi->channels);
+
+ /* recover the spectral envelope; store it in the PCM vector for now */
+ for(i=0;i<vi->channels;i++){
+ int submap=0;
+ int floorno;
+
+ if(info->submaps>1)
+ submap=info->chmuxlist[i];
+ floorno=info->submaplist[submap].floor;
+
+ if(ci->floor_type[floorno]){
+ /* floor 1 */
+ floormemo[i]=alloca(sizeof(*floormemo[i])*
+ floor1_memosize(ci->floor_param[floorno]));
+ floormemo[i]=floor1_inverse1(vd,ci->floor_param[floorno],floormemo[i]);
+ }else{
+ /* floor 0 */
+ floormemo[i]=alloca(sizeof(*floormemo[i])*
+ floor0_memosize(ci->floor_param[floorno]));
+ floormemo[i]=floor0_inverse1(vd,ci->floor_param[floorno],floormemo[i]);
+ }
+
+ if(floormemo[i])
+ nonzero[i]=1;
+ else
+ nonzero[i]=0;
+ memset(vd->work[i],0,sizeof(*vd->work[i])*n/2);
+ }
+
+ /* channel coupling can 'dirty' the nonzero listing */
+ for(i=0;i<info->coupling_steps;i++){
+ if(nonzero[info->coupling[i].mag] ||
+ nonzero[info->coupling[i].ang]){
+ nonzero[info->coupling[i].mag]=1;
+ nonzero[info->coupling[i].ang]=1;
+ }
+ }
+
+ /* recover the residue into our working vectors */
+ for(i=0;i<info->submaps;i++){
+ int ch_in_bundle=0;
+ for(j=0;j<vi->channels;j++){
+ if(!info->chmuxlist || info->chmuxlist[j]==i){
+ if(nonzero[j])
+ zerobundle[ch_in_bundle]=1;
+ else
+ zerobundle[ch_in_bundle]=0;
+ pcmbundle[ch_in_bundle++]=vd->work[j];
+ }
+ }
+
+ res_inverse(vd,ci->residue_param+info->submaplist[i].residue,
+ pcmbundle,zerobundle,ch_in_bundle);
+ }
+
+ //for(j=0;j<vi->channels;j++)
+ //_analysis_output("coupled",seq+j,vb->pcm[j],-8,n/2,0,0);
+
+ /* channel coupling */
+ for(i=info->coupling_steps-1;i>=0;i--){
+ ogg_int32_t *pcmM=vd->work[info->coupling[i].mag];
+ ogg_int32_t *pcmA=vd->work[info->coupling[i].ang];
+
+ for(j=0;j<n/2;j++){
+ ogg_int32_t mag=pcmM[j];
+ ogg_int32_t ang=pcmA[j];
+
+ if(mag>0)
+ if(ang>0){
+ pcmM[j]=mag;
+ pcmA[j]=mag-ang;
+ }else{
+ pcmA[j]=mag;
+ pcmM[j]=mag+ang;
+ }
+ else
+ if(ang>0){
+ pcmM[j]=mag;
+ pcmA[j]=mag+ang;
+ }else{
+ pcmA[j]=mag;
+ pcmM[j]=mag-ang;
+ }
+ }
+ }
+
+ //for(j=0;j<vi->channels;j++)
+ //_analysis_output("residue",seq+j,vb->pcm[j],-8,n/2,0,0);
+
+ /* compute and apply spectral envelope */
+ for(i=0;i<vi->channels;i++){
+ ogg_int32_t *pcm=vd->work[i];
+ int submap=0;
+ int floorno;
+
+ if(info->submaps>1)
+ submap=info->chmuxlist[i];
+ floorno=info->submaplist[submap].floor;
+
+ if(ci->floor_type[floorno]){
+ /* floor 1 */
+ floor1_inverse2(vd,ci->floor_param[floorno],floormemo[i],pcm);
+ }else{
+ /* floor 0 */
+ floor0_inverse2(vd,ci->floor_param[floorno],floormemo[i],pcm);
+ }
+ }
+
+ //for(j=0;j<vi->channels;j++)
+ //_analysis_output("mdct",seq+j,vb->pcm[j],-24,n/2,0,1);
+
+ /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
+ /* only MDCT right now.... */
+ for(i=0;i<vi->channels;i++)
+ mdct_backward(n,vd->work[i]);
+
+ //for(j=0;j<vi->channels;j++)
+ //_analysis_output("imdct",seq+j,vb->pcm[j],-24,n,0,0);
+
+ /* all done! */
+ return(0);
+}