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