Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/media/libvorbis/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 http://www.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
0
197
0
  memcpy(f,in+x[is],sizeof(*f));
198
0
199
0
  /* 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
0
215
0
    for(i=0;i<=maxbook;i++)
216
0
      ci->book_param[ci->books++]=(static_codebook *)books[x[is]][i];
217
0
  }
218
0
219
0
  /* 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
0
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
0
235
0
  memcpy(g,in+(int)x[is],sizeof(*g));
236
0
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
0
245
0
  /* 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
0
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
0
267
0
    if(hi->managed){
268
0
      /* 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
0
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
0
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
0
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
0
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
0
320
0
  memcpy(p,&_psy_info_template,sizeof(*p));
321
0
  p->blockflag=block>>1;
322
0
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
0
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
0
342
0
  /* 0 and 2 are only used by bitmanagement, but there's no harm to always
343
0
     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
0
350
0
  p->max_curve_dB=max[is]*(1.-ds)+max[is+1]*ds;
351
0
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
0
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
0
374
0
  /* 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
0
387
0
  p->tone_abs_limit=suppress[is]*(1.-ds)+suppress[is+1]*ds;
388
0
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
0
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
0
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
0
411
0
  /* impulse blocks may take a user specified bias to boost the
412
0
     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
0
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
0
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
0
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
0
445
0
  codec_setup_info *ci=vi->codec_setup;
446
0
  int is=s;
447
0
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
0
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
0
459
0
  codec_setup_info *ci=vi->codec_setup;
460
0
  int i;
461
0
462
0
  vorbis_info_residue0 *r=ci->residue_param[number]=
463
0
    _ogg_malloc(sizeof(*r));
464
0
465
0
  memcpy(r,res->res,sizeof(*r));
466
0
  if(ci->residues<=number)ci->residues=number+1;
467
0
468
0
  r->grouping=res->grouping;
469
0
  ci->residue_type[number]=res->res_type;
470
0
471
0
  /* fill in all the books */
472
0
  {
473
0
    int booklist=0,k;
474
0
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
0
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
0
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
0
494
0
    }else{
495
0
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
0
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
0
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
0
516
0
  /* 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
0
523
0
    /* lowpass needs to be set in the floor and the residue. */
524
0
    if(freq>nyq)freq=nyq;
525
0
    /* in the floor, the granularity can be very fine; it doesn't alter
526
0
       the encoding structure, only the samples used to fit the floor
527
0
       approximation */
528
0
    f->n=freq/nyq*blocksize;
529
0
530
0
    /* this res may by limited by the maximum pointlimit of the mode,
531
0
       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
0
      /* already set */
545
0
      break;
546
0
    }
547
0
548
0
    /* in the residue, we're constrained, physically, by partition
549
0
       boundaries.  We still lowpass 'wherever', but we have to round up
550
0
       here to next boundary, or the vorbis spec will round it *down* to
551
0
       previous boundary in encode/decode */
552
0
    if(ci->residue_type[number]==2){
553
0
      /* residue 2 bundles together multiple channels; used by stereo
554
0
         and surround.  Count the channels in use */
555
0
      /* Multiple maps/submaps can point to the same residue.  In the case
556
0
         of residue 2, they all better have the same number of
557
0
         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
0
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
0
      /* 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
0
573
0
    }else{
574
0
575
0
      r->end=(int)((freq/nyq*blocksize)/r->grouping+.9)* /* round up only if we're well past */
576
0
        r->grouping;
577
0
      /* the blocksize and grouping may disagree at the end */
578
0
      if(r->end>blocksize)r->end=blocksize/r->grouping*r->grouping;
579
0
580
0
    }
581
0
582
0
    if(r->end==0)r->end=r->grouping; /* LFE channel */
583
0
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
0
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
0
597
0
  if(ci->blocksizes[0]==ci->blocksizes[1])modes=1;
