add the metadata callback back in the stream encoder
authorJosh Coalson <jcoalson@users.sourceforce.net>
Wed, 24 Sep 2003 22:03:35 +0000 (22:03 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Wed, 24 Sep 2003 22:03:35 +0000 (22:03 +0000)
include/OggFLAC++/encoder.h
include/OggFLAC/stream_encoder.h
src/libOggFLAC++/stream_encoder.cpp
src/libOggFLAC/stream_encoder.c
src/test_libOggFLAC++/encoders.cpp
src/test_libOggFLAC/encoders.c

index 96721e2..b92145f 100644 (file)
@@ -158,10 +158,12 @@ namespace OggFLAC {
                        bool process_interleaved(const FLAC__int32 buffer[], unsigned samples);
                protected:
                        virtual ::FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame) = 0;
+                       virtual void metadata_callback(const FLAC__StreamMetadata *metadata) = 0;
 
                        ::OggFLAC__StreamEncoder *encoder_;
                private:
                        static ::FLAC__StreamEncoderWriteStatus write_callback_(const ::OggFLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
+                       static void metadata_callback_(const ::OggFLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
 
                        // Private and undefined so you can't use them:
                        Stream(const Stream &);
index 559f2f6..c5d05e8 100644 (file)
@@ -55,10 +55,11 @@ extern "C" {
  *  \ingroup oggflac
  *
  *  \brief
- *  This module describes the encoder layers provided by libOggFLAC.
+ *  This module describes the three encoder layers provided by libOggFLAC.
  *
- * libOggFLAC currently provides the same stream layer access as libFLAC;
- * the interface is nearly identical.  See the \link flac_encoder FLAC
+ * libOggFLAC currently provides the same three layers of access as libFLAC;
+ * the interfaces are nearly identical, with the addition of a method for
+ * specifying the Ogg serial number.  See the \link flac_encoder FLAC
  * encoder module \endlink for full documentation.
  */
 
@@ -70,8 +71,10 @@ extern "C" {
  *  encoder.
  *
  * The interface here is nearly identical to FLAC's stream encoder,
- * including the callbacks.  See the \link flac_stream_encoder
- * FLAC stream encoder module \endlink for full documentation.
+ * including the callbacks, with the addition of
+ * OggFLAC__stream_encoder_set_serial_number().  See the
+ * \link flac_stream_encoder FLAC stream encoder module \endlink
+ * for full documentation.
  *
  * \{
  */
@@ -154,6 +157,17 @@ typedef struct {
  */
 typedef FLAC__StreamEncoderWriteStatus (*OggFLAC__StreamEncoderWriteCallback)(const OggFLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
 
+/** Signature for the metadata callback.
+ *  See OggFLAC__stream_encoder_set_metadata_callback()
+ *  and FLAC__stream_encoder_set_metadata_callback() for more info.
+ *
+ * \param  encoder      The encoder instance calling the callback.
+ * \param  metadata     The final populated STREAMINFO block.
+ * \param  client_data  The callee's client data set through
+ *                      FLAC__stream_encoder_set_client_data().
+ */
+typedef void (*OggFLAC__StreamEncoderMetadataCallback)(const OggFLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
+
 
 /***********************************************************************
  *
@@ -439,6 +453,24 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_metadata(OggFLAC__StreamEncod
  */
 OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_write_callback(OggFLAC__StreamEncoder *encoder, OggFLAC__StreamEncoderWriteCallback value);
 
+/** Set the metadata callback.
+ *  This is inherited from FLAC__StreamEncoder; see
+ *  FLAC__stream_encoder_set_metadata_callback().
+ *
+ * \note
+ * The callback is mandatory and must be set before initialization.
+ *
+ * \default \c NULL
+ * \param  encoder  An encoder instance to set.
+ * \param  value    See above.
+ * \assert
+ *    \code encoder != NULL \endcode
+ *    \code value != NULL \endcode
+ * \retval FLAC__bool
+ *    \c false if the encoder is already initialized, else \c true.
+ */
+OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_metadata_callback(OggFLAC__StreamEncoder *encoder, OggFLAC__StreamEncoderMetadataCallback value);
+
 /** Set the client data to be passed back to callbacks.
  *  This value will be supplied to callbacks in their \a client_data
  *  argument.
index 52a0b1b..ab22170 100644 (file)
@@ -296,6 +296,7 @@ namespace OggFLAC {
                {
                        FLAC__ASSERT(is_valid());
                        ::OggFLAC__stream_encoder_set_write_callback(encoder_, write_callback_);
+                       ::OggFLAC__stream_encoder_set_metadata_callback(encoder_, metadata_callback_);
                        ::OggFLAC__stream_encoder_set_client_data(encoder_, (void*)this);
                        return State(::OggFLAC__stream_encoder_init(encoder_));
                }
@@ -327,5 +328,14 @@ namespace OggFLAC {
                        return instance->write_callback(buffer, bytes, samples, current_frame);
                }
 
+               void Stream::metadata_callback_(const ::OggFLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data)
+               {
+                       (void)encoder;
+                       FLAC__ASSERT(0 != client_data);
+                       Stream *instance = reinterpret_cast<Stream *>(client_data);
+                       FLAC__ASSERT(0 != instance);
+                       return instance->metadata_callback(metadata);
+               }
+
        };
 };
index afcc5a9..98143d7 100644 (file)
@@ -61,6 +61,7 @@ static void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__S
 
 typedef struct OggFLAC__StreamEncoderPrivate {
        OggFLAC__StreamEncoderWriteCallback write_callback;
+       OggFLAC__StreamEncoderMetadataCallback metadata_callback;
        void *client_data;
        FLAC__StreamEncoder *FLAC_stream_encoder;
        /* internal vars (all the above are class settings) */
@@ -162,7 +163,7 @@ OggFLAC_API OggFLAC__StreamEncoderState OggFLAC__stream_encoder_init(OggFLAC__St
        if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
                return encoder->protected_->state = OggFLAC__STREAM_ENCODER_ALREADY_INITIALIZED;
 
-       if(0 == encoder->private_->write_callback)
+       if(0 == encoder->private_->write_callback || 0 == encoder->private_->metadata_callback)
                return encoder->protected_->state = OggFLAC__STREAM_ENCODER_INVALID_CALLBACK;
 
        if(ogg_stream_init(&encoder->private_->ogg.stream_state, encoder->protected_->serial_number) != 0)
@@ -423,6 +424,18 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_write_callback(OggFLAC__Strea
        return true;
 }
 
+OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_metadata_callback(OggFLAC__StreamEncoder *encoder, OggFLAC__StreamEncoderMetadataCallback value)
+{
+       FLAC__ASSERT(0 != encoder);
+       FLAC__ASSERT(0 != encoder->private_);
+       FLAC__ASSERT(0 != encoder->protected_);
+       FLAC__ASSERT(0 != value);
+       if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
+               return false;
+       encoder->private_->metadata_callback = value;
+       return true;
+}
+
 OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_client_data(OggFLAC__StreamEncoder *encoder, void *value)
 {
        FLAC__ASSERT(0 != encoder);
@@ -670,6 +683,7 @@ void set_defaults_(OggFLAC__StreamEncoder *encoder)
        FLAC__ASSERT(0 != encoder);
 
        encoder->private_->write_callback = 0;
+       encoder->private_->metadata_callback = 0;
        encoder->private_->client_data = 0;
        encoder->protected_->serial_number = 0;
 }
@@ -717,13 +731,12 @@ FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *unused
        return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
 }
 
-void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data)
+void metadata_callback_(const FLAC__StreamEncoder *unused, const FLAC__StreamMetadata *metadata, void *client_data)
 {
-       /*
-        * We don't try to go back and update metadata blocks by mucking
-        * around inside the Ogg layer.  Maybe someday we will care to
-        * and an OggFLAC__SeekableStreamEncoder and OggFLAC__FileEncoder
-        * will be possible but it may just never be useful.
-        */
-       (void)encoder, (void)metadata, (void)client_data;
+       OggFLAC__StreamEncoder *encoder = (OggFLAC__StreamEncoder*)client_data;
+
+       (void)unused;
+       FLAC__ASSERT(encoder->private_->FLAC_stream_encoder == unused);
+
+       encoder->private_->metadata_callback(encoder, metadata, encoder->private_->client_data);
 }
index 1179226..0a30f71 100644 (file)
@@ -48,6 +48,7 @@ public:
 
        // from OggFLAC::Encoder::Stream
        ::FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame);
+       void metadata_callback(const FLAC__StreamMetadata *metadata);
 
        bool die(const char *msg = 0) const;
 };
@@ -59,6 +60,11 @@ public:
        return ::FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
 }
 
+void StreamEncoder::metadata_callback(const FLAC__StreamMetadata *metadata)
+{
+       (void)metadata;
+}
+
 bool StreamEncoder::die(const char *msg) const
 {
        State state = get_state();
index 77bffe2..40c06fa 100644 (file)
@@ -69,6 +69,12 @@ static FLAC__StreamEncoderWriteStatus stream_encoder_write_callback_(const OggFL
        return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
 }
 
+static void stream_encoder_metadata_callback_(const OggFLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data)
+{
+       (void)encoder, (void)metadata, (void)client_data;
+}
+
+
 static FLAC__bool test_stream_encoder()
 {
        OggFLAC__StreamEncoder *encoder;
@@ -191,6 +197,11 @@ static FLAC__bool test_stream_encoder()
                return die_s_("returned false", encoder);
        printf("OK\n");
 
+       printf("testing OggFLAC__stream_encoder_set_metadata_callback()... ");
+       if(!OggFLAC__stream_encoder_set_metadata_callback(encoder, stream_encoder_metadata_callback_))
+               return die_s_("returned false", encoder);
+       printf("OK\n");
+
        printf("testing OggFLAC__stream_encoder_set_client_data()... ");
        if(!OggFLAC__stream_encoder_set_client_data(encoder, 0))
                return die_s_("returned false", encoder);