/* Add the timing of a new packet to the TimingBuffer */ static void tb_add(struct TimingBuffer *tb, spx_int16_t timing) { int pos; /* Discard packet that won't make it into the list because they're too early */ if (tb->filled >= MAX_TIMINGS && timing >= tb->timing[tb->filled - 1]) { tb->curr_count++; return; } /* Find where the timing info goes in the sorted list */ pos = 0; /* FIXME: Do bisection instead of linear search */ while (pos < tb->filled && timing >= tb->timing[pos]) { pos++; } speex_assert(pos <= tb->filled && pos < MAX_TIMINGS); /* Shift everything so we can perform the insertion */ if (pos < tb->filled) { int move_size = tb->filled - pos; if (tb->filled == MAX_TIMINGS) move_size -= 1; SPEEX_MOVE(&tb->timing[pos + 1], &tb->timing[pos], move_size); SPEEX_MOVE(&tb->counts[pos + 1], &tb->counts[pos], move_size); } /* Insert */ tb->timing[pos] = timing; tb->counts[pos] = tb->curr_count; tb->curr_count++; if (tb->filled < MAX_TIMINGS) tb->filled++; }
/*Callback to process an audio frame.*/ static FLAC__StreamDecoderWriteStatus write_callback( const FLAC__StreamDecoder *decoder,const FLAC__Frame *frame, const FLAC__int32 *const buffer[],void *client_data){ flacfile *flac; int channels; opus_int32 blocksize; int bits_per_sample; float scale; const int *channel_permute; float *block_buf; int ci; opus_int32 si; (void)decoder; flac=(flacfile *)client_data; /*We do not allow the number of channels to change.*/ channels=frame->header.channels; if(channels!=flac->channels){ return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; } /*We do not allow block sizes larger than the declared maximum.*/ blocksize=frame->header.blocksize; if(blocksize>flac->max_blocksize){ return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; } /*We do allow the bits per sample to change, though this will confound Opus's silence detection.*/ bits_per_sample=frame->header.bits_per_sample; speex_assert(bits_per_sample>0&&bits_per_sample<=32); scale=(0x80000000U>>(bits_per_sample-1))*(1.0F/0x80000000U); channel_permute=flac->channel_permute; block_buf=flac->block_buf; for(ci=0;ci<channels;ci++){ const FLAC__int32 *channel_buf; channel_buf=buffer[channel_permute[ci]]; for(si=0;si<blocksize;si++){ /*There's a loss of precision here for 32-bit samples, but libFLAC doesn't currently support more than 24.*/ block_buf[si*channels+ci]=scale*(float)channel_buf[si]; } } flac->block_buf_pos=0; flac->block_buf_len=blocksize; return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; }
int flac_open(FILE *in,oe_enc_opt *opt,unsigned char *oldbuf,int buflen){ flacfile *flac; /*Ok. At this point, we know we have a FLAC or an OggFLAC file. Set up the FLAC decoder.*/ flac=malloc(sizeof(*flac)); flac->decoder=FLAC__stream_decoder_new(); FLAC__stream_decoder_set_md5_checking(flac->decoder,false); /*We get STREAMINFO packets by default, but not VORBIS_COMMENT or PICTURE.*/ FLAC__stream_decoder_set_metadata_respond(flac->decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT); FLAC__stream_decoder_set_metadata_respond(flac->decoder, FLAC__METADATA_TYPE_PICTURE); flac->inopt=opt; flac->f=in; flac->oldbuf=malloc(buflen*sizeof(*flac->oldbuf)); memcpy(flac->oldbuf,oldbuf,buflen*sizeof(*flac->oldbuf)); flac->bufpos=0; flac->buflen=buflen; flac->block_buf=NULL; if((*(flac_id(oldbuf,buflen)? FLAC__stream_decoder_init_stream:FLAC__stream_decoder_init_ogg_stream))( flac->decoder,read_callback,NULL,NULL,NULL,eof_callback, write_callback,metadata_callback,error_callback,flac)== FLAC__STREAM_DECODER_INIT_STATUS_OK){ /*Decode until we get the file length, sample rate, the number of channels, and the Vorbis comments (if any).*/ if(FLAC__stream_decoder_process_until_end_of_metadata(flac->decoder)){ opt->read_samples=flac_read; opt->readdata=flac; /*FLAC supports 1 to 8 channels only.*/ speex_assert(flac->channels>0&&flac->channels<=8); /*It uses the same channel mappings as WAV.*/ flac->channel_permute=wav_permute_matrix[flac->channels-1]; return 1; } } flac_close(flac); fprintf(stderr,_("ERROR: Could not open FLAC stream.\n")); return 0; }