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 )