598
0
599
0
  for(i=0;i<modes;i++){
600
0
601
0
    ci->map_param[i]=_ogg_calloc(1,sizeof(*map));
602
0
    ci->mode_param[i]=_ogg_calloc(1,sizeof(*mode));
603
0
604
0
    memcpy(ci->mode_param[i],mode+i,sizeof(*_mode_template));
605
0
    if(i>=ci->modes)ci->modes=i+1;
606
0
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
0
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
0
626
0
  if(r==NULL)
627
0
    return(-1);
628
0
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
0
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
0
648
0
        /* the template matches.  Does the requested quality mode
649
0
           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
0
        /* 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
0
664
0
        return(setup_list[i]);
665
0
      }
666
0
    }
667
0
    i++;
668
0
  }
669
0
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
0
686
0
  if(ci==NULL)return(OV_EINVAL);
687
0
  if(!hi->impulse_block_p)i0=1;
688
0
689
0
  /* too low/high an ATH floater is nonsensical, but doesn't break anything */
690
0
  if(hi->ath_floating_dB>-80)hi->ath_floating_dB=-80;
691
0
  if(hi->ath_floating_dB<-200)hi->ath_floating_dB=-200;
692
0
693
0
  /* again, bound this to avoid the app shooting itself int he foot
694
0
     too badly */
695
0
  if(hi->amplitude_track_dBpersec>0.)hi->amplitude_track_dBpersec=0.;
696
0
  if(hi->amplitude_track_dBpersec<-99999.)hi->amplitude_track_dBpersec=-99999.;
697
0
698
0
  /* get the appropriate setup template; matches the fetch in previous
699
0
     stages */
700
0
  setup=(ve_setup_data_template *)hi->setup;
701
0
  if(setup==NULL)return(OV_EINVAL);
702
0
703
0
  hi->set_in_stone=1;
704
0
  /* choose block sizes from configured sizes as well as paying
705
0
     attention to long_block_p and short_block_p.  If the configured
706
0
     short and long blocks are the same length, we set long_block_p
707
0
     and unset short_block_p */
708
0
  vorbis_encode_blocksize_setup(vi,hi->base_setting,
709
0
                                setup->blocksize_short,
710
0
                                setup->blocksize_long);
711
0
  if(ci->blocksizes[0]==ci->blocksizes[1])singleblock=1;
712
0
713
0
  /* floor setup; choose proper floor params.  Allocated on the floor
714
0
     stack in order; if we alloc only a single long floor, it's 0 */
715
0
  for(i=0;i<setup->floor_mappings;i++)
716
0
    vorbis_encode_floor_setup(vi,hi->base_setting,
717
0
                              setup->floor_books,
718
0
                              setup->floor_params,
719
0
                              setup->floor_mapping_list[i]);
720
0
721
0
  /* setup of [mostly] short block detection and stereo*/
722
0
  vorbis_encode_global_psych_setup(vi,hi->trigger_setting,
723
0
                                   setup->global_params,
724
0
                                   setup->global_mapping);
725
0
  vorbis_encode_global_stereo(vi,hi,setup->stereo_modes);
726
0
727
0
  /* basic psych setup and noise normalization */
728
0
  vorbis_encode_psyset_setup(vi,hi->base_setting,
729
0
                             setup->psy_noise_normal_start[0],
730
0
                             setup->psy_noise_normal_partition[0],
731
0
                             setup->psy_noise_normal_thresh,
732
0
                             0);
733
0
  vorbis_encode_psyset_setup(vi,hi->base_setting,
734
0
                             setup->psy_noise_normal_start[0],
735
0
                             setup->psy_noise_normal_partition[0],
736
0
                             setup->psy_noise_normal_thresh,
737
0
                             1);
738
0
  if(!singleblock){
739
0
    vorbis_encode_psyset_setup(vi,hi->base_setting,
740
0
                               setup->psy_noise_normal_start[1],
741
0
                               setup->psy_noise_normal_partition[1],
742
0
                                    setup->psy_noise_normal_thresh,
743
0
                               2);
744
0
    vorbis_encode_psyset_setup(vi,hi->base_setting,
745
0
                               setup->psy_noise_normal_start[1],
746
0
                               setup->psy_noise_normal_partition[1],
747
0
                               setup->psy_noise_normal_thresh,
748
0
                               3);
749
0
  }
750
0
751
0
  /* tone masking setup */
752
0
  vorbis_encode_tonemask_setup(vi,hi->block[i0].tone_mask_setting,0,
753
0
                               setup->psy_tone_masteratt,
754
0
                               setup->psy_tone_0dB,
755
0
                               setup->psy_tone_adj_impulse);
756
0
  vorbis_encode_tonemask_setup(vi,hi->block[1].tone_mask_setting,1,
757
0
                               setup->psy_tone_masteratt,
758
0
                               setup->psy_tone_0dB,
759
0
                               setup->psy_tone_adj_other);
760
0
  if(!singleblock){
761
0
    vorbis_encode_tonemask_setup(vi,hi->block[2].tone_mask_setting,2,
762
0
                                 setup->psy_tone_masteratt,
763
0
                                 setup->psy_tone_0dB,
764
0
                                 setup->psy_tone_adj_other);
765
0
    vorbis_encode_tonemask_setup(vi,hi->block[3].tone_mask_setting,3,
766
0
                                 setup->psy_tone_masteratt,
767
0
                                 setup->psy_tone_0dB,
768
0
                                 setup->psy_tone_adj_long);
769
0
  }
770
0
771
0
  /* noise companding setup */
772
0
  vorbis_encode_compand_setup(vi,hi->block[i0].noise_compand_setting,0,
773
0
                              setup->psy_noise_compand,
774
0
                              setup->psy_noise_compand_short_mapping);
775
0
  vorbis_encode_compand_setup(vi,hi->block[1].noise_compand_setting,1,
776
0
                              setup->psy_noise_compand,
777
0
                              setup->psy_noise_compand_short_mapping);
778
0
  if(!singleblock){
779
0
    vorbis_encode_compand_setup(vi,hi->block[2].noise_compand_setting,2,
780
0
                                setup->psy_noise_compand,
781
0
                                setup->psy_noise_compand_long_mapping);
782
0
    vorbis_encode_compand_setup(vi,hi->block[3].noise_compand_setting,3,
783
0
                                setup->psy_noise_compand,
784
0
                                setup->psy_noise_compand_long_mapping);
785
0
  }
786
0
787
0
  /* peak guarding setup  */
788
0
  vorbis_encode_peak_setup(vi,hi->block[i0].tone_peaklimit_setting,0,
789
0
                           setup->psy_tone_dBsuppress);
790
0
  vorbis_encode_peak_setup(vi,hi->block[1].tone_peaklimit_setting,1,
791
0
                           setup->psy_tone_dBsuppress);
792
0
  if(!singleblock){
793
0
    vorbis_encode_peak_setup(vi,hi->block[2].tone_peaklimit_setting,2,
794
0
                             setup->psy_tone_dBsuppress);
795
0
    vorbis_encode_peak_setup(vi,hi->block[3].tone_peaklimit_setting,3,
796
0
                             setup->psy_tone_dBsuppress);
797
0
  }
798
0
799
0
  /* noise bias setup */
800
0
  vorbis_encode_noisebias_setup(vi,hi->block[i0].noise_bias_setting,0,
801
0
                                setup->psy_noise_dBsuppress,
802
0
                                setup->psy_noise_bias_impulse,
803
0
                                setup->psy_noiseguards,
804
0
                                (i0==0?hi->impulse_noisetune:0.));
805
0
  vorbis_encode_noisebias_setup(vi,hi->block[1].noise_bias_setting,1,
806
0
                                setup->psy_noise_dBsuppress,
807
0
                                setup->psy_noise_bias_padding,
808
0
                                setup->psy_noiseguards,0.);
809
0
  if(!singleblock){
810
0
    vorbis_encode_noisebias_setup(vi,hi->block[2].noise_bias_setting,2,
811
0
                                  setup->psy_noise_dBsuppress,
812
0
                                  setup->psy_noise_bias_trans,
813
0
                                  setup->psy_noiseguards,0.);
814
0
    vorbis_encode_noisebias_setup(vi,hi->block[3].noise_bias_setting,3,
815
0
                                  setup->psy_noise_dBsuppress,
816
0
                                  setup->psy_noise_bias_long,
817
0
                                  setup->psy_noiseguards,0.);
818
0
  }
819
0
820
0
  vorbis_encode_ath_setup(vi,0);
821
0
  vorbis_encode_ath_setup(vi,1);
822
0
  if(!singleblock){
823
0
    vorbis_encode_ath_setup(vi,2);
824
0
    vorbis_encode_ath_setup(vi,3);
825
0
  }
826
0
827
0
  vorbis_encode_map_n_res_setup(vi,hi->base_setting,setup->maps);
828
0
829
0
  /* set bitrate readonlies and management */
830
0
  if(hi->bitrate_av>0)
831
0
    vi->bitrate_nominal=hi->bitrate_av;
832
0
  else{
833
0
    vi->bitrate_nominal=setting_to_approx_bitrate(vi);
834
0
  }
835
0
836
0
  vi->bitrate_lower=hi->bitrate_min;
837
0
  vi->bitrate_upper=hi->bitrate_max;
838
0
  if(hi->bitrate_av)
839
0
    vi->bitrate_window=(double)hi->bitrate_reservoir/hi->bitrate_av;
840
0
  else
841
0
    vi->bitrate_window=0.;
842
0
843
0
  if(hi->managed){
844
0
    ci->bi.avg_rate=hi->bitrate_av;
845
0
    ci->bi.min_rate=hi->bitrate_min;
846
0
    ci->bi.max_rate=hi->bitrate_max;
847
0
848
0
    ci->bi.reservoir_bits=hi->bitrate_reservoir;
849
0
    ci->bi.reservoir_bias=
850
0
      hi->bitrate_reservoir_bias;
851
0
852
0
    ci->bi.slew_damp=hi->bitrate_av_damp;
853
0
854
0
  }
855
0
856
0
  return(0);
857
0
858
0
}
859
860
static void vorbis_encode_setup_setting(vorbis_info *vi,
861
                                       long  channels,
862
0
                                       long  rate){
863
0
  int i,is;
864
0
  codec_setup_info *ci=vi->codec_setup;
865
0
  highlevel_encode_setup *hi=&ci->hi;
866
0
  const ve_setup_data_template *setup=hi->setup;
867
0
  double ds;
868
0
869
0
  vi->version=0;
870
0
  vi->channels=channels;
871
0
  vi->rate=rate;
872
0
873
0
  hi->impulse_block_p=1;
874
0
  hi->noise_normalize_p=1;
875
0
876
0
  is=hi->base_setting;
877
0
  ds=hi->base_setting-is;
878
0
879
0
  hi->stereo_point_setting=hi->base_setting;
880
0
881
0
  if(!hi->lowpass_altered)
882
0
    hi->lowpass_kHz=
883
0
      setup->psy_lowpass[is]*(1.-ds)+setup->psy_lowpass[is+1]*ds;
884
0
885
0
  hi->ath_floating_dB=setup->psy_ath_float[is]*(1.-ds)+
886
0
    setup->psy_ath_float[is+1]*ds;
887
0
  hi->ath_absolute_dB=setup->psy_ath_abs[is]*(1.-ds)+
888
0
    setup->psy_ath_abs[is+1]*ds;
889
0
890
0
  hi->amplitude_track_dBpersec=-6.;
891
0
  hi->trigger_setting=hi->base_setting;
892
0
893
0
  for(i=0;i<4;i++){
894
0
    hi->block[i].tone_mask_setting=hi->base_setting;
895
0
    hi->block[i].tone_peaklimit_setting=hi->base_setting;
896
0
    hi->block[i].noise_bias_setting=hi->base_setting;
897
0
    hi->block[i].noise_compand_setting=hi->base_setting;
898
0
  }
899
0
}
900
901
int vorbis_encode_setup_vbr(vorbis_info *vi,
902
                            long  channels,
903
                            long  rate,
904
0
                            float quality){
905
0
  codec_setup_info *ci;
906
0
  highlevel_encode_setup *hi;
907
0
  if(rate<=0) return OV_EINVAL;
908
0
909
0
  ci=vi->codec_setup;
910
0
  hi=&ci->hi;
911
0
912
0
  quality+=.0000001;
913
0
  if(quality>=1.)quality=.9999;
914
0
915
0
  hi->req=quality;
916
0
  hi->setup=get_setup_template(channels,rate,quality,0,&hi->base_setting);
917
0
  if(!hi->setup)return OV_EIMPL;
918
0
919
0
  vorbis_encode_setup_setting(vi,channels,rate);
920
0
  hi->managed=0;
921
0
  hi->coupling_p=1;
922
0
923
0
  return 0;
924
0
}
925
926
int vorbis_encode_init_vbr(vorbis_info *vi,
927
                           long channels,
928
                           long rate,
929
930
                           float base_quality /* 0. to 1. */
931
0
                           ){
932
0
  int ret=0;
933
0
934
0
  ret=vorbis_encode_setup_vbr(vi,channels,rate,base_quality);
935
0
936
0
  if(ret){
937
0
    vorbis_info_clear(vi);
938
0
    return ret;
939
0
  }
940
0
  ret=vorbis_encode_setup_init(vi);
941
0
  if(ret)
942
0
    vorbis_info_clear(vi);
943
0
  return(ret);
944
0
}
945
946
int vorbis_encode_setup_managed(vorbis_info *vi,
947
                                long channels,
948
                                long rate,
949
950
                                long max_bitrate,
951
                                long nominal_bitrate,
952
0
                                long min_bitrate){
953
0
954
0
  codec_setup_info *ci;
955
0
  highlevel_encode_setup *hi;
956
0
  double tnominal;
957
0
  if(rate<=0) return OV_EINVAL;
958
0
959
0
  ci=vi->codec_setup;
960
0
  hi=&ci->hi;
961
0
  tnominal=nominal_bitrate;
962
0
963
0
  if(nominal_bitrate<=0.){
964
0
    if(max_bitrate>0.){
965
0
      if(min_bitrate>0.)
966
0
        nominal_bitrate=(max_bitrate+min_bitrate)*.5;
967
0
      else
968
0
        nominal_bitrate=max_bitrate*.875;
969
0
    }else{
970
0
      if(min_bitrate>0.){
971
0
        nominal_bitrate=min_bitrate;
972
0
      }else{
973
0
        return(OV_EINVAL);
974
0
      }
975
0
    }
976
0
  }
977
0
978
0
  hi->req=nominal_bitrate;
979
0
  hi->setup=get_setup_template(channels,rate,nominal_bitrate,1,&hi->base_setting);
980
0
  if(!hi->setup)return OV_EIMPL;
981
0
982
0
  vorbis_encode_setup_setting(vi,channels,rate);
983
0
984
0
  /* initialize management with sane defaults */
985
0
  hi->coupling_p=1;
986
0
  hi->managed=1;
987
0
  hi->bitrate_min=min_bitrate;
988
0
  hi->bitrate_max=max_bitrate;
989
0
  hi->bitrate_av=tnominal;
990
0
  hi->bitrate_av_damp=1.5f; /* full range in no less than 1.5 second */
991
0
  hi->bitrate_reservoir=nominal_bitrate*2;
992
0
  hi->bitrate_reservoir_bias=.1; /* bias toward hoarding bits */
993
0
994
0
  return(0);
995
0
996
0
}
997
998
int vorbis_encode_init(vorbis_info *vi,
999
                       long channels,
1000
                       long rate,
1001
1002
                       long max_bitrate,
1003
                       long nominal_bitrate,
1004
0
                       long min_bitrate){
1005
0
1006
0
  int ret=vorbis_encode_setup_managed(vi,channels,rate,
1007
0
                                      max_bitrate,
1008
0
                                      nominal_bitrate,
1009
0
                                      min_bitrate);
1010
0
  if(ret){
1011
0
    vorbis_info_clear(vi);
1012
0
    return(ret);
1013
0
  }
1014
0
1015
0
  ret=vorbis_encode_setup_init(vi);
1016
0
  if(ret)
1017
0
    vorbis_info_clear(vi);
1018
0
  return(ret);
1019
0
}
1020
1021
0
int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){
1022
0
  if(vi){
1023
0
    codec_setup_info *ci=vi->codec_setup;
1024
0
    highlevel_encode_setup *hi=&ci->hi;
1025
0
    int setp=(number&0xf); /* a read request has a low nibble of 0 */
1026
0
1027
0
    if(setp && hi->set_in_stone)return(OV_EINVAL);
1028
0
1029
0
    switch(number){
1030
0
1031
0
    /* now deprecated *****************/
1032
0
    case OV_ECTL_RATEMANAGE_GET:
1033
0
      {
1034
0
1035
0
        struct ovectl_ratemanage_arg *ai=
1036
0
          (struct ovectl_ratemanage_arg *)arg;
1037
0
1038
0
        ai->management_active=hi->managed;
1039
0
        ai->bitrate_hard_window=ai->bitrate_av_window=
1040
0
          (double)hi->bitrate_reservoir/vi->rate;
1041
0
        ai->bitrate_av_window_center=1.;
1042
0
        ai->bitrate_hard_min=hi->bitrate_min;
1043
0
        ai->bitrate_hard_max=hi->bitrate_max;
1044
0
        ai->bitrate_av_lo=hi->bitrate_av;
1045
0
        ai->bitrate_av_hi=hi->bitrate_av;
1046
0
1047
0
      }
1048
0
      return(0);
1049
0
1050
0
    /* now deprecated *****************/
1051
0
    case OV_ECTL_RATEMANAGE_SET:
1052
0
      {
1053
0
        struct ovectl_ratemanage_arg *ai=
1054
0
          (struct ovectl_ratemanage_arg *)arg;
1055
0
        if(ai==NULL){
1056
0
          hi->managed=0;
1057
0
        }else{
1058
0
          hi->managed=ai->management_active;
1059
0
          vorbis_encode_ctl(vi,OV_ECTL_RATEMANAGE_AVG,arg);
1060
0
          vorbis_encode_ctl(vi,OV_ECTL_RATEMANAGE_HARD,arg);
1061
0
        }
1062
0
      }
1063
0
      return 0;
1064
0
1065
0
    /* now deprecated *****************/
1066
0
    case OV_ECTL_RATEMANAGE_AVG:
1067
0
      {
1068
0
        struct ovectl_ratemanage_arg *ai=
1069
0
          (struct ovectl_ratemanage_arg *)arg;
1070
0
        if(ai==NULL){
1071
0
          hi->bitrate_av=0;
1072
0
        }else{
1073
0
          hi->bitrate_av=(ai->bitrate_av_lo+ai->bitrate_av_hi)*.5;
1074
0
        }
1075
0
      }
1076
0
      return(0);
1077
0
    /* now deprecated *****************/
1078
0
    case OV_ECTL_RATEMANAGE_HARD:
1079
0
      {
1080
0
        struct ovectl_ratemanage_arg *ai=
1081
0
          (struct ovectl_ratemanage_arg *)arg;
1082
0
        if(ai==NULL){
1083
0
          hi->bitrate_min=0;
1084
0
          hi->bitrate_max=0;
1085
0
        }else{
1086
0
          hi->bitrate_min=ai->bitrate_hard_min;
1087
0
          hi->bitrate_max=ai->bitrate_hard_max;
1088
0
          hi->bitrate_reservoir=ai->bitrate_hard_window*
1089
0
            (hi->bitrate_max+hi->bitrate_min)*.5;
1090
0
        }
1091
0
        if(hi->bitrate_reservoir<128.)
1092
0
          hi->bitrate_reservoir=128.;
1093
0
      }
1094
0
      return(0);
1095
0
1096
0
      /* replacement ratemanage interface */
1097
0
    case OV_ECTL_RATEMANAGE2_GET:
1098
0
      {
1099
0
        struct ovectl_ratemanage2_arg *ai=
1100
0
          (struct ovectl_ratemanage2_arg *)arg;
1101
0
        if(ai==NULL)return OV_EINVAL;
1102
0
1103
0
        ai->management_active=hi->managed;
1104
0
        ai->bitrate_limit_min_kbps=hi->bitrate_min/1000;
1105
0
        ai->bitrate_limit_max_kbps=hi->bitrate_max/1000;
1106
0
        ai->bitrate_average_kbps=hi->bitrate_av/1000;
1107
0
        ai->bitrate_average_damping=hi->bitrate_av_damp;
1108
0
        ai->bitrate_limit_reservoir_bits=hi->bitrate_reservoir;
1109
0
        ai->bitrate_limit_reservoir_bias=hi->bitrate_reservoir_bias;
1110
0
      }
1111
0
      return (0);
1112
0
    case OV_ECTL_RATEMANAGE2_SET:
1113
0
      {
1114
0
        struct ovectl_ratemanage2_arg *ai=
1115
0
          (struct ovectl_ratemanage2_arg *)arg;
1116
0
        if(ai==NULL){
1117
0
          hi->managed=0;
1118
0
        }else{
1119
0
          /* sanity check; only catch invariant violations */
1120
0
          if(ai->bitrate_limit_min_kbps>0 &&
1121
0
             ai->bitrate_average_kbps>0 &&
1122
0
             ai->bitrate_limit_min_kbps>ai->bitrate_average_kbps)
1123
0
            return OV_EINVAL;
1124
0
1125
0
          if(ai->bitrate_limit_max_kbps>0 &&
1126
0
             ai->bitrate_average_kbps>0 &&
1127
0
             ai->bitrate_limit_max_kbps<ai->bitrate_average_kbps)
1128
0
            return OV_EINVAL;
1129
0
1130
0
          if(ai->bitrate_limit_min_kbps>0 &&
1131
0
             ai->bitrate_limit_max_kbps>0 &&
1132
0
             ai->bitrate_limit_min_kbps>ai->bitrate_limit_max_kbps)
1133
0
            return OV_EINVAL;
1134
0
1135
0
          if(ai->bitrate_average_damping <= 0.)
1136
0
            return OV_EINVAL;
1137
0
1138
0
          if(ai->bitrate_limit_reservoir_bits < 0)
1139
0
            return OV_EINVAL;
1140
0
1141
0
          if(ai->bitrate_limit_reservoir_bias < 0.)
1142
0
            return OV_EINVAL;
1143
0
1144
0
          if(ai->bitrate_limit_reservoir_bias > 1.)
1145
0
            return OV_EINVAL;
1146
0
1147
0
          hi->managed=ai->management_active;
1148
0
          hi->bitrate_min=ai->bitrate_limit_min_kbps * 1000;
1149
0
          hi->bitrate_max=ai->bitrate_limit_max_kbps * 1000;
1150
0
          hi->bitrate_av=ai->bitrate_average_kbps * 1000;
1151
0
          hi->bitrate_av_damp=ai->bitrate_average_damping;
1152
0
          hi->bitrate_reservoir=ai->bitrate_limit_reservoir_bits;
1153
0
          hi->bitrate_reservoir_bias=ai->bitrate_limit_reservoir_bias;
1154
0
        }
1155
0
      }
1156
0
      return 0;
1157
0
1158
0
    case OV_ECTL_LOWPASS_GET:
1159
0
      {
1160
0
        double *farg=(double *)arg;
1161
0
        *farg=hi->lowpass_kHz;
1162
0
      }
1163
0
      return(0);
1164
0
    case OV_ECTL_LOWPASS_SET:
1165
0
      {
1166
0
        double *farg=(double *)arg;
1167
0
        hi->lowpass_kHz=*farg;
1168
0
1169
0
        if(hi->lowpass_kHz<2.)hi->lowpass_kHz=2.;
1170
0
        if(hi->lowpass_kHz>99.)hi->lowpass_kHz=99.;
1171
0
        hi->lowpass_altered=1;
1172
0
      }
1173
0
      return(0);
1174
0
    case OV_ECTL_IBLOCK_GET:
1175
0
      {
1176
0
        double *farg=(double *)arg;
1177
0
        *farg=hi->impulse_noisetune;
1178
0
      }
1179
0
      return(0);
1180
0
    case OV_ECTL_IBLOCK_SET:
1181
0
      {
1182
0
        double *farg=(double *)arg;
1183
0
        hi->impulse_noisetune=*farg;
1184
0
1185
0
        if(hi->impulse_noisetune>0.)hi->impulse_noisetune=0.;
1186
0
        if(hi->impulse_noisetune<-15.)hi->impulse_noisetune=-15.;
1187
0
      }
1188
0
      return(0);
1189
0
    case OV_ECTL_COUPLING_GET:
1190
0
      {
1191
0
        int *iarg=(int *)arg;
1192
0
        *iarg=hi->coupling_p;
1193
0
      }
1194
0
      return(0);
1195
0
    case OV_ECTL_COUPLING_SET:
1196
0
      {
1197
0
        const void *new_template;
1198
0
        double new_base=0.;
1199
0
        int *iarg=(int *)arg;
1200
0
        hi->coupling_p=((*iarg)!=0);
1201
0
1202
0
        /* Fetching a new template can alter the base_setting, which
1203
0
           many other parameters are based on.  Right now, the only
1204
0
           parameter drawn from the base_setting that can be altered
1205
0
           by an encctl is the lowpass, so that is explictly flagged
1206
0
           to not be overwritten when we fetch a new template and
1207
0
           recompute the dependant settings */
1208
0
        new_template = get_setup_template(hi->coupling_p?vi->channels:-1,
1209
0
                                          vi->rate,
1210
0
                                          hi->req,
1211
0
                                          hi->managed,
1212
0
                                          &new_base);
1213
0
        if(!hi->setup)return OV_EIMPL;
1214
0
        hi->setup=new_template;
1215
0
        hi->base_setting=new_base;
1216
0
        vorbis_encode_setup_setting(vi,vi->channels,vi->rate);
1217
0
      }
1218
0
      return(0);
1219
0
    }
1220
0
    return(OV_EIMPL);
1221
0
  }
1222
0
  return(OV_EINVAL);
1223
0
}