FLAC__FileDecoder *FLAC__file_decoder_new() { FLAC__FileDecoder *decoder; FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ decoder = (FLAC__FileDecoder*)malloc(sizeof(FLAC__FileDecoder)); if(decoder == 0) { return 0; } memset(decoder, 0, sizeof(FLAC__FileDecoder)); decoder->protected_ = (FLAC__FileDecoderProtected*)malloc(sizeof(FLAC__FileDecoderProtected)); if(decoder->protected_ == 0) { free(decoder); return 0; } memset(decoder->protected_, 0, sizeof(FLAC__FileDecoderProtected)); decoder->private_ = (FLAC__FileDecoderPrivate*)malloc(sizeof(FLAC__FileDecoderPrivate)); if(decoder->private_ == 0) { free(decoder->protected_); free(decoder); return 0; } memset(decoder->private_, 0, sizeof(FLAC__FileDecoderPrivate)); decoder->private_->seekable_stream_decoder = FLAC__seekable_stream_decoder_new(); if(0 == decoder->private_->seekable_stream_decoder) { free(decoder->private_); free(decoder->protected_); free(decoder); return 0; } decoder->private_->file = 0; set_defaults_(decoder); decoder->protected_->state = FLAC__FILE_DECODER_UNINITIALIZED; return decoder; }
bool FLACInputStream::initialize(FilePtr file) { m_file = file; // initialize the decoder m_decoder = FLAC__seekable_stream_decoder_new(); if (!m_decoder) { m_file = 0; return false; } #define SET_CALLBACK(name) \ FLAC__seekable_stream_decoder_set_##name##_callback( \ m_decoder, \ name##_callback) // set callbacks FLAC__seekable_stream_decoder_set_client_data (m_decoder, this); SET_CALLBACK(read); SET_CALLBACK(seek); SET_CALLBACK(tell); SET_CALLBACK(length); SET_CALLBACK(eof); SET_CALLBACK(write); SET_CALLBACK(metadata); SET_CALLBACK(error); FLAC__SeekableStreamDecoderState state = FLAC__seekable_stream_decoder_init(m_decoder); if (state != FLAC__SEEKABLE_STREAM_DECODER_OK) { FLAC__seekable_stream_decoder_finish(m_decoder); FLAC__seekable_stream_decoder_delete(m_decoder); m_decoder = 0; m_file = 0; return false; } // make sure we have metadata before we return! if (!FLAC__seekable_stream_decoder_process_until_end_of_metadata(m_decoder)) { FLAC__seekable_stream_decoder_finish(m_decoder); FLAC__seekable_stream_decoder_delete(m_decoder); m_decoder = 0; m_file = 0; return false; } // process one frame so we can do something! if (!FLAC__seekable_stream_decoder_process_single(m_decoder)) { FLAC__seekable_stream_decoder_finish(m_decoder); FLAC__seekable_stream_decoder_delete(m_decoder); m_decoder = 0; m_file = 0; return false; } // get info about the flac file m_channel_count = FLAC__seekable_stream_decoder_get_channels(m_decoder); m_sample_rate = FLAC__seekable_stream_decoder_get_sample_rate(m_decoder); int bps = FLAC__seekable_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; }
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; }