Coverage Report

Created: 2026-05-16 07:49

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
351
static void floor0_free_info(vorbis_info_floor *i){
50
351
  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
51
351
  if(info){
52
351
    memset(info,0,sizeof(*info));
53
351
    _ogg_free(info);
54
351
  }
55
351
}
56
57
263
static void floor0_free_look(vorbis_look_floor *i){
58
263
  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
59
263
  if(look){
60
61
263
    if(look->linearmap){
62
63
263
      if(look->linearmap[0])_ogg_free(look->linearmap[0]);
64
263
      if(look->linearmap[1])_ogg_free(look->linearmap[1]);
65
66
263
      _ogg_free(look->linearmap);
67
263
    }
68
263
    memset(look,0,sizeof(*look));
69
263
    _ogg_free(look);
70
263
  }
71
263
}
72
73
351
static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
74
351
  codec_setup_info     *ci=vi->codec_setup;
75
351
  int j;
76
77
351
  vorbis_info_floor0 *info=_ogg_malloc(sizeof(*info));
78
351
  info->order=oggpack_read(opb,8);
79
351
  info->rate=oggpack_read(opb,16);
80
351
  info->barkmap=oggpack_read(opb,16);
81
351
  info->ampbits=oggpack_read(opb,6);
82
351
  info->ampdB=oggpack_read(opb,8);
83
351
  info->numbooks=oggpack_read(opb,4)+1;
84
85
351
  if(info->order<1)goto err_out;
86
341
  if(info->rate<1)goto err_out;
87
339
  if(info->barkmap<1)goto err_out;
88
335
  if(info->numbooks<1)goto err_out;
89
90
3.04k
  for(j=0;j<info->numbooks;j++){
91
2.72k
    info->books[j]=oggpack_read(opb,8);
92
2.72k
    if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
93
2.71k
    if(ci->book_param[info->books[j]]->maptype==0)goto err_out;
94
2.70k
    if(ci->book_param[info->books[j]]->dim<1)goto err_out;
95
2.70k
  }
96
318
  return(info);
97
98
33
 err_out:
99
33
  floor0_free_info(info);
100
33
  return(NULL);
101
332
}
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
511k
                                 vorbis_look_floor0 *look){
114
511k
  if(!look->linearmap[vb->W]){
115
260
    vorbis_dsp_state   *vd=vb->vd;
116
260
    vorbis_info        *vi=vd->vi;
117
260
    codec_setup_info   *ci=vi->codec_setup;
118
260
    vorbis_info_floor0 *info=(vorbis_info_floor0 *)infoX;
119
260
    int W=vb->W;
120
260
    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
260
    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
260
    look->linearmap[W]=_ogg_malloc((n+1)*sizeof(**look->linearmap));
134
398k
    for(j=0;j<n;j++){
135
398k
      int val=floor( toBARK((info->rate/2.f)/n*j)
136
398k
                     *scale); /* bark numbers represent band edges */
137
398k
      if(val>=look->ln)val=look->ln-1; /* guard against the approximation */
138
398k
      look->linearmap[W][j]=val;
139
398k
    }
140
260
    look->linearmap[W][j]=-1;
141
260
    look->n[W]=n;
142
260
  }
143
511k
}
144
145
static vorbis_look_floor *floor0_look(vorbis_dsp_state *vd,
146
263
                                      vorbis_info_floor *i){
147
263
  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
148
263
  vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(*look));
149
150
263
  (void)vd;
151
152
263
  look->m=info->order;
153
263
  look->ln=info->barkmap;
154
263
  look->vi=info;
155
156
263
  look->linearmap=_ogg_calloc(2,sizeof(*look->linearmap));
157
158
263
  return look;
159
263
}
160
161
511k
static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
162
511k
  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
163
511k
  vorbis_info_floor0 *info=look->vi;
164
511k
  int j,k;
165
166
511k
  int ampraw=oggpack_read(&vb->opb,info->ampbits);
167
511k
  if(ampraw>0){ /* also handles the -1 out of data case */
168
57.4k
    long maxval=(1<<info->ampbits)-1;
169
57.4k
    float amp=(float)ampraw/maxval*info->ampdB;
170
57.4k
    int booknum=oggpack_read(&vb->opb,ov_ilog(info->numbooks));
171
172
57.4k
    if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
173
31.5k
      codec_setup_info  *ci=vb->vd->vi->codec_setup;
174
31.5k
      codebook *b=ci->fullbooks+info->books[booknum];
175
31.5k
      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
31.5k
      float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+b->dim+1));
181
182
31.5k
      if(vorbis_book_decodev_set(b,lsp,&vb->opb,look->m)==-1)goto eop;
183
221k
      for(j=0;j<look->m;){
184
959k
        for(k=0;j<look->m && k<b->dim;k++,j++)lsp[j]+=last;
185
190k
        last=lsp[j-1];
186
190k
      }
187
188
31.0k
      lsp[look->m]=amp;
189
31.0k
      return(lsp);
190
31.5k
    }
191
57.4k
  }
192
480k
 eop:
193
480k
  return(NULL);
194
511k
}
195
196
static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i,
197
511k
                           void *memo,float *out){
198
511k
  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
199
511k
  vorbis_info_floor0 *info=look->vi;
200
201
511k
  floor0_map_lazy_init(vb,info,look);
202
203
511k
  if(memo){
204
31.0k
    float *lsp=(float *)memo;
205
31.0k
    float amp=lsp[look->m];
206
207
    /* take the coefficients back to a spectral envelope curve */
208
31.0k
    vorbis_lsp_to_curve(out,
209
31.0k
                        look->linearmap[vb->W],
210
31.0k
                        look->n[vb->W],
211
31.0k
                        look->ln,
212
31.0k
                        lsp,look->m,amp,(float)info->ampdB);
213
31.0k
    return(1);
214
31.0k
  }
215
480k
  memset(out,0,sizeof(*out)*look->n[vb->W]);
216
480k
  return(0);
217
511k
}
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
};