FLAC__FileDecoderState FLAC__file_decoder_init(FLAC__FileDecoder *decoder) { FLAC__ASSERT(0 != decoder); if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED) return decoder->protected_->state = FLAC__FILE_DECODER_ALREADY_INITIALIZED; if(0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback) return decoder->protected_->state = FLAC__FILE_DECODER_INVALID_CALLBACK; if(0 == decoder->private_->filename) decoder->private_->file = get_binary_stdin_(); else decoder->private_->file = fopen(decoder->private_->filename, "rb"); if(decoder->private_->file == 0) return decoder->protected_->state = FLAC__FILE_DECODER_ERROR_OPENING_FILE; FLAC__seekable_stream_decoder_set_read_callback(decoder->private_->seekable_stream_decoder, read_callback_); FLAC__seekable_stream_decoder_set_seek_callback(decoder->private_->seekable_stream_decoder, seek_callback_); FLAC__seekable_stream_decoder_set_tell_callback(decoder->private_->seekable_stream_decoder, tell_callback_); FLAC__seekable_stream_decoder_set_length_callback(decoder->private_->seekable_stream_decoder, length_callback_); FLAC__seekable_stream_decoder_set_eof_callback(decoder->private_->seekable_stream_decoder, eof_callback_); FLAC__seekable_stream_decoder_set_write_callback(decoder->private_->seekable_stream_decoder, write_callback_); FLAC__seekable_stream_decoder_set_metadata_callback(decoder->private_->seekable_stream_decoder, metadata_callback_); FLAC__seekable_stream_decoder_set_error_callback(decoder->private_->seekable_stream_decoder, error_callback_); FLAC__seekable_stream_decoder_set_client_data(decoder->private_->seekable_stream_decoder, decoder); if(FLAC__seekable_stream_decoder_init(decoder->private_->seekable_stream_decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK) return decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR; return decoder->protected_->state = FLAC__FILE_DECODER_OK; }
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; }
int main(int argc, char *argv[]) { if (argc!=2) { fprintf(stderr, "usage: %s flacfile\n", argv[0]); return -1; } myfile = fopen(argv[1], "ro"); if (!myfile) { perror("fopen()"); return -1; } decoder = FLAC__seekable_stream_decoder_new(); if (!decoder) { fprintf(stderr, "FLAC__seekable_stream_decoder_new() failed, out of memory?\n"); return 1; } FLAC__seekable_stream_decoder_set_md5_checking(decoder, 0); FLAC__seekable_stream_decoder_set_read_callback(decoder, read_callback); FLAC__seekable_stream_decoder_set_write_callback(decoder, write_callback); FLAC__seekable_stream_decoder_set_metadata_callback(decoder, metadata_callback); FLAC__seekable_stream_decoder_set_seek_callback(decoder, seek_callback); FLAC__seekable_stream_decoder_set_tell_callback(decoder, tell_callback); FLAC__seekable_stream_decoder_set_length_callback(decoder, length_callback); FLAC__seekable_stream_decoder_set_eof_callback(decoder, eof_callback); FLAC__seekable_stream_decoder_set_client_data(decoder, myvar); FLAC__seekable_stream_decoder_set_error_callback(decoder, error_callback); switch (FLAC__seekable_stream_decoder_init(decoder)) { case FLAC__SEEKABLE_STREAM_DECODER_OK: fprintf(stderr, "init ok\n"); break; case FLAC__SEEKABLE_STREAM_DECODER_SEEKING: fprintf(stderr, "seeking\n"); break; case FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM: fprintf(stderr, "eof\n"); break; case FLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR: fprintf(stderr, "malloc failed\n"); break; case FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR: fprintf(stderr, "decoder error\n"); break; case FLAC__SEEKABLE_STREAM_DECODER_READ_ERROR: fprintf(stderr, "read error\n"); break; case FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR: fprintf(stderr, "seek error\n"); break; case FLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED: fprintf(stderr, "already init'ed\n"); break; case FLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK: fprintf(stderr, "invalid callback\n"); break; case FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED: fprintf(stderr, "decoder uninted\n"); break; default: fprintf(stderr, "init not ok\n"); break; } FLAC__seekable_stream_decoder_process_until_end_of_metadata(decoder); FLAC__seekable_stream_decoder_process_single(decoder); fprintf(stderr, "channels=%d\n", FLAC__seekable_stream_decoder_get_channels(decoder)); fprintf(stderr, "bits per sample=%d\n", FLAC__seekable_stream_decoder_get_bits_per_sample(decoder)); /* fprintf(stderr, "position=%d\n", FLAC__seekable_stream_decoder_get_decode_position(decoder)); */ FLAC__seekable_stream_decoder_finish(decoder); FLAC__seekable_stream_decoder_delete(decoder); fclose(myfile); return 0; }
/* this is the codec entry point */ enum codec_status codec_start(struct codec_api* api) { struct codec_api* ci = api; FLAC__SeekableStreamDecoder* flacDecoder; FLAC__uint64 offset; TEST_CODEC_API(ci); #ifndef SIMULATOR ci->memcpy(iramstart, iramcopy, iramend-iramstart); #endif ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*10)); ci->configure(CODEC_SET_FILEBUF_WATERMARK, (int *)(1024*512)); ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*1024)); ci->configure(CODEC_DSP_ENABLE, (bool *)true); ci->configure(DSP_DITHER, (bool *)false); ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_INTERLEAVED); ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(16)); next_track: metadata_length = 0; seek_table = NULL; stream_info = NULL; if (codec_init(api)) { return CODEC_ERROR; } while (!ci->taginfo_ready) ci->yield(); ci->configure(DSP_SET_FREQUENCY, (long *)(ci->id3->frequency)); codec_set_replaygain(ci->id3); /* Create a decoder instance */ flacDecoder = FLAC__seekable_stream_decoder_new(); /* Set up the decoder and the callback functions - this must be done before init */ /* The following are required for stream_decoder and higher */ FLAC__seekable_stream_decoder_set_client_data(flacDecoder,ci); FLAC__seekable_stream_decoder_set_write_callback(flacDecoder, flac_write_handler); FLAC__seekable_stream_decoder_set_read_callback(flacDecoder, flac_read_handler); FLAC__seekable_stream_decoder_set_metadata_callback(flacDecoder, flac_metadata_handler); FLAC__seekable_stream_decoder_set_error_callback(flacDecoder, flac_error_handler); FLAC__seekable_stream_decoder_set_metadata_respond_all(flacDecoder); /* The following are only for the seekable_stream_decoder */ FLAC__seekable_stream_decoder_set_seek_callback(flacDecoder, flac_seek_handler); FLAC__seekable_stream_decoder_set_tell_callback(flacDecoder, flac_tell_handler); FLAC__seekable_stream_decoder_set_length_callback(flacDecoder, flac_length_handler); FLAC__seekable_stream_decoder_set_eof_callback(flacDecoder, flac_eof_handler); /* QUESTION: What do we do when the init fails? */ if (FLAC__seekable_stream_decoder_init(flacDecoder)) { return CODEC_ERROR; } /* The first thing to do is to parse the metadata */ FLAC__seekable_stream_decoder_process_until_end_of_metadata(flacDecoder); if (ci->id3->offset && stream_info) { FLAC__uint64 sample; sample = find_sample_number(ci, ci->id3->offset - metadata_length); ci->advance_buffer(ci->id3->offset); FLAC__seekable_stream_decoder_seek_absolute(flacDecoder, sample); FLAC__seekable_stream_decoder_get_decode_position(flacDecoder, &offset); ci->set_offset(offset); samplesdone = (uint32_t)sample; ci->set_elapsed(sample/(ci->id3->frequency/1000)); } else { samplesdone = 0; ci->set_elapsed(0); } /* The main decoder loop */ while (FLAC__seekable_stream_decoder_get_state(flacDecoder) != FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) { ci->yield(); if (ci->stop_codec || ci->reload_codec) { break; } if (ci->seek_time) { int sample_loc; sample_loc = ci->seek_time/1000 * ci->id3->frequency; if (FLAC__seekable_stream_decoder_seek_absolute(flacDecoder, sample_loc)) { samplesdone = sample_loc; ci->set_elapsed(samplesdone/(ci->id3->frequency/1000)); } ci->seek_time = 0; } FLAC__seekable_stream_decoder_process_single(flacDecoder); FLAC__seekable_stream_decoder_get_decode_position(flacDecoder, &offset); ci->set_offset(offset); } /* Flush the libFLAC buffers */ FLAC__seekable_stream_decoder_finish(flacDecoder); if (ci->request_next_track()) { if (stream_info) { FLAC__metadata_object_delete(stream_info); } if (seek_table) { FLAC__metadata_object_delete(seek_table); } metadata_length = 0; goto next_track; } return CODEC_OK; }
int FlacPcm::processData(MediaInfo *infos, ChunkList *chunk_list, bool *killswitch) { reader = infos->getReader(); if(reader == 0) return 0; if(decoder == 0) { decoder = FLAC__seekable_stream_decoder_new(); if(decoder == 0) return 0; FLAC__seekable_stream_decoder_set_md5_checking(decoder, false); FLAC__seekable_stream_decoder_set_read_callback(decoder, readCallback_); FLAC__seekable_stream_decoder_set_seek_callback(decoder, seekCallback_); FLAC__seekable_stream_decoder_set_tell_callback(decoder, tellCallback_); FLAC__seekable_stream_decoder_set_length_callback(decoder, lengthCallback_); FLAC__seekable_stream_decoder_set_eof_callback(decoder, eofCallback_); FLAC__seekable_stream_decoder_set_write_callback(decoder, writeCallback_); FLAC__seekable_stream_decoder_set_metadata_callback(decoder, metadataCallback_); FLAC__seekable_stream_decoder_set_error_callback(decoder, errorCallback_); FLAC__seekable_stream_decoder_set_client_data(decoder, this); if(FLAC__seekable_stream_decoder_init(decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK) { cleanup(); return 0; } if(!FLAC__seekable_stream_decoder_process_until_end_of_metadata(decoder)) { cleanup(); return 0; } } if(needs_seek) { FLAC__seekable_stream_decoder_seek_absolute(decoder, seek_sample); needs_seek = false; } bool eof = false; while(samples_in_reservoir < 576) { if(FLAC__seekable_stream_decoder_get_state(decoder) == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) { eof = true; break; } else if(!FLAC__seekable_stream_decoder_process_single(decoder)) { //@@@ how to do this? MessageBox(mod_.hMainWindow, FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder_)], "READ ERROR processing frame", 0); eof = true; break; } } if(samples_in_reservoir == 0) { eof = true; } else { const unsigned channels = streaminfo.data.stream_info.channels; const unsigned bits_per_sample = streaminfo.data.stream_info.bits_per_sample; const unsigned bytes_per_sample = (bits_per_sample+7)/8; const unsigned sample_rate = streaminfo.data.stream_info.sample_rate; unsigned i, n = min(samples_in_reservoir, 576), delta; signed short *ssbuffer = (signed short*)output; for(i = 0; i < n*channels; i++) ssbuffer[i] = reservoir[i]; delta = i; for( ; i < samples_in_reservoir*channels; i++) reservoir[i-delta] = reservoir[i]; samples_in_reservoir -= n; const int bytes = n * channels * bytes_per_sample; ChunkInfosI *ci=new ChunkInfosI(); ci->addInfo("srate", sample_rate); ci->addInfo("bps", bits_per_sample); ci->addInfo("nch", channels); chunk_list->setChunk("PCM", output, bytes, ci); } if(eof) return 0; return 1; }