Coverage Report

Created: 2024-09-06 07:53

/src/vorbis/lib/vorbisenc.c
Line
Count
Source (jump to first uncovered line)
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: simple programmatic interface for encoder mode setup
14
15
 ********************************************************************/
16
17
#include <stdlib.h>
18
#include <string.h>
19
#include <math.h>
20
21
#include "vorbis/codec.h"
22
#include "vorbis/vorbisenc.h"
23
24
#include "codec_internal.h"
25
26
#include "os.h"
27
#include "misc.h"
28
29
/* careful with this; it's using static array sizing to make managing
30
   all the modes a little less annoying.  If we use a residue backend
31
   with > 12 partition types, or a different division of iteration,
32
   this needs to be updated. */
33
typedef struct {
34
  const static_codebook *books[12][4];
35
} static_bookblock;
36
37
typedef struct {
38
  int res_type;
39
  int limit_type; /* 0 lowpass limited, 1 point stereo limited */
40
  int grouping;
41
  const vorbis_info_residue0 *res;
42
  const static_codebook  *book_aux;
43
  const static_codebook  *book_aux_managed;
44
  const static_bookblock *books_base;
45
  const static_bookblock *books_base_managed;
46
} vorbis_residue_template;
47
48
typedef struct {
49
  const vorbis_info_mapping0    *map;
50
  const vorbis_residue_template *res;
51
} vorbis_mapping_template;
52
53
typedef struct vp_adjblock{
54
  int block[P_BANDS];
55
} vp_adjblock;
56
57
typedef struct {
58
  int data[NOISE_COMPAND_LEVELS];
59
} compandblock;
60
61
/* high level configuration information for setting things up
62
   step-by-step with the detailed vorbis_encode_ctl interface.
63
   There's a fair amount of redundancy such that interactive setup
64
   does not directly deal with any vorbis_info or codec_setup_info
65
   initialization; it's all stored (until full init) in this highlevel
66
   setup, then flushed out to the real codec setup structs later. */
