Coverage Report

Created: 2025-11-16 07:20

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