App-MHFS

 view release on metacpan or  search on metacpan

share/public_html/static/music_inc/src/miniaudio.h  view on Meta::CPAN

            if (masterVolumeFactor < 1) {
                if (pFramesIn == NULL) {    /* <-- In full-duplex situations, the volume will have been applied to the input samples before the data callback. Applying it again post-callback will incorrectly compound it. */
                    ma_apply_volume_factor_pcm_frames(pFramesOut, frameCount, pDevice->playback.format, pDevice->playback.channels, masterVolumeFactor);
                }
            }

            if (!pDevice->noClip && pDevice->playback.format == ma_format_f32) {
                ma_clip_pcm_frames_f32((float*)pFramesOut, frameCount, pDevice->playback.channels);
            }
        }
    }
}



/* A helper function for reading sample data from the client. */
static void ma_device__read_frames_from_client(ma_device* pDevice, ma_uint32 frameCount, void* pFramesOut)
{
    MA_ASSERT(pDevice != NULL);
    MA_ASSERT(frameCount > 0);
    MA_ASSERT(pFramesOut != NULL);

    if (pDevice->playback.converter.isPassthrough) {
        ma_device__on_data(pDevice, pFramesOut, NULL, frameCount);
    } else {
        ma_result result;
        ma_uint64 totalFramesReadOut;
        ma_uint64 totalFramesReadIn;
        void* pRunningFramesOut;

        totalFramesReadOut = 0;
        totalFramesReadIn  = 0;
        pRunningFramesOut  = pFramesOut;

        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;
            }

            requiredInputFrameCount = ma_data_converter_get_required_input_frame_count(&pDevice->playback.converter, framesToReadThisIterationOut);
            if (framesToReadThisIterationIn > requiredInputFrameCount) {
                framesToReadThisIterationIn = requiredInputFrameCount;
            }

            if (framesToReadThisIterationIn > 0) {
                ma_device__on_data(pDevice, pIntermediaryBuffer, NULL, (ma_uint32)framesToReadThisIterationIn);
                totalFramesReadIn += 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__on_data(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__on_data(pDevice, NULL, pFramesInClientFormat, (ma_uint32)clientFramesProcessedThisIteration);    /* Safe cast. */
            }

            pRunningFramesInDeviceFormat = ma_offset_ptr(pRunningFramesInDeviceFormat, deviceFramesProcessedThisIteration * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels));
            totalDeviceFramesProcessed  += deviceFramesProcessedThisIteration;
            totalClientFramesProcessed  += clientFramesProcessedThisIteration;

            if (deviceFramesProcessedThisIteration == 0 && clientFramesProcessedThisIteration == 0) {
                break;  /* We're done. */
            }

share/public_html/static/music_inc/src/miniaudio.h  view on Meta::CPAN

    return 0;
}

