view release on metacpan or search on metacpan
share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h view on Meta::CPAN
/*
We run slightly different logic depending on whether or not we're using a heap-allocated
buffer for caching input data. This will be the case if the data converter does not have
the ability to retrieve the required input frame count for a given output frame count.
*/
if (pDevice->playback.pInputCache != NULL) {
while (totalFramesReadOut < frameCount) {
ma_uint64 framesToReadThisIterationIn;
ma_uint64 framesToReadThisIterationOut;
/* If there's any data available in the cache, that needs to get processed first. */
if (pDevice->playback.inputCacheRemaining > 0) {
framesToReadThisIterationOut = (frameCount - totalFramesReadOut);
framesToReadThisIterationIn = framesToReadThisIterationOut;
if (framesToReadThisIterationIn > pDevice->playback.inputCacheRemaining) {
framesToReadThisIterationIn = pDevice->playback.inputCacheRemaining;
}
result = ma_data_converter_process_pcm_frames(&pDevice->playback.converter, ma_offset_pcm_frames_ptr(pDevice->playback.pInputCache, pDevice->playback.inputCacheConsumed, pDevice->playback.format, pDevice->playback.channels), &fram...
if (result != MA_SUCCESS) {
break;
}
pDevice->playback.inputCacheConsumed += framesToReadThisIterationIn;
pDevice->playback.inputCacheRemaining -= framesToReadThisIterationIn;
totalFramesReadOut += framesToReadThisIterationOut;
pRunningFramesOut = ma_offset_ptr(pRunningFramesOut, framesToReadThisIterationOut * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels));
if (framesToReadThisIterationIn == 0 && framesToReadThisIterationOut == 0) {
break; /* We're done. */
}
}
/* Getting here means there's no data in the cache and we need to fill it up with data from the client. */
if (pDevice->playback.inputCacheRemaining == 0) {
ma_device__handle_data_callback(pDevice, pDevice->playback.pInputCache, NULL, (ma_uint32)pDevice->playback.inputCacheCap);
pDevice->playback.inputCacheConsumed = 0;
pDevice->playback.inputCacheRemaining = pDevice->playback.inputCacheCap;
}
}
} else {
while (totalFramesReadOut < frameCount) {
ma_uint8 pIntermediaryBuffer[MA_DATA_CONVERTER_STACK_BUFFER_SIZE]; /* In client format. */
ma_uint64 intermediaryBufferCap = sizeof(pIntermediaryBuffer) / ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
ma_uint64 framesToReadThisIterationIn;
ma_uint64 framesReadThisIterationIn;
ma_uint64 framesToReadThisIterationOut;
ma_uint64 framesReadThisIterationOut;
ma_uint64 requiredInputFrameCount;
framesToReadThisIterationOut = (frameCount - totalFramesReadOut);
framesToReadThisIterationIn = framesToReadThisIterationOut;
if (framesToReadThisIterationIn > intermediaryBufferCap) {
framesToReadThisIterationIn = intermediaryBufferCap;
}
ma_data_converter_get_required_input_frame_count(&pDevice->playback.converter, framesToReadThisIterationOut, &requiredInputFrameCount);
if (framesToReadThisIterationIn > requiredInputFrameCount) {
framesToReadThisIterationIn = requiredInputFrameCount;
}
if (framesToReadThisIterationIn > 0) {
ma_device__handle_data_callback(pDevice, pIntermediaryBuffer, NULL, (ma_uint32)framesToReadThisIterationIn);
}
/*
At this point we have our decoded data in input format and now we need to convert to output format. Note that even if we didn't read any
input frames, we still want to try processing frames because there may some output frames generated from cached input data.
*/
framesReadThisIterationIn = framesToReadThisIterationIn;
framesReadThisIterationOut = framesToReadThisIterationOut;
result = ma_data_converter_process_pcm_frames(&pDevice->playback.converter, pIntermediaryBuffer, &framesReadThisIterationIn, pRunningFramesOut, &framesReadThisIterationOut);
if (result != MA_SUCCESS) {
break;
}
totalFramesReadOut += framesReadThisIterationOut;
pRunningFramesOut = ma_offset_ptr(pRunningFramesOut, framesReadThisIterationOut * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels));
if (framesReadThisIterationIn == 0 && framesReadThisIterationOut == 0) {
break; /* We're done. */
}
}
}
}
}
/* A helper for sending sample data to the client. */
static void ma_device__send_frames_to_client(ma_device* pDevice, ma_uint32 frameCountInDeviceFormat, const void* pFramesInDeviceFormat)
{
MA_ASSERT(pDevice != NULL);
MA_ASSERT(frameCountInDeviceFormat > 0);
MA_ASSERT(pFramesInDeviceFormat != NULL);
if (pDevice->capture.converter.isPassthrough) {
ma_device__handle_data_callback(pDevice, NULL, pFramesInDeviceFormat, frameCountInDeviceFormat);
} else {
ma_result result;
ma_uint8 pFramesInClientFormat[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
ma_uint64 framesInClientFormatCap = sizeof(pFramesInClientFormat) / ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels);
ma_uint64 totalDeviceFramesProcessed = 0;
ma_uint64 totalClientFramesProcessed = 0;
const void* pRunningFramesInDeviceFormat = pFramesInDeviceFormat;
/* We just keep going until we've exhaused all of our input frames and cannot generate any more output frames. */
for (;;) {
ma_uint64 deviceFramesProcessedThisIteration;
ma_uint64 clientFramesProcessedThisIteration;
deviceFramesProcessedThisIteration = (frameCountInDeviceFormat - totalDeviceFramesProcessed);
clientFramesProcessedThisIteration = framesInClientFormatCap;
result = ma_data_converter_process_pcm_frames(&pDevice->capture.converter, pRunningFramesInDeviceFormat, &deviceFramesProcessedThisIteration, pFramesInClientFormat, &clientFramesProcessedThisIteration);
if (result != MA_SUCCESS) {
break;
}
if (clientFramesProcessedThisIteration > 0) {
ma_device__handle_data_callback(pDevice, NULL, pFramesInClientFormat, (ma_uint32)clientFramesProcessedThisIteration); /* Safe cast. */
share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h view on Meta::CPAN
if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "[ALSA] Dropping playback device...\n");
((ma_snd_pcm_drop_proc)pDevice->pContext->alsa.snd_pcm_drop)((ma_snd_pcm_t*)pDevice->alsa.pPCMPlayback);
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "[ALSA] Dropping playback device successful.\n");
/* We need to prepare the device again, otherwise we won't be able to restart the device. */
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "[ALSA] Preparing playback device...\n");
if (((ma_snd_pcm_prepare_proc)pDevice->pContext->alsa.snd_pcm_prepare)((ma_snd_pcm_t*)pDevice->alsa.pPCMPlayback) < 0) {
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "[ALSA] Preparing playback device failed.\n");
} else {
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "[ALSA] Preparing playback device successful.\n");
}
}
return MA_SUCCESS;
}
static ma_result ma_device_wait__alsa(ma_device* pDevice, ma_snd_pcm_t* pPCM, struct pollfd* pPollDescriptors, int pollDescriptorCount, short requiredEvent)
{
for (;;) {
unsigned short revents;
int resultALSA;
int resultPoll = poll(pPollDescriptors, pollDescriptorCount, -1);
if (resultPoll < 0) {
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[ALSA] poll() failed.");
return ma_result_from_errno(errno);
}
/*
Before checking the ALSA poll descriptor flag we need to check if the wakeup descriptor
has had it's POLLIN flag set. If so, we need to actually read the data and then exit
function. The wakeup descriptor will be the first item in the descriptors buffer.
*/
if ((pPollDescriptors[0].revents & POLLIN) != 0) {
ma_uint64 t;
int resultRead = read(pPollDescriptors[0].fd, &t, sizeof(t)); /* <-- Important that we read here so that the next write() does not block. */
if (resultRead < 0) {
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[ALSA] read() failed.");
return ma_result_from_errno(errno);
}
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "[ALSA] POLLIN set for wakeupfd\n");
return MA_DEVICE_NOT_STARTED;
}
/*
Getting here means that some data should be able to be read. We need to use ALSA to
translate the revents flags for us.
*/
resultALSA = ((ma_snd_pcm_poll_descriptors_revents_proc)pDevice->pContext->alsa.snd_pcm_poll_descriptors_revents)(pPCM, pPollDescriptors + 1, pollDescriptorCount - 1, &revents); /* +1, -1 to ignore the wakeup descriptor. */
if (resultALSA < 0) {
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[ALSA] snd_pcm_poll_descriptors_revents() failed.");
return ma_result_from_errno(-resultALSA);
}
if ((revents & POLLERR) != 0) {
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[ALSA] POLLERR detected.");
return ma_result_from_errno(errno);
}
if ((revents & requiredEvent) == requiredEvent) {
break; /* We're done. Data available for reading or writing. */
}
}
return MA_SUCCESS;
}
static ma_result ma_device_wait_read__alsa(ma_device* pDevice)
{
return ma_device_wait__alsa(pDevice, (ma_snd_pcm_t*)pDevice->alsa.pPCMCapture, (struct pollfd*)pDevice->alsa.pPollDescriptorsCapture, pDevice->alsa.pollDescriptorCountCapture + 1, POLLIN); /* +1 to account for the wakeup descriptor. */
}
static ma_result ma_device_wait_write__alsa(ma_device* pDevice)
{
return ma_device_wait__alsa(pDevice, (ma_snd_pcm_t*)pDevice->alsa.pPCMPlayback, (struct pollfd*)pDevice->alsa.pPollDescriptorsPlayback, pDevice->alsa.pollDescriptorCountPlayback + 1, POLLOUT); /* +1 to account for the wakeup descriptor. */
}
static ma_result ma_device_read__alsa(ma_device* pDevice, void* pFramesOut, ma_uint32 frameCount, ma_uint32* pFramesRead)
{
ma_snd_pcm_sframes_t resultALSA = 0;
MA_ASSERT(pDevice != NULL);
MA_ASSERT(pFramesOut != NULL);
if (pFramesRead != NULL) {
*pFramesRead = 0;
}
while (ma_device_get_state(pDevice) == ma_device_state_started) {
ma_result result;
/* The first thing to do is wait for data to become available for reading. This will return an error code if the device has been stopped. */
result = ma_device_wait_read__alsa(pDevice);
if (result != MA_SUCCESS) {
return result;
}
/* Getting here means we should have data available. */
resultALSA = ((ma_snd_pcm_readi_proc)pDevice->pContext->alsa.snd_pcm_readi)((ma_snd_pcm_t*)pDevice->alsa.pPCMCapture, pFramesOut, frameCount);
if (resultALSA >= 0) {
break; /* Success. */
} else {
if (resultALSA == -EAGAIN) {
/*ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "EGAIN (read)\n");*/
continue; /* Try again. */
} else if (resultALSA == -EPIPE) {
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "EPIPE (read)\n");
/* Overrun. Recover and try again. If this fails we need to return an error. */
resultALSA = ((ma_snd_pcm_recover_proc)pDevice->pContext->alsa.snd_pcm_recover)((ma_snd_pcm_t*)pDevice->alsa.pPCMCapture, resultALSA, MA_TRUE);
if (resultALSA < 0) {
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[ALSA] Failed to recover device after overrun.");
return ma_result_from_errno((int)-resultALSA);
}
resultALSA = ((ma_snd_pcm_start_proc)pDevice->pContext->alsa.snd_pcm_start)((ma_snd_pcm_t*)pDevice->alsa.pPCMCapture);
if (resultALSA < 0) {
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[ALSA] Failed to start device after underrun.");
return ma_result_from_errno((int)-resultALSA);
}
share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h view on Meta::CPAN
if ((caps->confs[iConfig].enc & (1UL << iEncoding)) == 0) {
continue;
}
bits = caps->enc[iEncoding].bits;
bps = caps->enc[iEncoding].bps;
sig = caps->enc[iEncoding].sig;
le = caps->enc[iEncoding].le;
msb = caps->enc[iEncoding].msb;
format = ma_format_from_sio_enc__sndio(bits, bps, sig, le, msb);
if (format == ma_format_unknown) {
continue; /* Format not supported. */
}
if (bestFormat == ma_format_unknown) {
bestFormat = format;
} else {
if (ma_get_format_priority_index(bestFormat) > ma_get_format_priority_index(format)) { /* <-- Lower = better. */
bestFormat = format;
}
}
}
}
return bestFormat;
}
static ma_uint32 ma_find_best_channels_from_sio_cap__sndio(struct ma_sio_cap* caps, ma_device_type deviceType, ma_format requiredFormat)
{
ma_uint32 maxChannels;
unsigned int iConfig;
MA_ASSERT(caps != NULL);
MA_ASSERT(requiredFormat != ma_format_unknown);
/* Just pick whatever configuration has the most channels. */
maxChannels = 0;
for (iConfig = 0; iConfig < caps->nconf; iConfig += 1) {
/* The encoding should be of requiredFormat. */
unsigned int iEncoding;
for (iEncoding = 0; iEncoding < MA_SIO_NENC; iEncoding += 1) {
unsigned int iChannel;
unsigned int bits;
unsigned int bps;
unsigned int sig;
unsigned int le;
unsigned int msb;
ma_format format;
if ((caps->confs[iConfig].enc & (1UL << iEncoding)) == 0) {
continue;
}
bits = caps->enc[iEncoding].bits;
bps = caps->enc[iEncoding].bps;
sig = caps->enc[iEncoding].sig;
le = caps->enc[iEncoding].le;
msb = caps->enc[iEncoding].msb;
format = ma_format_from_sio_enc__sndio(bits, bps, sig, le, msb);
if (format != requiredFormat) {
continue;
}
/* Getting here means the format is supported. Iterate over each channel count and grab the biggest one. */
for (iChannel = 0; iChannel < MA_SIO_NCHAN; iChannel += 1) {
unsigned int chan = 0;
unsigned int channels;
if (deviceType == ma_device_type_playback) {
chan = caps->confs[iConfig].pchan;
} else {
chan = caps->confs[iConfig].rchan;
}
if ((chan & (1UL << iChannel)) == 0) {
continue;
}
if (deviceType == ma_device_type_playback) {
channels = caps->pchan[iChannel];
} else {
channels = caps->rchan[iChannel];
}
if (maxChannels < channels) {
maxChannels = channels;
}
}
}
}
return maxChannels;
}
static ma_uint32 ma_find_best_sample_rate_from_sio_cap__sndio(struct ma_sio_cap* caps, ma_device_type deviceType, ma_format requiredFormat, ma_uint32 requiredChannels)
{
ma_uint32 firstSampleRate;
ma_uint32 bestSampleRate;
unsigned int iConfig;
MA_ASSERT(caps != NULL);
MA_ASSERT(requiredFormat != ma_format_unknown);
MA_ASSERT(requiredChannels > 0);
MA_ASSERT(requiredChannels <= MA_MAX_CHANNELS);
firstSampleRate = 0; /* <-- If the device does not support a standard rate we'll fall back to the first one that's found. */
bestSampleRate = 0;
for (iConfig = 0; iConfig < caps->nconf; iConfig += 1) {
/* The encoding should be of requiredFormat. */
unsigned int iEncoding;
for (iEncoding = 0; iEncoding < MA_SIO_NENC; iEncoding += 1) {
unsigned int iChannel;
unsigned int bits;
unsigned int bps;
unsigned int sig;
unsigned int le;
unsigned int msb;
ma_format format;
if ((caps->confs[iConfig].enc & (1UL << iEncoding)) == 0) {
continue;
}
bits = caps->enc[iEncoding].bits;
bps = caps->enc[iEncoding].bps;
sig = caps->enc[iEncoding].sig;
le = caps->enc[iEncoding].le;
msb = caps->enc[iEncoding].msb;
format = ma_format_from_sio_enc__sndio(bits, bps, sig, le, msb);
if (format != requiredFormat) {
continue;
}
/* Getting here means the format is supported. Iterate over each channel count and grab the biggest one. */
for (iChannel = 0; iChannel < MA_SIO_NCHAN; iChannel += 1) {
unsigned int chan = 0;
unsigned int channels;
unsigned int iRate;
if (deviceType == ma_device_type_playback) {
chan = caps->confs[iConfig].pchan;
} else {
chan = caps->confs[iConfig].rchan;
}
if ((chan & (1UL << iChannel)) == 0) {
continue;
}
if (deviceType == ma_device_type_playback) {
channels = caps->pchan[iChannel];
} else {
channels = caps->rchan[iChannel];
}
if (channels != requiredChannels) {
continue;
}
/* Getting here means we have found a compatible encoding/channel pair. */
for (iRate = 0; iRate < MA_SIO_NRATE; iRate += 1) {
ma_uint32 rate = (ma_uint32)caps->rate[iRate];
ma_uint32 ratePriority;
if (firstSampleRate == 0) {
firstSampleRate = rate;
}
/* Disregard this rate if it's not a standard one. */
ratePriority = ma_get_standard_sample_rate_priority_index__sndio(rate);
if (ratePriority == (ma_uint32)-1) {
continue;
}
if (ma_get_standard_sample_rate_priority_index__sndio(bestSampleRate) > ratePriority) { /* Lower = better. */
bestSampleRate = rate;
}
}
}
}
}
/* If a standard sample rate was not found just fall back to the first one that was iterated. */
if (bestSampleRate == 0) {
bestSampleRate = firstSampleRate;
}
return bestSampleRate;
}
static ma_result ma_context_enumerate_devices__sndio(ma_context* pContext, ma_enum_devices_callback_proc callback, void* pUserData)
{
ma_bool32 isTerminating = MA_FALSE;
struct ma_sio_hdl* handle;
MA_ASSERT(pContext != NULL);
MA_ASSERT(callback != NULL);
/* sndio doesn't seem to have a good device enumeration API, so I'm therefore only enumerating over default devices for now. */
/* Playback. */
if (!isTerminating) {
handle = ((ma_sio_open_proc)pContext->sndio.sio_open)(MA_SIO_DEVANY, MA_SIO_PLAY, 0);
if (handle != NULL) {
/* Supports playback. */
ma_device_info deviceInfo;
MA_ZERO_OBJECT(&deviceInfo);
ma_strcpy_s(deviceInfo.id.sndio, sizeof(deviceInfo.id.sndio), MA_SIO_DEVANY);
ma_strcpy_s(deviceInfo.name, sizeof(deviceInfo.name), MA_DEFAULT_PLAYBACK_DEVICE_NAME);
isTerminating = !callback(pContext, ma_device_type_playback, &deviceInfo, pUserData);
((ma_sio_close_proc)pContext->sndio.sio_close)(handle);
}
}
share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h view on Meta::CPAN
framesProcessedOut = 0;
tempBufferInCap = sizeof(pTempBufferIn) / ma_get_bytes_per_frame(pConverter->resampler.format, pConverter->resampler.channels);
tempBufferMidCap = sizeof(pTempBufferIn) / ma_get_bytes_per_frame(pConverter->resampler.format, pConverter->resampler.channels);
tempBufferOutCap = sizeof(pTempBufferOut) / ma_get_bytes_per_frame(pConverter->channelConverter.format, pConverter->channelConverter.channelsOut);
while (framesProcessedOut < frameCountOut) {
ma_uint64 frameCountInThisIteration;
ma_uint64 frameCountOutThisIteration;
const void* pRunningFramesIn = NULL;
void* pRunningFramesOut = NULL;
const void* pResampleBufferIn;
void* pChannelsBufferOut;
if (pFramesIn != NULL) {
pRunningFramesIn = ma_offset_ptr(pFramesIn, framesProcessedIn * ma_get_bytes_per_frame(pConverter->formatIn, pConverter->channelsIn));
}
if (pFramesOut != NULL) {
pRunningFramesOut = ma_offset_ptr(pFramesOut, framesProcessedOut * ma_get_bytes_per_frame(pConverter->formatOut, pConverter->channelsOut));
}
/* Run input data through the resampler and output it to the temporary buffer. */
frameCountInThisIteration = (frameCountIn - framesProcessedIn);
if (pConverter->hasPreFormatConversion) {
if (frameCountInThisIteration > tempBufferInCap) {
frameCountInThisIteration = tempBufferInCap;
}
}
frameCountOutThisIteration = (frameCountOut - framesProcessedOut);
if (frameCountOutThisIteration > tempBufferMidCap) {
frameCountOutThisIteration = tempBufferMidCap;
}
/* We can't read more frames than can fit in the output buffer. */
if (pConverter->hasPostFormatConversion) {
if (frameCountOutThisIteration > tempBufferOutCap) {
frameCountOutThisIteration = tempBufferOutCap;
}
}
/* We need to ensure we don't try to process too many input frames that we run out of room in the output buffer. If this happens we'll end up glitching. */
/*
We need to try to predict how many input frames will be required for the resampler. If the
resampler can tell us, we'll use that. Otherwise we'll need to make a best guess. The further
off we are from this, the more wasted format conversions we'll end up doing.
*/
#if 1
{
ma_uint64 requiredInputFrameCount;
result = ma_resampler_get_required_input_frame_count(&pConverter->resampler, frameCountOutThisIteration, &requiredInputFrameCount);
if (result != MA_SUCCESS) {
/* Fall back to a best guess. */
requiredInputFrameCount = (frameCountOutThisIteration * pConverter->resampler.sampleRateIn) / pConverter->resampler.sampleRateOut;
}
if (frameCountInThisIteration > requiredInputFrameCount) {
frameCountInThisIteration = requiredInputFrameCount;
}
}
#endif
if (pConverter->hasPreFormatConversion) {
if (pFramesIn != NULL) {
ma_convert_pcm_frames_format(pTempBufferIn, pConverter->resampler.format, pRunningFramesIn, pConverter->formatIn, frameCountInThisIteration, pConverter->channelsIn, pConverter->ditherMode);
pResampleBufferIn = pTempBufferIn;
} else {
pResampleBufferIn = NULL;
}
} else {
pResampleBufferIn = pRunningFramesIn;
}
result = ma_resampler_process_pcm_frames(&pConverter->resampler, pResampleBufferIn, &frameCountInThisIteration, pTempBufferMid, &frameCountOutThisIteration);
if (result != MA_SUCCESS) {
return result;
}
/*
The input data has been resampled so now we need to run it through the channel converter. The input data is always contained in pTempBufferMid. We only need to do
this part if we have an output buffer.
*/
if (pFramesOut != NULL) {
if (pConverter->hasPostFormatConversion) {
pChannelsBufferOut = pTempBufferOut;
} else {
pChannelsBufferOut = pRunningFramesOut;
}
result = ma_channel_converter_process_pcm_frames(&pConverter->channelConverter, pChannelsBufferOut, pTempBufferMid, frameCountOutThisIteration);
if (result != MA_SUCCESS) {
return result;
}
/* Finally we do post format conversion. */
if (pConverter->hasPostFormatConversion) {
ma_convert_pcm_frames_format(pRunningFramesOut, pConverter->formatOut, pChannelsBufferOut, pConverter->channelConverter.format, frameCountOutThisIteration, pConverter->channelConverter.channelsOut, pConverter->ditherMode);
}
}
framesProcessedIn += frameCountInThisIteration;
framesProcessedOut += frameCountOutThisIteration;
MA_ASSERT(framesProcessedIn <= frameCountIn);
MA_ASSERT(framesProcessedOut <= frameCountOut);
if (frameCountOutThisIteration == 0) {
break; /* Consumed all of our input data. */
}
}
if (pFrameCountIn != NULL) {
*pFrameCountIn = framesProcessedIn;
}
if (pFrameCountOut != NULL) {
*pFrameCountOut = framesProcessedOut;
share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h view on Meta::CPAN
while (framesProcessedOut < frameCountOut) {
ma_uint64 frameCountInThisIteration;
ma_uint64 frameCountOutThisIteration;
const void* pRunningFramesIn = NULL;
void* pRunningFramesOut = NULL;
const void* pChannelsBufferIn;
void* pResampleBufferOut;
if (pFramesIn != NULL) {
pRunningFramesIn = ma_offset_ptr(pFramesIn, framesProcessedIn * ma_get_bytes_per_frame(pConverter->formatIn, pConverter->channelsIn));
}
if (pFramesOut != NULL) {
pRunningFramesOut = ma_offset_ptr(pFramesOut, framesProcessedOut * ma_get_bytes_per_frame(pConverter->formatOut, pConverter->channelsOut));
}
/*
Before doing any processing we need to determine how many frames we should try processing
this iteration, for both input and output. The resampler requires us to perform format and
channel conversion before passing any data into it. If we get our input count wrong, we'll
end up peforming redundant pre-processing. This isn't the end of the world, but it does
result in some inefficiencies proportionate to how far our estimates are off.
If the resampler has a means to calculate exactly how much we'll need, we'll use that.
Otherwise we'll make a best guess. In order to do this, we'll need to calculate the output
frame count first.
*/
frameCountOutThisIteration = (frameCountOut - framesProcessedOut);
if (frameCountOutThisIteration > tempBufferMidCap) {
frameCountOutThisIteration = tempBufferMidCap;
}
if (pConverter->hasPostFormatConversion) {
if (frameCountOutThisIteration > tempBufferOutCap) {
frameCountOutThisIteration = tempBufferOutCap;
}
}
/* Now that we have the output frame count we can determine the input frame count. */
frameCountInThisIteration = (frameCountIn - framesProcessedIn);
if (pConverter->hasPreFormatConversion) {
if (frameCountInThisIteration > tempBufferInCap) {
frameCountInThisIteration = tempBufferInCap;
}
}
if (frameCountInThisIteration > tempBufferMidCap) {
frameCountInThisIteration = tempBufferMidCap;
}
#if 1
{
ma_uint64 requiredInputFrameCount;
result = ma_resampler_get_required_input_frame_count(&pConverter->resampler, frameCountOutThisIteration, &requiredInputFrameCount);
if (result != MA_SUCCESS) {
/* Fall back to a best guess. */
requiredInputFrameCount = (frameCountOutThisIteration * pConverter->resampler.sampleRateIn) / pConverter->resampler.sampleRateOut;
}
if (frameCountInThisIteration > requiredInputFrameCount) {
frameCountInThisIteration = requiredInputFrameCount;
}
}
#endif
/* Pre format conversion. */
if (pConverter->hasPreFormatConversion) {
if (pRunningFramesIn != NULL) {
ma_convert_pcm_frames_format(pTempBufferIn, pConverter->channelConverter.format, pRunningFramesIn, pConverter->formatIn, frameCountInThisIteration, pConverter->channelsIn, pConverter->ditherMode);
pChannelsBufferIn = pTempBufferIn;
} else {
pChannelsBufferIn = NULL;
}
} else {
pChannelsBufferIn = pRunningFramesIn;
}
/* Channel conversion. */
result = ma_channel_converter_process_pcm_frames(&pConverter->channelConverter, pTempBufferMid, pChannelsBufferIn, frameCountInThisIteration);
if (result != MA_SUCCESS) {
return result;
}
/* Resampling. */
if (pConverter->hasPostFormatConversion) {
pResampleBufferOut = pTempBufferOut;
} else {
pResampleBufferOut = pRunningFramesOut;
}
result = ma_resampler_process_pcm_frames(&pConverter->resampler, pTempBufferMid, &frameCountInThisIteration, pResampleBufferOut, &frameCountOutThisIteration);
if (result != MA_SUCCESS) {
return result;
}
/* Post format conversion. */
if (pConverter->hasPostFormatConversion) {
if (pRunningFramesOut != NULL) {
ma_convert_pcm_frames_format(pRunningFramesOut, pConverter->formatOut, pResampleBufferOut, pConverter->resampler.format, frameCountOutThisIteration, pConverter->channelsOut, pConverter->ditherMode);
}
}
framesProcessedIn += frameCountInThisIteration;
framesProcessedOut += frameCountOutThisIteration;
MA_ASSERT(framesProcessedIn <= frameCountIn);
MA_ASSERT(framesProcessedOut <= frameCountOut);
if (frameCountOutThisIteration == 0) {
break; /* Consumed all of our input data. */
}
}
if (pFrameCountIn != NULL) {
*pFrameCountIn = framesProcessedIn;
}
share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h view on Meta::CPAN
while (totalFramesReadOut < frameCount) {
ma_uint64 framesToReadThisIterationIn;
ma_uint64 framesToReadThisIterationOut;
/* If there's any data available in the cache, that needs to get processed first. */
if (pDecoder->inputCacheRemaining > 0) {
framesToReadThisIterationOut = (frameCount - totalFramesReadOut);
framesToReadThisIterationIn = framesToReadThisIterationOut;
if (framesToReadThisIterationIn > pDecoder->inputCacheRemaining) {
framesToReadThisIterationIn = pDecoder->inputCacheRemaining;
}
result = ma_data_converter_process_pcm_frames(&pDecoder->converter, ma_offset_pcm_frames_ptr(pDecoder->pInputCache, pDecoder->inputCacheConsumed, internalFormat, internalChannels), &framesToReadThisIterationIn, pRunningFramesO...
if (result != MA_SUCCESS) {
break;
}
pDecoder->inputCacheConsumed += framesToReadThisIterationIn;
pDecoder->inputCacheRemaining -= framesToReadThisIterationIn;
totalFramesReadOut += framesToReadThisIterationOut;
if (pRunningFramesOut != NULL) {
pRunningFramesOut = ma_offset_ptr(pRunningFramesOut, framesToReadThisIterationOut * ma_get_bytes_per_frame(pDecoder->outputFormat, pDecoder->outputChannels));
}
if (framesToReadThisIterationIn == 0 && framesToReadThisIterationOut == 0) {
break; /* We're done. */
}
}
/* Getting here means there's no data in the cache and we need to fill it up from the data source. */
if (pDecoder->inputCacheRemaining == 0) {
pDecoder->inputCacheConsumed = 0;
result = ma_data_source_read_pcm_frames(pDecoder->pBackend, pDecoder->pInputCache, pDecoder->inputCacheCap, &pDecoder->inputCacheRemaining);
if (result != MA_SUCCESS) {
break;
}
}
}
} else {
/* We have a way of determining the required number of input frames so just use the stack. */
while (totalFramesReadOut < frameCount) {
ma_uint8 pIntermediaryBuffer[MA_DATA_CONVERTER_STACK_BUFFER_SIZE]; /* In internal format. */
ma_uint64 intermediaryBufferCap = sizeof(pIntermediaryBuffer) / ma_get_bytes_per_frame(internalFormat, internalChannels);
ma_uint64 framesToReadThisIterationIn;
ma_uint64 framesReadThisIterationIn;
ma_uint64 framesToReadThisIterationOut;
ma_uint64 framesReadThisIterationOut;
ma_uint64 requiredInputFrameCount;
framesToReadThisIterationOut = (frameCount - totalFramesReadOut);
framesToReadThisIterationIn = framesToReadThisIterationOut;
if (framesToReadThisIterationIn > intermediaryBufferCap) {
framesToReadThisIterationIn = intermediaryBufferCap;
}
ma_data_converter_get_required_input_frame_count(&pDecoder->converter, framesToReadThisIterationOut, &requiredInputFrameCount);
if (framesToReadThisIterationIn > requiredInputFrameCount) {
framesToReadThisIterationIn = requiredInputFrameCount;
}
if (requiredInputFrameCount > 0) {
result = ma_data_source_read_pcm_frames(pDecoder->pBackend, pIntermediaryBuffer, framesToReadThisIterationIn, &framesReadThisIterationIn);
} else {
framesReadThisIterationIn = 0;
}
/*
At this point we have our decoded data in input format and now we need to convert to output format. Note that even if we didn't read any
input frames, we still want to try processing frames because there may some output frames generated from cached input data.
*/
framesReadThisIterationOut = framesToReadThisIterationOut;
result = ma_data_converter_process_pcm_frames(&pDecoder->converter, pIntermediaryBuffer, &framesReadThisIterationIn, pRunningFramesOut, &framesReadThisIterationOut);
if (result != MA_SUCCESS) {
break;
}
totalFramesReadOut += framesReadThisIterationOut;
if (pRunningFramesOut != NULL) {
pRunningFramesOut = ma_offset_ptr(pRunningFramesOut, framesReadThisIterationOut * ma_get_bytes_per_frame(pDecoder->outputFormat, pDecoder->outputChannels));
}
if (framesReadThisIterationIn == 0 && framesReadThisIterationOut == 0) {
break; /* We're done. */
}
}
}
}
}
pDecoder->readPointerInPCMFrames += totalFramesReadOut;
if (pFramesRead != NULL) {
*pFramesRead = totalFramesReadOut;
}
if (result == MA_SUCCESS && totalFramesReadOut == 0) {
result = MA_AT_END;
}
return result;
}
MA_API ma_result ma_decoder_seek_to_pcm_frame(ma_decoder* pDecoder, ma_uint64 frameIndex)
{
if (pDecoder == NULL) {
return MA_INVALID_ARGS;
}
if (pDecoder->pBackend != NULL) {
ma_result result;
ma_uint64 internalFrameIndex;
ma_uint32 internalSampleRate;
ma_uint64 currentFrameIndex;
result = ma_data_source_get_data_format(pDecoder->pBackend, NULL, NULL, &internalSampleRate, NULL, 0);
if (result != MA_SUCCESS) {
return result; /* Failed to retrieve the internal sample rate. */