Coverage Report

Created: 2026-05-23 07:06

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