[xiph-cvs] cvs commit: vorbis-tools/oggenc easyflac.c easyflac.h flac.c flac.h Makefile.am audio.c encode.h oggenc.c

Stan Seibert volsung at xiph.org
Sun Aug 24 14:22:47 PDT 2003



volsung     03/08/24 17:22:47

  Modified:    .        configure.in
               oggenc   Makefile.am audio.c encode.h oggenc.c
  Added:       oggenc   easyflac.c easyflac.h flac.c flac.h
  Log:
  FLAC read support for oggenc.  Comments from the FLAC are preserved by
  default.
  
  Special thanks to OldMan, adiabatic, and smack from #vorbis for sponsoring
  this feature.

Revision  Changes    Path
1.51      +21 -4     vorbis-tools/configure.in

Index: configure.in
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/configure.in,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -r1.50 -r1.51
--- configure.in	6 Aug 2003 21:51:35 -0000	1.50
+++ configure.in	24 Aug 2003 21:22:46 -0000	1.51
@@ -133,9 +133,9 @@
   have_libFLAC=no, [$FLAC_LIBS]
 )
 AC_CHECK_LIB(OggFLAC, [OggFLAC__stream_decoder_new],
-  [FLAC_LIBS="-lOggFLAC $FLAC_LIBS"],
+  [FLAC_LIBS="-lOggFLAC $FLAC_LIBS $OGG_LIBS"],
   AC_MSG_WARN([libOggFLAC missing])
-  have_libFLAC=no, [$FLAC_LIBS]
+  have_libFLAC=no, [$FLAC_LIBS $OGG_LIBS]
 )
 AC_CHECK_HEADER(FLAC/stream_decoder.h,,
   AC_MSG_WARN(libFLAC headers missing)
@@ -209,10 +209,13 @@
   OPT_SUBDIRS="$OPT_SUBDIRS ogg123"
   if test "x$have_libFLAC" = xyes; then
     OGG123_FLAC_OBJS='flac_format.$(OBJEXT) easyflac.$(OBJEXT)'
+    OGGENC_FLAC_OBJS='flac.$(OBJEXT) easyflac.$(OBJEXT)'
   else
     OGG123_FLAC_OBJS=''
+    OGGENC_FLAC_OBJS=''
   fi
   AC_SUBST(OGG123_FLAC_OBJS)
+  AC_SUBST(OGGENC_FLAC_OBJS)
   if test "x$have_libspeex" = xyes; then
     OGG123_SPEEX_OBJS='speex_format.$(OBJEXT)'
   else
@@ -249,8 +252,22 @@
 
 AC_OUTPUT(Makefile intl/Makefile po/Makefile.in include/Makefile share/Makefile win32/Makefile oggdec/Makefile oggenc/Makefile oggenc/man/Makefile ogg123/Makefile vorbiscomment/Makefile vcut/Makefile ogginfo/Makefile debian/Makefile)
 
+if test "x$build_oggenc" = xyes -a "x$have_libFLAC" != xyes; then
+    AC_MSG_WARN([FLAC and OggFLAC libraries or headers missing, oggenc 
+will NOT be built with FLAC read support.])
+fi
+
 if test "x$build_ogg123" != xyes; then
     AC_MSG_WARN([Prerequisites for ogg123 not met, ogg123 will be skipped.
-    Please ensure that you have POSIX threads, libcurl and libao libraries and
-    headers present if you would like to build ogg123.])
+Please ensure that you have POSIX threads, libcurl and libao libraries and
+headers present if you would like to build ogg123.])
+else
+    if test "x$have_libFLAC" != xyes; then
+        AC_MSG_WARN([FLAC and OggFLAC libraries or headers missing, ogg123 
+will NOT be built with FLAC read support.])
+    fi
+    if test "x$have_libspeex" != xyes; then
+        AC_MSG_WARN([Speex libraries or headers missing, ogg123 will NOT be 
+built with FLAC read support.])
+    fi         
 fi

<p><p>1.23      +7 -7      vorbis-tools/oggenc/Makefile.am

Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/oggenc/Makefile.am,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- Makefile.am	24 Jun 2003 02:29:32 -0000	1.22
+++ Makefile.am	24 Aug 2003 21:22:46 -0000	1.23
@@ -4,9 +4,6 @@
 
 SUBDIRS = man
 
-oggencsources = oggenc.c audio.c encode.c platform.c \
-                 audio.h encode.h platform.h resample.c resample.h
-
 datadir = @datadir@
 localedir = $(datadir)/locale
 DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@
@@ -15,13 +12,16 @@
 
 INCLUDES = @SHARE_CFLAGS@ @OGG_CFLAGS@ @VORBIS_CFLAGS@ @I18N_CFLAGS@
 