MA_API ma_uint64 ma_decoder_read_pcm_frames(ma_decoder* pDecoder, void* pFramesOut, ma_uint64 frameCount)
{
    ma_result result;
    ma_uint64 totalFramesReadOut;
    ma_uint64 totalFramesReadIn;
    void* pRunningFramesOut;
    
    if (pDecoder == NULL) {
        return 0;
    }

    if (pDecoder->onReadPCMFrames == NULL) {
        return 0;
    }

    /* Fast path. */
    if (pDecoder->converter.isPassthrough) {
        totalFramesReadOut = pDecoder->onReadPCMFrames(pDecoder, pFramesOut, frameCount);
    } else {
        /*
        Getting here means we need to do data conversion. If we're seeking forward and are _not_ doing resampling we can run this in a fast path. If we're doing resampling we
        need to run through each sample because we need to ensure it's internal cache is updated.
        */
        if (pFramesOut == NULL && pDecoder->converter.hasResampler == MA_FALSE) {
            totalFramesReadOut = pDecoder->onReadPCMFrames(pDecoder, NULL, frameCount);   /* All decoder backends must support passing in NULL for the output buffer. */
        } else {
            /* Slow path. Need to run everything through the data converter. */
            totalFramesReadOut = 0;
            totalFramesReadIn  = 0;
            pRunningFramesOut  = pFramesOut;
    
            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(pDecoder->internalFormat, pDecoder->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;
                }

                requiredInputFrameCount = ma_data_converter_get_required_input_frame_count(&pDecoder->converter, framesToReadThisIterationOut);
                if (framesToReadThisIterationIn > requiredInputFrameCount) {
                    framesToReadThisIterationIn = requiredInputFrameCount;
                }

                if (requiredInputFrameCount > 0) {
                    framesReadThisIterationIn = pDecoder->onReadPCMFrames(pDecoder, pIntermediaryBuffer, framesToReadThisIterationIn);
                    totalFramesReadIn += framesReadThisIterationIn;
                }

                /*
                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;

    return totalFramesReadOut;
}

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->onSeekToPCMFrame) {
        ma_result result;
        ma_uint64 internalFrameIndex;
        if (pDecoder->internalSampleRate == pDecoder->outputSampleRate) {
            internalFrameIndex = frameIndex;
        } else {
            internalFrameIndex = ma_calculate_frame_count_after_resampling(pDecoder->internalSampleRate, pDecoder->outputSampleRate, frameIndex);
        }

        result = pDecoder->onSeekToPCMFrame(pDecoder, internalFrameIndex);
        if (result == MA_SUCCESS) {
            pDecoder->readPointerInPCMFrames = frameIndex;
        }

        return result;
    }

    /* Should never get here, but if we do it means onSeekToPCMFrame was not set by the backend. */
    return MA_INVALID_ARGS;
}

MA_API ma_result ma_decoder_get_available_frames(ma_decoder* pDecoder, ma_uint64* pAvailableFrames)
{
    ma_uint64 totalFrameCount;

    if (pAvailableFrames == NULL) {
        return MA_INVALID_ARGS;
    }

share/public_html/static/music_inc/src/miniaudio.h  view on Meta::CPAN

#ifdef DRFLAC_64BIT
    prediction = 0;
    switch (order)
    {
    case 32: prediction += coefficients[31] * (drflac_int64)pDecodedSamples[-32];
    case 31: prediction += coefficients[30] * (drflac_int64)pDecodedSamples[-31];
    case 30: prediction += coefficients[29] * (drflac_int64)pDecodedSamples[-30];
    case 29: prediction += coefficients[28] * (drflac_int64)pDecodedSamples[-29];
    case 28: prediction += coefficients[27] * (drflac_int64)pDecodedSamples[-28];
    case 27: prediction += coefficients[26] * (drflac_int64)pDecodedSamples[-27];
    case 26: prediction += coefficients[25] * (drflac_int64)pDecodedSamples[-26];
    case 25: prediction += coefficients[24] * (drflac_int64)pDecodedSamples[-25];
    case 24: prediction += coefficients[23] * (drflac_int64)pDecodedSamples[-24];
    case 23: prediction += coefficients[22] * (drflac_int64)pDecodedSamples[-23];
    case 22: prediction += coefficients[21] * (drflac_int64)pDecodedSamples[-22];
    case 21: prediction += coefficients[20] * (drflac_int64)pDecodedSamples[-21];
    case 20: prediction += coefficients[19] * (drflac_int64)pDecodedSamples[-20];
    case 19: prediction += coefficients[18] * (drflac_int64)pDecodedSamples[-19];
    case 18: prediction += coefficients[17] * (drflac_int64)pDecodedSamples[-18];
    case 17: prediction += coefficients[16] * (drflac_int64)pDecodedSamples[-17];
    case 16: prediction += coefficients[15] * (drflac_int64)pDecodedSamples[-16];
    case 15: prediction += coefficients[14] * (drflac_int64)pDecodedSamples[-15];
    case 14: prediction += coefficients[13] * (drflac_int64)pDecodedSamples[-14];
    case 13: prediction += coefficients[12] * (drflac_int64)pDecodedSamples[-13];
    case 12: prediction += coefficients[11] * (drflac_int64)pDecodedSamples[-12];
    case 11: prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11];
    case 10: prediction += coefficients[ 9] * (drflac_int64)pDecodedSamples[-10];
    case  9: prediction += coefficients[ 8] * (drflac_int64)pDecodedSamples[- 9];
    case  8: prediction += coefficients[ 7] * (drflac_int64)pDecodedSamples[- 8];
    case  7: prediction += coefficients[ 6] * (drflac_int64)pDecodedSamples[- 7];
    case  6: prediction += coefficients[ 5] * (drflac_int64)pDecodedSamples[- 6];
    case  5: prediction += coefficients[ 4] * (drflac_int64)pDecodedSamples[- 5];
    case  4: prediction += coefficients[ 3] * (drflac_int64)pDecodedSamples[- 4];
    case  3: prediction += coefficients[ 2] * (drflac_int64)pDecodedSamples[- 3];
    case  2: prediction += coefficients[ 1] * (drflac_int64)pDecodedSamples[- 2];
    case  1: prediction += coefficients[ 0] * (drflac_int64)pDecodedSamples[- 1];
    }
#endif
    return (drflac_int32)(prediction >> shift);
}
#if 0
static drflac_bool32 drflac__decode_samples_with_residual__rice__reference(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int3...
{
    drflac_uint32 i;
    DRFLAC_ASSERT(bs != NULL);
    DRFLAC_ASSERT(count > 0);
    DRFLAC_ASSERT(pSamplesOut != NULL);
    for (i = 0; i < count; ++i) {
        drflac_uint32 zeroCounter = 0;
        for (;;) {
            drflac_uint8 bit;
            if (!drflac__read_uint8(bs, 1, &bit)) {
                return DRFLAC_FALSE;
            }
            if (bit == 0) {
                zeroCounter += 1;
            } else {
                break;
            }
        }
        drflac_uint32 decodedRice;
        if (riceParam > 0) {
            if (!drflac__read_uint32(bs, riceParam, &decodedRice)) {
                return DRFLAC_FALSE;
            }
        } else {
            decodedRice = 0;
        }
        decodedRice |= (zeroCounter << riceParam);
        if ((decodedRice & 0x01)) {
            decodedRice = ~(decodedRice >> 1);
        } else {
            decodedRice =  (decodedRice >> 1);
        }
        if (bitsPerSample+shift >= 32) {
            pSamplesOut[i] = decodedRice + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + i);
        } else {
            pSamplesOut[i] = decodedRice + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + i);
        }
    }
    return DRFLAC_TRUE;
}
#endif
#if 0
static drflac_bool32 drflac__read_rice_parts__reference(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
{
    drflac_uint32 zeroCounter = 0;
    drflac_uint32 decodedRice;
    for (;;) {
        drflac_uint8 bit;
        if (!drflac__read_uint8(bs, 1, &bit)) {
            return DRFLAC_FALSE;
        }
        if (bit == 0) {
            zeroCounter += 1;
        } else {
            break;
        }
    }
    if (riceParam > 0) {
        if (!drflac__read_uint32(bs, riceParam, &decodedRice)) {
            return DRFLAC_FALSE;
        }
    } else {
        decodedRice = 0;
    }
    *pZeroCounterOut = zeroCounter;
    *pRiceParamPartOut = decodedRice;
    return DRFLAC_TRUE;
}
#endif
#if 0
static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
{
    drflac_cache_t riceParamMask;
    drflac_uint32 zeroCounter;
    drflac_uint32 setBitOffsetPlus1;
    drflac_uint32 riceParamPart;
    drflac_uint32 riceLength;
    DRFLAC_ASSERT(riceParam > 0);
    riceParamMask = DRFLAC_CACHE_L1_SELECTION_MASK(riceParam);
    zeroCounter = 0;
    while (bs->cache == 0) {
        zeroCounter += (drflac_uint32)DRFLAC_CACHE_L1_BITS_REMAINING(bs);
        if (!drflac__reload_cache(bs)) {
            return DRFLAC_FALSE;
        }
    }
    setBitOffsetPlus1 = drflac__clz(bs->cache);
    zeroCounter += setBitOffsetPlus1;
    setBitOffsetPlus1 += 1;
    riceLength = setBitOffsetPlus1 + riceParam;
    if (riceLength < DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
        riceParamPart = (drflac_uint32)((bs->cache & (riceParamMask >> setBitOffsetPlus1)) >> DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceLength));
        bs->consumedBits += riceLength;
        bs->cache <<= riceLength;
    } else {
        drflac_uint32 bitCountLo;
        drflac_cache_t resultHi;
        bs->consumedBits += riceLength;
        bs->cache <<= setBitOffsetPlus1 & (DRFLAC_CACHE_L1_SIZE_BITS(bs)-1);
        bitCountLo = bs->consumedBits - DRFLAC_CACHE_L1_SIZE_BITS(bs);
        resultHi = DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, riceParam);
        if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
#ifndef DR_FLAC_NO_CRC
            drflac__update_crc16(bs);
#endif
            bs->cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
            bs->consumedBits = 0;
#ifndef DR_FLAC_NO_CRC
            bs->crc16Cache = bs->cache;
#endif
        } else {
            if (!drflac__reload_cache(bs)) {
                return DRFLAC_FALSE;
            }
        }
        riceParamPart = (drflac_uint32)(resultHi | DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE(bs, bitCountLo));
        bs->consumedBits += bitCountLo;
        bs->cache <<= bitCountLo;
    }
    pZeroCounterOut[0] = zeroCounter;
    pRiceParamPartOut[0] = riceParamPart;
    return DRFLAC_TRUE;
}
#endif
static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts_x1(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
{

share/public_html/static/music_inc/src/miniaudio.h  view on Meta::CPAN

            drflac_uint8 flags;
            drflac_uint32 headerSize;
            if (onRead(pUserData, header, 6) != 6) {
                return DRFLAC_FALSE;
            }
            pInit->runningFilePos += 6;
            flags = header[1];
            DRFLAC_COPY_MEMORY(&headerSize, header+2, 4);
            headerSize = drflac__unsynchsafe_32(drflac__be2host_32(headerSize));
            if (flags & 0x10) {
                headerSize += 10;
            }
            if (!onSeek(pUserData, headerSize, drflac_seek_origin_current)) {
                return DRFLAC_FALSE;
            }
            pInit->runningFilePos += headerSize;
        } else {
            break;
        }
    }
    if (id[0] == 'f' && id[1] == 'L' && id[2] == 'a' && id[3] == 'C') {
        return drflac__init_private__native(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
    }
#ifndef DR_FLAC_NO_OGG
    if (id[0] == 'O' && id[1] == 'g' && id[2] == 'g' && id[3] == 'S') {
        return drflac__init_private__ogg(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
    }
#endif
    if (relaxed) {
        if (container == drflac_container_native) {
            return drflac__init_private__native(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
        }
#ifndef DR_FLAC_NO_OGG
        if (container == drflac_container_ogg) {
            return drflac__init_private__ogg(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
        }
#endif
    }
    return DRFLAC_FALSE;
}
static void drflac__init_from_info(drflac* pFlac, const drflac_init_info* pInit)
{
    DRFLAC_ASSERT(pFlac != NULL);
    DRFLAC_ASSERT(pInit != NULL);
    DRFLAC_ZERO_MEMORY(pFlac, sizeof(*pFlac));
    pFlac->bs                      = pInit->bs;
    pFlac->onMeta                  = pInit->onMeta;
    pFlac->pUserDataMD             = pInit->pUserDataMD;
    pFlac->maxBlockSizeInPCMFrames = pInit->maxBlockSizeInPCMFrames;
    pFlac->sampleRate              = pInit->sampleRate;
    pFlac->channels                = (drflac_uint8)pInit->channels;
    pFlac->bitsPerSample           = (drflac_uint8)pInit->bitsPerSample;
    pFlac->totalPCMFrameCount      = pInit->totalPCMFrameCount;
    pFlac->container               = pInit->container;
}
static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, void* pUserDataMD, const drflac_allocation_callbacks* pAllocationCallbacks)
{
    drflac_init_info init;
    drflac_uint32 allocationSize;
    drflac_uint32 wholeSIMDVectorCountPerChannel;
    drflac_uint32 decodedSamplesAllocationSize;
#ifndef DR_FLAC_NO_OGG
    drflac_oggbs oggbs;
#endif
    drflac_uint64 firstFramePos;
    drflac_uint64 seektablePos;
    drflac_uint32 seektableSize;
    drflac_allocation_callbacks allocationCallbacks;
    drflac* pFlac;
    drflac__init_cpu_caps();
    if (!drflac__init_private(&init, onRead, onSeek, onMeta, container, pUserData, pUserDataMD)) {
        return NULL;
    }
    if (pAllocationCallbacks != NULL) {
        allocationCallbacks = *pAllocationCallbacks;
        if (allocationCallbacks.onFree == NULL || (allocationCallbacks.onMalloc == NULL && allocationCallbacks.onRealloc == NULL)) {
            return NULL;
        }
    } else {
        allocationCallbacks.pUserData = NULL;
        allocationCallbacks.onMalloc  = drflac__malloc_default;
        allocationCallbacks.onRealloc = drflac__realloc_default;
        allocationCallbacks.onFree    = drflac__free_default;
    }
    allocationSize = sizeof(drflac);
    if ((init.maxBlockSizeInPCMFrames % (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))) == 0) {
        wholeSIMDVectorCountPerChannel = (init.maxBlockSizeInPCMFrames / (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32)));
    } else {
        wholeSIMDVectorCountPerChannel = (init.maxBlockSizeInPCMFrames / (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))) + 1;
    }
    decodedSamplesAllocationSize = wholeSIMDVectorCountPerChannel * DRFLAC_MAX_SIMD_VECTOR_SIZE * init.channels;
    allocationSize += decodedSamplesAllocationSize;
    allocationSize += DRFLAC_MAX_SIMD_VECTOR_SIZE;
