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