Coverage Report

Created: 2026-02-14 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vorbis/lib/floor0.c
Line
Count
Source
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-2015             *
9
 * by the Xiph.Org Foundation https://xiph.org/                     *
10
 *                                                                  *
11
 ********************************************************************
12
13
 function: floor backend 0 implementation
14
15
 ********************************************************************/
16
17
#include <stdlib.h>
18
#include <string.h>
19
#include <math.h>
20
#include <ogg/ogg.h>
21
#include "vorbis/codec.h"
22
#include "codec_internal.h"
23
#include "registry.h"
24
#include "lpc.h"
25
#include "lsp.h"
26
#include "codebook.h"
27
#include "scales.h"
28
#include "misc.h"
29
#include "os.h"
30
31
#include "misc.h"
32
#include <stdio.h>
33
34
typedef struct {
35
  int ln;
36
  int  m;
37
  int **linearmap;
38
  int  n[2];
39
40
  vorbis_info_floor0 *vi;
41
42
  long bits;
43
  long frames;
44
} vorbis_look_floor0;
45
46
47
/***********************************************/
48
49
334
static void floor0_free_info(vorbis_info_floor *i){
50
334
  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
51
334
  if(info){
52
334
    memset(info,0,sizeof(*info));
53
334
    _ogg_free(info);
54
334
  }
55
334
}
56
57
232
static void floor0_free_look(vorbis_look_floor *i){
58
232
  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
59
232
  if(look){
60
61
232
    if(look->linearmap){
62
63
232
      if(look->linearmap[0])_ogg_free(look->linearmap[0]);
64
232
      if(look->linearmap[1])_ogg_free(look->linearmap[1]);
65
66
232
      _ogg_free(look->linearmap);
67
232
    }
68
232
    memset(look,0,sizeof(*look));
69
232
    _ogg_free(look);
70
232
  }
71
232
}
72
73
334
static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
74
334
  codec_setup_info     *ci=vi->codec_setup;
75
334
  int j;
76
77
334
  vorbis_info_floor0 *info=_ogg_malloc(sizeof(*info));
78
334
  info->order=oggpack_read(opb,8);
79
334
  info->rate=oggpack_read(opb,16);
80
334
  info->barkmap=oggpack_read(opb,16);
81
334
  info->ampbits=oggpack_read(opb,6);
82
334
  info->ampdB=oggpack_read(opb,8);
83
334
  info->numbooks=oggpack_read(opb,4)+1;
84
85
334
  if(info->order<1)goto err_out;
86
325
  if(info->rate<1)goto err_out;
87
323
  if(info->barkmap<1)goto err_out;
88
319
  if(info->numbooks<1)goto err_out;
89
90
2.84k
  for(j=0;j<info->numbooks;j++){
91
2.55k
    info->books[j]=oggpack_read(opb,8);
92
2.55k
    if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
93
2.53k
    if(ci->book_param[info->books[j]]->maptype==0)goto err_out;
94
2.53k
    if(ci->book_param[info->books[j]]->dim<1)goto err_out;
95
2.53k
  }
96
297
  return(info);
97
98
37
 err_out:
99
37
  floor0_free_info(info);
100
37
  return(NULL);
101
315
}
102
103
/* initialize Bark scale and normalization lookups.  We could do this
104
   with static tables, but Vorbis allows a number of possible
105
   combinations, so it's best to do it computationally.
106
107
   The below is authoritative in terms of defining scale mapping.
108
   Note that the scale depends on the sampling rate as well as the
109
   linear block and mapping sizes */