#ifndef DR_FLAC_NO_OGG
    if (init.container == drflac_container_ogg) {
        allocationSize += sizeof(drflac_oggbs);
    }
    DRFLAC_ZERO_MEMORY(&oggbs, sizeof(oggbs));
    if (init.container == drflac_container_ogg) {
        oggbs.onRead = onRead;
        oggbs.onSeek = onSeek;
        oggbs.pUserData = pUserData;
        oggbs.currentBytePos = init.oggFirstBytePos;
        oggbs.firstBytePos = init.oggFirstBytePos;
        oggbs.serialNumber = init.oggSerial;
        oggbs.bosPageHeader = init.oggBosHeader;
        oggbs.bytesRemainingInPage = 0;
    }
#endif
    firstFramePos = 42;
    seektablePos  = 0;
    seektableSize = 0;
    if (init.hasMetadataBlocks) {
        drflac_read_proc onReadOverride = onRead;
        drflac_seek_proc onSeekOverride = onSeek;
        void* pUserDataOverride = pUserData;
#ifndef DR_FLAC_NO_OGG
        if (init.container == drflac_container_ogg) {
            onReadOverride = drflac__on_read_ogg;
            onSeekOverride = drflac__on_seek_ogg;
            pUserDataOverride = (void*)&oggbs;
        }
#endif
        if (!drflac__read_and_decode_metadata(onReadOverride, onSeekOverride, onMeta, pUserDataOverride, pUserDataMD, &firstFramePos, &seektablePos, &seektableSize, &allocationCallbacks)) {
            return NULL;
        }
        allocationSize += seektableSize;
    }
    pFlac = (drflac*)drflac__malloc_from_callbacks(allocationSize, &allocationCallbacks);
    if (pFlac == NULL) {
        return NULL;
    }
    drflac__init_from_info(pFlac, &init);
    pFlac->allocationCallbacks = allocationCallbacks;
    pFlac->pDecodedSamples = (drflac_int32*)drflac_align((size_t)pFlac->pExtraData, DRFLAC_MAX_SIMD_VECTOR_SIZE);
