Coverage Report

Created: 2025-12-31 07:57

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