-oggenc_LDADD = @SHARE_LIBS@ \
+oggenc_LDADD = @OGGENC_FLAC_OBJS@ @SHARE_LIBS@ \
                @VORBISENC_LIBS@ @VORBIS_LIBS@ @OGG_LIBS@ \
-	       @LIBICONV@ @I18N_LIBS@
-oggenc_DEPENDENCIES = @SHARE_LIBS@
+	       @LIBICONV@ @I18N_LIBS@ @FLAC_LIBS@
 
-oggenc_SOURCES = $(oggencsources)
+oggenc_DEPENDENCIES = @OGGENC_FLAC_OBJS@ @SHARE_LIBS@
+
+oggenc_SOURCES = oggenc.c audio.c encode.c platform.c \
+                 audio.h encode.h platform.h resample.c resample.h
 
+EXTRA_oggenc_SOURCES = flac.c flac.h easyflac.c easyflac.h
 
 debug:
         $(MAKE) all CFLAGS="@DEBUG@"

<p><p>1.33      +8 -0      vorbis-tools/oggenc/audio.c

Index: audio.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/oggenc/audio.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -r1.32 -r1.33
--- audio.c	29 Mar 2003 13:15:26 -0000	1.32
+++ audio.c	24 Aug 2003 21:22:46 -0000	1.33
@@ -19,6 +19,10 @@
 #include "i18n.h"
 #include "resample.h"
 
+#ifdef HAVE_LIBFLAC
+#include "flac.h"
+#endif
+
 #define WAV_HEADER_SIZE 44
 
 /* Macros to read header data */
@@ -38,6 +42,10 @@
 input_format formats[] = {
         {wav_id, 12, wav_open, wav_close, "wav", N_("WAV file reader")},
         {aiff_id, 12, aiff_open, wav_close, "aiff", N_("AIFF/AIFC file reader")},
+#ifdef HAVE_LIBFLAC
+	{flac_id,     4, flac_open, flac_close, "flac", N_("FLAC file reader")},
+	{oggflac_id, 32, flac_open, flac_close, "ogg", N_("Ogg FLAC file reader")},
+#endif
         {NULL, 0, NULL, NULL, NULL, NULL}
 };
 

<p><p>1.23      +2 -0      vorbis-tools/oggenc/encode.h

Index: encode.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/oggenc/encode.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- encode.h	7 Nov 2002 10:18:32 -0000	1.22
+++ encode.h	24 Aug 2003 21:22:46 -0000	1.23
@@ -56,6 +56,7 @@
         int genre_count;
     adv_opt *advopt;
     int advopt_count;
+	int copy_comments;
 
         int quiet;
 
@@ -106,6 +107,7 @@
         int samplesize;
     int endianness;
     int resamplefreq;
+	int copy_comments;
 
         /* Various bitrate/quality options */
     int managed;

<p><p>1.72      +9 -2      vorbis-tools/oggenc/oggenc.c

Index: oggenc.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/oggenc/oggenc.c,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -r1.71 -r1.72
--- oggenc.c	29 Mar 2003 13:15:26 -0000	1.71
+++ oggenc.c	24 Aug 2003 21:22:46 -0000	1.72
@@ -60,6 +60,7 @@
     {"downmix", 0,0,0},
     {"scale", 1, 0, 0}, 
     {"advanced-encode-option", 1, 0, 0},
+	{"discard-comments", 0, 0, 0},
         {NULL,0,0,0}
 };
         
@@ -76,7 +77,7 @@
 {
         /* Default values */
         oe_options opt = {NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 
-			  0, NULL, 0, NULL, 0, NULL, 0, 0, 0,16,44100,2, 0, NULL,
+			  0, NULL, 0, NULL, 0, NULL, 0, 1, 0, 0,16,44100,2, 0, NULL,
                           DEFAULT_NAMEFMT_REMOVE, DEFAULT_NAMEFMT_REPLACE, 
                           NULL, 0, -1,-1,-1,.3,-1,0, 0,0.f, 0}; 
 
@@ -148,7 +149,9 @@
         enc_opts.start_encode = start_encode_full;
                 enc_opts.end_encode = final_statistics;
                 enc_opts.error = encode_error;
-		
+		enc_opts.comments = &vc;
+		enc_opts.copy_comments = opt.copy_comments;
+
                 /* OK, let's build the vorbis_comments structure */
                 build_comments(&vc, &opt, i, &artist, &album, &title, &track, 
                 &date, &genre);
@@ -624,6 +627,10 @@
                     opt->advopt[opt->advopt_count - 1].arg = arg;
                     opt->advopt[opt->advopt_count - 1].val = val;
                 }
