annotate src/libvorbis-1.3.3/lib/floor0.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 05aa0afa9217
children
rev   line source
Chris@1 1 /********************************************************************
Chris@1 2 * *
Chris@1 3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
Chris@1 4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
Chris@1 5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
Chris@1 6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
Chris@1 7 * *
Chris@1 8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
Chris@1 9 * by the Xiph.Org Foundation http://www.xiph.org/ *
Chris@1 10 * *
Chris@1 11 ********************************************************************
Chris@1 12
Chris@1 13 function: floor backend 0 implementation
Chris@1 14 last mod: $Id: floor0.c 18184 2012-02-03 20:55:12Z xiphmont $
Chris@1 15
Chris@1 16 ********************************************************************/
Chris@1 17
Chris@1 18 #include <stdlib.h>
Chris@1 19 #include <string.h>
Chris@1 20 #include <math.h>
Chris@1 21 #include <ogg/ogg.h>
Chris@1 22 #include "vorbis/codec.h"
Chris@1 23 #include "codec_internal.h"
Chris@1 24 #include "registry.h"
Chris@1 25 #include "lpc.h"
Chris@1 26 #include "lsp.h"
Chris@1 27 #include "codebook.h"
Chris@1 28 #include "scales.h"
Chris@1 29 #include "misc.h"
Chris@1 30 #include "os.h"
Chris@1 31
Chris@1 32 #include "misc.h"
Chris@1 33 #include <stdio.h>
Chris@1 34
Chris@1 35 typedef struct {
Chris@1 36 int ln;
Chris@1 37 int m;
Chris@1 38 int **linearmap;
Chris@1 39 int n[2];
Chris@1 40
Chris@1 41 vorbis_info_floor0 *vi;
Chris@1 42
Chris@1 43 long bits;
Chris@1 44 long frames;
Chris@1 45 } vorbis_look_floor0;
Chris@1 46
Chris@1 47
Chris@1 48 /***********************************************/
Chris@1 49
Chris@1 50 static void floor0_free_info(vorbis_info_floor *i){
Chris@1 51 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
Chris@1 52 if(info){
Chris@1 53 memset(info,0,sizeof(*info));
Chris@1 54 _ogg_free(info);
Chris@1 55 }
Chris@1 56 }
Chris@1 57
Chris@1 58 static void floor0_free_look(vorbis_look_floor *i){
Chris@1 59 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
Chris@1 60 if(look){
Chris@1 61
Chris@1 62 if(look->linearmap){
Chris@1 63
Chris@1 64 if(look->linearmap[0])_ogg_free(look->linearmap[0]);
Chris@1 65 if(look->linearmap[1])_ogg_free(look->linearmap[1]);
Chris@1 66
Chris@1 67 _ogg_free(look->linearmap);
Chris@1 68 }
Chris@1 69 memset(look,0,sizeof(*look));
Chris@1 70 _ogg_free(look);
Chris@1 71 }
Chris@1 72 }
Chris@1 73
Chris@1 74 static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
Chris@1 75 codec_setup_info *ci=vi->codec_setup;
Chris@1 76 int j;
Chris@1 77
Chris@1 78 vorbis_info_floor0 *info=_ogg_malloc(sizeof(*info));
Chris@1 79 info->order=oggpack_read(opb,8);
Chris@1 80 info->rate=oggpack_read(opb,16);
Chris@1 81 info->barkmap=oggpack_read(opb,16);
Chris@1 82 info->ampbits=oggpack_read(opb,6);
Chris@1 83 info->ampdB=oggpack_read(opb,8);
Chris@1 84 info->numbooks=oggpack_read(opb,4)+1;
Chris@1 85
Chris@1 86 if(info->order<1)goto err_out;
Chris@1 87 if(info->rate<1)goto err_out;
Chris@1 88 if(info->barkmap<1)goto err_out;
Chris@1 89 if(info->numbooks<1)goto err_out;
Chris@1 90
Chris@1 91 for(j=0;j<info->numbooks;j++){
Chris@1 92 info->books[j]=oggpack_read(opb,8);
Chris@1 93 if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
Chris@1 94 if(ci->book_param[info->books[j]]->maptype==0)goto err_out;
Chris@1 95 if(ci->book_param[info->books[j]]->dim<1)goto err_out;
Chris@1 96 }
Chris@1 97 return(info);
Chris@1 98
Chris@1 99 err_out:
Chris@1 100 floor0_free_info(info);
Chris@1 101 return(NULL);
Chris@1 102 }
Chris@1 103
Chris@1 104 /* initialize Bark scale and normalization lookups. We could do this
Chris@1 105 with static tables, but Vorbis allows a number of possible
Chris@1 106 combinations, so it's best to do it computationally.
Chris@1 107
Chris@1 108 The below is authoritative in terms of defining scale mapping.
Chris@1 109 Note that the scale depends on the sampling rate as well as the
Chris@1 110 linear block and mapping sizes */
Chris@1 111
Chris@1 112 static void floor0_map_lazy_init(vorbis_block *vb,
Chris@1 113 vorbis_info_floor *infoX,
Chris@1 114 vorbis_look_floor0 *look){
Chris@1 115 if(!look->linearmap[vb->W]){
Chris@1 116 vorbis_dsp_state *vd=vb->vd;
Chris@1 117 vorbis_info *vi=vd->vi;
Chris@1 118 codec_setup_info *ci=vi->codec_setup;
Chris@1 119 vorbis_info_floor0 *info=(vorbis_info_floor0 *)infoX;
Chris@1 120 int W=vb->W;
Chris@1 121 int n=ci->blocksizes[W]/2,j;
Chris@1 122
Chris@1 123 /* we choose a scaling constant so that:
Chris@1 124 floor(bark(rate/2-1)*C)=mapped-1
Chris@1 125 floor(bark(rate/2)*C)=mapped */
Chris@1 126 float scale=look->ln/toBARK(info->rate/2.f);
Chris@1 127
Chris@1 128 /* the mapping from a linear scale to a smaller bark scale is
Chris@1 129 straightforward. We do *not* make sure that the linear mapping
Chris@1 130 does not skip bark-scale bins; the decoder simply skips them and
Chris@1 131 the encoder may do what it wishes in filling them. They're
Chris@1 132 necessary in some mapping combinations to keep the scale spacing
Chris@1 133 accurate */
Chris@1 134 look->linearmap[W]=_ogg_malloc((n+1)*sizeof(**look->linearmap));
Chris@1 135 for(j=0;j<n;j++){
Chris@1 136 int val=floor( toBARK((info->rate/2.f)/n*j)
Chris@1 137 *scale); /* bark numbers represent band edges */
Chris@1 138 if(val>=look->ln)val=look->ln-1; /* guard against the approximation */
Chris@1 139 look->linearmap[W][j]=val;
Chris@1 140 }
Chris@1 141 look->linearmap[W][j]=-1;
Chris@1 142 look->n[W]=n;
Chris@1 143 }
Chris@1 144 }
Chris@1 145
Chris@1 146 static vorbis_look_floor *floor0_look(vorbis_dsp_state *vd,
Chris@1 147 vorbis_info_floor *i){
Chris@1 148 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
Chris@1 149 vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(*look));
Chris@1 150 look->m=info->order;
Chris@1 151 look->ln=info->barkmap;
Chris@1 152 look->vi=info;
Chris@1 153
Chris@1 154 look->linearmap=_ogg_calloc(2,sizeof(*look->linearmap));
Chris@1 155
Chris@1 156 return look;
Chris@1 157 }
Chris@1 158
Chris@1 159 static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
Chris@1 160 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
Chris@1 161 vorbis_info_floor0 *info=look->vi;
Chris@1 162 int j,k;
Chris@1 163
Chris@1 164 int ampraw=oggpack_read(&vb->opb,info->ampbits);
Chris@1 165 if(ampraw>0){ /* also handles the -1 out of data case */
Chris@1 166 long maxval=(1<<info->ampbits)-1;
Chris@1 167 float amp=(float)ampraw/maxval*info->ampdB;
Chris@1 168 int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
Chris@1 169
Chris@1 170 if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
Chris@1 171 codec_setup_info *ci=vb->vd->vi->codec_setup;
Chris@1 172 codebook *b=ci->fullbooks+info->books[booknum];
Chris@1 173 float last=0.f;
Chris@1 174
Chris@1 175 /* the additional b->dim is a guard against any possible stack
Chris@1 176 smash; b->dim is provably more than we can overflow the
Chris@1 177 vector */
Chris@1 178 float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+b->dim+1));
Chris@1 179
Chris@1 180 if(vorbis_book_decodev_set(b,lsp,&vb->opb,look->m)==-1)goto eop;
Chris@1 181 for(j=0;j<look->m;){
Chris@1 182 for(k=0;j<look->m && k<b->dim;k++,j++)lsp[j]+=last;
Chris@1 183 last=lsp[j-1];
Chris@1 184 }
Chris@1 185
Chris@1 186 lsp[look->m]=amp;
Chris@1 187 return(lsp);
Chris@1 188 }
Chris@1 189 }
Chris@1 190 eop:
Chris@1 191 return(NULL);
Chris@1 192 }
Chris@1 193
Chris@1 194 static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i,
Chris@1 195 void *memo,float *out){
Chris@1 196 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
Chris@1 197 vorbis_info_floor0 *info=look->vi;
Chris@1 198
Chris@1 199 floor0_map_lazy_init(vb,info,look);
Chris@1 200
Chris@1 201 if(memo){
Chris@1 202 float *lsp=(float *)memo;
Chris@1 203 float amp=lsp[look->m];
Chris@1 204
Chris@1 205 /* take the coefficients back to a spectral envelope curve */
Chris@1 206 vorbis_lsp_to_curve(out,
Chris@1 207 look->linearmap[vb->W],
Chris@1 208 look->n[vb->W],
Chris@1 209 look->ln,
Chris@1 210 lsp,look->m,amp,(float)info->ampdB);
Chris@1 211 return(1);
Chris@1 212 }
Chris@1 213 memset(out,0,sizeof(*out)*look->n[vb->W]);
Chris@1 214 return(0);
Chris@1 215 }
Chris@1 216
Chris@1 217 /* export hooks */
Chris@1 218 const vorbis_func_floor floor0_exportbundle={
Chris@1 219 NULL,&floor0_unpack,&floor0_look,&floor0_free_info,
Chris@1 220 &floor0_free_look,&floor0_inverse1,&floor0_inverse2
Chris@1 221 };