#ifndef DR_FLAC_NO_OGG
    if (init.container == drflac_container_ogg) {
        drflac_oggbs* pInternalOggbs = (drflac_oggbs*)((drflac_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize + seektableSize);
        *pInternalOggbs = oggbs;
        pFlac->bs.onRead = drflac__on_read_ogg;
        pFlac->bs.onSeek = drflac__on_seek_ogg;
        pFlac->bs.pUserData = (void*)pInternalOggbs;
        pFlac->_oggbs = (void*)pInternalOggbs;
    }
#endif
    pFlac->firstFLACFramePosInBytes = firstFramePos;
#ifndef DR_FLAC_NO_OGG
    if (init.container == drflac_container_ogg)
    {
        pFlac->pSeekpoints = NULL;
        pFlac->seekpointCount = 0;
    }
    else
#endif
    {
        if (seektablePos != 0) {
            pFlac->seekpointCount = seektableSize / sizeof(*pFlac->pSeekpoints);
            pFlac->pSeekpoints = (drflac_seekpoint*)((drflac_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize);
            DRFLAC_ASSERT(pFlac->bs.onSeek != NULL);
            DRFLAC_ASSERT(pFlac->bs.onRead != NULL);
            if (pFlac->bs.onSeek(pFlac->bs.pUserData, (int)seektablePos, drflac_seek_origin_start)) {
                if (pFlac->bs.onRead(pFlac->bs.pUserData, pFlac->pSeekpoints, seektableSize) == seektableSize) {
                    drflac_uint32 iSeekpoint;
                    for (iSeekpoint = 0; iSeekpoint < pFlac->seekpointCount; ++iSeekpoint) {
                        pFlac->pSeekpoints[iSeekpoint].firstPCMFrame   = drflac__be2host_64(pFlac->pSeekpoints[iSeekpoint].firstPCMFrame);
                        pFlac->pSeekpoints[iSeekpoint].flacFrameOffset = drflac__be2host_64(pFlac->pSeekpoints[iSeekpoint].flacFrameOffset);
                        pFlac->pSeekpoints[iSeekpoint].pcmFrameCount   = drflac__be2host_16(pFlac->pSeekpoints[iSeekpoint].pcmFrameCount);
                    }
                } else {
                    pFlac->pSeekpoints = NULL;
                    pFlac->seekpointCount = 0;
                }
                if (!pFlac->bs.onSeek(pFlac->bs.pUserData, (int)pFlac->firstFLACFramePosInBytes, drflac_seek_origin_start)) {
                    drflac__free_from_callbacks(pFlac, &allocationCallbacks);
                    return NULL;
                }
            } else {
                pFlac->pSeekpoints = NULL;
                pFlac->seekpointCount = 0;
            }
        }
    }
    if (!init.hasStreamInfoBlock) {
        pFlac->currentFLACFrame.header = init.firstFrameHeader;
        for (;;) {
            drflac_result result = drflac__decode_flac_frame(pFlac);
            if (result == DRFLAC_SUCCESS) {
                break;
            } else {
                if (result == DRFLAC_CRC_MISMATCH) {
                    if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
                        drflac__free_from_callbacks(pFlac, &allocationCallbacks);
                        return NULL;
                    }
                    continue;
                } else {
                    drflac__free_from_callbacks(pFlac, &allocationCallbacks);
                    return NULL;
                }
            }
        }
    }
    return pFlac;
}
#ifndef DR_FLAC_NO_STDIO
#include <stdio.h>
#include <wchar.h>
#include <errno.h>
static drflac_result drflac_result_from_errno(int e)
{
    switch (e)
    {
        case 0: return DRFLAC_SUCCESS;
    #ifdef EPERM
        case EPERM: return DRFLAC_INVALID_OPERATION;
    #endif
    #ifdef ENOENT
        case ENOENT: return DRFLAC_DOES_NOT_EXIST;



( run in 1.493 second using v1.01-cache-2.11-cpan-d7f47b0818f )