void FLACDecoder::close() { if (mDecoder != nullptr) { FLAC__stream_decoder_finish(mDecoder); FLAC__stream_decoder_delete(mDecoder); mDecoder = nullptr; } }
void SoundFileReaderFlac::close() { if (m_decoder) { FLAC__stream_decoder_finish(m_decoder); FLAC__stream_decoder_delete(m_decoder); m_decoder = NULL; } }
void SoundSourceFLAC::close() { if (m_decoder) { FLAC__stream_decoder_finish(m_decoder); FLAC__stream_decoder_delete(m_decoder); // frees memory m_decoder = NULL; } m_file.close(); }
FlacDecoder::~FlacDecoder() { if (_opened) { FLAC__stream_decoder_finish(_streamdecoder); if (_file) { fclose(_file); } } FLAC__stream_decoder_delete(_streamdecoder); }
static void flac_decode_internal(struct decoder * decoder, struct input_stream *input_stream, bool is_ogg) { FLAC__StreamDecoder *flac_dec; struct flac_data data; flac_dec = flac_decoder_new(); if (flac_dec == NULL) return; flac_data_init(&data, decoder, input_stream); data.tag = tag_new(); FLAC__StreamDecoderInitStatus status = stream_init(flac_dec, &data, is_ogg); if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK) { flac_data_deinit(&data); FLAC__stream_decoder_delete(flac_dec); #if defined(FLAC_API_VERSION_CURRENT) && FLAC_API_VERSION_CURRENT > 7 g_warning("%s", FLAC__StreamDecoderInitStatusString[status]); #endif return; } if (!flac_decoder_initialize(&data, flac_dec, 0)) { flac_data_deinit(&data); FLAC__stream_decoder_finish(flac_dec); FLAC__stream_decoder_delete(flac_dec); return; } flac_decoder_loop(&data, flac_dec, 0, 0); flac_data_deinit(&data); FLAC__stream_decoder_finish(flac_dec); FLAC__stream_decoder_delete(flac_dec); }
static void flac_decoder_loop(struct flac_data *data, FLAC__StreamDecoder *flac_dec, FLAC__uint64 t_start, FLAC__uint64 t_end) { struct decoder *decoder = data->decoder; enum decoder_command cmd; data->first_frame = t_start; while (true) { if (data->tag != NULL && !tag_is_empty(data->tag)) { cmd = decoder_tag(data->decoder, data->input_stream, data->tag); tag_free(data->tag); data->tag = tag_new(); } else cmd = decoder_get_command(decoder); if (cmd == DECODE_COMMAND_SEEK) { FLAC__uint64 seek_sample = t_start + decoder_seek_where(decoder) * data->audio_format.sample_rate; if (seek_sample >= t_start && (t_end == 0 || seek_sample <= t_end) && FLAC__stream_decoder_seek_absolute(flac_dec, seek_sample)) { data->next_frame = seek_sample; data->position = 0; decoder_command_finished(decoder); } else decoder_seek_error(decoder); } else if (cmd == DECODE_COMMAND_STOP || FLAC__stream_decoder_get_state(flac_dec) == FLAC__STREAM_DECODER_END_OF_STREAM) break; if (t_end != 0 && data->next_frame >= t_end) /* end of this sub track */ break; if (!FLAC__stream_decoder_process_single(flac_dec)) { cmd = decoder_get_command(decoder); if (cmd != DECODE_COMMAND_SEEK) break; } } if (cmd != DECODE_COMMAND_STOP) { flacPrintErroredState(FLAC__stream_decoder_get_state(flac_dec)); FLAC__stream_decoder_finish(flac_dec); } }
int close_flac(void* in){ flac_file_t* flac_file = (flac_file_t*)in; int i; for (i = 0; i < flac_file->channels; i++){ free(flac_file->buf[i]); } free(flac_file->buf); FLAC__stream_decoder_finish(flac_file->stream_decoder); FLAC__stream_decoder_delete(flac_file->stream_decoder); //free(flac); return 0; }
SoundSourceFLAC::~SoundSourceFLAC() { if (m_flacBuffer != NULL) { delete [] m_flacBuffer; m_flacBuffer = NULL; } if (m_leftoverBuffer != NULL) { delete [] m_leftoverBuffer; m_leftoverBuffer = NULL; } if (m_decoder) { FLAC__stream_decoder_finish(m_decoder); FLAC__stream_decoder_delete(m_decoder); // frees memory m_decoder = NULL; } }
static void flacdecode_eject(struct xlplayer *xlplayer) { struct flacdecode_vars *self = xlplayer->dec_data; FLAC__stream_decoder_finish(self->decoder); FLAC__stream_decoder_delete(self->decoder); if (self->flbuf) free(self->flbuf); if (self->resample_f) { free(xlplayer->src_data.data_in); free(xlplayer->src_data.data_out); xlplayer->src_state = src_delete(xlplayer->src_state); } free(self); }
void structLongSound :: v_destroy () noexcept { /* * The play callback may contain a pointer to my buffer. * That pointer is about to dangle, so kill the playback. */ MelderAudio_stopPlaying (MelderAudio_IMPLICIT); if (mp3f) mp3f_delete (mp3f); if (flacDecoder) { FLAC__stream_decoder_finish (flacDecoder); // closes f FLAC__stream_decoder_delete (flacDecoder); } else if (f) fclose (f); NUMvector_free <int16> (buffer, 0); LongSound_Parent :: v_destroy (); }
// soundsource overrides Result SoundSourceFLAC::open() { if (!m_file.open(QIODevice::ReadOnly)) { qWarning() << "SSFLAC: Could not read file!"; return ERR; } m_decoder = FLAC__stream_decoder_new(); if (m_decoder == NULL) { qWarning() << "SSFLAC: decoder allocation failed!"; return ERR; } FLAC__StreamDecoderInitStatus initStatus( FLAC__stream_decoder_init_stream( m_decoder, FLAC_read_cb, FLAC_seek_cb, FLAC_tell_cb, FLAC_length_cb, FLAC_eof_cb, FLAC_write_cb, FLAC_metadata_cb, FLAC_error_cb, (void*) this) ); if (initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK) { qWarning() << "SSFLAC: decoder init failed!"; goto decoderError; } if (!FLAC__stream_decoder_process_until_end_of_metadata(m_decoder)) { qWarning() << "SSFLAC: process to end of meta failed!"; qWarning() << "SSFLAC: decoder state: " << FLAC__stream_decoder_get_state(m_decoder); goto decoderError; } // now number of samples etc. should be populated if (m_flacBuffer == NULL) { // we want 2 samples per frame, see ::flacWrite code -- bkgood m_flacBuffer = new FLAC__int16[m_maxBlocksize * 2 /*m_iChannels*/]; } if (m_leftoverBuffer == NULL) { m_leftoverBuffer = new FLAC__int16[m_maxBlocksize * 2 /*m_iChannels*/]; } // qDebug() << "SSFLAC: Total samples: " << m_samples; // qDebug() << "SSFLAC: Sampling rate: " << m_iSampleRate << " Hz"; // qDebug() << "SSFLAC: Channels: " << m_iChannels; // qDebug() << "SSFLAC: BPS: " << m_bps; return OK; decoderError: FLAC__stream_decoder_finish(m_decoder); FLAC__stream_decoder_delete(m_decoder); m_decoder = NULL; qWarning() << "SSFLAC: Decoder error at file" << m_qFilename; return ERR; }
void MV_ReleaseFLACVoice( VoiceNode * voice ) { flac_data * fd = (flac_data *) voice->extra; if (voice->wavetype != FLAC) { return; } if (fd->stream != NULL) { FLAC__stream_decoder_finish(fd->stream); FLAC__stream_decoder_delete(fd->stream); } if (fd->block != NULL) free(fd->block); free(fd); voice->extra = 0; }
void GarlickDecodeFlac(GarlickFile *gf) { const char * zz = FLAC__VERSION_STRING; //prepare flac FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new(); FLAC__stream_decoder_init_stream(decoder, GarlickDecodeFlac_Read, 0, 0, 0, 0, GarlickDecodeFlac_Write, GarlickDecodeFlac_Metadata, GarickDecodeFlac_Error, (void*)gf); //read the size of the flac stream Garlick_cb_read(&gf->flac_in_counter,1,4,gf->lib); //prep the output buffer GarlickEnsureBuffer(gf, gf->chunkleft); gf->buf_counter = 0; //decode and finish FLAC__stream_decoder_process_until_end_of_stream(decoder); FLAC__stream_decoder_finish(decoder); FLAC__stream_decoder_delete(decoder); printf("%d - %d - %d\n",gf->encode_mode, gf->buf_counter,gf->chunkleft); gf->buf_counter = 0; }
void OggFLAC__stream_decoder_finish(OggFLAC__StreamDecoder *decoder) { FLAC__ASSERT(0 != decoder); FLAC__ASSERT(0 != decoder->private_); FLAC__ASSERT(0 != decoder->protected_); if(decoder->protected_->state == OggFLAC__STREAM_DECODER_UNINITIALIZED) return; FLAC__ASSERT(0 != decoder->private_->FLAC_stream_decoder); FLAC__stream_decoder_finish(decoder->private_->FLAC_stream_decoder); (void)ogg_sync_clear(&decoder->private_->ogg.sync_state); (void)ogg_stream_clear(&decoder->private_->ogg.stream_state); set_defaults_(decoder); decoder->protected_->state = OggFLAC__STREAM_DECODER_UNINITIALIZED; }
bool OAFLACReader::isValid(const SPtr<DataStream>& stream, UINT32 offset) { stream->seek(offset); FLAC__StreamDecoder* decoder = FLAC__stream_decoder_new(); if (!decoder) return false; FLACDecoderData data; data.stream = stream; mData.streamOffset = offset; FLAC__stream_decoder_init_stream(decoder, &streamRead, &streamSeek, &streamTell, &streamLength, &streamEof, &streamWrite, nullptr, &streamError, &data); bool valid = FLAC__stream_decoder_process_until_end_of_metadata(decoder) != 0; FLAC__stream_decoder_finish(decoder); FLAC__stream_decoder_delete(decoder); return valid && !data.error; }
static void xmms_flac_destroy (xmms_xform_t *xform) { xmms_flac_data_t *data; g_return_if_fail (xform); data = xmms_xform_private_data_get (xform); g_return_if_fail (data); if (data->vorbiscomment) { FLAC__metadata_object_delete (data->vorbiscomment); } g_string_free (data->buffer, TRUE); FLAC__stream_decoder_finish (data->flacdecoder); FLAC__stream_decoder_delete (data->flacdecoder); g_free (data); }
bool SoundFileReaderFlac::check(InputStream& stream) { // Create a decoder FLAC__StreamDecoder* decoder = FLAC__stream_decoder_new(); if (!decoder) return false; // Initialize the decoder with our callbacks ClientData data; data.stream = &stream; data.error = false; FLAC__stream_decoder_init_stream(decoder, &streamRead, &streamSeek, &streamTell, &streamLength, &streamEof, &streamWrite, NULL, &streamError, &data); // Read the header bool valid = FLAC__stream_decoder_process_until_end_of_metadata(decoder) != 0; // Destroy the decoder FLAC__stream_decoder_finish(decoder); FLAC__stream_decoder_delete(decoder); return valid && !data.error; }
static bool DecodeFLAC(FILE *f, FILE *of) { fseek(f, 0, SEEK_SET); FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new(); if(decoder == nullptr) { return false; } FLAC__stream_decoder_set_metadata_respond_all(decoder); FLACClientData client; client.of = of; client.started = false; client.encoder = FLAC__stream_encoder_new(); FLAC__StreamDecoderInitStatus initStatus = FLAC__stream_decoder_init_FILE(decoder, f, write_cb, metadata_cb, error_cb, &client); if(initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK || client.encoder == nullptr) { FLAC__stream_decoder_delete(decoder); return false; } FLAC__stream_decoder_process_until_end_of_stream(decoder); FLAC__stream_decoder_finish(decoder); FLAC__stream_decoder_delete(decoder); FLAC__stream_encoder_finish(client.encoder); FLAC__stream_encoder_delete(client.encoder); for(auto m = client.metadata.begin(); m != client.metadata.end(); m++) { FLAC__metadata_object_delete(*m); } return client.started; }
void FlacDecoder::_reset() { if (_opened) { FLAC__stream_decoder_finish(_streamdecoder); if (_file) { fclose(_file); } } _file=NULL; _opened=false; _ended=true; _error=false; _data=NULL; _datasize=0; _dataindex=0; _sampleRate=0; _bufferpos=0; _bufferl.clear(); _bufferr.clear(); FLAC__stream_decoder_set_metadata_respond(_streamdecoder,FLAC__METADATA_TYPE_STREAMINFO); FLAC__stream_decoder_set_metadata_respond(_streamdecoder,FLAC__METADATA_TYPE_VORBIS_COMMENT); }
CBaseDec::RetCode CFlacDec::Decoder(FILE *in, const int /*OutputFd*/, State* const state, CAudioMetaData* meta_data, time_t* const time_played, unsigned int* const secondsToSkip) { int rval; // FLAC__uint64 jumptime=0; Status = OK; mState = state; mTimePlayed = time_played; mFrameCount = 0; mSamplesProcessed = 0; struct stat s; FLAC__uint64 filesize = 0; mFlacDec = FLAC__stream_decoder_new(); if (!Open(in, mFlacDec)) { Status=DATA_ERR; return Status; } if (fstat(fileno(in), &s)) { perror("CFlacDec::Decoder fstat"); *time_played = 0; } else filesize = (FLAC__uint64)s.st_size; /* up and away ... */ mSlotSize = MAX_OUTPUT_SAMPLES * 2 * FLAC__stream_decoder_get_channels(mFlacDec); // State oldstate=*state; int jumppos=0; int actSecsToSkip = (*secondsToSkip != 0) ? *secondsToSkip : MSECS_TO_SKIP / 1000; int bytes_to_skip = actSecsToSkip * meta_data->bitrate / 8; int bytes_to_play = MSECS_TO_PLAY * meta_data->bitrate / 8000; unsigned int oldSecsToSkip = *secondsToSkip; FLAC__uint64 position; do { while(*state==PAUSE) usleep(10000); if(*state==FF || *state==REV) { if (oldSecsToSkip != *secondsToSkip) { actSecsToSkip = (*secondsToSkip != 0) ? *secondsToSkip : MSECS_TO_SKIP / 1000; bytes_to_skip = actSecsToSkip * meta_data->bitrate / 8; oldSecsToSkip = *secondsToSkip; } printf("skipping %d secs and %d bytes\n",actSecsToSkip,bytes_to_skip); if(std::abs(ftell(in)-jumppos) > bytes_to_play) { if(*state==FF) { fseek(in, bytes_to_skip, SEEK_CUR); jumppos=ftell(in); } else { if(ftell(in) < bytes_to_skip) { fseek(in, 0, SEEK_SET); *state=PLAY; } else { fseek(in, -bytes_to_skip, SEEK_CUR); jumppos=ftell(in); } } } // if a custom value was set we only jump once if (*secondsToSkip != 0) { *state=PLAY; } } if (FLAC__stream_decoder_get_state(mFlacDec) == FLAC__STREAM_DECODER_END_OF_STREAM) { rval = false; break; } rval = FLAC__stream_decoder_process_single(mFlacDec); /* update playback position */ if (filesize > 0 && FLAC__stream_decoder_get_decode_position(mFlacDec, &position)) *time_played = position / 1000ULL * mLengthInMsec / filesize; } while (rval && *state != STOP_REQ && Status == OK); // let buffer run dry printf("let buffer run dry\n"); while (rval == true && *state != STOP_REQ && Status == OK /* && mReadSlot != mWriteSlot*/) { printf("...drying - *state=%x, Status=%x\n", *state, Status); usleep(100000); } /* clean up the junk from the party */ if (mMetadata) FLAC__metadata_object_delete(mMetadata); mMetadata = NULL; FLAC__stream_decoder_finish(mFlacDec); FLAC__stream_decoder_delete(mFlacDec); mFlacDec = NULL; audioDecoder->StopClip(); /* and drive home ;) */ return Status; }
CBaseDec::RetCode CFlacDec::Decoder(FILE *in, const int OutputFd, State* const state, CAudioMetaData* meta_data, time_t* const time_played, unsigned int* const secondsToSkip) { int rval; //FLAC__uint64 jumptime=0; Status = OK; mOutputFd = OutputFd; mState = state; mTimePlayed = time_played; mFrameCount = 0; mSamplesProcessed = 0; mFlacDec = FLAC__stream_decoder_new(); if (!Open(in, mFlacDec)) { Status=DATA_ERR; return Status; } //test //audioDecoder->PrepareClipPlay(frame->header.channels, frame->header.sample_rate, frame->header.bits_per_sample, 1); //audioDecoder->PrepareClipPlay(2, 16, 16, 1); /* up and away ... */ mSlotSize = MAX_OUTPUT_SAMPLES * 2 * FLAC__stream_decoder_get_channels(mFlacDec); //State oldstate=*state; int jumppos=0; int actSecsToSkip = (*secondsToSkip != 0) ? *secondsToSkip : MSECS_TO_SKIP / 1000; int bytes_to_skip = (int) (1.0 * actSecsToSkip * meta_data->bitrate / 8); int bytes_to_play = (int) (1.0 * MSECS_TO_PLAY / 1000 * meta_data->bitrate / 8); unsigned int oldSecsToSkip = *secondsToSkip; //FLAC__uint64 position; do { while(*state==PAUSE) usleep(10000); if(*state==FF || *state==REV) { if (oldSecsToSkip != *secondsToSkip) { actSecsToSkip = (*secondsToSkip != 0) ? *secondsToSkip : MSECS_TO_SKIP / 1000; bytes_to_skip = (int) (1.0 * actSecsToSkip * meta_data->bitrate / 8); oldSecsToSkip = *secondsToSkip; } printf("skipping %d secs and %d bytes\n",actSecsToSkip,bytes_to_skip); if(std::abs(ftell(in)-jumppos) > bytes_to_play) { if(*state==FF) { fseek(in, bytes_to_skip, SEEK_CUR); jumppos=ftell(in); } else { if(ftell(in) < bytes_to_skip) { fseek(in, 0, SEEK_SET); *state=PLAY; } else { fseek(in, -bytes_to_skip, SEEK_CUR); jumppos=ftell(in); } } } // if a custom value was set we only jump once if (*secondsToSkip != 0) { *state=PLAY; } } if (FLAC__stream_decoder_get_state(mFlacDec) == FLAC__STREAM_DECODER_END_OF_STREAM) { rval = false; break; } rval = FLAC__stream_decoder_process_single(mFlacDec); // TODO: calculate time_played from the actual file position so that REW/FF actions will be included *time_played = (mSamplesProcessed * (mLengthInMsec/1000)) / mTotalSamples; } while (rval && *state!=STOP_REQ && Status==OK); // let buffer run dry printf("let buffer run dry\n"); while (rval==true && *state!=STOP_REQ && Status==OK /* && mReadSlot != mWriteSlot*/) { printf("...drying - *state=%x, Status=%x\n", *state, Status); usleep(100000); } if(audioDecoder) audioDecoder->StopClip(); /* clean up the junk from the party */ if (mMetadata) FLAC__metadata_object_delete(mMetadata); mMetadata = NULL; FLAC__stream_decoder_finish(mFlacDec); FLAC__stream_decoder_delete(mFlacDec); mFlacDec = NULL; /* and drive home ;) */ return Status; }
bool FLACInputStream::initialize(FilePtr file) { m_file = file; // initialize the decoder m_decoder = FLAC__stream_decoder_new(); if (!m_decoder) { m_file = 0; return false; } // initialize the stream decoder! FLAC__StreamDecoderInitStatus state = FLAC__stream_decoder_init_stream( m_decoder, read_callback, seek_callback, tell_callback, length_callback, eof_callback, write_callback, metadata_callback, error_callback, this); if (state != FLAC__STREAM_DECODER_INIT_STATUS_OK) { FLAC__stream_decoder_finish(m_decoder); FLAC__stream_decoder_delete(m_decoder); m_decoder = 0; m_file = 0; return false; } // make sure we have metadata before we return! if (!FLAC__stream_decoder_process_until_end_of_metadata(m_decoder)) { FLAC__stream_decoder_finish(m_decoder); FLAC__stream_decoder_delete(m_decoder); m_decoder = 0; m_file = 0; return false; } // process one frame so we can do something! if (!FLAC__stream_decoder_process_single(m_decoder)) { FLAC__stream_decoder_finish(m_decoder); FLAC__stream_decoder_delete(m_decoder); m_decoder = 0; m_file = 0; return false; } // get info about the flac file m_channel_count = FLAC__stream_decoder_get_channels(m_decoder); m_sample_rate = FLAC__stream_decoder_get_sample_rate(m_decoder); int bps = FLAC__stream_decoder_get_bits_per_sample(m_decoder); if (bps == 16) { m_sample_format = SF_S16; } else if (bps == 8) { m_sample_format = SF_U8; } else { return false; } return true; }
static gboolean xmms_flac_init (xmms_xform_t *xform) { xmms_flac_data_t *data; xmms_sample_format_t sample_fmt; FLAC__bool retval; #if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7 FLAC__StreamDecoderState init_status; #else FLAC__StreamDecoderInitStatus init_status; #endif gint filesize; const gchar *metakey; g_return_val_if_fail (xform, FALSE); data = g_new0 (xmms_flac_data_t, 1); xmms_xform_private_data_set (xform, data); data->flacdecoder = FLAC__stream_decoder_new (); /* we don't need to explicitly tell the decoder to respond to * FLAC__METADATA_TYPE_STREAMINFO here, it always does. */ #if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7 FLAC__seekable_stream_decoder_set_metadata_respond (data->flacdecoder, FLAC__METADATA_TYPE_VORBIS_COMMENT); FLAC__seekable_stream_decoder_set_eof_callback (data->flacdecoder, flac_callback_eof); FLAC__seekable_stream_decoder_set_read_callback (data->flacdecoder, flac_callback_read); FLAC__seekable_stream_decoder_set_seek_callback (data->flacdecoder, flac_callback_seek); FLAC__seekable_stream_decoder_set_tell_callback (data->flacdecoder, flac_callback_tell); FLAC__seekable_stream_decoder_set_write_callback (data->flacdecoder, flac_callback_write); FLAC__seekable_stream_decoder_set_error_callback (data->flacdecoder, flac_callback_error); FLAC__seekable_stream_decoder_set_length_callback (data->flacdecoder, flac_callback_length); FLAC__seekable_stream_decoder_set_metadata_callback (data->flacdecoder, flac_callback_metadata); FLAC__seekable_stream_decoder_set_client_data (data->flacdecoder, xform); init_status = FLAC__seekable_stream_decoder_init (data->flacdecoder); if (init_status != FLAC__SEEKABLE_STREAM_DECODER_OK) { const gchar *errmsg = FLAC__seekable_stream_decoder_get_resolved_state_string (data->flacdecoder); XMMS_DBG ("FLAC init failed: %s", errmsg); goto err; } #else FLAC__stream_decoder_set_metadata_respond (data->flacdecoder, FLAC__METADATA_TYPE_VORBIS_COMMENT); FLAC__stream_decoder_set_metadata_respond (data->flacdecoder, FLAC__METADATA_TYPE_PICTURE); init_status = FLAC__stream_decoder_init_stream (data->flacdecoder, flac_callback_read, flac_callback_seek, flac_callback_tell, flac_callback_length, flac_callback_eof, flac_callback_write, flac_callback_metadata, flac_callback_error, xform); if (init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) { XMMS_DBG ("FLAC init failed: %s", FLAC__stream_decoder_get_resolved_state_string (data->flacdecoder)); goto err; } #endif retval = FLAC__stream_decoder_process_until_end_of_metadata (data->flacdecoder); if (!retval) goto err; if (data->vorbiscomment) { handle_comments (xform, data); } metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_BITRATE; xmms_xform_metadata_set_int (xform, metakey, (gint) data->bit_rate); metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE; if (xmms_xform_metadata_get_int (xform, metakey, &filesize)) { gint32 val = (gint32) data->total_samples / data->sample_rate * 1000; metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION; xmms_xform_metadata_set_int (xform, metakey, val); } if (data->bits_per_sample == 8) { sample_fmt = XMMS_SAMPLE_FORMAT_S8; } else if (data->bits_per_sample == 16) { sample_fmt = XMMS_SAMPLE_FORMAT_S16; } else if (data->bits_per_sample == 24) { sample_fmt = XMMS_SAMPLE_FORMAT_S32; } else if (data->bits_per_sample == 32) { sample_fmt = XMMS_SAMPLE_FORMAT_S32; } else { goto err; } xmms_xform_outdata_type_add (xform, XMMS_STREAM_TYPE_MIMETYPE, "audio/pcm", XMMS_STREAM_TYPE_FMT_FORMAT, sample_fmt, XMMS_STREAM_TYPE_FMT_CHANNELS, data->channels, XMMS_STREAM_TYPE_FMT_SAMPLERATE, data->sample_rate, XMMS_STREAM_TYPE_END); data->buffer = g_string_new (NULL); return TRUE; err: FLAC__stream_decoder_finish (data->flacdecoder); FLAC__stream_decoder_delete (data->flacdecoder); g_free (data); xmms_xform_private_data_set (xform, NULL); return FALSE; }
static int private_load_flac ( LISndSample* self, const char* file) { void* buffer; ALenum format; FLAC__uint32 bps; FLAC__uint32 channels; FLAC__uint32 length; FLAC__uint32 rate; FLAC__StreamDecoder* decoder; FLAC__StreamDecoderInitStatus status; LIArcWriter* writer; /* Create decoder. */ decoder = FLAC__stream_decoder_new (); if (decoder == NULL) { lisys_error_set (ENOMEM, NULL); return 0; } /* Allocate temporary storage. */ writer = liarc_writer_new (); if (writer == NULL) { FLAC__stream_decoder_delete (decoder); return 0; } /* Decode file. */ status = FLAC__stream_decoder_init_file (decoder, file, private_flac_stream_callback, NULL, private_flac_error_callback, writer); if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK) { lisys_error_set (EINVAL, "FLAC decoder cannot open file `%s'", file); liarc_writer_free (writer); FLAC__stream_decoder_delete (decoder); return 0; } if (!FLAC__stream_decoder_process_until_end_of_stream (decoder)) { lisys_error_set (EINVAL, "FLAC decoder failed to process file `%s'", file); liarc_writer_free (writer); FLAC__stream_decoder_finish (decoder); FLAC__stream_decoder_delete (decoder); return 0; } /* Stream format. */ bps = FLAC__stream_decoder_get_bits_per_sample (decoder); channels = FLAC__stream_decoder_get_channels (decoder); length = liarc_writer_get_length (writer); rate = FLAC__stream_decoder_get_sample_rate (decoder); /* Upload format. */ if (channels == 1 && bps == 8) format = AL_FORMAT_MONO8; else if (channels == 1 && bps == 16) format = AL_FORMAT_MONO16; else if (channels == 2 && bps == 8) format = AL_FORMAT_STEREO8; else if (channels == 2 && bps == 16) format = AL_FORMAT_STEREO16; else { lisys_error_set (EINVAL, "FLAC stream format unsupported in file `%s'", file); liarc_writer_free (writer); FLAC__stream_decoder_finish (decoder); FLAC__stream_decoder_delete (decoder); return 0; } /* Upload to OpenAL. */ buffer = lisys_calloc (length, sizeof (uint8_t)); if (buffer != NULL) { memcpy (buffer, liarc_writer_get_buffer (writer), length); private_load_raw (self, format, buffer, length, rate); lisys_free (buffer); } /* Finish reading. */ liarc_writer_free (writer); FLAC__stream_decoder_finish (decoder); FLAC__stream_decoder_delete (decoder); return 1; }
int32_t MV_PlayFLAC ( char *ptr, uint32_t ptrlength, int32_t loopstart, int32_t loopend, int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, int32_t priority, uint32_t callbackval ) { VoiceNode *voice; flac_data * fd = 0; FLAC__Metadata_Chain* metadata_chain; UNREFERENCED_PARAMETER(loopend); if ( !MV_Installed ) { MV_SetErrorCode( MV_NotInstalled ); return MV_Error; } fd = (flac_data *) malloc( sizeof(flac_data) ); if (!fd) { MV_SetErrorCode( MV_InvalidFLACFile ); return MV_Error; } memset(fd, 0, sizeof(flac_data)); fd->ptr = ptr; fd->pos = 0; fd->blocksize = 0; fd->length = ptrlength; fd->block = NULL; fd->stream = FLAC__stream_decoder_new(); fd->sample_pos = 0; FLAC__stream_decoder_set_metadata_ignore_all(fd->stream); if (FLAC__stream_decoder_init_stream(fd->stream, read_flac_stream, seek_flac_stream, tell_flac_stream, length_flac_stream, eof_flac_stream, write_flac_stream, /*metadata_flac_stream*/ NULL, error_flac_stream, (void*) fd) != FLAC__STREAM_DECODER_INIT_STATUS_OK) { MV_Printf("MV_PlayFLAC: %s\n", FLAC__stream_decoder_get_resolved_state_string(fd->stream)); MV_SetErrorCode( MV_InvalidFLACFile ); return MV_Error; } // Request a voice from the voice pool voice = MV_AllocVoice( priority ); if ( voice == NULL ) { FLAC__stream_decoder_finish(fd->stream); FLAC__stream_decoder_delete(fd->stream); free(fd); MV_SetErrorCode( MV_NoVoices ); return MV_Error; } fd->owner = voice; voice->wavetype = FLAC; voice->extra = (void*)fd; voice->GetSound = MV_GetNextFLACBlock; voice->NextBlock = fd->block; voice->DemandFeed = NULL; voice->LoopCount = 0; voice->BlockLength = 0; voice->PitchScale = PITCH_GetScale( pitchoffset ); voice->next = NULL; voice->prev = NULL; voice->priority = priority; voice->callbackval = callbackval; voice->Playing = TRUE; voice->Paused = FALSE; voice->LoopStart = 0; voice->LoopEnd = 0; voice->LoopSize = (loopstart >= 0 ? 1 : 0); // parse metadata // loop parsing designed with multiple repetitions in mind // In retrospect, it may be possible to MV_GetVorbisCommentLoops(voice, (vorbis_comment *) tags->data.vorbis_comment) // but libvorbisfile may be confused by the signedness of char* vs FLAC__byte* and this code does not depend on HAVE_VORBIS. metadata_chain = FLAC__metadata_chain_new(); if (metadata_chain != NULL) { if (FLAC__metadata_chain_read_with_callbacks(metadata_chain, fd, flac_callbacks)) { FLAC__Metadata_Iterator* metadata_iterator = FLAC__metadata_iterator_new(); if (metadata_iterator != NULL) { char *vc_loopstart = NULL; char *vc_loopend = NULL; char *vc_looplength = NULL; FLAC__metadata_iterator_init(metadata_iterator, metadata_chain); do { FLAC__StreamMetadata *tags = FLAC__metadata_iterator_get_block(metadata_iterator); if (tags->type == FLAC__METADATA_TYPE_STREAMINFO) { const FLAC__StreamMetadata_StreamInfo *info = &tags->data.stream_info; if (info->channels != 1 && info->channels != 2) { FLAC__metadata_object_delete(tags); FLAC__metadata_iterator_delete(metadata_iterator); // FLAC__metadata_chain_delete(metadata_chain); FLAC__stream_decoder_finish(fd->stream); FLAC__stream_decoder_delete(fd->stream); free(fd); MV_SetErrorCode( MV_InvalidFLACFile ); return MV_Error; } voice->channels = info->channels; voice->bits = info->bits_per_sample; voice->SamplingRate = info->sample_rate; } // load loop tags from metadata if (tags->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { FLAC__uint32 comment; uint8_t loopTagCount; for (comment = 0; comment < tags->data.vorbis_comment.num_comments; ++comment) { const char *entry = (const char *) tags->data.vorbis_comment.comments[comment].entry; if (entry != NULL && entry[0] != '\0') { const char *value = strchr(entry,'='); const size_t field = value-entry; value += 1; for (loopTagCount = 0; loopTagCount < loopStartTagCount && vc_loopstart == NULL; ++loopTagCount) if (strncasecmp(entry, loopStartTags[loopTagCount], field) == 0) vc_loopstart = strdup(value); for (loopTagCount = 0; loopTagCount < loopEndTagCount && vc_loopend == NULL; ++loopTagCount) if (strncasecmp(entry, loopEndTags[loopTagCount], field) == 0) vc_loopend = strdup(value); for (loopTagCount = 0; loopTagCount < loopLengthTagCount && vc_looplength == NULL; ++loopTagCount) if (strncasecmp(entry, loopLengthTags[loopTagCount], field) == 0) vc_looplength = strdup(value); } } } FLAC__metadata_object_delete(tags); // If it wasn't for this I would assign pointers instead of strdup(). } while (FLAC__metadata_iterator_next(metadata_iterator)); if (vc_loopstart != NULL) { { const FLAC__int64 flac_loopstart = atol(vc_loopstart); if (flac_loopstart >= 0) // a loop starting at 0 is valid { voice->LoopStart = (const char *) (intptr_t) flac_loopstart; voice->LoopSize = 1; } } free(vc_loopstart); } if (vc_loopend != NULL) { if (voice->LoopSize > 0) { const FLAC__int64 flac_loopend = atol(vc_loopend); if (flac_loopend > 0) // a loop ending at 0 is invalid voice->LoopEnd = (const char *) (intptr_t) flac_loopend; } free(vc_loopend); } if (vc_looplength != NULL) { if (voice->LoopSize > 0 && voice->LoopEnd == 0) { const FLAC__int64 flac_looplength = atol(vc_looplength); if (flac_looplength > 0) // a loop of length 0 is invalid voice->LoopEnd = (const char *) ((intptr_t) flac_looplength + (intptr_t) voice->LoopStart); } free(vc_looplength); } FLAC__metadata_iterator_delete(metadata_iterator); } else MV_Printf("Error allocating FLAC__Metadata_Iterator!\n"); } else MV_Printf("%s\n", FLAC__Metadata_ChainStatusString[FLAC__metadata_chain_status(metadata_chain)]); // FLAC__metadata_chain_delete(metadata_chain); // when run with GDB, this throws SIGTRAP about freed heap memory being modified } else MV_Printf("Error allocating FLAC__Metadata_Chain!\n"); // CODEDUP multivoc.c MV_SetVoicePitch voice->RateScale = ( voice->SamplingRate * voice->PitchScale ) / MV_MixRate; voice->FixedPointBufferSize = ( voice->RateScale * MV_MIXBUFFERSIZE ) - voice->RateScale; MV_SetVoiceMixMode( voice ); MV_SetVoiceVolume( voice, vol, left, right ); MV_PlayVoice( voice ); return voice->handle; }
int __stdcall WWFlacRW_DecodeAll(const wchar_t *path) { FLAC__bool ok = true; FILE *fp = NULL; errno_t ercd; FLAC__StreamDecoderInitStatus initStatus = FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE; FlacDecodeInfo *fdi = FlacTInfoNew<FlacDecodeInfo>(g_flacDecodeInfoMap); if (NULL == fdi) { return FRT_OtherError; } fdi->errorCode = FRT_Success; fdi->decoder = FLAC__stream_decoder_new(); if(fdi->decoder == NULL) { fdi->errorCode = FRT_FlacStreamDecoderNewFailed; dprintf("%s Flac decode error %d. set complete event.\n", __FUNCTION__, fdi->errorCode); goto end; } wcsncpy_s(fdi->path, path, (sizeof fdi->path)/2-1); FLAC__stream_decoder_set_md5_checking(fdi->decoder, true); FLAC__stream_decoder_set_metadata_respond(fdi->decoder, FLAC__METADATA_TYPE_STREAMINFO); FLAC__stream_decoder_set_metadata_respond(fdi->decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT); FLAC__stream_decoder_set_metadata_respond(fdi->decoder, FLAC__METADATA_TYPE_PICTURE); FLAC__stream_decoder_set_metadata_respond(fdi->decoder, FLAC__METADATA_TYPE_CUESHEET); // Windowsでは、この方法でファイルを開かなければならぬ。 ercd = _wfopen_s(&fp, fdi->path, L"rb"); if (ercd != 0 || NULL == fp) { fdi->errorCode = FRT_FileOpenError; goto end; } initStatus = FLAC__stream_decoder_init_FILE( fdi->decoder, fp, WriteCallback, MetadataCallback, ErrorCallback, fdi); // FLAC__stream_decoder_finish()がfcloseしてくれるので、忘れる。 fp = NULL; if(initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK) { fdi->errorCode = FRT_FlacStreamDecoderInitFailed; dprintf("%s Flac decode error %d. set complete event.\n", __FUNCTION__, fdi->errorCode); goto end; } fdi->errorCode = FRT_Success; ok = FLAC__stream_decoder_process_until_end_of_metadata(fdi->decoder); if (!ok) { if (fdi->errorCode == FRT_Success) { fdi->errorCode = FRT_DecorderProcessFailed; } dprintf("%s Flac metadata process error fdi->errorCode=%d\n", __FUNCTION__, fdi->errorCode); goto end; } ok = FLAC__stream_decoder_process_until_end_of_stream(fdi->decoder); if (!ok) { if (fdi->errorCode == FRT_Success) { fdi->errorCode = FRT_DecorderProcessFailed; } dprintf("%s Flac decode error fdi->errorCode=%d\n", __FUNCTION__, fdi->errorCode); goto end; } fdi->errorCode = FRT_Completed; end: if (fdi->errorCode < 0) { if (NULL != fdi->decoder) { if (initStatus == FLAC__STREAM_DECODER_INIT_STATUS_OK) { FLAC__stream_decoder_finish(fdi->decoder); } FLAC__stream_decoder_delete(fdi->decoder); fdi->decoder = NULL; } int result = fdi->errorCode; FlacTInfoDelete<FlacDecodeInfo>(g_flacDecodeInfoMap, fdi); fdi = NULL; return result; } return fdi->id; }
static FLAC__bool stream_decoder_test_respond_(FLAC__StreamDecoder *decoder, StreamDecoderClientData *dcd, FLAC__bool is_ogg) { FLAC__StreamDecoderInitStatus init_status; if(!FLAC__stream_decoder_set_md5_checking(decoder, true)) return die_s_("at FLAC__stream_decoder_set_md5_checking(), returned false", decoder); /* for FLAC__stream_encoder_init_FILE(), the FLAC__stream_encoder_finish() closes the file so we have to keep re-opening: */ if(dcd->layer == LAYER_FILE) { printf("opening %sFLAC file... ", is_ogg? "Ogg ":""); dcd->file = fopen(flacfilename(is_ogg), "rb"); if(0 == dcd->file) { printf("ERROR (%s)\n", strerror(errno)); return false; } printf("OK\n"); } switch(dcd->layer) { case LAYER_STREAM: printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_stream(decoder, stream_decoder_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) : FLAC__stream_decoder_init_stream(decoder, stream_decoder_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) ; break; case LAYER_SEEKABLE_STREAM: printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_stream(decoder, stream_decoder_read_callback_, stream_decoder_seek_callback_, stream_decoder_tell_callback_, stream_decoder_length_callback_, stream_decoder_eof_callback_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) : FLAC__stream_decoder_init_stream(decoder, stream_decoder_read_callback_, stream_decoder_seek_callback_, stream_decoder_tell_callback_, stream_decoder_length_callback_, stream_decoder_eof_callback_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd); break; case LAYER_FILE: printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_FILE(decoder, dcd->file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) : FLAC__stream_decoder_init_FILE(decoder, dcd->file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd); break; case LAYER_FILENAME: printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) : FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd); break; default: die_("internal error 000"); return false; } if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) return die_s_(0, decoder); printf("OK\n"); dcd->current_metadata_number = 0; if(dcd->layer < LAYER_FILE && fseeko(dcd->file, 0, SEEK_SET) < 0) { printf("FAILED rewinding input, errno = %d\n", errno); return false; } printf("testing FLAC__stream_decoder_process_until_end_of_stream()... "); if(!FLAC__stream_decoder_process_until_end_of_stream(decoder)) return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_finish()... "); if(!FLAC__stream_decoder_finish(decoder)) return die_s_("returned false", decoder); printf("OK\n"); return true; }
/* read mode: * 0 - no read after seek * 1 - read 2 frames * 2 - read until end */ static FLAC__bool seek_barrage(FLAC__bool is_ogg, const char *filename, off_t filesize, unsigned count, FLAC__int64 total_samples, unsigned read_mode) { FLAC__StreamDecoder *decoder; DecoderClientData decoder_client_data; unsigned i; long int n; decoder_client_data.got_data = false; decoder_client_data.total_samples = 0; decoder_client_data.quiet = false; decoder_client_data.ignore_errors = false; decoder_client_data.error_occurred = false; printf("\n+++ seek test: FLAC__StreamDecoder (%s FLAC, read_mode=%u)\n\n", is_ogg? "Ogg":"native", read_mode); decoder = FLAC__stream_decoder_new(); if(0 == decoder) return die_("FLAC__stream_decoder_new() FAILED, returned NULL\n"); if(is_ogg) { if(FLAC__stream_decoder_init_ogg_file(decoder, filename, write_callback_, metadata_callback_, error_callback_, &decoder_client_data) != FLAC__STREAM_DECODER_INIT_STATUS_OK) return die_s_("FLAC__stream_decoder_init_file() FAILED", decoder); } else { if(FLAC__stream_decoder_init_file(decoder, filename, write_callback_, metadata_callback_, error_callback_, &decoder_client_data) != FLAC__STREAM_DECODER_INIT_STATUS_OK) return die_s_("FLAC__stream_decoder_init_file() FAILED", decoder); } if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder)) return die_s_("FLAC__stream_decoder_process_until_end_of_metadata() FAILED", decoder); if(!is_ogg) { /* not necessary to do this for Ogg because of its seeking method */ /* process until end of stream to make sure we can still seek in that state */ decoder_client_data.quiet = true; if(!FLAC__stream_decoder_process_until_end_of_stream(decoder)) return die_s_("FLAC__stream_decoder_process_until_end_of_stream() FAILED", decoder); decoder_client_data.quiet = false; printf("stream decoder state is %s\n", FLAC__stream_decoder_get_resolved_state_string(decoder)); if(FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_END_OF_STREAM) return die_s_("expected FLAC__STREAM_DECODER_END_OF_STREAM", decoder); } #ifdef _MSC_VER printf("file's total_samples is %I64u\n", decoder_client_data.total_samples); #else printf("file's total_samples is %llu\n", (unsigned long long)decoder_client_data.total_samples); #endif #if !defined _MSC_VER && !defined __MINGW32__ && !defined __EMX__ if (decoder_client_data.total_samples > (FLAC__uint64)RAND_MAX) { printf("ERROR: must be total_samples < %u\n", (unsigned)RAND_MAX); return false; } #endif n = (long int)decoder_client_data.total_samples; if(n == 0 && total_samples >= 0) n = (long int)total_samples; /* if we don't have a total samples count, just guess based on the file size */ /* @@@ for is_ogg we should get it from last page's granulepos */ if(n == 0) { /* 8 would imply no compression, 9 guarantees that we will get some samples off the end of the stream to test that case */ n = 9 * filesize / (decoder_client_data.channels * decoder_client_data.bits_per_sample); #if !defined _MSC_VER && !defined __MINGW32__ if(n > RAND_MAX) n = RAND_MAX; #endif } printf("Begin seek barrage, count=%u\n", count); for (i = 0; !stop_signal_ && (count == 0 || i < count); i++) { FLAC__uint64 pos; /* for the first 10, seek to the first 10 samples */ if (n >= 10 && i < 10) { pos = i; } /* for the second 10, seek to the last 10 samples */ else if (n >= 10 && i < 20) { pos = n - 1 - (i-10); } /* for the third 10, seek past the end and make sure we fail properly as expected */ else if (i < 30) { pos = n + (i-20); } else { #if !defined _MSC_VER && !defined __MINGW32__ pos = (FLAC__uint64)(random() % n); #else /* RAND_MAX is only 32767 in my MSVC */ pos = (FLAC__uint64)((rand()<<15|rand()) % n); #endif } #ifdef _MSC_VER printf("seek(%I64u)... ", pos); #else printf("seek(%llu)... ", (unsigned long long)pos); #endif fflush(stdout); if(!FLAC__stream_decoder_seek_absolute(decoder, pos)) { if(pos >= (FLAC__uint64)n) printf("seek past end failed as expected... "); else if(decoder_client_data.total_samples == 0 && total_samples <= 0) printf("seek failed, assuming it was past EOF... "); else return die_s_("FLAC__stream_decoder_seek_absolute() FAILED", decoder); if(!FLAC__stream_decoder_flush(decoder)) return die_s_("FLAC__stream_decoder_flush() FAILED", decoder); } else if(read_mode == 1) { printf("decode_frame... "); fflush(stdout); if(!FLAC__stream_decoder_process_single(decoder)) return die_s_("FLAC__stream_decoder_process_single() FAILED", decoder); printf("decode_frame... "); fflush(stdout); if(!FLAC__stream_decoder_process_single(decoder)) return die_s_("FLAC__stream_decoder_process_single() FAILED", decoder); } else if(read_mode == 2) { printf("decode_all... "); fflush(stdout); decoder_client_data.quiet = true; if(!FLAC__stream_decoder_process_until_end_of_stream(decoder)) return die_s_("FLAC__stream_decoder_process_until_end_of_stream() FAILED", decoder); decoder_client_data.quiet = false; } printf("OK\n"); fflush(stdout); } if(FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_UNINITIALIZED) { if(!FLAC__stream_decoder_finish(decoder)) return die_s_("FLAC__stream_decoder_finish() FAILED", decoder); } FLAC__stream_decoder_delete(decoder); printf("\nPASSED!\n"); return true; }
void FLAC_plugin__decoder_finish(FLAC__StreamDecoder *decoder) { if (decoder && FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_UNINITIALIZED) (void)FLAC__stream_decoder_finish(decoder); }
static FLAC__bool test_stream_decoder(Layer layer, FLAC__bool is_ogg) { FLAC__StreamDecoder *decoder; FLAC__StreamDecoderInitStatus init_status; FLAC__StreamDecoderState state; StreamDecoderClientData decoder_client_data; FLAC__bool expect; decoder_client_data.layer = layer; printf("\n+++ libFLAC unit test: FLAC__StreamDecoder (layer: %s, format: %s)\n\n", LayerString[layer], is_ogg? "Ogg FLAC" : "FLAC"); printf("testing FLAC__stream_decoder_new()... "); decoder = FLAC__stream_decoder_new(); if(0 == decoder) { printf("FAILED, returned NULL\n"); return false; } printf("OK\n"); printf("testing FLAC__stream_decoder_delete()... "); FLAC__stream_decoder_delete(decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_new()... "); decoder = FLAC__stream_decoder_new(); if(0 == decoder) { printf("FAILED, returned NULL\n"); return false; } printf("OK\n"); switch(layer) { case LAYER_STREAM: case LAYER_SEEKABLE_STREAM: printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_stream(decoder, 0, 0, 0, 0, 0, 0, 0, 0, 0) : FLAC__stream_decoder_init_stream(decoder, 0, 0, 0, 0, 0, 0, 0, 0, 0); break; case LAYER_FILE: printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_FILE(decoder, stdin, 0, 0, 0, 0) : FLAC__stream_decoder_init_FILE(decoder, stdin, 0, 0, 0, 0); break; case LAYER_FILENAME: printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), 0, 0, 0, 0) : FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), 0, 0, 0, 0); break; default: die_("internal error 003"); return false; } if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS) return die_s_(0, decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_delete()... "); FLAC__stream_decoder_delete(decoder); printf("OK\n"); num_expected_ = 0; expected_metadata_sequence_[num_expected_++] = &streaminfo_; printf("testing FLAC__stream_decoder_new()... "); decoder = FLAC__stream_decoder_new(); if(0 == decoder) { printf("FAILED, returned NULL\n"); return false; } printf("OK\n"); if(is_ogg) { printf("testing FLAC__stream_decoder_set_ogg_serial_number()... "); if(!FLAC__stream_decoder_set_ogg_serial_number(decoder, file_utils__ogg_serial_number)) return die_s_("returned false", decoder); printf("OK\n"); } printf("testing FLAC__stream_decoder_set_md5_checking()... "); if(!FLAC__stream_decoder_set_md5_checking(decoder, true)) return die_s_("returned false", decoder); printf("OK\n"); if(layer < LAYER_FILENAME) { printf("opening %sFLAC file... ", is_ogg? "Ogg ":""); decoder_client_data.file = fopen(flacfilename(is_ogg), "rb"); if(0 == decoder_client_data.file) { printf("ERROR (%s)\n", strerror(errno)); return false; } printf("OK\n"); } switch(layer) { case LAYER_STREAM: printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_stream(decoder, stream_decoder_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) : FLAC__stream_decoder_init_stream(decoder, stream_decoder_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data); break; case LAYER_SEEKABLE_STREAM: printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_stream(decoder, stream_decoder_read_callback_, stream_decoder_seek_callback_, stream_decoder_tell_callback_, stream_decoder_length_callback_, stream_decoder_eof_callback_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) : FLAC__stream_decoder_init_stream(decoder, stream_decoder_read_callback_, stream_decoder_seek_callback_, stream_decoder_tell_callback_, stream_decoder_length_callback_, stream_decoder_eof_callback_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data); break; case LAYER_FILE: printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_FILE(decoder, decoder_client_data.file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) : FLAC__stream_decoder_init_FILE(decoder, decoder_client_data.file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data); break; case LAYER_FILENAME: printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) : FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data); break; default: die_("internal error 009"); return false; } if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) return die_s_(0, decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_get_state()... "); state = FLAC__stream_decoder_get_state(decoder); printf("returned state = %u (%s)... OK\n", state, FLAC__StreamDecoderStateString[state]); decoder_client_data.current_metadata_number = 0; decoder_client_data.ignore_errors = false; decoder_client_data.error_occurred = false; printf("testing FLAC__stream_decoder_get_md5_checking()... "); if(!FLAC__stream_decoder_get_md5_checking(decoder)) { printf("FAILED, returned false, expected true\n"); return false; } printf("OK\n"); printf("testing FLAC__stream_decoder_process_until_end_of_metadata()... "); if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder)) return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_process_single()... "); if(!FLAC__stream_decoder_process_single(decoder)) return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_skip_single_frame()... "); if(!FLAC__stream_decoder_skip_single_frame(decoder)) return die_s_("returned false", decoder); printf("OK\n"); if(layer < LAYER_FILE) { printf("testing FLAC__stream_decoder_flush()... "); if(!FLAC__stream_decoder_flush(decoder)) return die_s_("returned false", decoder); printf("OK\n"); decoder_client_data.ignore_errors = true; printf("testing FLAC__stream_decoder_process_single()... "); if(!FLAC__stream_decoder_process_single(decoder)) return die_s_("returned false", decoder); printf("OK\n"); decoder_client_data.ignore_errors = false; } expect = (layer != LAYER_STREAM); printf("testing FLAC__stream_decoder_seek_absolute()... "); if(FLAC__stream_decoder_seek_absolute(decoder, 0) != expect) return die_s_(expect? "returned false" : "returned true", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_process_until_end_of_stream()... "); if(!FLAC__stream_decoder_process_until_end_of_stream(decoder)) return die_s_("returned false", decoder); printf("OK\n"); expect = (layer != LAYER_STREAM); printf("testing FLAC__stream_decoder_seek_absolute()... "); if(FLAC__stream_decoder_seek_absolute(decoder, 0) != expect) return die_s_(expect? "returned false" : "returned true", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_get_channels()... "); { unsigned channels = FLAC__stream_decoder_get_channels(decoder); if(channels != streaminfo_.data.stream_info.channels) { printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels); return false; } } printf("OK\n"); printf("testing FLAC__stream_decoder_get_bits_per_sample()... "); { unsigned bits_per_sample = FLAC__stream_decoder_get_bits_per_sample(decoder); if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) { printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample); return false; } } printf("OK\n"); printf("testing FLAC__stream_decoder_get_sample_rate()... "); { unsigned sample_rate = FLAC__stream_decoder_get_sample_rate(decoder); if(sample_rate != streaminfo_.data.stream_info.sample_rate) { printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate); return false; } } printf("OK\n"); printf("testing FLAC__stream_decoder_get_blocksize()... "); { unsigned blocksize = FLAC__stream_decoder_get_blocksize(decoder); /* value could be anything since we're at the last block, so accept any reasonable answer */ printf("returned %u... %s\n", blocksize, blocksize>0? "OK" : "FAILED"); if(blocksize == 0) return false; } printf("testing FLAC__stream_decoder_get_channel_assignment()... "); { FLAC__ChannelAssignment ca = FLAC__stream_decoder_get_channel_assignment(decoder); printf("returned %u (%s)... OK\n", (unsigned)ca, FLAC__ChannelAssignmentString[ca]); } if(layer < LAYER_FILE) { printf("testing FLAC__stream_decoder_reset()... "); if(!FLAC__stream_decoder_reset(decoder)) { state = FLAC__stream_decoder_get_state(decoder); printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__StreamDecoderStateString[state]); return false; } printf("OK\n"); if(layer == LAYER_STREAM) { /* after a reset() we have to rewind the input ourselves */ printf("rewinding input... "); if(fseeko(decoder_client_data.file, 0, SEEK_SET) < 0) { printf("FAILED, errno = %d\n", errno); return false; } printf("OK\n"); } decoder_client_data.current_metadata_number = 0; printf("testing FLAC__stream_decoder_process_until_end_of_stream()... "); if(!FLAC__stream_decoder_process_until_end_of_stream(decoder)) return die_s_("returned false", decoder); printf("OK\n"); } printf("testing FLAC__stream_decoder_finish()... "); if(!FLAC__stream_decoder_finish(decoder)) return die_s_("returned false", decoder); printf("OK\n"); /* * respond all */ printf("testing FLAC__stream_decoder_set_metadata_respond_all()... "); if(!FLAC__stream_decoder_set_metadata_respond_all(decoder)) return die_s_("returned false", decoder); printf("OK\n"); num_expected_ = 0; if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */ expected_metadata_sequence_[num_expected_++] = &streaminfo_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &padding_; expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected