Add Russian translation provided by Валерий Крувялис <valkru@mail.ru>
[xiph-mirror.git] / vorbis-tools / oggenc / encode.c
blob33d5a36776d02d0e00d4aceff3b3dbdf6c91e7ca
1 /* OggEnc
2 **
3 ** This program is distributed under the GNU General Public License, version 2.
4 ** A copy of this license is included with this source.
5 **
6 ** Copyright 2000-2002, Michael Smith <msmith@xiph.org>
7 **
8 ** Portions from Vorbize, (c) Kenneth Arnold <kcarnold-xiph@arnoldnet.net>
9 ** and libvorbis examples, (c) Monty <monty@xiph.org>
10 **/
12 #ifdef HAVE_CONFIG_H
13 #include <config.h>
14 #endif
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <math.h>
19 #include <string.h>
20 #include <time.h>
22 #include "platform.h"
23 #include <vorbis/vorbisenc.h>
24 #include "encode.h"
25 #include "i18n.h"
26 #include "skeleton.h"
28 #ifdef HAVE_KATE
29 #include "lyrics.h"
30 #include <kate/oggkate.h>
31 #endif
33 #define READSIZE 1024
36 int oe_write_page(ogg_page *page, FILE *fp);
38 #define SETD(toset) \
39 do {\
40 if(sscanf(opts[i].val, "%lf", &dval) != 1)\
41 fprintf(stderr, "For option %s, couldn't read value %s as double\n",\
42 opts[i].arg, opts[i].val);\
43 else\
44 toset = dval;\
45 } while(0)
47 #define SETL(toset) \
48 do {\
49 if(sscanf(opts[i].val, "%ld", &lval) != 1)\
50 fprintf(stderr, "For option %s, couldn't read value %s as integer\n",\
51 opts[i].arg, opts[i].val);\
52 else\
53 toset = lval;\
54 } while(0)
56 static void set_advanced_encoder_options(adv_opt *opts, int count,
57 vorbis_info *vi)
59 #ifdef OV_ECTL_RATEMANAGE2_GET
60 int manage = 0;
61 struct ovectl_ratemanage2_arg ai;
62 int i;
63 double dval;
64 long lval;
66 vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE2_GET, &ai);
68 for(i=0; i < count; i++) {
69 if(opts[i].val)
70 fprintf(stderr, _("Setting advanced encoder option \"%s\" to %s\n"),
71 opts[i].arg, opts[i].val);
72 else
73 fprintf(stderr, _("Setting advanced encoder option \"%s\"\n"),
74 opts[i].arg);
76 if(!strcmp(opts[i].arg, "bitrate_average_damping")) {
77 SETD(ai.bitrate_average_damping);
78 manage = 1;
80 else if(!strcmp(opts[i].arg, "bitrate_average")) {
81 SETL(ai.bitrate_average_kbps);
82 manage = 1;
84 else if(!strcmp(opts[i].arg, "bit_reservoir_bias")) {
85 SETD(ai.bitrate_limit_reservoir_bias);
86 manage = 1;
88 else if(!strcmp(opts[i].arg, "bit_reservoir_bits")) {
89 SETL(ai.bitrate_limit_reservoir_bits);
90 manage = 1;
92 else if(!strcmp(opts[i].arg, "bitrate_hard_min")) {
93 SETL(ai.bitrate_limit_min_kbps);
94 manage = 1;
96 else if(!strcmp(opts[i].arg, "bitrate_hard_max")) {
97 SETL(ai.bitrate_limit_max_kbps);
98 manage = 1;
100 else if(!strcmp(opts[i].arg, "disable_coupling")) {
101 int val=0;
102 vorbis_encode_ctl(vi, OV_ECTL_COUPLING_SET, &val);
104 else if(!strcmp(opts[i].arg, "impulse_noisetune")) {
105 double val;
106 SETD(val);
107 vorbis_encode_ctl(vi, OV_ECTL_IBLOCK_SET, &val);
109 else if(!strcmp(opts[i].arg, "lowpass_frequency")) {
110 double prev, new;
111 SETD(new);
112 vorbis_encode_ctl(vi, OV_ECTL_LOWPASS_GET, &prev);
113 vorbis_encode_ctl(vi, OV_ECTL_LOWPASS_SET, &new);
114 fprintf(stderr, _("Changed lowpass frequency from %f kHz to %f kHz\n"), prev, new);
116 else {
117 fprintf(stderr, _("Unrecognised advanced option \"%s\"\n"),
118 opts[i].arg);
122 if(manage) {
123 if(vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE2_SET, &ai)) {
124 fprintf(stderr, _("Failed to set advanced rate management parameters\n"));
127 #else
128 fprintf(stderr,_( "This version of libvorbisenc cannot set advanced rate management parameters\n"));
129 #endif
132 static void add_fishead_packet (ogg_stream_state *os) {
134 fishead_packet fp;
136 memset(&fp, 0, sizeof(fp));
137 fp.ptime_n = 0;
138 fp.ptime_d = 1000;
139 fp.btime_n = 0;
140 fp.btime_d = 1000;
142 add_fishead_to_stream(os, &fp);
146 * Adds the fishead packets in the skeleton output stream
148 static void add_vorbis_fisbone_packet (ogg_stream_state *os, oe_enc_opt *opt) {
150 fisbone_packet fp;
152 memset(&fp, 0, sizeof(fp));
153 fp.serial_no = opt->serialno;
154 fp.nr_header_packet = 3;
155 fp.granule_rate_n = opt->rate;
156 fp.granule_rate_d = 1;
157 fp.start_granule = 0;
158 fp.preroll = 2;
159 fp.granule_shift = 0;
161 add_message_header_field(&fp, "Content-Type", "audio/vorbis");
163 add_fisbone_to_stream(os, &fp);
166 #ifdef HAVE_KATE
167 static void add_kate_fisbone_packet (ogg_stream_state *os, oe_enc_opt *opt, kate_info *ki) {
169 fisbone_packet fp;
171 memset(&fp, 0, sizeof(fp));
172 fp.serial_no = opt->kate_serialno;
173 fp.nr_header_packet = ki->num_headers;
174 fp.granule_rate_n = ki->gps_numerator;
175 fp.granule_rate_d = ki->gps_denominator;
176 fp.start_granule = 0;
177 fp.preroll = 0;
178 fp.granule_shift = ki->granule_shift;
180 add_message_header_field(&fp, "Content-Type", "application/x-kate");
182 add_fisbone_to_stream(os, &fp);
184 #endif
186 #ifdef HAVE_KATE
187 static void add_kate_karaoke_style(kate_info *ki,unsigned char r,unsigned char g,unsigned char b,unsigned char a)
189 kate_style *ks;
190 int ret;
192 if (!ki) return;
194 ks=(kate_style*)malloc(sizeof(kate_style));
195 kate_style_init(ks);
196 ks->text_color.r = r;
197 ks->text_color.g = g;
198 ks->text_color.b = b;
199 ks->text_color.a = a;
200 ret=kate_info_add_style(ki,ks);
201 if (ret<0) {
202 fprintf(stderr, _("WARNING: failed to add Kate karaoke style\n"));
205 #endif
207 int oe_encode(oe_enc_opt *opt)
210 ogg_stream_state os;
211 ogg_stream_state so; /* stream for skeleton bitstream */
212 ogg_stream_state ko; /* stream for kate bitstream */
213 ogg_page og;
214 ogg_packet op;
216 vorbis_dsp_state vd;
217 vorbis_block vb;
218 vorbis_info vi;
220 #ifdef HAVE_KATE
221 kate_info ki;
222 kate_comment kc;
223 kate_state k;
224 oe_lyrics *lyrics=NULL;
225 size_t lyrics_index=0;
226 double vorbis_time = 0.0;
227 #endif
229 long samplesdone=0;
230 int eos;
231 long bytes_written = 0, packetsdone=0;
232 double time_elapsed;
233 int ret=0;
234 TIMER *timer;
235 int result;
237 if(opt->channels > 255) {
238 fprintf(stderr, _("255 channels should be enough for anyone. (Sorry, but Vorbis doesn't support more)\n"));
239 return 1;
242 /* get start time. */
243 timer = timer_start();
245 if(!opt->managed && (opt->min_bitrate>=0 || opt->max_bitrate>=0)){
246 fprintf(stderr, _("Requesting a minimum or maximum bitrate requires --managed\n"));
247 return 1;
250 /* if we had no quality or bitrate spec at all from the user, use
251 the default quality with no management --Monty 20020711 */
252 if(opt->bitrate < 0 && opt->min_bitrate < 0 && opt->max_bitrate < 0){
253 opt->quality_set=1;
256 opt->start_encode(opt->infilename, opt->filename, opt->bitrate, opt->quality,
257 opt->quality_set, opt->managed, opt->min_bitrate, opt->max_bitrate);
259 /* Have vorbisenc choose a mode for us */
260 vorbis_info_init(&vi);
262 if(opt->quality_set > 0){
263 if(vorbis_encode_setup_vbr(&vi, opt->channels, opt->rate, opt->quality)){
264 fprintf(stderr, _("Mode initialisation failed: invalid parameters for quality\n"));
265 vorbis_info_clear(&vi);
266 return 1;
269 /* do we have optional hard bitrate restrictions? */
270 if(opt->max_bitrate > 0 || opt->min_bitrate > 0){
271 #ifdef OV_ECTL_RATEMANAGE2_GET
272 long bitrate;
273 struct ovectl_ratemanage2_arg ai;
275 vorbis_encode_ctl(&vi, OV_ECTL_RATEMANAGE2_GET, &ai);
277 /* libvorbis 1.1 (and current svn) doesn't actually fill this in,
278 which looks like a bug. It'll then reject it when we call the
279 SET version below. So, fill it in with the values that libvorbis
280 would have used to fill in this structure if we were using the
281 bitrate-oriented setup functions. Unfortunately, some of those
282 values are dependent on the bitrate, and libvorbis has no way to
283 get a nominal bitrate from a quality value. Well, except by doing
284 a full setup... So, we do that.
285 Also, note that this won't work correctly unless you have
286 version 1.1.1 or later of libvorbis.
290 vorbis_info vi2;
291 vorbis_info_init(&vi2);
292 vorbis_encode_setup_vbr(&vi2, opt->channels, opt->rate, opt->quality);
293 vorbis_encode_setup_init(&vi2);
294 bitrate = vi2.bitrate_nominal;
295 vorbis_info_clear(&vi2);
298 ai.bitrate_average_kbps = bitrate/1000;
299 ai.bitrate_average_damping = 1.5;
300 ai.bitrate_limit_reservoir_bits = bitrate * 2;
301 ai.bitrate_limit_reservoir_bias = .1;
303 /* And now the ones we actually wanted to set */
304 ai.bitrate_limit_min_kbps=opt->min_bitrate;
305 ai.bitrate_limit_max_kbps=opt->max_bitrate;
306 ai.management_active=1;
308 if(vorbis_encode_ctl(&vi, OV_ECTL_RATEMANAGE2_SET, &ai) == 0)
309 fprintf(stderr, _("Set optional hard quality restrictions\n"));
310 else {
311 fprintf(stderr, _("Failed to set bitrate min/max in quality mode\n"));
312 vorbis_info_clear(&vi);
313 return 1;
315 #else
316 fprintf(stderr, _("This version of libvorbisenc cannot set advanced rate management parameters\n"));
317 return 1;
318 #endif
322 }else {
323 if(vorbis_encode_setup_managed(&vi, opt->channels, opt->rate,
324 opt->max_bitrate>0?opt->max_bitrate*1000:-1,
325 opt->bitrate*1000,
326 opt->min_bitrate>0?opt->min_bitrate*1000:-1)){
327 fprintf(stderr, _("Mode initialisation failed: invalid parameters for bitrate\n"));
328 vorbis_info_clear(&vi);
329 return 1;
333 #ifdef OV_ECTL_RATEMANAGE2_SET
334 if(opt->managed && opt->bitrate < 0)
336 struct ovectl_ratemanage2_arg ai;
337 vorbis_encode_ctl(&vi, OV_ECTL_RATEMANAGE2_GET, &ai);
338 ai.bitrate_average_kbps=-1;
339 vorbis_encode_ctl(&vi, OV_ECTL_RATEMANAGE2_SET, &ai);
341 else if(!opt->managed)
343 /* Turn off management entirely (if it was turned on). */
344 vorbis_encode_ctl(&vi, OV_ECTL_RATEMANAGE2_SET, NULL);
346 #endif
348 set_advanced_encoder_options(opt->advopt, opt->advopt_count, &vi);
350 vorbis_encode_setup_init(&vi);
353 /* Now, set up the analysis engine, stream encoder, and other
354 preparation before the encoding begins.
357 vorbis_analysis_init(&vd,&vi);
358 vorbis_block_init(&vd,&vb);
360 #ifdef HAVE_KATE
361 if (opt->lyrics) {
362 /* load lyrics */
363 lyrics=load_lyrics(opt->lyrics);
364 /* if it fails, don't do anything else for lyrics */
365 if (!lyrics) {
366 opt->lyrics = NULL;
367 } else {
368 /* init kate for encoding */
369 kate_info_init(&ki);
370 kate_info_set_category(&ki, "LRC");
371 if (opt->lyrics_language)
372 kate_info_set_language(&ki, opt->lyrics_language);
373 else
374 fprintf(stderr, _("WARNING: no language specified for %s\n"), opt->lyrics);
375 kate_comment_init(&kc);
376 kate_encode_init(&k,&ki);
378 /* if we're in karaoke mode (we have syllable level timing info),
379 add style info in case some graphical player is used */
380 add_kate_karaoke_style(&ki, 255, 255, 255, 255);
381 add_kate_karaoke_style(&ki, 255, 128, 128, 255);
384 #endif
386 ogg_stream_init(&os, opt->serialno);
387 if (opt->with_skeleton)
388 ogg_stream_init(&so, opt->skeleton_serialno);
389 if (opt->lyrics)
390 ogg_stream_init(&ko, opt->kate_serialno);
392 /* create the skeleton fishead packet and output it */
393 if (opt->with_skeleton) {
394 add_fishead_packet(&so);
395 if ((ret = flush_ogg_stream_to_file(&so, opt->out))) {
396 opt->error(_("Failed writing fishead packet to output stream\n"));
397 goto cleanup;
401 /* Now, build the three header packets and send through to the stream
402 output stage (but defer actual file output until the main encode loop) */
405 ogg_packet header_main;
406 ogg_packet header_comments;
407 ogg_packet header_codebooks;
409 /* Build the packets */
410 vorbis_analysis_headerout(&vd,opt->comments,
411 &header_main,&header_comments,&header_codebooks);
413 /* And stream them out */
414 /* output the vorbis bos first, then the kate bos, then the fisbone packets */
415 ogg_stream_packetin(&os,&header_main);
416 while((result = ogg_stream_flush(&os, &og)))
418 if(!result) break;
419 ret = oe_write_page(&og, opt->out);
420 if(ret != og.header_len + og.body_len)
422 opt->error(_("Failed writing header to output stream\n"));
423 ret = 1;
424 goto cleanup; /* Bail and try to clean up stuff */
428 #ifdef HAVE_KATE
429 if (opt->lyrics) {
430 ogg_packet kate_op;
431 ret = kate_ogg_encode_headers(&k, &kc, &kate_op);
432 if (ret < 0) {
433 opt->error(_("Failed encoding Kate header\n"));
434 goto cleanup;
436 ogg_stream_packetin(&ko,&kate_op);
437 while((result = ogg_stream_flush(&ko, &og)))
439 if(!result) break;
440 ret = oe_write_page(&og, opt->out);
441 if(ret != og.header_len + og.body_len)
443 opt->error(_("Failed writing header to output stream\n"));
444 ret = 1;
445 goto cleanup; /* Bail and try to clean up stuff */
448 ogg_packet_clear(&kate_op);
450 #endif
452 if (opt->with_skeleton) {
453 add_vorbis_fisbone_packet(&so, opt);
454 if ((ret = flush_ogg_stream_to_file(&so, opt->out))) {
455 opt->error(_("Failed writing fisbone header packet to output stream\n"));
456 goto cleanup;
458 #ifdef HAVE_KATE
459 if (opt->lyrics) {
460 add_kate_fisbone_packet(&so, opt, &ki);
461 if ((ret = flush_ogg_stream_to_file(&so, opt->out))) {
462 opt->error(_("Failed writing fisbone header packet to output stream\n"));
463 goto cleanup;
466 #endif
469 /* write the next Vorbis headers */
470 ogg_stream_packetin(&os,&header_comments);
471 ogg_stream_packetin(&os,&header_codebooks);
473 while((result = ogg_stream_flush(&os, &og)))
475 if(!result) break;
476 ret = oe_write_page(&og, opt->out);
477 if(ret != og.header_len + og.body_len)
479 opt->error(_("Failed writing header to output stream\n"));
480 ret = 1;
481 goto cleanup; /* Bail and try to clean up stuff */
486 /* build kate headers if requested */
487 #ifdef HAVE_KATE
488 if (opt->lyrics) {
489 while (kate_ogg_encode_headers(&k,&kc,&op)==0) {
490 ogg_stream_packetin(&ko,&op);
491 ogg_packet_clear(&op);
493 while((result = ogg_stream_flush(&ko, &og)))
495 if(!result) break;
496 ret = oe_write_page(&og, opt->out);
497 if(ret != og.header_len + og.body_len)
499 opt->error(_("Failed writing header to output stream\n"));
500 ret = 1;
501 goto cleanup; /* Bail and try to clean up stuff */
505 #endif
507 if (opt->with_skeleton) {
508 add_eos_packet_to_stream(&so);
509 if ((ret = flush_ogg_stream_to_file(&so, opt->out))) {
510 opt->error(_("Failed writing skeleton eos packet to output stream\n"));
511 goto cleanup;
515 eos = 0;
517 /* Main encode loop - continue until end of file */
518 while(!eos)
520 float **buffer = vorbis_analysis_buffer(&vd, READSIZE);
521 long samples_read = opt->read_samples(opt->readdata,
522 buffer, READSIZE);
524 if(samples_read ==0)
525 /* Tell the library that we wrote 0 bytes - signalling the end */
526 vorbis_analysis_wrote(&vd,0);
527 else
529 samplesdone += samples_read;
531 /* Call progress update every 40 pages */
532 if(packetsdone>=40)
534 double time;
536 packetsdone = 0;
537 time = timer_time(timer);
539 opt->progress_update(opt->filename, opt->total_samples_per_channel,
540 samplesdone, time);
543 /* Tell the library how many samples (per channel) we wrote
544 into the supplied buffer */
545 vorbis_analysis_wrote(&vd, samples_read);
548 /* While we can get enough data from the library to analyse, one
549 block at a time... */
550 while(vorbis_analysis_blockout(&vd,&vb)==1)
553 /* Do the main analysis, creating a packet */
554 vorbis_analysis(&vb, NULL);
555 vorbis_bitrate_addblock(&vb);
557 while(vorbis_bitrate_flushpacket(&vd, &op))
559 /* Add packet to bitstream */
560 ogg_stream_packetin(&os,&op);
561 packetsdone++;
563 /* If we've gone over a page boundary, we can do actual output,
564 so do so (for however many pages are available) */
566 while(!eos)
568 int result = ogg_stream_pageout(&os,&og);
569 if(!result) break;
571 /* now that we have a new Vorbis page, we scan lyrics for any that is due */
572 #ifdef HAVE_KATE
573 if (opt->lyrics && ogg_page_granulepos(&og)>=0) {
574 vorbis_time = vorbis_granule_time(&vd, ogg_page_granulepos(&og));
575 const oe_lyrics_item *item;
576 while ((item = get_lyrics(lyrics, vorbis_time, &lyrics_index))) {
577 ogg_packet kate_op;
578 if (item->km) {
579 ret = kate_encode_set_style_index(&k, 0);
580 if (ret < 0) {
581 opt->error(_("Failed encoding karaoke style - continuing anyway\n"));
583 ret = kate_encode_set_secondary_style_index(&k, 1);
584 if (ret < 0) {
585 opt->error(_("Failed encoding karaoke style - continuing anyway\n"));
587 ret = kate_encode_add_motion(&k, item->km, 0);
588 if (ret < 0) {
589 opt->error(_("Failed encoding karaoke motion - continuing anyway\n"));
592 ret = kate_ogg_encode_text(&k, item->t0, item->t1, item->text, strlen(item->text)+1, &kate_op);
593 if (ret < 0) {
594 opt->error(_("Failed encoding lyrics - continuing anyway\n"));
596 else {
597 ogg_stream_packetin(&ko, &kate_op);
598 ogg_packet_clear(&kate_op);
599 while (1) {
600 ogg_page ogk;
601 int result=ogg_stream_flush(&ko,&ogk);
602 if (!result) break;
603 ret = oe_write_page(&ogk, opt->out);
604 if(ret != ogk.header_len + ogk.body_len)
606 opt->error(_("Failed writing data to output stream\n"));
607 ret = 1;
608 goto cleanup; /* Bail */
610 else
611 bytes_written += ret;
616 #endif
618 ret = oe_write_page(&og, opt->out);
619 if(ret != og.header_len + og.body_len)
621 opt->error(_("Failed writing data to output stream\n"));
622 ret = 1;
623 goto cleanup; /* Bail */
625 else
626 bytes_written += ret;
628 if(ogg_page_eos(&og))
629 eos = 1;
635 /* if encoding lyrics, signal EOS and cleanup the kate state */
636 #ifdef HAVE_KATE
637 if (opt->lyrics) {
638 ogg_packet kate_op;
639 ret = kate_ogg_encode_finish(&k, vorbis_time, &kate_op);
640 if (ret < 0) {
641 opt->error(_("Failed encoding Kate EOS packet\n"));
643 else {
644 ogg_stream_packetin(&ko,&kate_op);
645 packetsdone++;
646 ogg_packet_clear(&kate_op);
648 eos = 0;
649 while(!eos)
651 int result = ogg_stream_pageout(&ko,&og);
652 if(!result) break;
654 ret = oe_write_page(&og, opt->out);
655 if(ret != og.header_len + og.body_len)
657 opt->error(_("Failed writing data to output stream\n"));
658 ret = 1;
659 goto cleanup; /* Bail */
661 else
662 bytes_written += ret;
664 if(ogg_page_eos(&og))
665 eos = 1;
669 #endif
671 ret = 0; /* Success. Set return value to 0 since other things reuse it
672 * for nefarious purposes. */
674 /* Cleanup time */
675 cleanup:
677 #ifdef HAVE_KATE
678 if (opt->lyrics) {
679 ogg_stream_clear(&ko);
680 kate_clear(&k);
681 kate_info_clear(&ki);
682 kate_comment_clear(&kc);
683 free_lyrics(lyrics);
685 #endif
687 if (opt->with_skeleton)
688 ogg_stream_clear(&so);
690 ogg_stream_clear(&os);
692 vorbis_block_clear(&vb);
693 vorbis_dsp_clear(&vd);
694 vorbis_info_clear(&vi);
696 time_elapsed = timer_time(timer);
697 opt->end_encode(opt->filename, time_elapsed, opt->rate, samplesdone, bytes_written);
699 timer_clear(timer);
701 return ret;
704 void update_statistics_full(char *fn, long total, long done, double time)
706 static char *spinner="|/-\\";
707 static int spinpoint = 0;
708 double remain_time;
709 int minutes=0,seconds=0;
711 remain_time = time/((double)done/(double)total) - time;
712 minutes = ((int)remain_time)/60;
713 seconds = (int)(remain_time - (double)((int)remain_time/60)*60);
715 fprintf(stderr, "\r");
716 fprintf(stderr, _("\t[%5.1f%%] [%2dm%.2ds remaining] %c "),
717 done*100.0/total, minutes, seconds, spinner[spinpoint++%4]);
720 void update_statistics_notime(char *fn, long total, long done, double time)
722 static char *spinner="|/-\\";
723 static int spinpoint =0;
725 fprintf(stderr, "\r");
726 fprintf(stderr, _("\tEncoding [%2dm%.2ds so far] %c "),
727 ((int)time)/60, (int)(time - (double)((int)time/60)*60),
728 spinner[spinpoint++%4]);
731 int oe_write_page(ogg_page *page, FILE *fp)
733 int written;
734 written = fwrite(page->header,1,page->header_len, fp);
735 written += fwrite(page->body,1,page->body_len, fp);
737 return written;
740 void final_statistics(char *fn, double time, int rate, long samples, long bytes)
742 double speed_ratio;
743 if(fn)
744 fprintf(stderr, _("\n\nDone encoding file \"%s\"\n"), fn);
745 else
746 fprintf(stderr, _("\n\nDone encoding.\n"));
748 speed_ratio = (double)samples / (double)rate / time;
750 fprintf(stderr, _("\n\tFile length: %dm %04.1fs\n"),
751 (int)(samples/rate/60),
752 samples/rate -
753 floor(samples/rate/60)*60);
754 fprintf(stderr, _("\tElapsed time: %dm %04.1fs\n"),
755 (int)(time/60),
756 time - floor(time/60)*60);
757 fprintf(stderr, _("\tRate: %.4f\n"), speed_ratio);
758 fprintf(stderr, _("\tAverage bitrate: %.1f kb/s\n\n"),
759 8./1000.*((double)bytes/((double)samples/(double)rate)));
762 void final_statistics_null(char *fn, double time, int rate, long samples,
763 long bytes)
765 /* Don't do anything, this is just a placeholder function for quiet mode */
768 void update_statistics_null(char *fn, long total, long done, double time)
770 /* So is this */
773 void encode_error(char *errmsg)
775 fprintf(stderr, "\n%s\n", errmsg);
778 static void print_brconstraints(int min, int max)
780 if(min > 0 && max > 0)
781 fprintf(stderr, _("(min %d kbps, max %d kbps)"), min,max);
782 else if(min > 0)
783 fprintf(stderr, _("(min %d kbps, no max)"), min);
784 else if(max > 0)
785 fprintf(stderr, _("(no min, max %d kbps)"), max);
786 else
787 fprintf(stderr, _("(no min or max)"));
790 void start_encode_full(char *fn, char *outfn, int bitrate, float quality, int qset,
791 int managed, int min, int max)
793 if(bitrate>0){
794 if(managed>0){
795 fprintf(stderr, _("Encoding %s%s%s to \n "
796 "%s%s%s \nat average bitrate %d kbps "),
797 fn?"\"":"", fn?fn:_("standard input"), fn?"\"":"",
798 outfn?"\"":"", outfn?outfn:_("standard output"), outfn?"\"":"",
799 bitrate);
800 print_brconstraints(min,max);
801 fprintf(stderr, ", \nusing full bitrate management engine\n");
802 } else {
803 fprintf(stderr, _("Encoding %s%s%s to \n %s%s%s \nat approximate bitrate %d kbps (VBR encoding enabled)\n"),
804 fn?"\"":"", fn?fn:_("standard input"), fn?"\"":"",
805 outfn?"\"":"", outfn?outfn:_("standard output"), outfn?"\"":"",
806 bitrate);
808 }else{
809 if(qset>0){
810 if(managed>0){
811 fprintf(stderr, _("Encoding %s%s%s to \n %s%s%s \nat quality level %2.2f using constrained VBR "),
812 fn?"\"":"", fn?fn:_("standard input"), fn?"\"":"",
813 outfn?"\"":"", outfn?outfn:_("standard output"), outfn?"\"":"",
814 quality * 10);
815 print_brconstraints(min,max);
816 fprintf(stderr, "\n");
817 }else{
818 fprintf(stderr, _("Encoding %s%s%s to \n %s%s%s \nat quality %2.2f\n"),
819 fn?"\"":"", fn?fn:_("standard input"), fn?"\"":"",
820 outfn?"\"":"", outfn?outfn:_("standard output"), outfn?"\"":"",
821 quality * 10);
823 }else{
824 fprintf(stderr, _("Encoding %s%s%s to \n %s%s%s \nusing bitrate management "),
825 fn?"\"":"", fn?fn:_("standard input"), fn?"\"":"",
826 outfn?"\"":"", outfn?outfn:_("standard output"), outfn?"\"":"");
827 print_brconstraints(min,max);
828 fprintf(stderr, "\n");
833 void start_encode_null(char *fn, char *outfn, int bitrate, float quality, int qset,
834 int managed, int min, int max)