110
111
static void floor0_map_lazy_init(vorbis_block      *vb,
112
                                 vorbis_info_floor *infoX,
113
409k
                                 vorbis_look_floor0 *look){
114
409k
  if(!look->linearmap[vb->W]){
115
230
    vorbis_dsp_state   *vd=vb->vd;
116
230
    vorbis_info        *vi=vd->vi;
117
230
    codec_setup_info   *ci=vi->codec_setup;
118
230
    vorbis_info_floor0 *info=(vorbis_info_floor0 *)infoX;
119
230
    int W=vb->W;
120
230
    int n=ci->blocksizes[W]/2,j;
121
122
    /* we choose a scaling constant so that:
123
       floor(bark(rate/2-1)*C)=mapped-1
124
     floor(bark(rate/2)*C)=mapped */
125
230
    float scale=look->ln/toBARK(info->rate/2.f);
126
127
    /* the mapping from a linear scale to a smaller bark scale is
128
       straightforward.  We do *not* make sure that the linear mapping
129
       does not skip bark-scale bins; the decoder simply skips them and
130
       the encoder may do what it wishes in filling them.  They're
131
       necessary in some mapping combinations to keep the scale spacing
132
       accurate */
133
230
    look->linearmap[W]=_ogg_malloc((n+1)*sizeof(**look->linearmap));
134
362k
    for(j=0;j<n;j++){
135
362k
      int val=floor( toBARK((info->rate/2.f)/n*j)
136
362k
                     *scale); /* bark numbers represent band edges */
137
362k
      if(val>=look->ln)val=look->ln-1; /* guard against the approximation */
138
362k
      look->linearmap[W][j]=val;
139
362k
    }
140
230
    look->linearmap[W][j]=-1;
141
230
    look->n[W]=n;
142
230
  }
143
409k
}
144
145
static vorbis_look_floor *floor0_look(vorbis_dsp_state *vd,
146
232
                                      vorbis_info_floor *i){
147
232
  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
148
232
  vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(*look));
149
150
232
  (void)vd;
151
152
232
  look->m=info->order;
153
232
  look->ln=info->barkmap;
154
232
  look->vi=info;
155
156
232
  look->linearmap=_ogg_calloc(2,sizeof(*look->linearmap));
157
158
232
  return look;
159
232
}
160
161
409k
static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
162
409k
  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
163
409k
  vorbis_info_floor0 *info=look->vi;
164
409k
  int j,k;
165
166
409k
  int ampraw=oggpack_read(&vb->opb,info->ampbits);
167
409k
  if(ampraw>0){ /* also handles the -1 out of data case */
168
56.5k
    long maxval=(1<<info->ampbits)-1;
169
56.5k
    float amp=(float)ampraw/maxval*info->ampdB;
170
56.5k
    int booknum=oggpack_read(&vb->opb,ov_ilog(info->numbooks));
171
172
56.5k
    if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
173
32.4k
      codec_setup_info  *ci=vb->vd->vi->codec_setup;
174
32.4k
      codebook *b=ci->fullbooks+info->books[booknum];
175
32.4k
      float last=0.f;
176
177
      /* the additional b->dim is a guard against any possible stack
178
         smash; b->dim is provably more than we can overflow the
179
         vector */
180
32.4k
      float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+b->dim+1));
181
182
32.4k
      if(vorbis_book_decodev_set(b,lsp,&vb->opb,look->m)==-1)goto eop;
183
92.4k
      for(j=0;j<look->m;){
184
632k
        for(k=0;j<look->m && k<b->dim;k++,j++)lsp[j]+=last;
185
60.1k
        last=lsp[j-1];
186
60.1k
      }
187
188
32.3k
      lsp[look->m]=amp;
189
32.3k
      return(lsp);
190
32.4k
    }
191
56.5k
  }
192
377k
 eop:
193
377k
  return(NULL);
194
409k
}
195
196
static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i,
197
409k
                           void *memo,float *out){
198
409k
  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
199
409k
  vorbis_info_floor0 *info=look->vi;
200
201
409k
  floor0_map_lazy_init(vb,info,look);
202
203
409k
  if(memo){
204
32.3k
    float *lsp=(float *)memo;
205
32.3k
    float amp=lsp[look->m];
206
207
    /* take the coefficients back to a spectral envelope curve */
208
32.3k
    vorbis_lsp_to_curve(out,
209
32.3k
                        look->linearmap[vb->W],
210
32.3k
                        look->n[vb->W],
211
32.3k
                        look->ln,
212
32.3k
                        lsp,look->m,amp,(float)info->ampdB);
213
32.3k
    return(1);
214
32.3k
  }
215
377k
  memset(out,0,sizeof(*out)*look->n[vb->W]);
216
377k
  return(0);
217
409k
}
218
219
/* export hooks */
220
const vorbis_func_floor floor0_exportbundle={
221
  NULL,&floor0_unpack,&floor0_look,&floor0_free_info,
222
  &floor0_free_look,&floor0_inverse1,&floor0_inverse2
223
};