+                else if(!strcmp(long_options[option_index].name, "discard-comments")) {
+		  opt->copy_comments = 0;
+		}
+
                 else {
                                     fprintf(stderr, _("Internal error parsing command line options\n"));
                                     exit(1);

<p><p>1.1                  vorbis-tools/oggenc/easyflac.c

Index: easyflac.c
===================================================================
/* EasyFLAC - A thin decoding wrapper around libFLAC and libOggFLAC to
 * make your code less ugly.  See easyflac.h for explanation.
 *
 * Copyright 2003 - Stan Seibert <volsung at xiph.org>
 * This code is licensed under a BSD style license:
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * - Neither the name of the Xiph.org Foundation nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <stdlib.h>
#include "easyflac.h"

<p>FLAC__bool EasyFLAC__is_oggflac(EasyFLAC__StreamDecoder *decoder)
{
        return decoder->is_oggflac;
}

<p>EasyFLAC__StreamDecoder *EasyFLAC__stream_decoder_new(FLAC__bool is_oggflac)
{
        EasyFLAC__StreamDecoder *decoder = malloc(sizeof(EasyFLAC__StreamDecoder));

        if (decoder != NULL)
        {
                decoder->is_oggflac = is_oggflac;
                
                if (decoder->is_oggflac)
                        decoder->oggflac = OggFLAC__stream_decoder_new();
                else
                        decoder->flac = FLAC__stream_decoder_new();

                if (  (decoder->is_oggflac && decoder->oggflac == NULL)
                    ||(!decoder->is_oggflac && decoder->flac == NULL)  )
                {
                        free(decoder);
                        decoder = NULL;
                }
        }

        return decoder;
}

<p>void EasyFLAC__stream_decoder_delete(EasyFLAC__StreamDecoder *decoder)
{
        if (decoder->is_oggflac)
                OggFLAC__stream_decoder_delete(decoder->oggflac);
        else
                FLAC__stream_decoder_delete(decoder->flac);

        free(decoder);
}

<p>/* Wrappers around the callbacks for OggFLAC */

FLAC__StreamDecoderReadStatus oggflac_read_callback(const OggFLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
{
        EasyFLAC__StreamDecoder *e_decoder = (EasyFLAC__StreamDecoder *) client_data;

        return (*e_decoder->callbacks.read)(e_decoder, buffer, bytes, e_decoder->callbacks.client_data);
}

<p>FLAC__StreamDecoderWriteStatus oggflac_write_callback(const OggFLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
{
        EasyFLAC__StreamDecoder *e_decoder = (EasyFLAC__StreamDecoder *) client_data;

        return (*(e_decoder->callbacks.write))(e_decoder, frame, buffer, e_decoder->callbacks.client_data);
}

<p>void oggflac_metadata_callback(const OggFLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
{
        EasyFLAC__StreamDecoder *e_decoder = (EasyFLAC__StreamDecoder *) client_data;

        (*e_decoder->callbacks.metadata)(e_decoder, metadata, e_decoder->callbacks.client_data);
}

<p>void oggflac_error_callback(const OggFLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
{
        EasyFLAC__StreamDecoder *e_decoder = (EasyFLAC__StreamDecoder *) client_data;

        (*e_decoder->callbacks.error)(e_decoder, status, e_decoder->callbacks.client_data);
}

<p>/* Wrappers around the callbacks for FLAC */

FLAC__StreamDecoderReadStatus flac_read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
{
        EasyFLAC__StreamDecoder *e_decoder = (EasyFLAC__StreamDecoder *) client_data;

        return (*e_decoder->callbacks.read)(e_decoder, buffer, bytes, e_decoder->callbacks.client_data);
}

<p>FLAC__StreamDecoderWriteStatus flac_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
{
        EasyFLAC__StreamDecoder *e_decoder = (EasyFLAC__StreamDecoder *) client_data;

        return (*e_decoder->callbacks.write)(e_decoder, frame, buffer, e_decoder->callbacks.client_data);
}

<p>void flac_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
{
        EasyFLAC__StreamDecoder *e_decoder = (EasyFLAC__StreamDecoder *) client_data;

        (*e_decoder->callbacks.metadata)(e_decoder, metadata, e_decoder->callbacks.client_data);
}

<p>void flac_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
{
        EasyFLAC__StreamDecoder *e_decoder = (EasyFLAC__StreamDecoder *) client_data;

        (*e_decoder->callbacks.error)(e_decoder, status, e_decoder->callbacks.client_data);
}

<p>FLAC__bool EasyFLAC__set_read_callback(EasyFLAC__StreamDecoder *decoder, EasyFLAC__StreamDecoderReadCallback value)
{
        decoder->callbacks.read = value;

        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_set_read_callback(decoder->oggflac, &oggflac_read_callback);
        else
                return FLAC__stream_decoder_set_read_callback(decoder->flac, &flac_read_callback);
}

<p>FLAC__bool EasyFLAC__set_write_callback(EasyFLAC__StreamDecoder *decoder, EasyFLAC__StreamDecoderWriteCallback value)
{
        decoder->callbacks.write = value;

        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_set_write_callback(decoder->oggflac, &oggflac_write_callback);
        else
                return FLAC__stream_decoder_set_write_callback(decoder->flac, &flac_write_callback);
}

<p>FLAC__bool EasyFLAC__set_metadata_callback(EasyFLAC__StreamDecoder *decoder, EasyFLAC__StreamDecoderMetadataCallback value)
{
        decoder->callbacks.metadata = value;

        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_set_metadata_callback(decoder->oggflac, &oggflac_metadata_callback);
        else
                return FLAC__stream_decoder_set_metadata_callback(decoder->flac, &flac_metadata_callback);
}

<p>FLAC__bool EasyFLAC__set_error_callback(EasyFLAC__StreamDecoder *decoder, EasyFLAC__StreamDecoderErrorCallback value)
{
        decoder->callbacks.error = value;

        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_set_error_callback(decoder->oggflac, &oggflac_error_callback);
        else
                return FLAC__stream_decoder_set_error_callback(decoder->flac, &flac_error_callback);
}

<p>FLAC__bool EasyFLAC__set_client_data(EasyFLAC__StreamDecoder *decoder, void *value)
{
        decoder->callbacks.client_data = value;
        
        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_set_client_data(decoder->oggflac, decoder);
        else
                return FLAC__stream_decoder_set_client_data(decoder->flac, decoder);
}

<p>FLAC__bool EasyFLAC__set_metadata_respond(EasyFLAC__StreamDecoder *decoder, FLAC__MetadataType type)
{
        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_set_metadata_respond(decoder->oggflac, type);
        else
                return FLAC__stream_decoder_set_metadata_respond(decoder->flac, type);
}

<p>FLAC__bool EasyFLAC__set_metadata_respond_application(EasyFLAC__StreamDecoder *decoder, const FLAC__byte id[4])
{
        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_set_metadata_respond_application(decoder->oggflac, id);
        else
                return FLAC__stream_decoder_set_metadata_respond_application(decoder->flac, id);
}

<p>FLAC__bool EasyFLAC__set_metadata_respond_all(EasyFLAC__StreamDecoder *decoder)
{
        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_set_metadata_respond_all(decoder->oggflac);
        else
                return FLAC__stream_decoder_set_metadata_respond_all(decoder->flac);
}

<p>FLAC__bool EasyFLAC__set_metadata_ignore(EasyFLAC__StreamDecoder *decoder, FLAC__MetadataType type)
{
        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_set_metadata_ignore(decoder->oggflac, type);
        else
                return FLAC__stream_decoder_set_metadata_ignore(decoder->flac, type);
}

<p>FLAC__bool EasyFLAC__set_metadata_ignore_application(EasyFLAC__StreamDecoder *decoder, const FLAC__byte id[4])
{
        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_set_metadata_ignore_application(decoder->oggflac, id);
        else
                return FLAC__stream_decoder_set_metadata_ignore_application(decoder->flac, id);
}

FLAC__bool EasyFLAC__set_metadata_ignore_all(EasyFLAC__StreamDecoder *decoder)
{
        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_set_metadata_ignore_all(decoder->oggflac);
        else
                return FLAC__stream_decoder_set_metadata_ignore_all(decoder->flac);
}

<p>FLAC__StreamDecoderState EasyFLAC__get_state(const EasyFLAC__StreamDecoder *decoder)
{
        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(decoder->oggflac);
        else
                return FLAC__stream_decoder_get_state(decoder->flac);
}

<p>unsigned EasyFLAC__get_channels(const EasyFLAC__StreamDecoder *decoder)
{
        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_get_channels(decoder->oggflac);
        else
                return FLAC__stream_decoder_get_channels(decoder->flac);
}

<p>FLAC__ChannelAssignment EasyFLAC__get_channel_assignment(const EasyFLAC__StreamDecoder *decoder)
{
        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_get_channel_assignment(decoder->oggflac);
        else
                return FLAC__stream_decoder_get_channel_assignment(decoder->flac);
}

<p>unsigned EasyFLAC__get_bits_per_sample(const EasyFLAC__StreamDecoder *decoder)
{
        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_get_bits_per_sample(decoder->oggflac);
        else
                return FLAC__stream_decoder_get_bits_per_sample(decoder->flac);
}

<p>unsigned EasyFLAC__get_sample_rate(const EasyFLAC__StreamDecoder *decoder)
{
        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_get_sample_rate(decoder->oggflac);
        else
                return FLAC__stream_decoder_get_sample_rate(decoder->flac);
}

<p>unsigned EasyFLAC__get_blocksize(const EasyFLAC__StreamDecoder *decoder)
{
        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_get_blocksize(decoder->oggflac);
        else
                return FLAC__stream_decoder_get_blocksize(decoder->flac);
}

<p>FLAC__StreamDecoderState EasyFLAC__init(EasyFLAC__StreamDecoder *decoder)
{
        if (decoder->is_oggflac)
        {
                OggFLAC__stream_decoder_init(decoder->oggflac);
                return OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(decoder->oggflac);
        }
        else
                return FLAC__stream_decoder_init(decoder->flac);
}

<p>void EasyFLAC__finish(EasyFLAC__StreamDecoder *decoder)
{
        if (decoder->is_oggflac)
                OggFLAC__stream_decoder_finish(decoder->oggflac);
        else
                FLAC__stream_decoder_finish(decoder->flac);
}

<p>FLAC__bool EasyFLAC__flush(EasyFLAC__StreamDecoder *decoder)
{
        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_flush(decoder->oggflac);
        else
                return FLAC__stream_decoder_flush(decoder->flac);
}

<p>FLAC__bool EasyFLAC__reset(EasyFLAC__StreamDecoder *decoder)
{
        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_reset(decoder->oggflac);
        else
                return FLAC__stream_decoder_reset(decoder->flac);
}

<p>FLAC__bool EasyFLAC__process_single(EasyFLAC__StreamDecoder *decoder)
{
        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_process_single(decoder->oggflac);
        else
                return FLAC__stream_decoder_process_single(decoder->flac);
}

<p>FLAC__bool EasyFLAC__process_until_end_of_metadata(EasyFLAC__StreamDecoder *decoder)
{
        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_process_until_end_of_metadata(decoder->oggflac);
        else
                return FLAC__stream_decoder_process_until_end_of_metadata(decoder->flac);
}

<p>FLAC__bool EasyFLAC__process_until_end_of_stream(EasyFLAC__StreamDecoder *decoder)
{
        if (decoder->is_oggflac)
                return OggFLAC__stream_decoder_process_until_end_of_stream(decoder->oggflac);
        else
                return FLAC__stream_decoder_process_until_end_of_stream(decoder->flac);
}

<p><p>1.1                  vorbis-tools/oggenc/easyflac.h

Index: easyflac.h
===================================================================
/* EasyFLAC - A thin decoding wrapper around libFLAC and libOggFLAC to
 * make your code less ugly.
 *
 * Copyright 2003 - Stan Seibert <volsung at xiph.org>
 * This code is licensed under a BSD style license:
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * - Neither the name of the Xiph.org Foundation nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ************************************************************************
 *
 * The motivation for this wrapper is to avoid issues where you need to
 * decode both FLAC and Ogg FLAC but don't want to enclose all of your code
 * in enormous if blocks where the body of the two branches is essentially 
 * the same.  For example, you don't want to do something like this:
 *
 *  if (is_ogg_flac)
 *  {
 *      OggFLAC__blah_blah();
 *      OggFLAC__more_stuff();
 *  }
 *  else
 *  {
 *      FLAC__blah_blah();
 *      FLAC__more_stuff();
 *  }
 * 
 * when you really just want this:
 *
 * EasyFLAC__blah_blah();
 * EasyFLAC__more_stuff();
 *
 * This is even more cumbersome when you have to deal with constants.
 *
 * EasyFLAC uses essentially the same API as
 * FLAC__stream_decoder with two additions:
 * 
 * - EasyFLAC__is_oggflac() for those rare occassions when you might
 * need to distiguish the difference cases.
 *
 * - EasyFLAC__stream_decoder_new() takes a parameter to select when
 * you are reading FLAC or Ogg FLAC.
 *
 * The constants are all FLAC__stream_decoder_*.
 *
 * WARNING: Always call EasyFLAC__set_client_data() even if all you
 * want to do is set the client data to NULL.
 */

#ifndef __EASYFLAC_H
#define __EASYFLAC_H

#include <FLAC/stream_decoder.h>
#include <OggFLAC/stream_decoder.h>

#ifdef __cplusplus
extern "C" {
#endif

<p>typedef struct EasyFLAC__StreamDecoder  EasyFLAC__StreamDecoder;

<p>typedef FLAC__StreamDecoderReadStatus (*EasyFLAC__StreamDecoderReadCallback)(const EasyFLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
typedef FLAC__StreamDecoderWriteStatus (*EasyFLAC__StreamDecoderWriteCallback)(const EasyFLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
typedef void (*EasyFLAC__StreamDecoderMetadataCallback)(const EasyFLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
typedef void (*EasyFLAC__StreamDecoderErrorCallback)(const EasyFLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);

truct EasyFLAC__StreamDecoder {
        FLAC__bool is_oggflac;
        FLAC__StreamDecoder *flac;
        OggFLAC__StreamDecoder *oggflac;
        struct {
                EasyFLAC__StreamDecoderReadCallback     read;
                EasyFLAC__StreamDecoderWriteCallback    write;
                EasyFLAC__StreamDecoderMetadataCallback metadata;
                EasyFLAC__StreamDecoderErrorCallback    error;
                void *client_data;
        } callbacks;
};

<p><p>FLAC__bool EasyFLAC__is_oggflac(EasyFLAC__StreamDecoder *decoder);

EasyFLAC__StreamDecoder *EasyFLAC__stream_decoder_new(FLAC__bool is_oggflac);
void EasyFLAC__stream_decoder_delete(EasyFLAC__StreamDecoder *decoder);
FLAC__bool EasyFLAC__set_read_callback(EasyFLAC__StreamDecoder *decoder, EasyFLAC__StreamDecoderReadCallback value);
FLAC__bool EasyFLAC__set_write_callback(EasyFLAC__StreamDecoder *decoder, EasyFLAC__StreamDecoderWriteCallback value);
FLAC__bool EasyFLAC__set_metadata_callback(EasyFLAC__StreamDecoder *decoder, EasyFLAC__StreamDecoderMetadataCallback value);
FLAC__bool EasyFLAC__set_error_callback(EasyFLAC__StreamDecoder *decoder, EasyFLAC__StreamDecoderErrorCallback value);
FLAC__bool EasyFLAC__set_client_data(EasyFLAC__StreamDecoder *decoder, void *value);
FLAC__bool EasyFLAC__set_metadata_respond(EasyFLAC__StreamDecoder *decoder, FLAC__MetadataType type);
FLAC__bool EasyFLAC__set_metadata_respond_application(EasyFLAC__StreamDecoder *decoder, const FLAC__byte id[4]);
FLAC__bool EasyFLAC__set_metadata_respond_all(EasyFLAC__StreamDecoder *decoder);
FLAC__bool EasyFLAC__set_metadata_ignore(EasyFLAC__StreamDecoder *decoder, FLAC__MetadataType type);
FLAC__bool EasyFLAC__set_metadata_ignore_application(EasyFLAC__StreamDecoder *decoder, const FLAC__byte id[4]);
FLAC__bool EasyFLAC__set_metadata_ignore_all(EasyFLAC__StreamDecoder *decoder);
FLAC__StreamDecoderState EasyFLAC__get_state(const EasyFLAC__StreamDecoder *decoder);
unsigned EasyFLAC__get_channels(const EasyFLAC__StreamDecoder *decoder);
FLAC__ChannelAssignment EasyFLAC__get_channel_assignment(const EasyFLAC__StreamDecoder *decoder);
unsigned EasyFLAC__get_bits_per_sample(const EasyFLAC__StreamDecoder *decoder);
unsigned EasyFLAC__get_sample_rate(const EasyFLAC__StreamDecoder *decoder);
unsigned EasyFLAC__get_blocksize(const EasyFLAC__StreamDecoder *decoder);
FLAC__StreamDecoderState EasyFLAC__init(EasyFLAC__StreamDecoder *decoder);
void EasyFLAC__finish(EasyFLAC__StreamDecoder *decoder);
FLAC__bool EasyFLAC__flush(EasyFLAC__StreamDecoder *decoder);
FLAC__bool EasyFLAC__reset(EasyFLAC__StreamDecoder *decoder);
FLAC__bool EasyFLAC__process_single(EasyFLAC__StreamDecoder *decoder);
FLAC__bool EasyFLAC__process_until_end_of_metadata(EasyFLAC__StreamDecoder *decoder);
FLAC__bool EasyFLAC__process_until_end_of_stream(EasyFLAC__StreamDecoder *decoder);

#ifdef __cplusplus
}
#endif

#endif

<p><p>1.1                  vorbis-tools/oggenc/flac.c

Index: flac.c
===================================================================
/* OggEnc
 **
 ** This program is distributed under the GNU General Public License, version 2.
 ** A copy of this license is included with this source.
 **
 ** Copyright 2002, Stan Seibert <volsung at xiph.org>
 **
 **/

<p>#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <math.h>
#include <FLAC/metadata.h>
#include "audio.h"
#include "flac.h"
#include "i18n.h"
#include "platform.h"
#include "resample.h"

#define DEFAULT_FLAC_FRAME_SIZE 4608

FLAC__StreamDecoderReadStatus easyflac_read_callback(const EasyFLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
FLAC__StreamDecoderWriteStatus easyflac_write_callback(const EasyFLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
void easyflac_metadata_callback(const EasyFLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
void easyflac_error_callback(const EasyFLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);

void resize_buffer(flacfile *flac, int newchannels, int newsamples);
void copy_comments (vorbis_comment *v_comments, FLAC__StreamMetadata_VorbisComment *f_comments);

<p>int flac_id(unsigned char *buf, int len)
{
        if (len < 4) return 0;

        return memcmp(buf, "fLaC", 4) == 0;
}

<p>int oggflac_id(unsigned char *buf, int len)
{
        if (len < 32) return 0;

        return memcmp(buf, "OggS", 4) == 0 && flac_id(buf+28, len - 28);
}

<p>int flac_open(FILE *in, oe_enc_opt *opt, unsigned char *oldbuf, int buflen)
{
        flacfile *flac = malloc(sizeof(flacfile));

        flac->decoder = NULL;
        flac->channels = 0;
        flac->rate = 0;
        flac->totalsamples = 0;
        flac->comments = NULL;
        flac->in = NULL;
        flac->eos = 0;

        /* Setup empty audio buffer that will be resized on first frame 
           callback */
        flac->buf = NULL;
        flac->buf_len = 0;
        flac->buf_start = 0;
        flac->buf_fill = 0;

        /* Copy old input data over */
        flac->oldbuf = malloc(buflen);
        flac->oldbuf_len = buflen;
        memcpy(flac->oldbuf, oldbuf, buflen);
        flac->oldbuf_start = 0;

        /* Need to save FILE pointer for read callback */
        flac->in = in;

        /* Setup FLAC decoder */
        flac->decoder = EasyFLAC__stream_decoder_new(oggflac_id(oldbuf, buflen));
        EasyFLAC__set_client_data(flac->decoder, flac);
        EasyFLAC__set_read_callback(flac->decoder, &easyflac_read_callback);
        EasyFLAC__set_write_callback(flac->decoder, &easyflac_write_callback);
        EasyFLAC__set_metadata_callback(flac->decoder, &easyflac_metadata_callback);
        EasyFLAC__set_error_callback(flac->decoder, &easyflac_error_callback);
        EasyFLAC__set_metadata_respond(flac->decoder, FLAC__METADATA_TYPE_STREAMINFO);
        EasyFLAC__set_metadata_respond(flac->decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
        EasyFLAC__init(flac->decoder);
        
        /* Callback will set the total samples and sample rate */
        EasyFLAC__process_until_end_of_metadata(flac->decoder);

        /* Callback will set the number of channels and resize the 
           audio buffer */
        EasyFLAC__process_single(flac->decoder);
        
        /* Copy format info for caller */
        opt->rate = flac->rate;
        opt->channels = flac->channels;
        /* flac->total_samples_per_channel was already set by metadata
           callback when metadata was processed. */
        opt->total_samples_per_channel = flac->totalsamples;
        /* Copy Vorbis-style comments from FLAC file (read in metadata 
           callback)*/
        if (flac->comments != NULL && opt->copy_comments)
                copy_comments(opt->comments, &flac->comments->data.vorbis_comment);
        opt->read_samples = flac_read;
        opt->readdata = (void *)flac;

        return 1;
}

<p>long flac_read(void *in, float **buffer, int samples)
{
        flacfile *flac = (flacfile *)in;
        long realsamples = 0;
        FLAC__bool ret;
        int i,j;
        while (realsamples < samples)
        {
                if (flac->buf_fill > 0)
                {
                        int copy = flac->buf_fill < (samples - realsamples) ?
                                flac->buf_fill : (samples - realsamples);
                        
                        for (i = 0; i < flac->channels; i++)
                                for (j = 0; j < copy; j++)
                                        buffer[i][j+realsamples] = 
                                                flac->buf[i][j+flac->buf_start];
                        flac->buf_start += copy;
                        flac->buf_fill -= copy;
                        realsamples += copy;
                }
                else if (!flac->eos)
                {
                        ret = EasyFLAC__process_single(flac->decoder);
                        if (!ret ||
                            EasyFLAC__get_state(flac->decoder)
                            == FLAC__STREAM_DECODER_END_OF_STREAM)
                                flac->eos = 1;  /* Bail out! */
                } else
                        break;
        }

        return realsamples;
}

<p>void flac_close(void *info)
{
        int i;
        flacfile *flac =  (flacfile *) info;

        for (i = 0; i < flac->channels; i++)
                free(flac->buf[i]);

        free(flac->buf);
        free(flac->oldbuf);
        free(flac->comments);
        EasyFLAC__finish(flac->decoder);
        EasyFLAC__stream_decoder_delete(flac->decoder);
        free(flac);
}

<p>FLAC__StreamDecoderReadStatus easyflac_read_callback(const EasyFLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
{
        flacfile *flac = (flacfile *) client_data;
        int i = 0;
        int oldbuf_fill = flac->oldbuf_len - flac->oldbuf_start;
        
        /* Immediately return if errors occured */
        if(feof(flac->in))
        {
                *bytes = 0;
                return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
        }
        else if(ferror(flac->in))
        {
                *bytes = 0;
                return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
        }

<p>        if(oldbuf_fill > 0) 
        {
                int copy;
                
                copy = oldbuf_fill < (*bytes - i) ? oldbuf_fill : (*bytes - i);
                memcpy(buffer + i, flac->oldbuf, copy);
                i += copy;
                flac->oldbuf_start += copy;
        }
        
        if(i < *bytes)
                i += fread(buffer+i, sizeof(FLAC__byte), *bytes - i, flac->in);

        *bytes = i;
        
        return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;	 
}

FLAC__StreamDecoderWriteStatus easyflac_write_callback(const EasyFLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
{
        flacfile *flac = (flacfile *) client_data;
        int samples = frame->header.blocksize;
        int channels = frame->header.channels;
        int bits_per_sample = frame->header.bits_per_sample;
        int i, j;

        resize_buffer(flac, channels, samples);

        for (i = 0; i < channels; i++)
                for (j = 0; j < samples; j++)
                        flac->buf[i][j] = buffer[i][j] / 
                                 (float) (1 << (bits_per_sample - 1));

        flac->buf_start = 0;
        flac->buf_fill = samples;
 
        return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}

void easyflac_metadata_callback(const EasyFLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
{
        flacfile *flac = (flacfile *) client_data;

        switch (metadata->type)
        {
        case FLAC__METADATA_TYPE_STREAMINFO:
                flac->totalsamples = metadata->data.stream_info.total_samples;
                flac->rate = metadata->data.stream_info.sample_rate;
                break;

        case FLAC__METADATA_TYPE_VORBIS_COMMENT:
                flac->comments = FLAC__metadata_object_clone(metadata);
                break;
        default:
                break;
        }
}

void easyflac_error_callback(const EasyFLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
{
        flacfile *flac = (flacfile *) client_data;

}

<p>void resize_buffer(flacfile *flac, int newchannels, int newsamples)
{
        int i;

        if (newchannels == flac->channels && newsamples == flac->buf_len)
        {
                flac->buf_start = 0;
                flac->buf_fill = 0;
                return;
        }

<p>        /* Not the most efficient approach, but it is easy to follow */
        if(newchannels != flac->channels)
        {
                /* Deallocate all of the sample vectors */
                for (i = 0; i < flac->channels; i++)
                        free(flac->buf[i]);

                flac->buf = realloc(flac->buf, sizeof(float*) * newchannels);
                flac->channels = newchannels;

        }

        for (i = 0; i < newchannels; i++)
                flac->buf[i] = malloc(sizeof(float) * newsamples);

        flac->buf_len = newsamples;
        flac->buf_start = 0;
        flac->buf_fill = 0;
}

void copy_comments (vorbis_comment *v_comments, FLAC__StreamMetadata_VorbisComment *f_comments)
{
        int i;

        for (i = 0; i < f_comments->num_comments; i++)
        {
                char *comment = malloc(f_comments->comments[i].length + 1);
                memset(comment, '\0', f_comments->comments[i].length + 1);
                strncpy(comment, f_comments->comments[i].entry, f_comments->comments[i].length);
                vorbis_comment_add(v_comments, comment);
                free(comment);
        }
}

<p><p><p>1.1                  vorbis-tools/oggenc/flac.h

Index: flac.h
===================================================================

#ifndef __FLAC_H
#define __FLAC_H

#include "encode.h"
#include "audio.h"
#include <stdio.h>
#include "easyflac.h"

typedef struct {
        EasyFLAC__StreamDecoder *decoder;
        short channels;
        int rate;
        long totalsamples; /* per channel, of course */

        FLAC__StreamMetadata *comments;

        FILE *in;  /* Cache the FILE pointer so the FLAC read callback can use it */
        int eos;  /* End of stream read */

<p>        /* Buffer for decoded audio */
        float **buf;  /* channels by buf_len array */
        int buf_len;
        int buf_start; /* Offset to start of audio data */
        int buf_fill; /* Number of bytes of audio data in buffer */

        /* Buffer for input data we already read in the id phase */
        unsigned char *oldbuf;
        int oldbuf_len;
        int oldbuf_start;
} flacfile;

<p>int flac_id(unsigned char *buf, int len);
int oggflac_id(unsigned char *buf, int len);
int flac_open(FILE *in, oe_enc_opt *opt, unsigned char *buf, int buflen);
void flac_close(void *);

long flac_read(void *, float **buffer, int samples);

#endif /* __FLAC_H */

<p><p><p>--- >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