add -T, --tag options
authorJosh Coalson <jcoalson@users.sourceforce.net>
Fri, 20 Sep 2002 05:53:10 +0000 (05:53 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Fri, 20 Sep 2002 05:53:10 +0000 (05:53 +0000)
doc/html/documentation.html
man/flac.1
man/flac.sgml
src/flac/Makefile.am
src/flac/Makefile.lite
src/flac/Makefile.vc
src/flac/encode.c
src/flac/encode.h
src/flac/main.c

index bca8e43..45e6682 100644 (file)
                                Skip over the first # of samples of the input.  This works for both encoding and decoding, but not testing.
                        </TD>
                </TR>
+               <TR>
+                       <TD NOWRAP ALIGN="RIGHT" VALIGN="TOP" BGCOLOR="#F4F4CC">
+                               <TT>--ogg</TT>
+                       </TD>
+                       <TD>
+                               When encoding, generate Ogg-FLAC output instead of native-FLAC.  Ogg-FLAC streams are FLAC streams wrapped in an Ogg transport layer.  The resulting file should have an '.ogg' extension and will still be decodable by <TT><B>flac</B></TT>.<P>
+                               When decoding, force the input to be treated as Ogg-FLAC.  This is useful when piping input from stdin or when the filename does not end in '.ogg'.
+                       </TD>
+               </TR>
+               <TR>
+                       <TD NOWRAP ALIGN="RIGHT" VALIGN="TOP" BGCOLOR="#F4F4CC">
+                               <TT>--serial-number=#</TT>
+                       </TD>
+                       <TD>
+                               When used with --ogg, specifies the serial number to use the for the FLAC stream.  When encoding and no serial number is given, flac uses '0'.  When decoding and no number is given, flac uses the serial number of the first page.<P>
+                       </TD>
+               </TR>
        </TABLE>
        </TD></TR></TABLE>
        </P>
                </TR>
                <TR>
                        <TD NOWRAP ALIGN="RIGHT" VALIGN="TOP" BGCOLOR="#F4F4CC">
-                               <TT>--ogg</TT>
-                       </TD>
-                       <TD>
-                               When encoding, generate Ogg-FLAC output instead of native-FLAC.  Ogg-FLAC streams are FLAC streams wrapped in an Ogg transport layer.  The resulting file should have an '.ogg' extension and will still be decodable by <TT><B>flac</B></TT>.<P>
-                               When decoding, force the input to be treated as Ogg-FLAC.  This is useful when piping input from stdin or when the filename does not end in '.ogg'.
-                       </TD>
-               </TR>
-               <TR>
-                       <TD NOWRAP ALIGN="RIGHT" VALIGN="TOP" BGCOLOR="#F4F4CC">
-                               <TT>--serial-number=#</TT>
-                       </TD>
-                       <TD>
-                               When used with --ogg, specifies the serial number to use the for the FLAC stream.  When encoding and no serial number is given, flac uses '0'.  When decoding and no number is given, flac uses the serial number of the first page.<P>
-                       </TD>
-               </TR>
-               <TR>
-                       <TD NOWRAP ALIGN="RIGHT" VALIGN="TOP" BGCOLOR="#F4F4CC">
                                <TT>--lax</TT>
                        </TD>
                        <TD>
                </TR>
                <TR>
                        <TD NOWRAP ALIGN="RIGHT" VALIGN="TOP" BGCOLOR="#F4F4CC">
+                               <TT>-T FIELD=VALUE</TT>, <TT>--tag=FIELD=VALUE</TT>
+                       </TD>
+                       <TD>
+                               Add a Vorbis comment.  The comment must adhere to the Vorbis comment spec; i.e. the FIELD must contain only legal characters, terminated by an 'equals' sign.  Make sure to quote the comment if necessary.  This option may appear more than once to add several comments.  NOTE: all tags will be added to all encoded files.
+                       </TD>
+               </TR>
+               <TR>
+                       <TD NOWRAP ALIGN="RIGHT" VALIGN="TOP" BGCOLOR="#F4F4CC">
                                <TT>-b #</TT>, <TT>--blocksize=#</TT>
                        </TD>
                        <TD>
index cb7e99c..6499ad7 100644 (file)
@@ -3,7 +3,7 @@
 .\" <http://shell.ipoline.com/~elmert/comp/docbook2X/> 
 .\" Please send any bug reports, improvements, comments, patches, 
 .\" etc. to Steve Cheng <steve@ggi-project.org>.
-.TH "FLAC" "1" "03 September 2002" "" ""
+.TH "FLAC" "1" "19 September 2002" "" ""
 .SH NAME
 flac \- Free Lossless Audio Codec
 .SH SYNOPSIS
@@ -75,6 +75,24 @@ is left intact.
 Skip the specified number of samples at the
 beginning of the input file (can be used for both
 encoding and decoding)
+.TP
+\fB--ogg\fR
+When encoding, generate Ogg-FLAC output instead
+of native-FLAC.  Ogg-FLAC streams are FLAC streams
+wrapped in an Ogg transport layer.  The resulting
+file should have an '.ogg' extension and will still
+be decodable by flac.
+
+When decoding, force the input to be treated as
+Ogg-FLAC.  This is useful when piping input from
+stdin or when the filename does not end in '.ogg'.
+.TP
+\fB--serial-number=\fI#\fB\fR
+When used with --ogg, specifies the serial
+number to use for the FLAC stream.  When encoding and
+no serial number is given, flac uses '0'.  When
+decoding and no number is given, flac uses the serial
+number of the first page.
 .SS "ANALYSIS OPTIONS"
 .TP
 \fB--residual-text \fR
@@ -104,24 +122,6 @@ Verify a correct encoding by decoding the
 output in parallel and comparing to the
 original
 .TP
-\fB--ogg\fR
-When encoding, generate Ogg-FLAC output instead
-of native-FLAC.  Ogg-FLAC streams are FLAC streams
-wrapped in an Ogg transport layer.  The resulting
-file should have an '.ogg' extension and will still
-be decodable by flac.
-
-When decoding, force the input to be treated as
-Ogg-FLAC.  This is useful when piping input from
-stdin or when the filename does not end in '.ogg'.
-.TP
-\fB--ogg=\fI#\fB\fR
-When used with --ogg, specifies the serial
-number to use for the FLAC stream.  When encoding and
-no serial number is given, flac uses '0'.  When
-decoding and no number is given, flac uses the serial
-number of the first page.
-.TP
 \fB--lax\fR
 Allow encoder to generate non-Subset
 files.
@@ -161,6 +161,15 @@ the length given because of the 4 metadata block
 header bytes.  You can force no PADDING block at
 all to be written with -P-, which is the default.
 .TP
+\fB-T \fIFIELD=VALUE\fB, --tag=\fIFIELD=VALUE\fB\fR
+Add a Vorbis comment.  The comment must adhere
+to the Vorbis comment spec; i.e. the FIELD must
+contain only legal characters, terminated by an
+\&'equals' sign.  Make sure to quote the comment if
+necessary.  This option may appear more than once
+to add several comments.  NOTE: all tags will be
+added to all encoded files.
+.TP
 \fB-b \fI#\fB, --blocksize=\fI#\fB\fR
 Specify the block size in samples.  The
 default is 1152 for -l 0, else 4608; must be one of
index 120b342..9aa1660 100644 (file)
@@ -4,7 +4,7 @@
   <!ENTITY dhfirstname "<firstname>Matt</firstname>">
   <!ENTITY dhsurname   "<surname>Zimmerman</surname>">
   <!-- Please adjust the date whenever revising the manpage. -->
-  <!ENTITY dhdate      "<date>September 3, 2002</date>">
+  <!ENTITY dhdate      "<date>September 19, 2002</date>">
   <!-- SECTION should be 1-8, maybe w/ subsection other parameters are
        allowed: see man(7), man(1). -->
   <!ENTITY dhsection   "<manvolnum>1</manvolnum>">
                </listitem>
              </varlistentry>
 
+             <varlistentry>
+               <term><option>--ogg</option></term>
+
+               <listitem>
+                 <para>When encoding, generate Ogg-FLAC output instead
+                   of native-FLAC.  Ogg-FLAC streams are FLAC streams
+                   wrapped in an Ogg transport layer.  The resulting
+                   file should have an '.ogg' extension and will still
+                   be decodable by flac.</para>
+                 <para>When decoding, force the input to be treated as
+                   Ogg-FLAC.  This is useful when piping input from
+                   stdin or when the filename does not end in '.ogg'.</para>
+               </listitem>
+             </varlistentry>
+
+             <varlistentry>
+               <term><option>--serial-number</option>=<replaceable>#</replaceable></term>
+
+               <listitem>
+                 <para>When used with --ogg, specifies the serial
+                   number to use for the FLAC stream.  When encoding and
+                   no serial number is given, flac uses '0'.  When
+                   decoding and no number is given, flac uses the serial
+                   number of the first page.</para>
+               </listitem>
+             </varlistentry>
+
            </variablelist>
          </refsect2>
 
              </varlistentry>
 
              <varlistentry>
-               <term><option>--ogg</option></term>
-
-               <listitem>
-                 <para>When encoding, generate Ogg-FLAC output instead
-                   of native-FLAC.  Ogg-FLAC streams are FLAC streams
-                   wrapped in an Ogg transport layer.  The resulting
-                   file should have an '.ogg' extension and will still
-                   be decodable by flac.</para>
-                 <para>When decoding, force the input to be treated as
-                   Ogg-FLAC.  This is useful when piping input from
-                   stdin or when the filename does not end in '.ogg'.</para>
-               </listitem>
-             </varlistentry>
-
-             <varlistentry>
-               <term><option>--ogg</option>=<replaceable>#</replaceable></term>
-
-               <listitem>
-                 <para>When used with --ogg, specifies the serial
-                   number to use for the FLAC stream.  When encoding and
-                   no serial number is given, flac uses '0'.  When
-                   decoding and no number is given, flac uses the serial
-                   number of the first page.</para>
-               </listitem>
-             </varlistentry>
-
-             <varlistentry>
                <term><option>--lax</option></term>
 
                <listitem>
              </varlistentry>
 
              <varlistentry>
+               <term><option>-T</option> <replaceable>FIELD=VALUE</replaceable>, <option>--tag</option>=<replaceable>FIELD=VALUE</replaceable></term>
+
+               <listitem>
+                 <para>Add a Vorbis comment.  The comment must adhere
+                   to the Vorbis comment spec; i.e. the FIELD must
+                   contain only legal characters, terminated by an
+                   'equals' sign.  Make sure to quote the comment if
+                   necessary.  This option may appear more than once
+                   to add several comments.  NOTE: all tags will be
+                   added to all encoded files.</para>
+               </listitem>
+             </varlistentry>
+
+             <varlistentry>
                <term><option>-b</option> <replaceable>#</replaceable>, <option>--blocksize</option>=<replaceable>#</replaceable></term>
 
                <listitem>
index cc77b73..ab8d1a6 100644 (file)
@@ -32,9 +32,11 @@ flac_SOURCES = \
        encode.c \
        file.c \
        main.c \
+       vorbiscomment.c \
        analyze.h \
        decode.h \
        encode.h \
-       file.h
+       file.h \
+       vorbiscomment.h
 
 flac_LDADD = $(NEED_OGGFLAC_LIB) $(top_builddir)/src/libFLAC/libFLAC.la @OGG_LIBS@ @SHARE_LIBS@ -lm
index 3984457..fc3088f 100644 (file)
 PROGRAM_NAME = flac
 ifeq ($(DARWIN_BUILD),yes)
 INCLUDES     = -I./include -I../../include
-LIBS         = -lFLAC -lgetopt -lc -lm
+LIBS         = -lFLAC -lgetopt -lutf8 -lc -lm
 else
 #@@@ TODO: conditionalize ogg includes, defines, and -logg
 ifeq ($(SOLARIS_BUILD),yes)
 INCLUDES     = -I./include -I../../include -I$(HOME)/local/include -DFLAC__HAS_OGG
-LIBS         = -lOggFLAC -lFLAC -lgetopt -lm -L$(HOME)/local/lib -logg
+LIBS         = -lOggFLAC -lFLAC -lgetopt -lutf8 -lm -L$(HOME)/local/lib -logg
 else
 #@@@ TODO: conditionalize ogg includes, defines, and -logg
 INCLUDES     = -I./include -I../../include -I$(HOME)/local/include -DFLAC__HAS_OGG
-LIBS         = -lOggFLAC -lFLAC -lgetopt -lm -L$(HOME)/local/lib -logg
+LIBS         = -lOggFLAC -lFLAC -lgetopt -lutf8 -lm -L$(HOME)/local/lib -logg
 endif
 endif
 
@@ -40,7 +40,8 @@ OBJS = \
        decode.o \
        encode.o \
        file.o \
-       main.o
+       main.o \
+       vorbiscomment.o
 
 include ../../build/exe.mk
 
index 19f1200..6bfe5f7 100644 (file)
@@ -32,14 +32,15 @@ C_FILES= \
        decode.c \\r
        encode.c \\r
        file.c \\r
-       main.c\r
+       main.c \\r
+       vorbiscomment.c\r
 \r
 OBJS= $(C_FILES:.c=.obj)\r
 \r
 all: flac.exe\r
 \r
 flac.exe: $(OBJS)\r
-       link.exe /libpath:"..\..\obj\lib" -out:../../obj/bin/$*.exe $(OBJS) libOggFLAC.lib libFLAC.lib ogg_static.lib getopt.lib\r
+       link.exe /libpath:"..\..\obj\lib" -out:../../obj/bin/$*.exe $(OBJS) libOggFLAC.lib libFLAC.lib ogg_static.lib getopt.lib utf8.lib\r
 \r
 clean:\r
        -del *.obj *.pch\r
index b29a54f..2300d26 100644 (file)
@@ -1154,7 +1154,7 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
 {
        unsigned num_metadata;
        FLAC__StreamMetadata padding;
-       FLAC__StreamMetadata *metadata[2];
+       FLAC__StreamMetadata *metadata[3];
 
        if(channels != 2)
                options.do_mid_side = options.loose_mid_side = false;
@@ -1165,6 +1165,7 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
        }
 
        num_metadata = 0;
+       metadata[num_metadata++] = options.vorbis_comment;
        if(e->seek_table_template->data.seek_table.num_points > 0) {
                e->seek_table_template->is_last = false; /* the encoder will set this for us */
                metadata[num_metadata++] = e->seek_table_template;
index 5838a13..a675ab5 100644 (file)
@@ -19,7 +19,7 @@
 #ifndef flac__encode_h
 #define flac__encode_h
 
-#include "FLAC/ordinals.h"
+#include "FLAC/metadata.h"
 
 typedef struct {
        FLAC__bool verbose;
@@ -51,6 +51,8 @@ typedef struct {
        FLAC__int32 **align_reservoir;
        unsigned *align_reservoir_samples;
        FLAC__bool sector_align;
+
+       FLAC__StreamMetadata *vorbis_comment;
 } encode_options_t;
 
 typedef struct {
index 6241fab..ac5d8b5 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <ctype.h>
+#include <locale.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -32,6 +33,7 @@
 #include "decode.h"
 #include "encode.h"
 #include "file.h"
+#include "vorbiscomment.h"
 
 #if 0
 /*[JEC] was:#if HAVE_GETOPT_LONG*/
@@ -45,7 +47,7 @@ typedef enum { RAW, WAV, AIF } FileFormat;
 
 static int do_it();
 
-static void init_options();
+static FLAC__bool init_options();
 static int parse_options(int argc, char *argv[]);
 static int parse_option(int short_option, const char *long_option, const char *option_argument);
 static void free_options();
@@ -93,6 +95,7 @@ static struct FLAC__share__option long_options_[] = {
        /*
         * encoding options
         */
+       { "tag", 1, 0, 'T' },
        { "compression-level-0", 0, 0, '0' },
        { "compression-level-1", 0, 0, '1' },
        { "compression-level-2", 0, 0, '2' },
@@ -221,6 +224,8 @@ static struct {
 
        unsigned num_files;
        char **filenames;
+
+       FLAC__StreamMetadata *vorbis_comment;
 } option_values;
 
 
@@ -239,10 +244,15 @@ int main(int argc, char *argv[])
 {
        int retval = 0;
 
-       init_options();
-
-       if((retval = parse_options(argc, argv)) == 0)
-               retval = do_it();
+       setlocale(LC_ALL, "");
+       if(!init_options()) {
+               fprintf(stderr, "ERROR: allocating memory\n");
+               retval = 1;
+       }
+       else {
+               if((retval = parse_options(argc, argv)) == 0)
+                       retval = do_it();
+       }
 
        free_options();
 
@@ -434,7 +444,7 @@ int do_it()
        return retval;
 }
 
-void init_options()
+FLAC__bool init_options()
 {
        option_values.show_help = false;
        option_values.show_explain = false;
@@ -479,6 +489,11 @@ void init_options()
 
        option_values.num_files = 0;
        option_values.filenames = 0;
+
+       if(0 == (option_values.vorbis_comment = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT)))
+               return false;
+
+       return true;
 }
 
 int parse_options(int argc, char *argv[])
@@ -487,7 +502,7 @@ int parse_options(int argc, char *argv[])
        int option_index = 1;
        FLAC__bool had_error = false;
        /*@@@ E and R: are deprecated */
-       const char *short_opts = "0123456789ab:cdeFhHl:mMo:pP:q:r:sS:tvV";
+       const char *short_opts = "0123456789ab:cdeFhHl:mMo:pP:q:r:sS:tT:vV";
 
        while ((short_option = FLAC__share__getopt_long(argc, argv, short_opts, long_options_, &option_index)) != -1) {
                switch (short_option) {
@@ -664,6 +679,7 @@ int parse_option(int short_option, const char *long_option, const char *option_a
                }
        }
        else {
+               const char *violation;
                switch(short_option) {
                        case 'h':
                                option_values.show_help = true;
@@ -698,6 +714,11 @@ int parse_option(int short_option, const char *long_option, const char *option_a
                        case 'F':
                                option_values.continue_through_decode_errors = true;
                                break;
+                       case 'T':
+                               FLAC__ASSERT(0 != option_argument);
+                               if(!flac__vorbiscomment_add(option_values.vorbis_comment, option_argument, &violation))
+                                       return usage_error("ERROR: (-T/--tag) %s\n", violation);
+                               break;
                        case '0':
                                option_values.do_exhaustive_model_search = false;
                                option_values.do_escape_coding = false;
@@ -867,6 +888,8 @@ void free_options()
 {
        if(0 != option_values.filenames)
                free(option_values.filenames);
+       if(0 != option_values.vorbis_comment)
+               FLAC__metadata_object_delete(option_values.vorbis_comment);
 }
 
 int usage_error(const char *message, ...)
@@ -975,6 +998,7 @@ void show_help()
        printf("      --sector-align           Align multiple files on sector boundaries\n");
        printf("  -S, --seekpoint={#|X|#x}     Add seek point(s)\n");
        printf("  -P, --padding=#              Write a PADDING block of length #\n");
+       printf("  -T, --tag=FIELD=VALUE        Add a Vorbis comment; may appear multiple times\n");
        printf("  -0, --compression-level-0, --fast  Synonymous with -l 0 -b 1152 -r 2,2\n");
        printf("  -1, --compression-level-1          Synonymous with -l 0 -b 1152 -M -r 2,2\n");
        printf("  -2, --compression-level-2          Synonymous with -l 0 -b 1152 -m -r 3\n");
@@ -1145,6 +1169,10 @@ void show_explain()
        printf("                               576, 1152, 2304, 4608, 256, 512, 1024, 2048,\n");
        printf("                               4096, 8192, 16384, or 32768 (unless --lax is\n");
        printf("                               used)\n");
+       printf("  -T, --tag=FIELD=VALUE        Add a Vorbis comment.  Make sure to quote the\n");
+       printf("                               comment if necessary.  This option may appear\n");
+       printf("                               more than once to add several comments.  NOTE:\n");
+       printf("                               all tags will be added to all encoded files.\n");
        printf("  -0, --compression-level-0, --fast  Synonymous with -l 0 -b 1152 -r 2,2\n");
        printf("  -1, --compression-level-1          Synonymous with -l 0 -b 1152 -M -r 2,2\n");
        printf("  -2, --compression-level-2          Synonymous with -l 0 -b 1152 -m -r 3\n");
@@ -1334,6 +1362,7 @@ int encode_file(const char *infilename, const char *forced_outfilename, FLAC__bo
        common_options.align_reservoir = align_reservoir;
        common_options.align_reservoir_samples = &align_reservoir_samples;
        common_options.sector_align = option_values.sector_align;
+       common_options.vorbis_comment = option_values.vorbis_comment;
 
        if(fmt == RAW) {
                raw_encode_options_t options;