Line data Source code
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 : last mod: $Id$
15 :
16 : ********************************************************************/
17 :
18 : #include <stdlib.h>
19 : #include <string.h>
20 : #include <math.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 0 : 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 : 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 : {
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 : }
214 : }
215 :
216 0 : for(i=0;i<=maxbook;i++)
217 0 : ci->book_param[ci->books++]=(static_codebook *)books[x[is]][i];
218 : }
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 : }
227 :
228 0 : static void vorbis_encode_global_psych_setup(vorbis_info *vi,double s,
229 : const vorbis_info_psy_global *in,
230 : 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 : }
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 : }
251 0 : g->ampmax_att_per_sec=ci->hi.amplitude_track_dBpersec;
252 0 : return;
253 : }
254 :
255 0 : static void vorbis_encode_global_stereo(vorbis_info *vi,
256 : const highlevel_encode_setup *const hi,
257 : 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 : }
281 : }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 : }
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 : }
294 : }
295 : }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 : }
300 : }
301 0 : return;
302 : }
303 :
304 0 : 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 : 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 : }
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 : }
330 :
331 0 : return;
332 : }
333 :
334 0 : static void vorbis_encode_tonemask_setup(vorbis_info *vi,double s,int block,
335 : const att3 *att,
336 : const int *max,
337 : 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 : }
357 :
358 :
359 0 : static void vorbis_encode_compand_setup(vorbis_info *vi,double s,int block,
360 : const compandblock *in,
361 : 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 : }
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 : }
380 :
381 0 : static void vorbis_encode_peak_setup(vorbis_info *vi,double s,int block,
382 : 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 : }
392 :
393 0 : 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 : 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 : }
420 : }
421 :
422 0 : return;
423 : }
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 : }
433 :
434 :
435 0 : static int book_dup_or_new(codec_setup_info *ci,const static_codebook *book){
436 : 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 : }
442 :
443 0 : static void vorbis_encode_blocksize_setup(vorbis_info *vi,double s,
444 : 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 0 : static void vorbis_encode_residue_setup(vorbis_info *vi,
457 : int number, int block,
458 : const vorbis_residue_template *res){
459 :
460 0 : codec_setup_info *ci=vi->codec_setup;
461 : 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 : {
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 : }
492 : }
493 : }
494 :
495 : }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 : }
512 : }
513 : }
514 : }
515 : }
516 :
517 : /* lowpass setup/pointlimit */
518 : {
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 : case 1: /* point stereo limited */
535 0 : if(ci->hi.managed)
536 0 : freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS-1]*1000.;
537 : else
538 0 : freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS/2]*1000.;
539 0 : if(freq>nyq)freq=nyq;
540 0 : break;
541 : case 2: /* LFE channel; lowpass at ~ 250Hz */
542 0 : freq=250;
543 0 : break;
544 : default:
545 : /* already set */
546 0 : break;
547 : }
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 : }
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 : }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 : }
582 :
583 0 : if(r->end==0)r->end=r->grouping; /* LFE channel */
584 :
585 : }
586 0 : }
587 :
588 : /* we assume two maps in this encoder */
589 0 : static void vorbis_encode_map_n_res_setup(vorbis_info *vi,double s,
590 : 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 : }
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 : }
632 :
633 0 : static const void *get_setup_template(long ch,long srate,
634 : double req,int q_or_bitrate,
635 : 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 : else{
659 0 : float low=map[j];
660 0 : float high=map[j+1];
661 0 : float del=(req-low)/(high-low);
662 0 : *base_setting=j+del;
663 : }
664 :
665 0 : return(setup_list[i]);
666 : }
667 : }
668 0 : i++;
669 : }
670 :
671 0 : return NULL;
672 : }
673 :
674 : /* encoders will need to use vorbis_info_init beforehand and call
675 : vorbis_info clear when all done */
676 :
677 : /* two interfaces; this, more detailed one, and later a convenience
678 : layer on top */
679 :
680 : /* the final setup call */
681 0 : int vorbis_encode_setup_init(vorbis_info *vi){
682 0 : int i,i0=0,singleblock=0;
683 0 : codec_setup_info *ci=vi->codec_setup;
684 0 : ve_setup_data_template *setup=NULL;
685 0 : highlevel_encode_setup *hi=&ci->hi;
686 :
687 0 : if(ci==NULL)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 : setup->blocksize_short,
711 : 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 : setup->floor_books,
719 : 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 : setup->global_params,
725 : 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 : setup->psy_noise_normal_start[0],
731 : setup->psy_noise_normal_partition[0],
732 : setup->psy_noise_normal_thresh,
733 : 0);
734 0 : vorbis_encode_psyset_setup(vi,hi->base_setting,
735 : setup->psy_noise_normal_start[0],
736 : setup->psy_noise_normal_partition[0],
737 : setup->psy_noise_normal_thresh,
738 : 1);
739 0 : if(!singleblock){
740 0 : vorbis_encode_psyset_setup(vi,hi->base_setting,
741 : setup->psy_noise_normal_start[1],
742 : setup->psy_noise_normal_partition[1],
743 : setup->psy_noise_normal_thresh,
744 : 2);
745 0 : vorbis_encode_psyset_setup(vi,hi->base_setting,
746 : setup->psy_noise_normal_start[1],
747 : setup->psy_noise_normal_partition[1],
748 : setup->psy_noise_normal_thresh,
749 : 3);
750 : }
751 :
752 : /* tone masking setup */
753 0 : vorbis_encode_tonemask_setup(vi,hi->block[i0].tone_mask_setting,0,
754 : setup->psy_tone_masteratt,
755 : setup->psy_tone_0dB,
756 : setup->psy_tone_adj_impulse);
757 0 : vorbis_encode_tonemask_setup(vi,hi->block[1].tone_mask_setting,1,
758 : setup->psy_tone_masteratt,
759 : setup->psy_tone_0dB,
760 : setup->psy_tone_adj_other);
761 0 : if(!singleblock){
762 0 : vorbis_encode_tonemask_setup(vi,hi->block[2].tone_mask_setting,2,
763 : setup->psy_tone_masteratt,
764 : setup->psy_tone_0dB,
765 : setup->psy_tone_adj_other);
766 0 : vorbis_encode_tonemask_setup(vi,hi->block[3].tone_mask_setting,3,
767 : setup->psy_tone_masteratt,
768 : setup->psy_tone_0dB,
769 : setup->psy_tone_adj_long);
770 : }
771 :
772 : /* noise companding setup */
773 0 : vorbis_encode_compand_setup(vi,hi->block[i0].noise_compand_setting,0,
774 : setup->psy_noise_compand,
775 : setup->psy_noise_compand_short_mapping);
776 0 : vorbis_encode_compand_setup(vi,hi->block[1].noise_compand_setting,1,
777 : setup->psy_noise_compand,
778 : 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 : setup->psy_noise_compand,
782 : setup->psy_noise_compand_long_mapping);
783 0 : vorbis_encode_compand_setup(vi,hi->block[3].noise_compand_setting,3,
784 : setup->psy_noise_compand,
785 : setup->psy_noise_compand_long_mapping);
786 : }
787 :
788 : /* peak guarding setup */
789 0 : vorbis_encode_peak_setup(vi,hi->block[i0].tone_peaklimit_setting,0,
790 : setup->psy_tone_dBsuppress);
791 0 : vorbis_encode_peak_setup(vi,hi->block[1].tone_peaklimit_setting,1,
792 : setup->psy_tone_dBsuppress);
793 0 : if(!singleblock){
794 0 : vorbis_encode_peak_setup(vi,hi->block[2].tone_peaklimit_setting,2,
795 : setup->psy_tone_dBsuppress);
796 0 : vorbis_encode_peak_setup(vi,hi->block[3].tone_peaklimit_setting,3,
797 : setup->psy_tone_dBsuppress);
798 : }
799 :
800 : /* noise bias setup */
801 0 : vorbis_encode_noisebias_setup(vi,hi->block[i0].noise_bias_setting,0,
802 : setup->psy_noise_dBsuppress,
803 : setup->psy_noise_bias_impulse,
804 : setup->psy_noiseguards,
805 : (i0==0?hi->impulse_noisetune:0.));
806 0 : vorbis_encode_noisebias_setup(vi,hi->block[1].noise_bias_setting,1,
807 : setup->psy_noise_dBsuppress,
808 : setup->psy_noise_bias_padding,
809 : setup->psy_noiseguards,0.);
810 0 : if(!singleblock){
811 0 : vorbis_encode_noisebias_setup(vi,hi->block[2].noise_bias_setting,2,
812 : setup->psy_noise_dBsuppress,
813 : setup->psy_noise_bias_trans,
814 : setup->psy_noiseguards,0.);
815 0 : vorbis_encode_noisebias_setup(vi,hi->block[3].noise_bias_setting,3,
816 : setup->psy_noise_dBsuppress,
817 : setup->psy_noise_bias_long,
818 : setup->psy_noiseguards,0.);
819 : }
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 : }
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 : else{
834 0 : vi->bitrate_nominal=setting_to_approx_bitrate(vi);
835 : }
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 : 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 : }
856 :
857 0 : return(0);
858 :
859 : }
860 :
861 0 : static void vorbis_encode_setup_setting(vorbis_info *vi,
862 : long channels,
863 : long rate){
864 : 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 : 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 : }
900 0 : }
901 :
902 0 : int vorbis_encode_setup_vbr(vorbis_info *vi,
903 : long channels,
904 : long rate,
905 : float quality){
906 : codec_setup_info *ci;
907 : 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 : }
926 :
927 0 : int vorbis_encode_init_vbr(vorbis_info *vi,
928 : long channels,
929 : long rate,
930 :
931 : float base_quality /* 0. to 1. */
932 : ){
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 : }
941 0 : ret=vorbis_encode_setup_init(vi);
942 0 : if(ret)
943 0 : vorbis_info_clear(vi);
944 0 : return(ret);
945 : }
946 :
947 0 : int vorbis_encode_setup_managed(vorbis_info *vi,
948 : long channels,
949 : long rate,
950 :
951 : long max_bitrate,
952 : long nominal_bitrate,
953 : long min_bitrate){
954 :
955 : codec_setup_info *ci;
956 : highlevel_encode_setup *hi;
957 : 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 : else
969 0 : nominal_bitrate=max_bitrate*.875;
970 : }else{
971 0 : if(min_bitrate>0.){
972 0 : nominal_bitrate=min_bitrate;
973 : }else{
974 0 : return(OV_EINVAL);
975 : }
976 : }
977 : }
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 : }
998 :
999 0 : int vorbis_encode_init(vorbis_info *vi,
1000 : long channels,
1001 : long rate,
1002 :
1003 : long max_bitrate,
1004 : long nominal_bitrate,
1005 : long min_bitrate){
1006 :
1007 0 : int ret=vorbis_encode_setup_managed(vi,channels,rate,
1008 : max_bitrate,
1009 : nominal_bitrate,
1010 : min_bitrate);
1011 0 : if(ret){
1012 0 : vorbis_info_clear(vi);
1013 0 : return(ret);
1014 : }
1015 :
1016 0 : ret=vorbis_encode_setup_init(vi);
1017 0 : if(ret)
1018 0 : vorbis_info_clear(vi);
1019 0 : return(ret);
1020 : }
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 : case OV_ECTL_RATEMANAGE_GET:
1034 : {
1035 :
1036 0 : struct ovectl_ratemanage_arg *ai=
1037 : (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 : }
1049 0 : return(0);
1050 :
1051 : /* now deprecated *****************/
1052 : case OV_ECTL_RATEMANAGE_SET:
1053 : {
1054 0 : struct ovectl_ratemanage_arg *ai=
1055 : (struct ovectl_ratemanage_arg *)arg;
1056 0 : if(ai==NULL){
1057 0 : hi->managed=0;
1058 : }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 : }
1063 : }
1064 0 : return 0;
1065 :
1066 : /* now deprecated *****************/
1067 : case OV_ECTL_RATEMANAGE_AVG:
1068 : {
1069 0 : struct ovectl_ratemanage_arg *ai=
1070 : (struct ovectl_ratemanage_arg *)arg;
1071 0 : if(ai==NULL){
1072 0 : hi->bitrate_av=0;
1073 : }else{
1074 0 : hi->bitrate_av=(ai->bitrate_av_lo+ai->bitrate_av_hi)*.5;
1075 : }
1076 : }
1077 0 : return(0);
1078 : /* now deprecated *****************/
1079 : case OV_ECTL_RATEMANAGE_HARD:
1080 : {
1081 0 : struct ovectl_ratemanage_arg *ai=
1082 : (struct ovectl_ratemanage_arg *)arg;
1083 0 : if(ai==NULL){
1084 0 : hi->bitrate_min=0;
1085 0 : hi->bitrate_max=0;
1086 : }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 : }
1092 0 : if(hi->bitrate_reservoir<128.)
1093 0 : hi->bitrate_reservoir=128.;
1094 : }
1095 0 : return(0);
1096 :
1097 : /* replacement ratemanage interface */
1098 : case OV_ECTL_RATEMANAGE2_GET:
1099 : {
1100 0 : struct ovectl_ratemanage2_arg *ai=
1101 : (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 : }
1112 0 : return (0);
1113 : case OV_ECTL_RATEMANAGE2_SET:
1114 : {
1115 0 : struct ovectl_ratemanage2_arg *ai=
1116 : (struct ovectl_ratemanage2_arg *)arg;
1117 0 : if(ai==NULL){
1118 0 : hi->managed=0;
1119 : }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 : }
1156 : }
1157 0 : return 0;
1158 :
1159 : case OV_ECTL_LOWPASS_GET:
1160 : {
1161 0 : double *farg=(double *)arg;
1162 0 : *farg=hi->lowpass_kHz;
1163 : }
1164 0 : return(0);
1165 : case OV_ECTL_LOWPASS_SET:
1166 : {
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 : }
1174 0 : return(0);
1175 : case OV_ECTL_IBLOCK_GET:
1176 : {
1177 0 : double *farg=(double *)arg;
1178 0 : *farg=hi->impulse_noisetune;
1179 : }
1180 0 : return(0);
1181 : case OV_ECTL_IBLOCK_SET:
1182 : {
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 : }
1189 0 : return(0);
1190 : case OV_ECTL_COUPLING_GET:
1191 : {
1192 0 : int *iarg=(int *)arg;
1193 0 : *iarg=hi->coupling_p;
1194 : }
1195 0 : return(0);
1196 : case OV_ECTL_COUPLING_SET:
1197 : {
1198 : 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 : vi->rate,
1211 0 : hi->req,
1212 : hi->managed,
1213 : &new_base);
1214 0 : if(!hi->setup)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 : }
1219 0 : return(0);
1220 : }
1221 0 : return(OV_EIMPL);
1222 : }
1223 0 : return(OV_EINVAL);
1224 : }
|