App-MHFS
view release on metacpan or search on metacpan
share/public_html/static/music_worklet_inprogress/decoder/src/mhfs_cl_decoder.h view on Meta::CPAN
}
}
// fast path, no resampling / channel conversion needed
if((pTrack->meta.sampleRate == mhfs_d->outputSampleRate) && (pTrack->meta.channels == mhfs_d->outputChannels))
{
return mhfs_cl_track_read_pcm_frames_f32(pTrack, desired_pcm_frames, outFloat, pReturnData);
}
else
{
// initialize the data converter
if(mhfs_d->has_madc && (mhfs_d->madc.channelsIn != pTrack->meta.channels))
{
ma_data_converter_uninit(&mhfs_d->madc, NULL);
mhfs_d->has_madc = false;
}
if(!mhfs_d->has_madc)
{
ma_data_converter_config config = ma_data_converter_config_init(ma_format_f32, ma_format_f32, pTrack->meta.channels, mhfs_d->outputChannels, pTrack->meta.sampleRate, mhfs_d->outputSampleRate);
if(ma_data_converter_init(&config, NULL, &mhfs_d->madc) != MA_SUCCESS)
{
MHFSCLDEC_PRINT("failed to init data converter\n");
return MHFS_CL_ERROR;
}
mhfs_d->has_madc = true;
MHFSCLDEC_PRINT("success init data converter\n");
}
else if(mhfs_d->madc.sampleRateIn != pTrack->meta.sampleRate)
{
if(ma_data_converter_set_rate(&mhfs_d->madc, pTrack->meta.sampleRate, mhfs_d->outputSampleRate) != MA_SUCCESS)
{
MHFSCLDEC_PRINT("failed to change data converter samplerate\n");
return MHFS_CL_ERROR;
}
}
// decode
uint64_t dec_frames_req;
if(ma_data_converter_get_required_input_frame_count(&mhfs_d->madc, desired_pcm_frames, &dec_frames_req) != MA_SUCCESS)
{
MHFSCLDEC_PRINT("failed to get data converter input frame count\n");
return MHFS_CL_ERROR;
}
const size_t reqBytes = dec_frames_req * sizeof(float32_t)*pTrack->meta.channels;
if(reqBytes > mhfs_d->dcTempOutSize)
{
float32_t *tempOut = realloc(mhfs_d->pDCTempOut, reqBytes);
if(tempOut == NULL)
{
MHFSCLDEC_PRINT("realloc failed\n");
return MHFS_CL_ERROR;
}
mhfs_d->dcTempOutSize = reqBytes;
mhfs_d->pDCTempOut = tempOut;
}
const mhfs_cl_error readCode = mhfs_cl_track_read_pcm_frames_f32(pTrack, dec_frames_req, mhfs_d->pDCTempOut, pReturnData);
if((readCode != MHFS_CL_SUCCESS) || (pReturnData->frames_read == 0))
{
return readCode;
}
uint64_t decoded_frames = pReturnData->frames_read;
// resample
uint64_t frameCountOut = desired_pcm_frames;
ma_result result = ma_data_converter_process_pcm_frames(&mhfs_d->madc, mhfs_d->pDCTempOut, &decoded_frames, outFloat, &frameCountOut);
if(result != MA_SUCCESS)
{
MHFSCLDEC_PRINT("resample failed\n");
return MHFS_CL_ERROR;
}
pReturnData->frames_read = frameCountOut;
return MHFS_CL_SUCCESS;
}
}
mhfs_cl_error mhfs_cl_decoder_read_pcm_frames_f32_deinterleaved(mhfs_cl_decoder *mhfs_d, mhfs_cl_track *pTrack, const uint32_t desired_pcm_frames, float32_t *outFloat[], mhfs_cl_track_return_data *pReturnData)
{
if(desired_pcm_frames > mhfs_d->interleaveData_pcm_frames)
{
MHFSCLDEC_PRINT("%s: Not enough space to deinterleave internally\n", __func__);
return MHFS_CL_ERROR;
}
const mhfs_cl_error code = mhfs_cl_decoder_read_pcm_frames_f32(mhfs_d, pTrack, desired_pcm_frames, mhfs_d->interleavedData, pReturnData);
if(code == MHFS_CL_SUCCESS)
{
for(unsigned i = 0; i < pReturnData->frames_read; i++)
{
for(unsigned j = 0; j < mhfs_d->outputChannels; j++)
{
const float32_t sample = mhfs_d->interleavedData[(i*mhfs_d->outputChannels) + j];
outFloat[j][i] = sample;
}
}
}
return code;
}
#endif /* mhfs_cl_decoder_c */
#endif /* MHFSCLDECODER_IMPLEMENTATION */
( run in 1.261 second using v1.01-cache-2.11-cpan-d7f47b0818f )