Instead of creating an encoder or decoder of a certain layer, now the client will always create a FLAC__StreamEncoder or FLAC__StreamDecoder. The old layers are now differentiated by the initialization function. For example, for the decoder, FLAC__stream_decoder_init() has been replaced by FLAC__stream_decoder_init_stream(). This init function takes callbacks for the I/O, and the seeking callbacks are optional. This allows the client to use the same object for seekable and non-seekable streams. For decoding a FLAC file directly, the client can use FLAC__stream_decoder_init_file() and pass just a filename and fewer callbacks; most of the other callbacks are supplied internally. For situations where fopen()ing by filename is not possible (e.g. Unicode filenames on Windows) the client can instead open the file itself and supply the FILE* to FLAC__stream_decoder_init_FILE(). The init functions now returns a FLAC__StreamDecoderInitStatus instead of FLAC__StreamDecoderState. Since the callbacks and client data are now passed to the init function, the FLAC__stream_decoder_set_*_callback() functions and FLAC__stream_decoder_set_client_data() are no longer needed. The rest of the calls to the decoder are the same as before.
There are counterpart init functions for Ogg FLAC, e.g. FLAC__stream_decoder_init_ogg_stream(). All the rest of the calls and callbacks are the same as for native FLAC.
As an example, in FLAC 1.1.2 a seekable stream decoder would have been set up like so:
FLAC__SeekableStreamDecoder *decoder = FLAC__seekable_stream_decoder_new(); if(decoder == NULL) do_something; FLAC__seekable_stream_decoder_set_md5_checking(decoder, true); [... other settings ...] FLAC__seekable_stream_decoder_set_read_callback(decoder, my_read_callback); FLAC__seekable_stream_decoder_set_seek_callback(decoder, my_seek_callback); FLAC__seekable_stream_decoder_set_tell_callback(decoder, my_tell_callback); FLAC__seekable_stream_decoder_set_length_callback(decoder, my_length_callback); FLAC__seekable_stream_decoder_set_eof_callback(decoder, my_eof_callback); FLAC__seekable_stream_decoder_set_write_callback(decoder, my_write_callback); FLAC__seekable_stream_decoder_set_metadata_callback(decoder, my_metadata_callback); FLAC__seekable_stream_decoder_set_error_callback(decoder, my_error_callback); FLAC__seekable_stream_decoder_set_client_data(decoder, my_client_data); if(FLAC__seekable_stream_decoder_init(decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK) do_something;
In FLAC 1.1.3 it is like this:
FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new(); if(decoder == NULL) do_something; FLAC__stream_decoder_set_md5_checking(decoder, true); [... other settings ...] if(FLAC__stream_decoder_init_stream( decoder, my_read_callback, my_seek_callback, // or NULL my_tell_callback, // or NULL my_length_callback, // or NULL my_eof_callback, // or NULL my_write_callback, my_metadata_callback, // or NULL my_error_callback, my_client_data ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something;
or you could do;
[...] FILE *file = fopen("somefile.flac","rb"); if(file == NULL) do_somthing; if(FLAC__stream_decoder_init_FILE( decoder, file, my_write_callback, my_metadata_callback, // or NULL my_error_callback, my_client_data ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something;
or just:
[...] if(FLAC__stream_decoder_init_file( decoder, "somefile.flac", my_write_callback, my_metadata_callback, // or NULL my_error_callback, my_client_data ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something;
Another small change to the decoder is in how it handles unparseable streams. Before, when the decoder found an unparseable stream (reserved for when the decoder encounters a stream from a future encoder that it can't parse), it changed the state to FLAC__STREAM_DECODER_UNPARSEABLE_STREAM
. Now the decoder instead drops sync and calls the error callback with a new error code FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM
. This is more robust. If your error callback does not discriminate on the the error state, your code does not need to be changed.
The encoder now has a new setting: FLAC__stream_encoder_set_apodization(). This is for setting the method used to window the data before LPC analysis. You only need to add a call to this function if the default is not suitable. There are also two new convenience functions that may be useful: FLAC__metadata_object_cuesheet_calculate_cddb_id() and FLAC__metadata_get_cuesheet().
The bytes parameter to FLAC__StreamDecoderReadCallback, FLAC__StreamEncoderReadCallback, and FLAC__StreamEncoderWriteCallback is now size_t
instead of unsigned
.