unsigned EasyFLAC__get_channels(const EasyFLAC__StreamDecoder *decoder) { if (decoder->is_oggflac) return OggFLAC__stream_decoder_get_channels(decoder->oggflac); else return FLAC__stream_decoder_get_channels(decoder->flac); }
clFLACDataProvider::clFLACDataProvider( const std::shared_ptr<clBlob>& Data ) : m_Data( Data ) , m_Format() , m_StreamData( std::make_shared<sFLACStreamData>() ) , m_DecodingBuffer() , m_BufferUsed( 0 ) , m_IsEndOfStream( false ) { { FLAC__StreamDecoderInitStatus Status = FLAC__stream_decoder_init_stream( m_StreamData->m_Decoder, &flacRead, &flacSeek, &flacTell, &flacLength, &flacEof, &flacWrite, &flacMeta, &flacError, this ); } FLAC__bool Status = FLAC__stream_decoder_process_until_end_of_metadata( m_StreamData->m_Decoder ); if ( !Status ) return; if ( !FLAC__stream_decoder_process_single( m_StreamData->m_Decoder ) ) return; m_Format.m_NumChannels = FLAC__stream_decoder_get_channels( m_StreamData->m_Decoder ); m_Format.m_SamplesPerSecond = FLAC__stream_decoder_get_sample_rate( m_StreamData->m_Decoder ); m_Format.m_BitsPerSample = FLAC__stream_decoder_get_bits_per_sample( m_StreamData->m_Decoder ); int BufSize = FLAC__stream_decoder_get_blocksize( m_StreamData->m_Decoder ) * m_Format.m_BitsPerSample * 8 * m_Format.m_NumChannels; // store two blocks m_DecodingBuffer.resize( BufSize * 2 ); int TotalSamples = FLAC__stream_decoder_get_total_samples( m_StreamData->m_Decoder ); }
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; }
FLAC_API unsigned FLAC__seekable_stream_decoder_get_channels(const FLAC__SeekableStreamDecoder *decoder) { FLAC__ASSERT(0 != decoder); FLAC__ASSERT(0 != decoder->private_); return FLAC__stream_decoder_get_channels(decoder->private_->stream_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
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; }
unsigned OggFLAC__stream_decoder_get_channels(const OggFLAC__StreamDecoder *decoder) { FLAC__ASSERT(0 != decoder); FLAC__ASSERT(0 != decoder->private_); return FLAC__stream_decoder_get_channels(decoder->private_->FLAC_stream_decoder); }
static playbackstatus MV_GetNextFLACBlock ( VoiceNode *voice ) { flac_data * fd = (flac_data *) voice->extra; FLAC__StreamDecoderState decode_state; // FLAC__bool decode_status; voice->Playing = TRUE; if ((FLAC__uint64)(uintptr_t)voice->LoopEnd > 0 && fd->sample_pos >= (FLAC__uint64)(uintptr_t)voice->LoopEnd) if (!FLAC__stream_decoder_seek_absolute(fd->stream, (FLAC__uint64)(uintptr_t)voice->LoopStart)) MV_Printf("MV_GetNextFLACBlock FLAC__stream_decoder_seek_absolute: LOOP_START %ul, LOOP_END %ul\n", (FLAC__uint64)(uintptr_t)voice->LoopStart, (FLAC__uint64)(uintptr_t)voice->LoopEnd); /*decode_status =*/ FLAC__stream_decoder_process_single(fd->stream); decode_state = FLAC__stream_decoder_get_state(fd->stream); /* if (!decode_status) { MV_Printf("MV_GetNextFLACBlock: %s\n", FLAC__StreamDecoderStateString[decode_state]); voice->Playing = FALSE; return NoMoreData; } */ if (decode_state == FLAC__STREAM_DECODER_SEEK_ERROR) { FLAC__stream_decoder_flush(fd->stream); decode_state = FLAC__stream_decoder_get_state(fd->stream); } if (decode_state == FLAC__STREAM_DECODER_END_OF_STREAM) { if (voice->LoopSize > 0) { if (!FLAC__stream_decoder_seek_absolute(fd->stream, (FLAC__uint64)(uintptr_t)voice->LoopStart)) MV_Printf("MV_GetNextFLACBlock FLAC__stream_decoder_seek_absolute: LOOP_START %ul\n", (FLAC__uint64)(uintptr_t)voice->LoopStart); } else { voice->Playing = FALSE; return NoMoreData; } } #if 0 // unnecessary: duplicated in write_flac_stream() voice->channels = FLAC__stream_decoder_get_channels(fd->stream); voice->bits = FLAC__stream_decoder_get_bits_per_sample(fd->stream); voice->SamplingRate = FLAC__stream_decoder_get_sample_rate(fd->stream); // CODEDUP multivoc.c MV_SetVoicePitch voice->RateScale = ( voice->SamplingRate * voice->PitchScale ) / MV_MixRate; voice->FixedPointBufferSize = ( voice->RateScale * MV_MIXBUFFERSIZE ) - voice->RateScale; MV_SetVoiceMixMode( voice ); #endif return KeepPlaying; }
/* Populate the imFileInfoRec8 structure describing this file instance to Premiere. Check file validity, allocate any private instance data to share between different calls. */ prMALError SDKGetInfo8( imStdParms *stdParms, imFileAccessRec8 *fileAccessInfo, imFileInfoRec8 *fileInfo) { prMALError result = malNoError; PrivateDataH pdH = reinterpret_cast<PrivateDataH>(fileInfo->privatedata); stdParms->piSuites->memFuncs->lockHandle(reinterpret_cast<char**>(pdH)); //Lock private data (*pdH)->flacErrorCode = 0; (*pdH)->flacDecoder = 0; char filepathASCII[255]; int stringLength = (int)wcslen(reinterpret_cast<const wchar_t*>(fileAccessInfo->filepath)); wcstombs_s( NULL, reinterpret_cast<char*>(filepathASCII), sizeof (filepathASCII), fileAccessInfo->filepath, stringLength); FLAC__bool ok = true; FLAC__StreamDecoderInitStatus init_status; if(((*pdH)->flacDecoder = FLAC__stream_decoder_new()) == NULL) { (*pdH)->flacErrorCode = 1; } FLAC__stream_decoder_set_md5_checking((*pdH)->flacDecoder, true); init_status = FLAC__stream_decoder_init_file((*pdH)->flacDecoder, filepathASCII, write_callback, NULL, error_callback, pdH); if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK ) { return imBadFile; //Error, bail out } FLAC__stream_decoder_process_until_end_of_metadata((*pdH)->flacDecoder); FLAC__stream_decoder_process_single((*pdH)->flacDecoder); (*pdH)->audioChannels = FLAC__stream_decoder_get_channels((*pdH)->flacDecoder); (*pdH)->audioNumberOfSamples = FLAC__stream_decoder_get_total_samples((*pdH)->flacDecoder); (*pdH)->audioNumberOfSamplesPerSecond = FLAC__stream_decoder_get_sample_rate((*pdH)->flacDecoder); (*pdH)->audioBytesPerSample = FLAC__stream_decoder_get_bits_per_sample((*pdH)->flacDecoder) / 8; (*pdH)->audioPosition = 0; //Fill out the general file info fileInfo->accessModes = kSeparateSequentialAudio; fileInfo->hasDataRate = kPrFalse; fileInfo->hasVideo = kPrFalse; fileInfo->hasAudio = kPrTrue; fileInfo->alwaysUnquiet = 0; fileInfo->highMemUsage = 0; fileInfo->audInfo.numChannels = (*pdH)->audioChannels; fileInfo->audInfo.sampleRate = (float)(*pdH)->audioNumberOfSamplesPerSecond; fileInfo->audDuration = (*pdH)->audioNumberOfSamples; if((*pdH)->audioBytesPerSample == 1) { fileInfo->audInfo.sampleType = kPrAudioSampleType_8BitInt; } else if((*pdH)->audioBytesPerSample == 2) { fileInfo->audInfo.sampleType = kPrAudioSampleType_16BitInt; } else if((*pdH)->audioBytesPerSample == 3) { fileInfo->audInfo.sampleType = kPrAudioSampleType_24BitInt; } else if((*pdH)->audioBytesPerSample == 4) { fileInfo->audInfo.sampleType = kPrAudioSampleType_32BitInt; } else { fileInfo->audInfo.sampleType = kPrAudioSampleType_Other; } (*pdH)->suiteBasic = stdParms->piSuites->utilFuncs->getSPBasicSuite(); //Allocate an audio suite if ((*pdH)->suiteBasic) { (*pdH)->suiteBasic->AcquireSuite (kPrSDKAudioSuite, kPrSDKAudioSuiteVersion, (const void**)&(*pdH)->suiteAudio); } stdParms->piSuites->memFuncs->unlockHandle(reinterpret_cast<char**>(pdH)); //Unlock private data return result; }
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; }
FLAC__StreamDecoderWriteStatus flacwrite( const FLAC__StreamDecoder* decoder, const FLAC__Frame* frame, const FLAC__int32* const buffer[], void *client_data) { struct audiosource* source = (struct audiosource*)client_data; struct audiosourceflac_internaldata* idata = source->internaldata; if (idata->eof && idata->returnerroroneof) { // simply ignore data return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; } // if we still need format info, grab it now: if (source->samplerate == 0) { int channels = FLAC__stream_decoder_get_channels(idata->decoder); unsigned int bits = FLAC__stream_decoder_get_bits_per_sample( idata->decoder); unsigned int samplerate = FLAC__stream_decoder_get_sample_rate( idata->decoder); if (samplerate <= 3000 || channels < 1 || bits < 8 || bits > 32) { // this is invalid idata->eof = 1; idata->returnerroroneof = 1; return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; } source->samplerate = samplerate; source->channels = channels; // check if we can deal with the audio format: switch (bits) { case 8: source->format = AUDIOSOURCEFORMAT_U8; break; case 16: source->format = AUDIOSOURCEFORMAT_S16LE; break; case 24: source->format = AUDIOSOURCEFORMAT_S24LE; break; case 32: source->format = AUDIOSOURCEFORMAT_S32LE; break; default: // invalid format idata->eof = 1; idata->returnerroroneof = 1; return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; } idata->bytespersample = bits/8; } // see how much samples we can process: unsigned int samples = frame->header.blocksize; while (samples * source->channels * idata->bytespersample > DECODE_BUFFER-(idata->decodedbytes+idata->decodedbufoffset)) { samples /= 2; } // get correct write pointer to our decode buffer: void* p = ((char*)idata->decodedbuf) + idata->decodedbufoffset + idata->decodedbytes; // fetch and write out samples: unsigned int j = 0; unsigned int k = 0; while (j < samples) { unsigned int i = 0; while (i < source->channels) { const void* sample = ((char*)(buffer[i]))+(j*sizeof(int32_t)); memcpy(p, sample, idata->bytespersample); k += idata->bytespersample; p += idata->bytespersample; i++; } j++; } idata->decodedbytes += k; return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; }