67
68
typedef struct {
69
  int att[P_NOISECURVES];
70
  float boost;
71
  float decay;
72
} att3;
73
typedef struct { int data[P_NOISECURVES]; } adj3;
74
75
typedef struct {
76
  int   pre[PACKETBLOBS];
77
  int   post[PACKETBLOBS];
78
  float kHz[PACKETBLOBS];
79
  float lowpasskHz[PACKETBLOBS];
80
} adj_stereo;
81
82
typedef struct {
83
  int lo;
84
  int hi;
85
  int fixed;
86
} noiseguard;
87
typedef struct {
88
  int data[P_NOISECURVES][17];
89
} noise3;
90
91
typedef struct {
92
  int      mappings;
93
  const double  *rate_mapping;
94
  const double  *quality_mapping;
95
  int      coupling_restriction;
96
  long     samplerate_min_restriction;
97
  long     samplerate_max_restriction;
98
99
100
  const int     *blocksize_short;
101
  const int     *blocksize_long;
102
103
  const att3    *psy_tone_masteratt;
104
  const int     *psy_tone_0dB;
105
  const int     *psy_tone_dBsuppress;
106
107
  const vp_adjblock *psy_tone_adj_impulse;
108
  const vp_adjblock *psy_tone_adj_long;
109
  const vp_adjblock *psy_tone_adj_other;
110
111
  const noiseguard  *psy_noiseguards;
112
  const noise3      *psy_noise_bias_impulse;
113
  const noise3      *psy_noise_bias_padding;
114
  const noise3      *psy_noise_bias_trans;
115
  const noise3      *psy_noise_bias_long;
116
  const int         *psy_noise_dBsuppress;
117
118
  const compandblock  *psy_noise_compand;
119
  const double        *psy_noise_compand_short_mapping;
120
  const double        *psy_noise_compand_long_mapping;
121
122
  const int      *psy_noise_normal_start[2];
123
  const int      *psy_noise_normal_partition[2];
124
  const double   *psy_noise_normal_thresh;
125
126
  const int      *psy_ath_float;
127
  const int      *psy_ath_abs;
128
129
  const double   *psy_lowpass;
130
131
  const vorbis_info_psy_global *global_params;
132
  const double     *global_mapping;
133
  const adj_stereo *stereo_modes;
134
135
  const static_codebook *const *const *const floor_books;
136
  const vorbis_info_floor1 *floor_params;
137
  const int floor_mappings;
138
  const int **floor_mapping_list;
139
140
  const vorbis_mapping_template *maps;
141
} ve_setup_data_template;
142
143
/* a few static coder conventions */
144
static const vorbis_info_mode _mode_template[2]={
145
  {0,0,0,0},
146
  {1,0,0,1}
147
};
148
149
static const vorbis_info_mapping0 _map_nominal[2]={
150
  {1, {0,0}, {0}, {0}, 1,{0},{1}},
151
  {1, {0,0}, {1}, {1}, 1,{0},{1}}
152
};
153
154
#include "modes/setup_44.h"
155
#include "modes/setup_44u.h"
156
#include "modes/setup_44p51.h"
157
#include "modes/setup_32.h"
158
#include "modes/setup_8.h"
159
#include "modes/setup_11.h"
160
#include "modes/setup_16.h"
161
#include "modes/setup_22.h"
162
#include "modes/setup_X.h"
163
164
static const ve_setup_data_template *const setup_list[]={
165
  &ve_setup_44_stereo,
166
  &ve_setup_44_51,
167
  &ve_setup_44_uncoupled,
168
169
  &ve_setup_32_stereo,
170
  &ve_setup_32_uncoupled,
171
172
  &ve_setup_22_stereo,
173
  &ve_setup_22_uncoupled,
174
  &ve_setup_16_stereo,
175
  &ve_setup_16_uncoupled,
176
177
  &ve_setup_11_stereo,
178
  &ve_setup_11_uncoupled,
179
  &ve_setup_8_stereo,
180
  &ve_setup_8_uncoupled,
181
182
  &ve_setup_X_stereo,
183
  &ve_setup_X_uncoupled,
184
  &ve_setup_XX_stereo,
185
  &ve_setup_XX_uncoupled,
186
  0
187
};
188
189
static void vorbis_encode_floor_setup(vorbis_info *vi,int s,
190
                                     const static_codebook *const *const *const books,
191
                                     const vorbis_info_floor1 *in,
192
0
                                     const int *x){
193
0
  int i,k,is=s;
194
0
  vorbis_info_floor1 *f=_ogg_calloc(1,sizeof(*f));
195
0
  codec_setup_info *ci=vi->codec_setup;
196
197
0
  memcpy(f,in+x[is],sizeof(*f));
198
199
  /* books */
200
0
  {
201
0
    int partitions=f->partitions;
202
0
    int maxclass=-1;
203
0
    int maxbook=-1;
204
0
    for(i=0;i<partitions;i++)
205
0
      if(f->partitionclass[i]>maxclass)maxclass=f->partitionclass[i];
206
0
    for(i=0;i<=maxclass;i++){
207
0
      if(f->class_book[i]>maxbook)maxbook=f->class_book[i];
208
0
      f->class_book[i]+=ci->books;
209
0
      for(k=0;k<(1<<f->class_subs[i]);k++){
210
0
        if(f->class_subbook[i][k]>maxbook)maxbook=f->class_subbook[i][k];
211
0
        if(f->class_subbook[i][k]>=0)f->class_subbook[i][k]+=ci->books;
212
0
      }
213
0
    }
214
215
0
    for(i=0;i<=maxbook;i++)
216
0
      ci->book_param[ci->books++]=(static_codebook *)books[x[is]][i];
217
0
  }
218
219
  /* for now, we're only using floor 1 */
220
0
  ci->floor_type[ci->floors]=1;
221
0
  ci->floor_param[ci->floors]=f;
222
0
  ci->floors++;
223
224
0
  return;
225
0
}
226
227
static void vorbis_encode_global_psych_setup(vorbis_info *vi,double s,
228
                                            const vorbis_info_psy_global *in,
229
0
                                            const double *x){
230
0
  int i,is=s;
231
0
  double ds=s-is;
232
0
  codec_setup_info *ci=vi->codec_setup;
233
0
  vorbis_info_psy_global *g=&ci->psy_g_param;
234
235
0
  memcpy(g,in+(int)x[is],sizeof(*g));
236
237
0
  ds=x[is]*(1.-ds)+x[is+1]*ds;
238
0
  is=(int)ds;
239
0
  ds-=is;
240
0
  if(ds==0 && is>0){
241
0
    is--;
242
0
    ds=1.;
243
0
  }
244
245
  /* interpolate the trigger threshholds */
246
0
  for(i=0;i<4;i++){
247
0
    g->preecho_thresh[i]=in[is].preecho_thresh[i]*(1.-ds)+in[is+1].preecho_thresh[i]*ds;
248
0
    g->postecho_thresh[i]=in[is].postecho_thresh[i]*(1.-ds)+in[is+1].postecho_thresh[i]*ds;
249
0
  }
250
0
  g->ampmax_att_per_sec=ci->hi.amplitude_track_dBpersec;
251
0
  return;
252
0
}
253
254
static void vorbis_encode_global_stereo(vorbis_info *vi,
255
                                        const highlevel_encode_setup *const hi,
256
0
                                        const adj_stereo *p){
257
0
  float s=hi->stereo_point_setting;
258
0
  int i,is=s;
259
0
  double ds=s-is;
260
0
  codec_setup_info *ci=vi->codec_setup;
261
0
  vorbis_info_psy_global *g=&ci->psy_g_param;
262
263
0
  if(p){
264
0
    memcpy(g->coupling_prepointamp,p[is].pre,sizeof(*p[is].pre)*PACKETBLOBS);
265
0
    memcpy(g->coupling_postpointamp,p[is].post,sizeof(*p[is].post)*PACKETBLOBS);
266
267
0
    if(hi->managed){
268
      /* interpolate the kHz threshholds */
269
0
      for(i=0;i<PACKETBLOBS;i++){
270
0
        float kHz=p[is].kHz[i]*(1.-ds)+p[is+1].kHz[i]*ds;
271
0
        g->coupling_pointlimit[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
272
0
        g->coupling_pointlimit[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
273
0
        g->coupling_pkHz[i]=kHz;
274
275
0
        kHz=p[is].lowpasskHz[i]*(1.-ds)+p[is+1].lowpasskHz[i]*ds;
276
0
        g->sliding_lowpass[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
277
0
        g->sliding_lowpass[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
278
279
0
      }
280
0
    }else{
281
0
      float kHz=p[is].kHz[PACKETBLOBS/2]*(1.-ds)+p[is+1].kHz[PACKETBLOBS/2]*ds;
282
0
      for(i=0;i<PACKETBLOBS;i++){
283
0
        g->coupling_pointlimit[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
284
0
        g->coupling_pointlimit[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
285
0
        g->coupling_pkHz[i]=kHz;
286
0
      }
287
288
0
      kHz=p[is].lowpasskHz[PACKETBLOBS/2]*(1.-ds)+p[is+1].lowpasskHz[PACKETBLOBS/2]*ds;
289
0
      for(i=0;i<PACKETBLOBS;i++){
290
0
        g->sliding_lowpass[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
291
0
        g->sliding_lowpass[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
292
0
      }
293
0
    }
294
0
  }else{
295
0
    for(i=0;i<PACKETBLOBS;i++){
296
0
      g->sliding_lowpass[0][i]=ci->blocksizes[0];
297
0
      g->sliding_lowpass[1][i]=ci->blocksizes[1];
298
0
    }
299
0
  }
300
0
  return;
301
0
}
302
303
static void vorbis_encode_psyset_setup(vorbis_info *vi,double s,
304
                                       const int *nn_start,
305
                                       const int *nn_partition,
306
                                       const double *nn_thresh,
307
0
                                       int block){
308
0
  codec_setup_info *ci=vi->codec_setup;
309
0
  vorbis_info_psy *p=ci->psy_param[block];
310
0
  highlevel_encode_setup *hi=&ci->hi;
311
0
  int is=s;
312
313
0
  if(block>=ci->psys)
314
0
    ci->psys=block+1;
315
0
  if(!p){
316
0
    p=_ogg_calloc(1,sizeof(*p));
317
0
    ci->psy_param[block]=p;
318
0
  }
319
320
0
  memcpy(p,&_psy_info_template,sizeof(*p));
321
0
  p->blockflag=block>>1;
322
323
0
  if(hi->noise_normalize_p){
324
0
    p->normal_p=1;
325
0
    p->normal_start=nn_start[is];
326
0
    p->normal_partition=nn_partition[is];
327
0
    p->normal_thresh=nn_thresh[is];
328
0
  }
329
330
0
  return;
331
0
}
332
333
static void vorbis_encode_tonemask_setup(vorbis_info *vi,double s,int block,
334
                                         const att3 *att,
335
                                         const int  *max,
336
0
                                         const vp_adjblock *in){
337
0
  int i,is=s;
338
0
  double ds=s-is;
339
0
  codec_setup_info *ci=vi->codec_setup;
340
0
  vorbis_info_psy *p=ci->psy_param[block];
341
342
  /* 0 and 2 are only used by bitmanagement, but there's no harm to always
343
     filling the values in here */
344
0
  p->tone_masteratt[0]=att[is].att[0]*(1.-ds)+att[is+1].att[0]*ds;
345
0
  p->tone_masteratt[1]=att[is].att[1]*(1.-ds)+att[is+1].att[1]*ds;
346
0
  p->tone_masteratt[2]=att[is].att[2]*(1.-ds)+att[is+1].att[2]*ds;
347
0
  p->tone_centerboost=att[is].boost*(1.-ds)+att[is+1].boost*ds;
348
0
  p->tone_decay=att[is].decay*(1.-ds)+att[is+1].decay*ds;
349
350
0
  p->max_curve_dB=max[is]*(1.-ds)+max[is+1]*ds;
351
352
0
  for(i=0;i<P_BANDS;i++)
353
0
    p->toneatt[i]=in[is].block[i]*(1.-ds)+in[is+1].block[i]*ds;
354
0
  return;
355
0
}
356
357
358
static void vorbis_encode_compand_setup(vorbis_info *vi,double s,int block,
359
                                        const compandblock *in,
360
0
                                        const double *x){
361
0
  int i,is=s;
362
0
  double ds=s-is;
363
0
  codec_setup_info *ci=vi->codec_setup;
364
0
  vorbis_info_psy *p=ci->psy_param[block];
365
366
0
  ds=x[is]*(1.-ds)+x[is+1]*ds;
367
0
  is=(int)ds;
368
0
  ds-=is;
369
0
  if(ds==0 && is>0){
370
0
    is--;
371
0
    ds=1.;
372
0
  }
373
374
  /* interpolate the compander settings */
375
0
  for(i=0;i<NOISE_COMPAND_LEVELS;i++)
376
0
    p->noisecompand[i]=in[is].data[i]*(1.-ds)+in[is+1].data[i]*ds;
377
0
  return;
378
0
}
379
380
static void vorbis_encode_peak_setup(vorbis_info *vi,double s,int block,
381
0
                                    const int *suppress){
382
0
  int is=s;
383
0
  double ds=s-is;
384
0
  codec_setup_info *ci=vi->codec_setup;
385
0
  vorbis_info_psy *p=ci->psy_param[block];
386
387
0
  p->tone_abs_limit=suppress[is]*(1.-ds)+suppress[is+1]*ds;
388
389
0
  return;
390
0
}
391
392
static void vorbis_encode_noisebias_setup(vorbis_info *vi,double s,int block,
393
                                         const int *suppress,
394
                                         const noise3 *in,
395
                                         const noiseguard *guard,
396
0
                                         double userbias){
397
0
  int i,is=s,j;
398
0
  double ds=s-is;
399
0
  codec_setup_info *ci=vi->codec_setup;
400
0
  vorbis_info_psy *p=ci->psy_param[block];
401
402
0
  p->noisemaxsupp=suppress[is]*(1.-ds)+suppress[is+1]*ds;
403
0
  p->noisewindowlomin=guard[block].lo;
404
0
  p->noisewindowhimin=guard[block].hi;
405
0
  p->noisewindowfixed=guard[block].fixed;
406
407
0
  for(j=0;j<P_NOISECURVES;j++)
408
0
    for(i=0;i<P_BANDS;i++)
409
0
      p->noiseoff[j][i]=in[is].data[j][i]*(1.-ds)+in[is+1].data[j][i]*ds;
410
411
  /* impulse blocks may take a user specified bias to boost the
412
     nominal/high noise encoding depth */
413
0
  for(j=0;j<P_NOISECURVES;j++){
414
0
    float min=p->noiseoff[j][0]+6; /* the lowest it can go */
415
0
    for(i=0;i<P_BANDS;i++){
416
0
      p->noiseoff[j][i]+=userbias;
417
0
      if(p->noiseoff[j][i]<min)p->noiseoff[j][i]=min;
418
0
    }
419
0
  }
420
421
0
  return;
422
0
}
423
424
0
static void vorbis_encode_ath_setup(vorbis_info *vi,int block){
425
0
  codec_setup_info *ci=vi->codec_setup;
426
0
  vorbis_info_psy *p=ci->psy_param[block];
427
428
0
  p->ath_adjatt=ci->hi.ath_floating_dB;
429
0
  p->ath_maxatt=ci->hi.ath_absolute_dB;
430
0
  return;
431
0
}
432
433
434
0
static int book_dup_or_new(codec_setup_info *ci,const static_codebook *book){
435
0
  int i;
436
0
  for(i=0;i<ci->books;i++)
437
0
    if(ci->book_param[i]==book)return(i);
438
439
0
  return(ci->books++);
440
0
}
441
442
static void vorbis_encode_blocksize_setup(vorbis_info *vi,double s,
443
0
                                         const int *shortb,const int *longb){
444
445
0
  codec_setup_info *ci=vi->codec_setup;
446
0
  int is=s;
447
448
0
  int blockshort=shortb[is];
449
0
  int blocklong=longb[is];
450
0
  ci->blocksizes[0]=blockshort;
451
0
  ci->blocksizes[1]=blocklong;
452
453
0
}
454
455
static void vorbis_encode_residue_setup(vorbis_info *vi,
456
                                        int number, int block,
457
0
                                        const vorbis_residue_template *res){
458
459
0
  codec_setup_info *ci=vi->codec_setup;
460
0
  int i;
461
462
0
  vorbis_info_residue0 *r=ci->residue_param[number]=
463
0
    _ogg_malloc(sizeof(*r));
464
465
0
  memcpy(r,res->res,sizeof(*r));
466
0
  if(ci->residues<=number)ci->residues=number+1;
467
468
0
  r->grouping=res->grouping;
469
0
  ci->residue_type[number]=res->res_type;
470
471
  /* fill in all the books */
472
0
  {
473
0
    int booklist=0,k;
474
475
0
    if(ci->hi.managed){
476
0
      for(i=0;i<r->partitions;i++)
477
0
        for(k=0;k<4;k++)
478
0
          if(res->books_base_managed->books[i][k])
479
0
            r->secondstages[i]|=(1<<k);
480
481
0
      r->groupbook=book_dup_or_new(ci,res->book_aux_managed);
482
0
      ci->book_param[r->groupbook]=(static_codebook *)res->book_aux_managed;
483
484
0
      for(i=0;i<r->partitions;i++){
485
0
        for(k=0;k<4;k++){
486
0
          if(res->books_base_managed->books[i][k]){
487
0
            int bookid=book_dup_or_new(ci,res->books_base_managed->books[i][k]);
488
0
            r->booklist[booklist++]=bookid;
489
0
            ci->book_param[bookid]=(static_codebook *)res->books_base_managed->books[i][k];
490
0
          }
491
0
        }
492
0
      }
493
494
0
    }else{
495
496
0
      for(i=0;i<r->partitions;i++)
497
0
        for(k=0;k<4;k++)
498
0
          if(res->books_base->books[i][k])
499
0
            r->secondstages[i]|=(1<<k);
500
501
0
      r->groupbook=book_dup_or_new(ci,res->book_aux);
502
0
      ci->book_param[r->groupbook]=(static_codebook *)res->book_aux;
503
504
0
      for(i=0;i<r->partitions;i++){
505
0
        for(k=0;k<4;k++){
506
0
          if(res->books_base->books[i][k]){
507
0
            int bookid=book_dup_or_new(ci,res->books_base->books[i][k]);
508
0
            r->booklist[booklist++]=bookid;
509
0
            ci->book_param[bookid]=(static_codebook *)res->books_base->books[i][k];
510
0
          }
511
0
        }
512
0
      }
513
0
    }
514
0
  }
515
516
  /* lowpass setup/pointlimit */
517
0
  {
518
0
    double freq=ci->hi.lowpass_kHz*1000.;
519
0
    vorbis_info_floor1 *f=ci->floor_param[block]; /* by convention */
520
0
    double nyq=vi->rate/2.;
521
0
    long blocksize=ci->blocksizes[block]>>1;
522
523
    /* lowpass needs to be set in the floor and the residue. */
524
0
    if(freq>nyq)freq=nyq;
525
    /* in the floor, the granularity can be very fine; it doesn't alter
526
       the encoding structure, only the samples used to fit the floor
527
       approximation */
528
0
    f->n=freq/nyq*blocksize;
529
530
    /* this res may by limited by the maximum pointlimit of the mode,
531
       not the lowpass. the floor is always lowpass limited. */
532
0
    switch(res->limit_type){
533
0
    case 1: /* point stereo limited */
534
0
      if(ci->hi.managed)
535
0
        freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS-1]*1000.;
536
0
      else
537
0
        freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS/2]*1000.;
538
0
      if(freq>nyq)freq=nyq;
539
0
      break;
540
0
    case 2: /* LFE channel; lowpass at ~ 250Hz */
541
0
      freq=250;
542
0
      break;
543
0
    default:
544
      /* already set */
545
0
      break;
546
0
    }
547
548
    /* in the residue, we're constrained, physically, by partition
549
       boundaries.  We still lowpass 'wherever', but we have to round up
550
       here to next boundary, or the vorbis spec will round it *down* to
551
       previous boundary in encode/decode */
552
0
    if(ci->residue_type[number]==2){
553
      /* residue 2 bundles together multiple channels; used by stereo
554
         and surround.  Count the channels in use */
555
      /* Multiple maps/submaps can point to the same residue.  In the case
556
         of residue 2, they all better have the same number of
557
         channels/samples. */
558
0
      int j,k,ch=0;
559
0
      for(i=0;i<ci->maps&&ch==0;i++){
560
0
        vorbis_info_mapping0 *mi=(vorbis_info_mapping0 *)ci->map_param[i];
561
0
        for(j=0;j<mi->submaps && ch==0;j++)
562
0
          if(mi->residuesubmap[j]==number) /* we found a submap referencing theis residue backend */
563
0
            for(k=0;k<vi->channels;k++)
564
0
              if(mi->chmuxlist[k]==j) /* this channel belongs to the submap */
565
0
                ch++;
566
0
      }
567
568
0
      r->end=(int)((freq/nyq*blocksize*ch)/r->grouping+.9)* /* round up only if we're well past */
569
0
        r->grouping;
570
      /* the blocksize and grouping may disagree at the end */
571
0
      if(r->end>blocksize*ch)r->end=blocksize*ch/r->grouping*r->grouping;
572
573
0
    }else{
574
575
0
      r->end=(int)((freq/nyq*blocksize)/r->grouping+.9)* /* round up only if we're well past */
576
0
        r->grouping;
577
      /* the blocksize and grouping may disagree at the end */
578
0
      if(r->end>blocksize)r->end=blocksize/r->grouping*r->grouping;
579
580
0
    }
581
582
0
    if(r->end==0)r->end=r->grouping; /* LFE channel */
583
584
0
  }
585
0
}
586
587
/* we assume two maps in this encoder */
588
static void vorbis_encode_map_n_res_setup(vorbis_info *vi,double s,
589
0
                                          const vorbis_mapping_template *maps){
590
591
0
  codec_setup_info *ci=vi->codec_setup;
592
0
  int i,j,is=s,modes=2;
593
0
  const vorbis_info_mapping0 *map=maps[is].map;
594
0
  const vorbis_info_mode *mode=_mode_template;
595
0
  const vorbis_residue_template *res=maps[is].res;
596
597
0
  if(ci->blocksizes[0]==ci->blocksizes[1])modes=1;
598
599
0
  for(i=0;i<modes;i++){
600
601
0
    ci->map_param[i]=_ogg_calloc(1,sizeof(*map));
602
0
    ci->mode_param[i]=_ogg_calloc(1,sizeof(*mode));
603
604
0
    memcpy(ci->mode_param[i],mode+i,sizeof(*_mode_template));
605
0
    if(i>=ci->modes)ci->modes=i+1;
606
607
0
    ci->map_type[i]=0;
608
0
    memcpy(ci->map_param[i],map+i,sizeof(*map));
609
0
    if(i>=ci->maps)ci->maps=i+1;
610
611
0
    for(j=0;j<map[i].submaps;j++)
612
0
      vorbis_encode_residue_setup(vi,map[i].residuesubmap[j],i
613
0
                                  ,res+map[i].residuesubmap[j]);
614
0
  }
615
0
}
616
617
0
static double setting_to_approx_bitrate(vorbis_info *vi){
618
0
  codec_setup_info *ci=vi->codec_setup;
619
0
  highlevel_encode_setup *hi=&ci->hi;
620
0
  ve_setup_data_template *setup=(ve_setup_data_template *)hi->setup;
621
0
  int is=hi->base_setting;
622
0
  double ds=hi->base_setting-is;
623
0
  int ch=vi->channels;
624
0
  const double *r=setup->rate_mapping;
625
626
0
  if(r==NULL)
627
0
    return(-1);
628
629
0
  return((r[is]*(1.-ds)+r[is+1]*ds)*ch);
630
0
}
631
632
static const void *get_setup_template(long ch,long srate,
633
                                      double req,int q_or_bitrate,
634
0
                                      double *base_setting){
635
0
  int i=0,j;
636
0
  if(q_or_bitrate)req/=ch;
637
638
0
  while(setup_list[i]){
639
0
    if(setup_list[i]->coupling_restriction==-1 ||
640
0
       setup_list[i]->coupling_restriction==ch){
641
0
      if(srate>=setup_list[i]->samplerate_min_restriction &&
642
0
         srate<=setup_list[i]->samplerate_max_restriction){
643
0
        int mappings=setup_list[i]->mappings;
644
0
        const double *map=(q_or_bitrate?
645
0
                     setup_list[i]->rate_mapping:
646
0
                     setup_list[i]->quality_mapping);
647
648
        /* the template matches.  Does the requested quality mode
649
           fall within this template's modes? */
650
0
        if(req<map[0]){++i;continue;}
651
0
        if(req>map[setup_list[i]->mappings]){++i;continue;}
652
0
        for(j=0;j<mappings;j++)
653
0
          if(req>=map[j] && req<map[j+1])break;
654
        /* an all-points match */
655
0
        if(j==mappings)
656
0
          *base_setting=j-.001;
657
0
        else{
658
0
          float low=map[j];
659
0
          float high=map[j+1];
660
0
          float del=(req-low)/(high-low);
661
0
          *base_setting=j+del;
662
0
        }
663
664
0
        return(setup_list[i]);
665
0
      }
666
0
    }
667
0
    i++;
668
0
  }
669
670
0
  return NULL;
671
0
}
672
673
/* encoders will need to use vorbis_info_init beforehand and call
674
   vorbis_info clear when all done */
675
676
/* two interfaces; this, more detailed one, and later a convenience
677
   layer on top */
678
679
/* the final setup call */
680
0
int vorbis_encode_setup_init(vorbis_info *vi){
681
0
  int i,i0=0,singleblock=0;
682
0
  codec_setup_info *ci=vi->codec_setup;
683
0
  ve_setup_data_template *setup=NULL;
684
0
  highlevel_encode_setup *hi=&ci->hi;
685
686
0
  if(ci==NULL)return(OV_EINVAL);
687
0
  if(vi->channels<1||vi->channels>255)return(OV_EINVAL);
688
0
  if(!hi->impulse_block_p)i0=1;
689
690
  /* too low/high an ATH floater is nonsensical, but doesn't break anything */
691
0
  if(hi->ath_floating_dB>-80)hi->ath_floating_dB=-80;
692
0
  if(hi->ath_floating_dB<-200)hi->ath_floating_dB=-200;
693
694
  /* again, bound this to avoid the app shooting itself int he foot
695
     too badly */
696
0
  if(hi->amplitude_track_dBpersec>0.)hi->amplitude_track_dBpersec=0.;
697
0
  if(hi->amplitude_track_dBpersec<-99999.)hi->amplitude_track_dBpersec=-99999.;
698
699
  /* get the appropriate setup template; matches the fetch in previous
700
     stages */
701
0
  setup=(ve_setup_data_template *)hi->setup;
702
0
  if(setup==NULL)return(OV_EINVAL);
703
704
0
  hi->set_in_stone=1;
705
  /* choose block sizes from configured sizes as well as paying
706
     attention to long_block_p and short_block_p.  If the configured
707
     short and long blocks are the same length, we set long_block_p
708
     and unset short_block_p */
709
0
  vorbis_encode_blocksize_setup(vi,hi->base_setting,
710
0
                                setup->blocksize_short,
711
0
                                setup->blocksize_long);
712
0
  if(ci->blocksizes[0]==ci->blocksizes[1])singleblock=1;
713
714
  /* floor setup; choose proper floor params.  Allocated on the floor
715
     stack in order; if we alloc only a single long floor, it's 0 */
716
0
  for(i=0;i<setup->floor_mappings;i++)
717
0
    vorbis_encode_floor_setup(vi,hi->base_setting,
718
0
                              setup->floor_books,
719
0
                              setup->floor_params,
720
0
                              setup->floor_mapping_list[i]);
721
722
  /* setup of [mostly] short block detection and stereo*/
723
0
  vorbis_encode_global_psych_setup(vi,hi->trigger_setting,
724
0
                                   setup->global_params,
725
0
                                   setup->global_mapping);
726
0
  vorbis_encode_global_stereo(vi,hi,setup->stereo_modes);
727
728
  /* basic psych setup and noise normalization */
729
0
  vorbis_encode_psyset_setup(vi,hi->base_setting,
730
0
                             setup->psy_noise_normal_start[0],
731
0
                             setup->psy_noise_normal_partition[0],
732
0
                             setup->psy_noise_normal_thresh,
733
0
                             0);
734
0
  vorbis_encode_psyset_setup(vi,hi->base_setting,
735
0
                             setup->psy_noise_normal_start[0],
736
0
                             setup->psy_noise_normal_partition[0],
737
0
                             setup->psy_noise_normal_thresh,
738
0
                             1);
739
0
  if(!singleblock){
740
0
    vorbis_encode_psyset_setup(vi,hi->base_setting,
741
0
                               setup->psy_noise_normal_start[1],
742
0
                               setup->psy_noise_normal_partition[1],
743
0
                                    setup->psy_noise_normal_thresh,
744
0
                               2);
745
0
    vorbis_encode_psyset_setup(vi,hi->base_setting,
746
0
                               setup->psy_noise_normal_start[1],
747
0
                               setup->psy_noise_normal_partition[1],
748
0
                               setup->psy_noise_normal_thresh,
749
0
                               3);
750
0
  }
751
752
  /* tone masking setup */
753
0
  vorbis_encode_tonemask_setup(vi,hi->block[i0].tone_mask_setting,0,
754
0
                               setup->psy_tone_masteratt,
755
0
                               setup->psy_tone_0dB,
756
0
                               setup->psy_tone_adj_impulse);
757
0
  vorbis_encode_tonemask_setup(vi,hi->block[1].tone_mask_setting,1,
758
0
                               setup->psy_tone_masteratt,
759
0
                               setup->psy_tone_0dB,
760
0
                               setup->psy_tone_adj_other);
761
0
  if(!singleblock){
762
0
    vorbis_encode_tonemask_setup(vi,hi->block[2].tone_mask_setting,2,
763
0
                                 setup->psy_tone_masteratt,
764
0
                                 setup->psy_tone_0dB,
765
0
                                 setup->psy_tone_adj_other);
766
0
    vorbis_encode_tonemask_setup(vi,hi->block[3].tone_mask_setting,3,
767
0
                                 setup->psy_tone_masteratt,
768
0
                                 setup->psy_tone_0dB,
769
0
                                 setup->psy_tone_adj_long);
770
0
  }
771
772
  /* noise companding setup */
773
0
  vorbis_encode_compand_setup(vi,hi->block[i0].noise_compand_setting,0,
774
0
                              setup->psy_noise_compand,
775
0
                              setup->psy_noise_compand_short_mapping);
776
0
  vorbis_encode_compand_setup(vi,hi->block[1].noise_compand_setting,1,
777
0
                              setup->psy_noise_compand,
778
0
                              setup->psy_noise_compand_short_mapping);
779
0
  if(!singleblock){
780
0
    vorbis_encode_compand_setup(vi,hi->block[2].noise_compand_setting,2,
781
0
                                setup->psy_noise_compand,
782
0
                                setup->psy_noise_compand_long_mapping);
783
0
    vorbis_encode_compand_setup(vi,hi->block[3].noise_compand_setting,3,
784
0
                                setup->psy_noise_compand,
785
0
                                setup->psy_noise_compand_long_mapping);
786
0
  }
787
788
  /* peak guarding setup  */
789
0
  vorbis_encode_peak_setup(vi,hi->block[i0].tone_peaklimit_setting,0,
790
0
                           setup->psy_tone_dBsuppress);
791
0
  vorbis_encode_peak_setup(vi,hi->block[1].tone_peaklimit_setting,1,
792
0
                           setup->psy_tone_dBsuppress);
793
0
  if(!singleblock){
794
0
    vorbis_encode_peak_setup(vi,hi->block[2].tone_peaklimit_setting,2,
795
0
                             setup->psy_tone_dBsuppress);
796
0
    vorbis_encode_peak_setup(vi,hi->block[3].tone_peaklimit_setting,3,
797
0
                             setup->psy_tone_dBsuppress);
798
0
  }
799
800
  /* noise bias setup */
801
0
  vorbis_encode_noisebias_setup(vi,hi->block[i0].noise_bias_setting,0,
802
0
                                setup->psy_noise_dBsuppress,
803
0
                                setup->psy_noise_bias_impulse,
804
0
                                setup->psy_noiseguards,
805
0
                                (i0==0?hi->impulse_noisetune:0.));
806
0
  vorbis_encode_noisebias_setup(vi,hi->block[1].noise_bias_setting,1,
807
0
                                setup->psy_noise_dBsuppress,
808
0
                                setup->psy_noise_bias_padding,
809
0
                                setup->psy_noiseguards,0.);
810
0
  if(!singleblock){
811
0
    vorbis_encode_noisebias_setup(vi,hi->block[2].noise_bias_setting,2,
812
0
                                  setup->psy_noise_dBsuppress,
813
0
                                  setup->psy_noise_bias_trans,
814
0
                                  setup->psy_noiseguards,0.);
815
0
    vorbis_encode_noisebias_setup(vi,hi->block[3].noise_bias_setting,3,
816
0
                                  setup->psy_noise_dBsuppress,
817
0
                                  setup->psy_noise_bias_long,
818
0
                                  setup->psy_noiseguards,0.);
819
0
  }
820
821
0
  vorbis_encode_ath_setup(vi,0);
822
0
  vorbis_encode_ath_setup(vi,1);
823
0
  if(!singleblock){
824
0
    vorbis_encode_ath_setup(vi,2);
825
0
    vorbis_encode_ath_setup(vi,3);
826
0
  }
827
828
0
  vorbis_encode_map_n_res_setup(vi,hi->base_setting,setup->maps);
829
830
  /* set bitrate readonlies and management */
831
0
  if(hi->bitrate_av>0)
832
0
    vi->bitrate_nominal=hi->bitrate_av;
833
0
  else{
834
0
    vi->bitrate_nominal=setting_to_approx_bitrate(vi);
835
0
  }
836
837
0
  vi->bitrate_lower=hi->bitrate_min;
838
0
  vi->bitrate_upper=hi->bitrate_max;
839
0
  if(hi->bitrate_av)
840
0
    vi->bitrate_window=(double)hi->bitrate_reservoir/hi->bitrate_av;
841
0
  else
842
0
    vi->bitrate_window=0.;
843
844
0
  if(hi->managed){
845
0
    ci->bi.avg_rate=hi->bitrate_av;
846
0
    ci->bi.min_rate=hi->bitrate_min;
847
0
    ci->bi.max_rate=hi->bitrate_max;
848
849
0
    ci->bi.reservoir_bits=hi->bitrate_reservoir;
850
0
    ci->bi.reservoir_bias=
851
0
      hi->bitrate_reservoir_bias;
852
853
0
    ci->bi.slew_damp=hi->bitrate_av_damp;
854
855
0
  }
856
857
0
  return(0);
858
859
0
}
860
861
static void vorbis_encode_setup_setting(vorbis_info *vi,
862
                                       long  channels,
863
0
                                       long  rate){
864
0
  int i,is;
865
0
  codec_setup_info *ci=vi->codec_setup;
866
0
  highlevel_encode_setup *hi=&ci->hi;
867
0
  const ve_setup_data_template *setup=hi->setup;
868
0
  double ds;
869
870
0
  vi->version=0;
871
0
  vi->channels=channels;
872
0
  vi->rate=rate;
873
874
0
  hi->impulse_block_p=1;
875
0
  hi->noise_normalize_p=1;
876
877
0
  is=hi->base_setting;
878
0
  ds=hi->base_setting-is;
879
880
0
  hi->stereo_point_setting=hi->base_setting;
881
882
0
  if(!hi->lowpass_altered)
883
0
    hi->lowpass_kHz=
884
0
      setup->psy_lowpass[is]*(1.-ds)+setup->psy_lowpass[is+1]*ds;
885
886
0
  hi->ath_floating_dB=setup->psy_ath_float[is]*(1.-ds)+
887
0
    setup->psy_ath_float[is+1]*ds;
888
0
  hi->ath_absolute_dB=setup->psy_ath_abs[is]*(1.-ds)+
889
0
    setup->psy_ath_abs[is+1]*ds;
890
891
0
  hi->amplitude_track_dBpersec=-6.;
892
0
  hi->trigger_setting=hi->base_setting;
893
894
0
  for(i=0;i<4;i++){
895
0
    hi->block[i].tone_mask_setting=hi->base_setting;
896
0
    hi->block[i].tone_peaklimit_setting=hi->base_setting;
897
0
    hi->block[i].noise_bias_setting=hi->base_setting;
898
0
    hi->block[i].noise_compand_setting=hi->base_setting;
899
0
  }
900
0
}
901
902
int vorbis_encode_setup_vbr(vorbis_info *vi,
903
                            long  channels,
904
                            long  rate,
905
0
                            float quality){
906
0
  codec_setup_info *ci;
907
0
  highlevel_encode_setup *hi;
908
0
  if(rate<=0) return OV_EINVAL;
909
910
0
  ci=vi->codec_setup;
911
0
  hi=&ci->hi;
912
913
0
  quality+=.0000001;
914
0
  if(quality>=1.)quality=.9999;
915
916
0
  hi->req=quality;
917
0
  hi->setup=get_setup_template(channels,rate,quality,0,&hi->base_setting);
918
0
  if(!hi->setup)return OV_EIMPL;
919
920
0
  vorbis_encode_setup_setting(vi,channels,rate);
921
0
  hi->managed=0;
922
0
  hi->coupling_p=1;
923
924
0
  return 0;
925
0
}
926
927
int vorbis_encode_init_vbr(vorbis_info *vi,
928
                           long channels,
929
                           long rate,
930
931
                           float base_quality /* 0. to 1. */
932
0
                           ){
933
0
  int ret=0;
934
935
0
  ret=vorbis_encode_setup_vbr(vi,channels,rate,base_quality);
936
937
0
  if(ret){
938
0
    vorbis_info_clear(vi);
939
0
    return ret;
940
0
  }
941
0
  ret=vorbis_encode_setup_init(vi);
942
0
  if(ret)
943
0
    vorbis_info_clear(vi);
944
0
  return(ret);
945
0
}
946
947
int vorbis_encode_setup_managed(vorbis_info *vi,
948
                                long channels,
949
                                long rate,
950
951
                                long max_bitrate,
952
                                long nominal_bitrate,
953
0
                                long min_bitrate){
954
955
0
  codec_setup_info *ci;
956
0
  highlevel_encode_setup *hi;
957
0
  double tnominal;
958
0
  if(rate<=0) return OV_EINVAL;
959
960
0
  ci=vi->codec_setup;
961
0
  hi=&ci->hi;
962
0
  tnominal=nominal_bitrate;
963
964
0
  if(nominal_bitrate<=0.){
965
0
    if(max_bitrate>0.){
966
0
      if(min_bitrate>0.)
967
0
        nominal_bitrate=(max_bitrate+min_bitrate)*.5;
968
0
      else
969
0
        nominal_bitrate=max_bitrate*.875;
970
0
    }else{
971
0
      if(min_bitrate>0.){
972
0
        nominal_bitrate=min_bitrate;
973
0
      }else{
974
0
        return(OV_EINVAL);
975
0
      }
976
0
    }
977
0
  }
978
979
0
  hi->req=nominal_bitrate;
980
0
  hi->setup=get_setup_template(channels,rate,nominal_bitrate,1,&hi->base_setting);
981
0
  if(!hi->setup)return OV_EIMPL;
982
983
0
  vorbis_encode_setup_setting(vi,channels,rate);
984
985
  /* initialize management with sane defaults */
986
0
  hi->coupling_p=1;
987
0
  hi->managed=1;
988
0
  hi->bitrate_min=min_bitrate;
989
0
  hi->bitrate_max=max_bitrate;
990
0
  hi->bitrate_av=tnominal;
991
0
  hi->bitrate_av_damp=1.5f; /* full range in no less than 1.5 second */
992
0
  hi->bitrate_reservoir=nominal_bitrate*2;
993
0
  hi->bitrate_reservoir_bias=.1; /* bias toward hoarding bits */
994
995
0
  return(0);
996
997
0
}
998
999
int vorbis_encode_init(vorbis_info *vi,
1000
                       long channels,
1001
                       long rate,
1002
1003
                       long max_bitrate,
1004
                       long nominal_bitrate,
1005
0
                       long min_bitrate){
1006
1007
0
  int ret=vorbis_encode_setup_managed(vi,channels,rate,
1008
0
                                      max_bitrate,
1009
0
                                      nominal_bitrate,
1010
0
                                      min_bitrate);
1011
0
  if(ret){
1012
0
    vorbis_info_clear(vi);
1013
0
    return(ret);
1014
0
  }
1015
1016
0
  ret=vorbis_encode_setup_init(vi);
1017
0
  if(ret)
1018
0
    vorbis_info_clear(vi);
1019
0
  return(ret);
1020
0
}
1021
1022
0
int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){
1023
0
  if(vi){
1024
0
    codec_setup_info *ci=vi->codec_setup;
1025
0
    highlevel_encode_setup *hi=&ci->hi;
1026
0
    int setp=(number&0xf); /* a read request has a low nibble of 0 */
1027
1028
0
    if(setp && hi->set_in_stone)return(OV_EINVAL);
1029
1030
0
    switch(number){
1031
1032
    /* now deprecated *****************/
1033
0
    case OV_ECTL_RATEMANAGE_GET:
1034
0
      {
1035
1036
0
        struct ovectl_ratemanage_arg *ai=
1037
0
          (struct ovectl_ratemanage_arg *)arg;
1038
1039
0
        ai->management_active=hi->managed;
1040
0
        ai->bitrate_hard_window=ai->bitrate_av_window=
1041
0
          (double)hi->bitrate_reservoir/vi->rate;
1042
0
        ai->bitrate_av_window_center=1.;
1043
0
        ai->bitrate_hard_min=hi->bitrate_min;
1044
0
        ai->bitrate_hard_max=hi->bitrate_max;
1045
0
        ai->bitrate_av_lo=hi->bitrate_av;
1046
0
        ai->bitrate_av_hi=hi->bitrate_av;
1047
1048
0
      }
1049
0
      return(0);
1050
1051
    /* now deprecated *****************/
1052
0
    case OV_ECTL_RATEMANAGE_SET:
1053
0
      {
1054
0
        struct ovectl_ratemanage_arg *ai=
1055
0
          (struct ovectl_ratemanage_arg *)arg;
1056
0
        if(ai==NULL){
1057
0
          hi->managed=0;
1058
0
        }else{
1059
0
          hi->managed=ai->management_active;
1060
0
          vorbis_encode_ctl(vi,OV_ECTL_RATEMANAGE_AVG,arg);
1061
0
          vorbis_encode_ctl(vi,OV_ECTL_RATEMANAGE_HARD,arg);
1062
0
        }
1063
0
      }
1064
0
      return 0;
1065
1066
    /* now deprecated *****************/
1067
0
    case OV_ECTL_RATEMANAGE_AVG:
1068
0
      {
1069
0
        struct ovectl_ratemanage_arg *ai=
1070
0
          (struct ovectl_ratemanage_arg *)arg;
1071
0
        if(ai==NULL){
1072
0
          hi->bitrate_av=0;
1073
0
        }else{
1074
0
          hi->bitrate_av=(ai->bitrate_av_lo+ai->bitrate_av_hi)*.5;
1075
0
        }
1076
0
      }
1077
0
      return(0);
1078
    /* now deprecated *****************/
1079
0
    case OV_ECTL_RATEMANAGE_HARD:
1080
0
      {
1081
0
        struct ovectl_ratemanage_arg *ai=
1082
0
          (struct ovectl_ratemanage_arg *)arg;
1083
0
        if(ai==NULL){
1084
0
          hi->bitrate_min=0;
1085
0
          hi->bitrate_max=0;
1086
0
        }else{
1087
0
          hi->bitrate_min=ai->bitrate_hard_min;
1088
0
          hi->bitrate_max=ai->bitrate_hard_max;
1089
0
          hi->bitrate_reservoir=ai->bitrate_hard_window*
1090
0
            (hi->bitrate_max+hi->bitrate_min)*.5;
1091
0
        }
1092
0
        if(hi->bitrate_reservoir<128.)
1093
0
          hi->bitrate_reservoir=128.;
1094
0
      }
1095
0
      return(0);
1096
1097
      /* replacement ratemanage interface */
1098
0
    case OV_ECTL_RATEMANAGE2_GET:
1099
0
      {
1100
0
        struct ovectl_ratemanage2_arg *ai=
1101
0
          (struct ovectl_ratemanage2_arg *)arg;
1102
0
        if(ai==NULL)return OV_EINVAL;
1103
1104
0
        ai->management_active=hi->managed;
1105
0
        ai->bitrate_limit_min_kbps=hi->bitrate_min/1000;
1106
0
        ai->bitrate_limit_max_kbps=hi->bitrate_max/1000;
1107
0
        ai->bitrate_average_kbps=hi->bitrate_av/1000;
1108
0
        ai->bitrate_average_damping=hi->bitrate_av_damp;
1109
0
        ai->bitrate_limit_reservoir_bits=hi->bitrate_reservoir;
1110
0
        ai->bitrate_limit_reservoir_bias=hi->bitrate_reservoir_bias;
1111
0
      }
1112
0
      return (0);
1113
0
    case OV_ECTL_RATEMANAGE2_SET:
1114
0
      {
1115
0
        struct ovectl_ratemanage2_arg *ai=
1116
0
          (struct ovectl_ratemanage2_arg *)arg;
1117
0
        if(ai==NULL){
1118
0
          hi->managed=0;
1119
0
        }else{
1120
          /* sanity check; only catch invariant violations */
1121
0
          if(ai->bitrate_limit_min_kbps>0 &&
1122
0
             ai->bitrate_average_kbps>0 &&
1123
0
             ai->bitrate_limit_min_kbps>ai->bitrate_average_kbps)
1124
0
            return OV_EINVAL;
1125
1126
0
          if(ai->bitrate_limit_max_kbps>0 &&
1127
0
             ai->bitrate_average_kbps>0 &&
1128
0
             ai->bitrate_limit_max_kbps<ai->bitrate_average_kbps)
1129
0
            return OV_EINVAL;
1130
1131
0
          if(ai->bitrate_limit_min_kbps>0 &&
1132
0
             ai->bitrate_limit_max_kbps>0 &&
1133
0
             ai->bitrate_limit_min_kbps>ai->bitrate_limit_max_kbps)
1134
0
            return OV_EINVAL;
1135
1136
0
          if(ai->bitrate_average_damping <= 0.)
1137
0
            return OV_EINVAL;
1138
1139
0
          if(ai->bitrate_limit_reservoir_bits < 0)
1140
0
            return OV_EINVAL;
1141
1142
0
          if(ai->bitrate_limit_reservoir_bias < 0.)
1143
0
            return OV_EINVAL;
1144
1145
0
          if(ai->bitrate_limit_reservoir_bias > 1.)
1146
0
            return OV_EINVAL;
1147
1148
0
          hi->managed=ai->management_active;
1149
0
          hi->bitrate_min=ai->bitrate_limit_min_kbps * 1000;
1150
0
          hi->bitrate_max=ai->bitrate_limit_max_kbps * 1000;
1151
0
          hi->bitrate_av=ai->bitrate_average_kbps * 1000;
1152
0
          hi->bitrate_av_damp=ai->bitrate_average_damping;
1153
0
          hi->bitrate_reservoir=ai->bitrate_limit_reservoir_bits;
1154
0
          hi->bitrate_reservoir_bias=ai->bitrate_limit_reservoir_bias;
1155
0
        }
1156
0
      }
1157
0
      return 0;
1158
1159
0
    case OV_ECTL_LOWPASS_GET:
1160
0
      {
1161
0
        double *farg=(double *)arg;
1162
0
        *farg=hi->lowpass_kHz;
1163
0
      }
1164
0
      return(0);
1165
0
    case OV_ECTL_LOWPASS_SET:
1166
0
      {
1167
0
        double *farg=(double *)arg;
1168
0
        hi->lowpass_kHz=*farg;
1169
1170
0
        if(hi->lowpass_kHz<2.)hi->lowpass_kHz=2.;
1171
0
        if(hi->lowpass_kHz>99.)hi->lowpass_kHz=99.;
1172
0
        hi->lowpass_altered=1;
1173
0
      }
1174
0
      return(0);
1175
0
    case OV_ECTL_IBLOCK_GET:
1176
0
      {
1177
0
        double *farg=(double *)arg;
1178
0
        *farg=hi->impulse_noisetune;
1179
0
      }
1180
0
      return(0);
1181
0
    case OV_ECTL_IBLOCK_SET:
1182
0
      {
1183
0
        double *farg=(double *)arg;
1184
0
        hi->impulse_noisetune=*farg;
1185
1186
0
        if(hi->impulse_noisetune>0.)hi->impulse_noisetune=0.;
1187
0
        if(hi->impulse_noisetune<-15.)hi->impulse_noisetune=-15.;
1188
0
      }
1189
0
      return(0);
1190
0
    case OV_ECTL_COUPLING_GET:
1191
0
      {
1192
0
        int *iarg=(int *)arg;
1193
0
        *iarg=hi->coupling_p;
1194
0
      }
1195
0
      return(0);
1196
0
    case OV_ECTL_COUPLING_SET:
1197
0
      {
1198
0
        const void *new_template;
1199
0
        double new_base=0.;
1200
0
        int *iarg=(int *)arg;
1201
0
        hi->coupling_p=((*iarg)!=0);
1202
1203
        /* Fetching a new template can alter the base_setting, which
1204
           many other parameters are based on.  Right now, the only
1205
           parameter drawn from the base_setting that can be altered
1206
           by an encctl is the lowpass, so that is explictly flagged
1207
           to not be overwritten when we fetch a new template and
1208
           recompute the dependant settings */
1209
0
        new_template = get_setup_template(hi->coupling_p?vi->channels:-1,
1210
0
                                          vi->rate,
1211
0
                                          hi->req,
1212
0
                                          hi->managed,
1213
0
                                          &new_base);
1214
0
        if(!new_template)return OV_EIMPL;
1215
0
        hi->setup=new_template;
1216
0
        hi->base_setting=new_base;
1217
0
        vorbis_encode_setup_setting(vi,vi->channels,vi->rate);
1218
0
      }
1219
0
      return(0);
1220
0
    }
1221
0
    return(OV_EIMPL);
1222
0
  }
1223
0
  return(OV_EINVAL);
1224
0
}