App-MHFS
view release on metacpan or search on metacpan
share/public_html/static/music_inc/src/miniaudio.h view on Meta::CPAN
MA_API const char* ma_get_format_name(ma_format format);
/*
Blends two frames in floating point format.
*/
MA_API void ma_blend_f32(float* pOut, float* pInA, float* pInB, float factor, ma_uint32 channels);
/*
Retrieves the size of a sample in bytes for the given format.
This API is efficient and is implemented using a lookup table.
Thread Safety: SAFE
This API is pure.
*/
MA_API ma_uint32 ma_get_bytes_per_sample(ma_format format);
static MA_INLINE ma_uint32 ma_get_bytes_per_frame(ma_format format, ma_uint32 channels) { return ma_get_bytes_per_sample(format) * channels; }
/*
Converts a log level to a string.
*/
MA_API const char* ma_log_level_to_string(ma_uint32 logLevel);
/************************************************************************************************************************************************************
*************************************************************************************************************************************************************
DEVICE I/O
==========
This section contains the APIs for device playback and capture. Here is where you'll find ma_device_init(), etc.
*************************************************************************************************************************************************************
************************************************************************************************************************************************************/
#ifndef MA_NO_DEVICE_IO
/* Some backends are only supported on certain platforms. */
#if defined(MA_WIN32)
#define MA_SUPPORT_WASAPI
#if defined(MA_WIN32_DESKTOP) /* DirectSound and WinMM backends are only supported on desktops. */
#define MA_SUPPORT_DSOUND
#define MA_SUPPORT_WINMM
#define MA_SUPPORT_JACK /* JACK is technically supported on Windows, but I don't know how many people use it in practice... */
#endif
#endif
#if defined(MA_UNIX)
#if defined(MA_LINUX)
#if !defined(MA_ANDROID) /* ALSA is not supported on Android. */
#define MA_SUPPORT_ALSA
#endif
#endif
#if !defined(MA_BSD) && !defined(MA_ANDROID) && !defined(MA_EMSCRIPTEN)
#define MA_SUPPORT_PULSEAUDIO
#define MA_SUPPORT_JACK
#endif
#if defined(MA_ANDROID)
#define MA_SUPPORT_AAUDIO
#define MA_SUPPORT_OPENSL
#endif
#if defined(__OpenBSD__) /* <-- Change this to "#if defined(MA_BSD)" to enable sndio on all BSD flavors. */
#define MA_SUPPORT_SNDIO /* sndio is only supported on OpenBSD for now. May be expanded later if there's demand. */
#endif
#if defined(__NetBSD__) || defined(__OpenBSD__)
#define MA_SUPPORT_AUDIO4 /* Only support audio(4) on platforms with known support. */
#endif
#if defined(__FreeBSD__) || defined(__DragonFly__)
#define MA_SUPPORT_OSS /* Only support OSS on specific platforms with known support. */
#endif
#endif
#if defined(MA_APPLE)
#define MA_SUPPORT_COREAUDIO
#endif
#if defined(MA_EMSCRIPTEN)
#define MA_SUPPORT_WEBAUDIO
#endif
/* Explicitly disable the Null backend for Emscripten because it uses a background thread which is not properly supported right now. */
#if !defined(MA_EMSCRIPTEN)
#define MA_SUPPORT_NULL
#endif
#if !defined(MA_NO_WASAPI) && defined(MA_SUPPORT_WASAPI)
#define MA_ENABLE_WASAPI
#endif
#if !defined(MA_NO_DSOUND) && defined(MA_SUPPORT_DSOUND)
#define MA_ENABLE_DSOUND
#endif
#if !defined(MA_NO_WINMM) && defined(MA_SUPPORT_WINMM)
#define MA_ENABLE_WINMM
#endif
#if !defined(MA_NO_ALSA) && defined(MA_SUPPORT_ALSA)
#define MA_ENABLE_ALSA
#endif
#if !defined(MA_NO_PULSEAUDIO) && defined(MA_SUPPORT_PULSEAUDIO)
#define MA_ENABLE_PULSEAUDIO
#endif
#if !defined(MA_NO_JACK) && defined(MA_SUPPORT_JACK)
#define MA_ENABLE_JACK
#endif
#if !defined(MA_NO_COREAUDIO) && defined(MA_SUPPORT_COREAUDIO)
#define MA_ENABLE_COREAUDIO
#endif
#if !defined(MA_NO_SNDIO) && defined(MA_SUPPORT_SNDIO)
#define MA_ENABLE_SNDIO
#endif
#if !defined(MA_NO_AUDIO4) && defined(MA_SUPPORT_AUDIO4)
#define MA_ENABLE_AUDIO4
#endif
#if !defined(MA_NO_OSS) && defined(MA_SUPPORT_OSS)
#define MA_ENABLE_OSS
#endif
#if !defined(MA_NO_AAUDIO) && defined(MA_SUPPORT_AAUDIO)
#define MA_ENABLE_AAUDIO
#endif
#if !defined(MA_NO_OPENSL) && defined(MA_SUPPORT_OPENSL)
#define MA_ENABLE_OPENSL
#endif
#if !defined(MA_NO_WEBAUDIO) && defined(MA_SUPPORT_WEBAUDIO)
#define MA_ENABLE_WEBAUDIO
#endif
share/public_html/static/music_inc/src/miniaudio.h view on Meta::CPAN
MA_API ma_result ma_channel_converter_init(const ma_channel_converter_config* pConfig, ma_channel_converter* pConverter)
{
ma_uint32 iChannelIn;
ma_uint32 iChannelOut;
if (pConverter == NULL) {
return MA_INVALID_ARGS;
}
MA_ZERO_OBJECT(pConverter);
if (pConfig == NULL) {
return MA_INVALID_ARGS;
}
/* Basic validation for channel counts. */
if (pConfig->channelsIn < MA_MIN_CHANNELS || pConfig->channelsIn > MA_MAX_CHANNELS ||
pConfig->channelsOut < MA_MIN_CHANNELS || pConfig->channelsOut > MA_MAX_CHANNELS) {
return MA_INVALID_ARGS;
}
if (!ma_channel_map_valid(pConfig->channelsIn, pConfig->channelMapIn)) {
return MA_INVALID_ARGS; /* Invalid input channel map. */
}
if (!ma_channel_map_valid(pConfig->channelsOut, pConfig->channelMapOut)) {
return MA_INVALID_ARGS; /* Invalid output channel map. */
}
pConverter->format = pConfig->format;
pConverter->channelsIn = pConfig->channelsIn;
pConverter->channelsOut = pConfig->channelsOut;
ma_channel_map_copy(pConverter->channelMapIn, pConfig->channelMapIn, pConfig->channelsIn);
ma_channel_map_copy(pConverter->channelMapOut, pConfig->channelMapOut, pConfig->channelsOut);
pConverter->mixingMode = pConfig->mixingMode;
for (iChannelIn = 0; iChannelIn < pConverter->channelsIn; iChannelIn += 1) {
for (iChannelOut = 0; iChannelOut < pConverter->channelsOut; ++iChannelOut) {
if (pConverter->format == ma_format_f32) {
pConverter->weights.f32[iChannelIn][iChannelOut] = pConfig->weights[iChannelIn][iChannelOut];
} else {
pConverter->weights.s16[iChannelIn][iChannelOut] = ma_channel_converter_float_to_fixed(pConfig->weights[iChannelIn][iChannelOut]);
}
}
}
/* If the input and output channels and channel maps are the same we should use a passthrough. */
if (pConverter->channelsIn == pConverter->channelsOut) {
if (ma_channel_map_equal(pConverter->channelsIn, pConverter->channelMapIn, pConverter->channelMapOut)) {
pConverter->isPassthrough = MA_TRUE;
}
if (ma_channel_map_blank(pConverter->channelsIn, pConverter->channelMapIn) || ma_channel_map_blank(pConverter->channelsOut, pConverter->channelMapOut)) {
pConverter->isPassthrough = MA_TRUE;
}
}
/*
We can use a simple case for expanding the mono channel. This will used when expanding a mono input into any output so long
as no LFE is present in the output.
*/
if (!pConverter->isPassthrough) {
if (pConverter->channelsIn == 1 && pConverter->channelMapIn[0] == MA_CHANNEL_MONO) {
/* Optimal case if no LFE is in the output channel map. */
pConverter->isSimpleMonoExpansion = MA_TRUE;
if (ma_channel_map_contains_channel_position(pConverter->channelsOut, pConverter->channelMapOut, MA_CHANNEL_LFE)) {
pConverter->isSimpleMonoExpansion = MA_FALSE;
}
}
}
/* Another optimized case is stereo to mono. */
if (!pConverter->isPassthrough) {
if (pConverter->channelsOut == 1 && pConverter->channelMapOut[0] == MA_CHANNEL_MONO && pConverter->channelsIn == 2) {
/* Optimal case if no LFE is in the input channel map. */
pConverter->isStereoToMono = MA_TRUE;
if (ma_channel_map_contains_channel_position(pConverter->channelsIn, pConverter->channelMapIn, MA_CHANNEL_LFE)) {
pConverter->isStereoToMono = MA_FALSE;
}
}
}
/*
Here is where we do a bit of pre-processing to know how each channel should be combined to make up the output. Rules:
1) If it's a passthrough, do nothing - it's just a simple memcpy().
2) If the channel counts are the same and every channel position in the input map is present in the output map, use a
simple shuffle. An example might be different 5.1 channel layouts.
3) Otherwise channels are blended based on spatial locality.
*/
if (!pConverter->isPassthrough) {
if (pConverter->channelsIn == pConverter->channelsOut) {
ma_bool32 areAllChannelPositionsPresent = MA_TRUE;
for (iChannelIn = 0; iChannelIn < pConverter->channelsIn; ++iChannelIn) {
ma_bool32 isInputChannelPositionInOutput = MA_FALSE;
for (iChannelOut = 0; iChannelOut < pConverter->channelsOut; ++iChannelOut) {
if (pConverter->channelMapIn[iChannelIn] == pConverter->channelMapOut[iChannelOut]) {
isInputChannelPositionInOutput = MA_TRUE;
break;
}
}
if (!isInputChannelPositionInOutput) {
areAllChannelPositionsPresent = MA_FALSE;
break;
}
}
if (areAllChannelPositionsPresent) {
pConverter->isSimpleShuffle = MA_TRUE;
/*
All the router will be doing is rearranging channels which means all we need to do is use a shuffling table which is just
a mapping between the index of the input channel to the index of the output channel.
*/
for (iChannelIn = 0; iChannelIn < pConverter->channelsIn; ++iChannelIn) {
for (iChannelOut = 0; iChannelOut < pConverter->channelsOut; ++iChannelOut) {
if (pConverter->channelMapIn[iChannelIn] == pConverter->channelMapOut[iChannelOut]) {
share/public_html/static/music_inc/src/miniaudio.h view on Meta::CPAN
{
float* pFramesOutF;
ma_uint64 totalFramesRead;
MA_ASSERT(pVorbis != NULL);
MA_ASSERT(pDecoder != NULL);
pFramesOutF = (float*)pFramesOut;
totalFramesRead = 0;
while (frameCount > 0) {
/* Read from the in-memory buffer first. */
ma_uint32 framesToReadFromCache = (ma_uint32)ma_min(pVorbis->framesRemaining, frameCount); /* Safe cast because pVorbis->framesRemaining is 32-bit. */
if (pFramesOut != NULL) {
ma_uint64 iFrame;
for (iFrame = 0; iFrame < framesToReadFromCache; iFrame += 1) {
ma_uint32 iChannel;
for (iChannel = 0; iChannel < pDecoder->internalChannels; ++iChannel) {
pFramesOutF[iChannel] = pVorbis->ppPacketData[iChannel][pVorbis->framesConsumed+iFrame];
}
pFramesOutF += pDecoder->internalChannels;
}
}
pVorbis->framesConsumed += framesToReadFromCache;
pVorbis->framesRemaining -= framesToReadFromCache;
frameCount -= framesToReadFromCache;
totalFramesRead += framesToReadFromCache;
if (frameCount == 0) {
break;
}
MA_ASSERT(pVorbis->framesRemaining == 0);
/* We've run out of cached frames, so decode the next packet and continue iteration. */
do
{
int samplesRead;
int consumedDataSize;
if (pVorbis->dataSize > INT_MAX) {
break; /* Too big. */
}
samplesRead = 0;
consumedDataSize = stb_vorbis_decode_frame_pushdata(pVorbis->pInternalVorbis, pVorbis->pData, (int)pVorbis->dataSize, NULL, (float***)&pVorbis->ppPacketData, &samplesRead);
if (consumedDataSize != 0) {
size_t leftoverDataSize = (pVorbis->dataSize - (size_t)consumedDataSize);
size_t i;
for (i = 0; i < leftoverDataSize; ++i) {
pVorbis->pData[i] = pVorbis->pData[i + consumedDataSize];
}
pVorbis->dataSize = leftoverDataSize;
pVorbis->framesConsumed = 0;
pVorbis->framesRemaining = samplesRead;
break;
} else {
/* Need more data. If there's any room in the existing buffer allocation fill that first. Otherwise expand. */
size_t bytesRead;
if (pVorbis->dataCapacity == pVorbis->dataSize) {
/* No room. Expand. */
size_t oldCap = pVorbis->dataCapacity;
size_t newCap = pVorbis->dataCapacity + MA_VORBIS_DATA_CHUNK_SIZE;
ma_uint8* pNewData;
pNewData = (ma_uint8*)ma__realloc_from_callbacks(pVorbis->pData, newCap, oldCap, &pDecoder->allocationCallbacks);
if (pNewData == NULL) {
return totalFramesRead; /* Out of memory. */
}
pVorbis->pData = pNewData;
pVorbis->dataCapacity = newCap;
}
/* Fill in a chunk. */
bytesRead = ma_decoder_read_bytes(pDecoder, pVorbis->pData + pVorbis->dataSize, (pVorbis->dataCapacity - pVorbis->dataSize));
if (bytesRead == 0) {
return totalFramesRead; /* Error reading more data. */
}
pVorbis->dataSize += bytesRead;
}
} while (MA_TRUE);
}
return totalFramesRead;
}
static ma_result ma_vorbis_decoder_seek_to_pcm_frame(ma_vorbis_decoder* pVorbis, ma_decoder* pDecoder, ma_uint64 frameIndex)
{
float buffer[4096];
MA_ASSERT(pVorbis != NULL);
MA_ASSERT(pDecoder != NULL);
/*
This is terribly inefficient because stb_vorbis does not have a good seeking solution with it's push API. Currently this just performs
a full decode right from the start of the stream. Later on I'll need to write a layer that goes through all of the Ogg pages until we
find the one containing the sample we need. Then we know exactly where to seek for stb_vorbis.
TODO: Use seeking logic documented for stb_vorbis_flush_pushdata().
*/
if (!ma_decoder_seek_bytes(pDecoder, 0, ma_seek_origin_start)) {
return MA_ERROR;
}
stb_vorbis_flush_pushdata(pVorbis->pInternalVorbis);
pVorbis->framesConsumed = 0;
pVorbis->framesRemaining = 0;
pVorbis->dataSize = 0;
while (frameIndex > 0) {
ma_uint32 framesRead;
ma_uint32 framesToRead = ma_countof(buffer)/pDecoder->internalChannels;
if (framesToRead > frameIndex) {
framesToRead = (ma_uint32)frameIndex;
}
( run in 0.309 second using v1.01-cache-2.11-cpan-483215c6ad5 )