[xiph-cvs] cvs commit: vorbis-tools/oggenc encode.c encode.h oggenc.c

Michael Smith msmith at xiph.org
Thu Sep 7 08:10:50 PDT 2000



msmith      00/09/07 08:10:49

  Modified:    oggenc   encode.c encode.h oggenc.c
  Log:
  Restructuring of lots of stuff, to make it better and generally neater.
  Couple of minor feature additions (--tracknum, --date, etc.)

Revision  Changes    Path
1.2       +56 -61    vorbis-tools/oggenc/encode.c

Index: encode.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/oggenc/encode.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- encode.c	2000/09/07 00:57:46	1.1
+++ encode.c	2000/09/07 15:10:49	1.2
@@ -21,7 +21,7 @@
 #define READSIZE 1024
 
 
-static void update_statistics(char *fn, long total, long done, double time,long counter);
+int oe_write_page(ogg_page *page, FILE *fp);
 
 int oe_encode(oe_enc_opt *opt)
 {
@@ -34,11 +34,10 @@
         vorbis_block     vb;
 
         long samplesdone=0;
-	long counter=0,counter2=0;
     int eos;
         long bytes_written = 0;
 
-	void *timer;
+	TIMER *timer;
 
 
         /* get start time. */
@@ -87,14 +86,14 @@
                 {
                         samplesdone += samples_read;
 
-			if((counter++%16==0) && !opt->quiet)
+			if(!opt->quiet)
                         {
                                 double time;
 
                                 time = timer_time(timer);
 
-				update_statistics(opt->filename, 
-						opt->total_samples_per_channel, samplesdone,time,counter2++);
+				opt->progress_update(opt->filename, opt->total_samples_per_channel, 
+						samplesdone, time);
                         }
 
                         /* Tell the library how many samples (per channel) we wrote 
@@ -121,11 +120,8 @@
                                 int result = ogg_stream_pageout(&os,&og);
                                 if(!result) break;
 
-				fwrite(og.header,1,og.header_len, opt->out);
-				fwrite(og.body,1,og.body_len, opt->out);
+				bytes_written += oe_write_page(&og, opt->out);
 
-				bytes_written += og.header_len + og.body_len;
-
                                 if(ogg_page_eos(&og))
                                         eos = 1;
                         }
@@ -141,27 +137,8 @@
 
         if(!opt->quiet)
         {
-		double time_elapsed, speed_ratio;
-		if(opt->filename)
-			fprintf(stderr, "\n\nDone encoding file \"%s\"\n", opt->filename);
-		else
-			fprintf(stderr, "\n\nDone encoding.\n");
-
-		time_elapsed = timer_time(timer);
-		speed_ratio = (double)opt->total_samples_per_channel / (double)opt->rate / time_elapsed;
-		
-
-		fprintf(stderr, "\n\tFile length:  %dm %04.1fs\n",
-				(int)(opt->total_samples_per_channel/opt->rate/60),
-				opt->total_samples_per_channel/opt->rate - 
-				floor(opt->total_samples_per_channel/opt->rate/60)*60);
-		fprintf(stderr, "\tElapsed time: %dm %04.1fs\n",
-				(int)(time_elapsed/60),
-				time_elapsed - floor(time_elapsed/60)*60);
-		fprintf(stderr, "\tRate:         %.4f\n", speed_ratio);
-		fprintf(stderr, "\tAverage bitrate: %.1f kb/s\n\n", 
-			8./1000.*((double)bytes_written/((double)opt->total_samples_per_channel/(double)opt->rate)));
-
+		double time_elapsed = timer_time(timer);
+		opt->end_encode(opt->filename, time_elapsed, opt->rate, samplesdone, bytes_written);
         }
 
         timer_clear(timer);
@@ -169,42 +146,60 @@
         return 0;
 }
 
-static void update_statistics(char *fn, long total, long done, double time,long counter)
+void update_statistics_full(char *fn, long total, long done, double time)
 {
-	static char *spinner="|/-\\";
+	static char *spinner="||||////----\\\\\\\\";
+	static int spinpoint = 0;
         double remain_time;
         int minutes=0,seconds=0;
+	
+	remain_time = time/((double)done/(double)total) - time;
+	minutes = ((int)remain_time)/60;
+	seconds = (int)(remain_time - (double)((int)remain_time/60)*60);
+
+	fprintf(stderr, "\rEncoding %s%s%s [%5.1f%%] [%2dm%.2ds remaining] %c", 
+			fn?"\"":"", fn?fn:"standard input", fn?"\"":"",
+			done*100.0/total, minutes, seconds, spinner[spinpoint++%16]);
+}
 
-	if(total)
-	{
-		remain_time = time/((double)done/(double)total) - time;
-		minutes = ((int)remain_time)/60;
-		seconds = (int)(remain_time - (float)((int)remain_time/60)*60);
-	}
+void update_statistics_notime(char *fn, long total, long done, double time)
+{
+	static char *spinner="||||////----\\\\\\\\";
+	static int spinpoint =0;
+	
+	fprintf(stderr, "\rEncoding %s%s%s %c", 
+			fn?"\"":"", fn?fn:"standard input", fn?"\"":"",
+			spinner[spinpoint++%16]);
+}
 
-	if(fn && total && time > 1.0)
-		fprintf(stderr, "\rEncoding \"%s\" [%5.1f%%] [%2dm%.2ds remaining] %c", fn, 
-				done*100.0/total, minutes, seconds,
-				spinner[counter%4]);
-	else if(fn && total)
-		fprintf(stderr, "\rEncoding \"%s\" [%5.1f%%] %c", fn, 
-				done*100.0/total,
-				spinner[counter%4]);
-	else if(fn)
-		fprintf(stderr, "\rEncoding \"%s\" [???%%] %c", fn, 
-				spinner[counter%4]);
-	else if(total && time > 1.0)
-		fprintf(stderr, "\rEncoding to standard output [%5.1f%%] [%dm%ds remaining] %c", 
-				done*100.0/total, minutes, seconds,
-				spinner[counter%4]);
-	else if(total)
-		fprintf(stderr, "\rEncoding to standard output [%5.1f%%] %c", 
-				done*100.0/total,
-				spinner[counter%4]);
-	else
-		fprintf(stderr, "\rEncoding to standard output [???%%] %c",
-				spinner[counter%4]);
+int oe_write_page(ogg_page *page, FILE *fp)
+{
+	fwrite(page->header,1,page->header_len, fp);
+	fwrite(page->body,1,page->body_len, fp);
+
+	return page->header_len+page->body_len;
 }
 
+void final_statistics(char *fn, double time, int rate, long samples, long bytes)
+{
+	double speed_ratio;
+	if(fn)
+		fprintf(stderr, "\n\nDone encoding file \"%s\"\n", fn);
+	else
+		fprintf(stderr, "\n\nDone encoding.\n");
+
+	speed_ratio = (double)samples / (double)rate / time;
+	
+	fprintf(stderr, "\n\tFile length:  %dm %04.1fs\n",
+			(int)(samples/rate/60),
+			samples/rate - 
+			floor(samples/rate/60)*60);
+	fprintf(stderr, "\tElapsed time: %dm %04.1fs\n",
+			(int)(time/60),
+			time - floor(time/60)*60);
+	fprintf(stderr, "\tRate:         %.4f\n", speed_ratio);
+	fprintf(stderr, "\tAverage bitrate: %.1f kb/s\n\n", 
+		8./1000.*((double)bytes/((double)samples/(double)rate)));
+}
 
 

1.2       +30 -6     vorbis-tools/oggenc/encode.h

Index: encode.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/oggenc/encode.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- encode.h	2000/09/07 00:57:46	1.1
+++ encode.h	2000/09/07 15:10:49	1.2
@@ -4,12 +4,32 @@
 #include <stdio.h>
 #include <vorbis/codec.h>
 
-typedef  long (*audio_read_func)(void *src, float **buffer, int samples);
+
+typedef void TIMER;
+typedef long (*audio_read_func)(void *src, float **buffer, int samples);
+typedef void (*progress_func)(char *fn, long totalsamples, 
+		long samples, double time);
+typedef void (*enc_end_func)(char *fn, double time, int rate, 
+		long samples, long bytes);
+
+
 void *timer_start(void);
 double timer_time(void *);
 void timer_clear(void *);
 
+void update_statistics_full(char *fn, long total, long done, double time);
+void update_statistics_notime(char *fn, long total, long done, double time);
+void final_statistics(char *fn, double time, int rate, long total_samples,
+		long bytes);
+
+typedef struct _taglist
+{
+	char *tag;
+	char *contents;
 
+	struct _taglist *next;
+} taglist;
+	
 typedef struct
 {
         char **title;
@@ -20,6 +40,10 @@
         int album_count;
         char **comments;
         int comment_count;
+	char **tracknum;
+	int track_count;
+	char **dates;
+	int date_count;
 
         int quiet;
         int rawmode;
@@ -33,21 +57,21 @@
 {
         vorbis_comment *comments;
         vorbis_info    *mode;
+	long serialno;
 
         audio_read_func read_samples;
+	progress_func progress_update;
+	enc_end_func end_encode;
+	
         void *readdata;
+
         long total_samples_per_channel;
         int channels;
         long rate;
 
         FILE *out;
         int quiet;
-	long serialno;
         char *filename;
-
-	char *artist;
-	char *album;
-	char *title;
 } oe_enc_opt;
 
 

1.2       +76 -33    vorbis-tools/oggenc/oggenc.c

Index: oggenc.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/oggenc/oggenc.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- oggenc.c	2000/09/07 00:57:47	1.1
+++ oggenc.c	2000/09/07 15:10:49	1.2
@@ -21,7 +21,7 @@
 #include "encode.h"
 #include "audio.h"
 
-#define VERSION_STRING "OggEnc v0.4\n"
+#define VERSION_STRING "OggEnc v0.5\n"
 #define CHUNK 4096 /* We do reads, etc. in multiples of this */
 
 /* Define supported formats here */
@@ -41,18 +41,22 @@
         {"output",1,0,'o'},
         {"version",0,0,'v'},
         {"raw",0,0,'r'},
-	{"mode",1,0,'m'}
+	{"mode",1,0,'m'},
+	{"date",1,0,'d'},
+	{"tracknum",1,0,'N'},
+	{NULL,0,0,0}
 };
         
-char *generate_name_string(char *format, char *artist, char *title, char *album);
+char *generate_name_string(char *format, char *artist, char *title, char *album, char *track, char *date);
 void parse_options(int argc, char **argv, oe_options *opt);
-void build_comments(vorbis_comment *vc, oe_options *opt, int filenum, oe_enc_opt *eopt);
+void build_comments(vorbis_comment *vc, oe_options *opt, int filenum, 
+		char **artist, char **album, char **title, char **tracknum, char **date);
 void usage(void);
 vorbis_info *choose_mode(int modenum, int channels);
 
 int main(int argc, char **argv)
 {
-	oe_options opt = {NULL, 0, NULL, 0, NULL, 0, NULL, 0, 
+	oe_options opt = {NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, 
                 0,0, NULL,NULL,0}; /* Default values */
         int i;
 
@@ -65,7 +69,7 @@
         if(optind >= argc)
         {
                 fprintf(stderr, "ERROR: No input files specified. Use -h for help.\n");
-		exit(1);
+		return 1;
         }
         else
         {
@@ -105,6 +109,7 @@
                 int foundformat = 0;
                 int closeout = 0, closein = 0;
                 int j=0;
+		char *artist=NULL, *album=NULL, *title=NULL, *track=NULL, *date=NULL;
 
 
 
@@ -112,12 +117,11 @@
 
                 enc_opts.serialno = nextserial++;
                 enc_opts.quiet = opt.quiet;
-		enc_opts.artist = NULL;
-		enc_opts.title = NULL;
-		enc_opts.album = NULL;
+		enc_opts.progress_update = update_statistics_full;
+		enc_opts.end_encode = final_statistics;
                 
                 /* OK, let's build the vorbis_comments structure */
-		build_comments(&vc, &opt, i, &enc_opts);
+		build_comments(&vc, &opt, i, &artist, &album, &title, &track, &date);
 
                 if(!strcmp(infiles[i], "-"))
                 {
@@ -156,25 +160,20 @@
                         }
                         else if(opt.namefmt)
                         {
-				out_fn = generate_name_string(opt.namefmt, enc_opts.artist, enc_opts.title, enc_opts.album);
+				out_fn = generate_name_string(opt.namefmt, artist, title, album, track,date);
                         }
                         else if(opt.title)
                         {
-				out_fn = malloc(strlen(enc_opts.title) + 5);
-				strcpy(out_fn, enc_opts.title);
+				out_fn = malloc(strlen(title) + 5);
+				strcpy(out_fn, title);
                                 strcat(out_fn, ".ogg");
                         }
                         else
                         {
                                 /* Create a filename from existing filename, replacing extension with .ogg */
                                 char *start, *end;
-
-				start = rindex(infiles[i], '/');
-				if(start)
-					start += 1; /* Skip over the / */
-				else
-					start = infiles[i];
 
+				start = infiles[i];
                                 end = rindex(infiles[i], '.');
                                 end = end?end:(start + strlen(infiles[i])+1);
                         
@@ -230,6 +229,8 @@
                 }
 
                 enc_opts.mode = choose_mode(opt.modenum, enc_opts.channels);
+		if(!enc_opts.total_samples_per_channel)
+			enc_opts.progress_update = update_statistics_notime;
 
                 if(!opt.quiet)
                         fprintf(stderr, "Encoding using encoder mode %d\n", opt.modenum?opt.modenum:3);
@@ -270,21 +271,26 @@
                 "\n"
                 " Naming:\n"
                 " -o, --output=fn      Write file to fn (only valid in single-file mode)\n"
-		" -n, --names=string   Produce filenames as this string, with %%a, %%t, %%l\n"
-		"                      replaced by artist, title, album respectively (see below\n"
-		"                      for specifying these). Note that this can be given as a \n"
-		"                      single string to specify a particular output filename.\n"
+		" -n, --names=string   Produce filenames as this string, with %%a, %%t, %%l,\n"
+		"                      %%n, %%d replaces by artist, title, album, track number,\n"
+		"                      and date, respectively (see below for specifying these).\n"
                 "                      %%%% gives a literal %%.\n"
                 " -c, --comment=c      Add the given string as an extra comment. This may be\n"
                 "                      used multiple times.\n"
+		" -d, --date           Date for track (usually date of performance)\n"
+		" -N, --tracknum       Track number for this track\n"
                 " -t, --title          Title for this track\n"
                 " -l, --album          Name of album\n"
                 " -a, --artist         Name of artist\n"
                 "                      If multiple input files are given, then multiple\n"
-		"                      instances of the previous three arguments will be used,\n"
+		"                      instances of the previous five arguments will be used,\n"
                 "                      in the order they are given. If fewer titles are\n"
                 "                      specified than files, OggEnc will print a warning, and\n"
-		"                      reuse the final one for the remaining files.\n"
+		"                      reuse the final one for the remaining files. If fewer\n"
+		"                      track numbers are given, the remaining files will be\n"
+		"                      unnumbered. For the others, the final tag will be reused\n"
+		"                      for all others without warning (so you can specify a date\n"
+		"                      once, for example, and have it used for all the files)\n"
                 "\n"
                 "INPUT FILES:\n"
                 " OggEnc input files must currently be 44.1kHz, 16 bit stereo WAV files.\n"
@@ -298,16 +304,17 @@
                 " OggEnc support multiple different modes. Each of these is a fully VBR mode,\n"
                 " but they vary in intended (average) bitrate. The following table shows \n"
                 " approximate average bitrates (note that mode 3 is the default)\n"
-		"     Mode    |    Bitrate\n"
+		"     Mode    |    Bitrate (stereo)\n"
                 "       1     |       N/A\n"
                 "       2     |    128 kbps\n"
-		"       3     |    160 kbps\n"
+		"      *3     |    160 kbps\n"
                 "       4     |    192 kbps\n"
                 "       5     |    256 kbps\n"
                 "       6     |    350 kbps\n\n");
 }
 
-char *generate_name_string(char *format, char *artist, char *title, char *album)
+char *generate_name_string(char *format, 
+		char *artist, char *title, char *album, char *track, char *date)
 {
         char *buffer;
         char *cur;
@@ -333,6 +340,10 @@
                                         strcat(buffer, artist?artist:"(none)");
                                         cur += strlen(artist?artist:"(none)");
                                         break;
+				case 'd':
+					strcat(buffer, date?date:"(none)");
+					cur += strlen(date?date:"(none)");
+					break;
                                 case 't':
                                         strcat(buffer, title?title:"(none)");
                                         cur += strlen(title?title:"(none)");
@@ -341,6 +352,10 @@
                                         strcat(buffer, album?album:"(none)");
                                         cur += strlen(album?album:"(none)");
                                         break;
+				case 'n':
+					strcat(buffer, track?track:"(none)");
+					cur += strlen(track?track:"(none)");
+					break;
                                 default:
                                         fprintf(stderr, "WARNING: Ignoring illegal escape character '%c' in name format\n", *(format - 1));
                                         break;
@@ -358,7 +373,7 @@
         int ret;
         int option_index = 1;
 
-	while((ret = getopt_long(argc, argv, "a:c:hl:m:n:o:qrt:v", 
+	while((ret = getopt_long(argc, argv, "a:c:d:hl:m:n:N:o:qrt:v", 
                                         long_options, &option_index)) != -1)
         {
                 switch(ret)
@@ -375,6 +390,10 @@
                                 opt->comments = realloc(opt->comments, (++opt->comment_count)*sizeof(char *));
                                 opt->comments[opt->comment_count - 1] = strdup(optarg);
                                 break;
+			case 'd':
+				opt->dates = realloc(opt->dates, (++opt->date_count)*sizeof(char *));
+				opt->dates[opt->date_count - 1] = strdup(optarg);
+				break;
                         case 'l':
                                 opt->album = realloc(opt->album, (++opt->album_count)*sizeof(char *));
                                 opt->album[opt->album_count - 1] = strdup(optarg);
@@ -416,6 +435,10 @@
                                 fprintf(stderr, VERSION_STRING);
                                 exit(0);
                                 break;
+			case 'N':
+				opt->tracknum = realloc(opt->tracknum, (++opt->track_count)*sizeof(char *));
+				opt->tracknum[opt->track_count - 1] = strdup(optarg);
+				break;
                         case '?':
                                 fprintf(stderr, "WARNING: Unknown option specified, ignoring->\n");
                                 break;
@@ -426,7 +449,8 @@
         }
 }
 
-void build_comments(vorbis_comment *vc, oe_options *opt, int filenum, oe_enc_opt *eopt)
+void build_comments(vorbis_comment *vc, oe_options *opt, int filenum, 
+		char **artist, char **album, char **title, char **tracknum, char **date)
 {
         int i;
 
@@ -446,7 +470,7 @@
                 else
                         i = filenum;
 
-		eopt->title = opt->title[i];
+		*title = opt->title[i];
                 vorbis_comment_add_tag(vc, "title", opt->title[i]);
         }
 
@@ -457,9 +481,20 @@
                 else
                         i = filenum;
         
-		eopt->artist = opt->artist[i];
+		*artist = opt->artist[i];
                 vorbis_comment_add_tag(vc, "artist", opt->artist[i]);
         }
+
+	if(opt->date_count)
+	{
+		if(filenum >= opt->date_count)
+			i = opt->date_count-1;
+		else
+			i = filenum;
+	
+		*date = opt->dates[i];
+		vorbis_comment_add_tag(vc, "date", opt->dates[i]);
+	}
         
         if(opt->album_count)
         {
@@ -470,9 +505,16 @@
                 else
                         i = filenum;
 
-		eopt->album = opt->album[i];	
+		*album = opt->album[i];	
                 vorbis_comment_add_tag(vc, "album", opt->album[i]);
         }
+
+	if(filenum < opt->track_count)
+	{
+		i = filenum;
+		*tracknum = opt->tracknum[i];
+		vorbis_comment_add_tag(vc, "tracknumber", opt->tracknum[i]);
+	}
 }
 
 vorbis_info *choose_mode(int modenum, int channels)
@@ -515,3 +557,4 @@
                                                            mono rather than stereo */
         return mode;
 }
+

--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list