App-MHFS

 view release on metacpan or  search on metacpan

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

    ma_context__try_get_device_name_by_id__enum_callback_data data;

    MA_ASSERT(pContext != NULL);
    MA_ASSERT(pName != NULL);

    if (pDeviceID == NULL) {
        return MA_NO_DEVICE;
    }

    data.deviceType = deviceType;
    data.pDeviceID = pDeviceID;
    data.pName = pName;
    data.nameBufferSize = nameBufferSize;
    data.foundDevice = MA_FALSE;
    result = ma_context_enumerate_devices(pContext, ma_context__try_get_device_name_by_id__enum_callback, &data);
    if (result != MA_SUCCESS) {
        return result;
    }

    if (!data.foundDevice) {
        return MA_NO_DEVICE;
    } else {
        return MA_SUCCESS;
    }
}


MA_API ma_uint32 ma_get_format_priority_index(ma_format format) /* Lower = better. */
{
    ma_uint32 i;
    for (i = 0; i < ma_countof(g_maFormatPriorities); ++i) {
        if (g_maFormatPriorities[i] == format) {
            return i;
        }
    }

    /* Getting here means the format could not be found or is equal to ma_format_unknown. */
    return (ma_uint32)-1;
}

static ma_result ma_device__post_init_setup(ma_device* pDevice, ma_device_type deviceType);


/*******************************************************************************

Null Backend

*******************************************************************************/
#ifdef MA_HAS_NULL

#define MA_DEVICE_OP_NONE__NULL    0
#define MA_DEVICE_OP_START__NULL   1
#define MA_DEVICE_OP_SUSPEND__NULL 2
#define MA_DEVICE_OP_KILL__NULL    3

static ma_thread_result MA_THREADCALL ma_device_thread__null(void* pData)
{
    ma_device* pDevice = (ma_device*)pData;
    MA_ASSERT(pDevice != NULL);

    for (;;) {  /* Keep the thread alive until the device is uninitialized. */
        /* Wait for an operation to be requested. */
        ma_event_wait(&pDevice->null_device.operationEvent);

        /* At this point an event should have been triggered. */

        /* Starting the device needs to put the thread into a loop. */
        if (pDevice->null_device.operation == MA_DEVICE_OP_START__NULL) {
            c89atomic_exchange_32(&pDevice->null_device.operation, MA_DEVICE_OP_NONE__NULL);

            /* Reset the timer just in case. */
            ma_timer_init(&pDevice->null_device.timer);

            /* Keep looping until an operation has been requested. */
            while (pDevice->null_device.operation != MA_DEVICE_OP_NONE__NULL && pDevice->null_device.operation != MA_DEVICE_OP_START__NULL) {
                ma_sleep(10); /* Don't hog the CPU. */
            }

            /* Getting here means a suspend or kill operation has been requested. */
            c89atomic_exchange_32((c89atomic_uint32*)&pDevice->null_device.operationResult, MA_SUCCESS);
            ma_event_signal(&pDevice->null_device.operationCompletionEvent);
            continue;
        }

        /* Suspending the device means we need to stop the timer and just continue the loop. */
        if (pDevice->null_device.operation == MA_DEVICE_OP_SUSPEND__NULL) {
            c89atomic_exchange_32(&pDevice->null_device.operation, MA_DEVICE_OP_NONE__NULL);

            /* We need to add the current run time to the prior run time, then reset the timer. */
            pDevice->null_device.priorRunTime += ma_timer_get_time_in_seconds(&pDevice->null_device.timer);
            ma_timer_init(&pDevice->null_device.timer);

            /* We're done. */
            c89atomic_exchange_32((c89atomic_uint32*)&pDevice->null_device.operationResult, MA_SUCCESS);
            ma_event_signal(&pDevice->null_device.operationCompletionEvent);
            continue;
        }

        /* Killing the device means we need to get out of this loop so that this thread can terminate. */
        if (pDevice->null_device.operation == MA_DEVICE_OP_KILL__NULL) {
            c89atomic_exchange_32(&pDevice->null_device.operation, MA_DEVICE_OP_NONE__NULL);
            c89atomic_exchange_32((c89atomic_uint32*)&pDevice->null_device.operationResult, MA_SUCCESS);
            ma_event_signal(&pDevice->null_device.operationCompletionEvent);
            break;
        }

        /* Getting a signal on a "none" operation probably means an error. Return invalid operation. */
        if (pDevice->null_device.operation == MA_DEVICE_OP_NONE__NULL) {
            MA_ASSERT(MA_FALSE);  /* <-- Trigger this in debug mode to ensure developers are aware they're doing something wrong (or there's a bug in a miniaudio). */
            c89atomic_exchange_32((c89atomic_uint32*)&pDevice->null_device.operationResult, (c89atomic_uint32)MA_INVALID_OPERATION);
            ma_event_signal(&pDevice->null_device.operationCompletionEvent);
            continue;   /* Continue the loop. Don't terminate. */
        }
    }

    return (ma_thread_result)0;
}

static ma_result ma_device_do_operation__null(ma_device* pDevice, ma_uint32 operation)
{
    c89atomic_exchange_32(&pDevice->null_device.operation, operation);

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

        ma_channel_map_copy(converterConfig.channelMapIn, pDevice->capture.internalChannelMap, ma_min(pDevice->capture.internalChannels, MA_MAX_CHANNELS));
        converterConfig.formatOut                  = pDevice->capture.format;
        converterConfig.channelsOut                = pDevice->capture.channels;
        converterConfig.sampleRateOut              = pDevice->sampleRate;
        ma_channel_map_copy(converterConfig.channelMapOut, pDevice->capture.channelMap, ma_min(pDevice->capture.channels, MA_MAX_CHANNELS));
        converterConfig.resampling.allowDynamicSampleRate = MA_FALSE;
        converterConfig.resampling.algorithm       = pDevice->resampling.algorithm;
        converterConfig.resampling.linear.lpfOrder = pDevice->resampling.linear.lpfOrder;
        converterConfig.resampling.speex.quality   = pDevice->resampling.speex.quality;

        result = ma_data_converter_init(&converterConfig, &pDevice->capture.converter);
        if (result != MA_SUCCESS) {
            return result;
        }
    }

    if (deviceType == ma_device_type_playback || deviceType == ma_device_type_duplex) {
        /* Converting from client format to device format. */
        ma_data_converter_config converterConfig = ma_data_converter_config_init_default();
        converterConfig.formatIn                   = pDevice->playback.format;
        converterConfig.channelsIn                 = pDevice->playback.channels;
        converterConfig.sampleRateIn               = pDevice->sampleRate;
        ma_channel_map_copy(converterConfig.channelMapIn, pDevice->playback.channelMap, ma_min(pDevice->playback.channels, MA_MAX_CHANNELS));
        converterConfig.formatOut                  = pDevice->playback.internalFormat;
        converterConfig.channelsOut                = pDevice->playback.internalChannels;
        converterConfig.sampleRateOut              = pDevice->playback.internalSampleRate;
        ma_channel_map_copy(converterConfig.channelMapOut, pDevice->playback.internalChannelMap, ma_min(pDevice->playback.internalChannels, MA_MAX_CHANNELS));
        converterConfig.resampling.allowDynamicSampleRate = MA_FALSE;
        converterConfig.resampling.algorithm       = pDevice->resampling.algorithm;
        converterConfig.resampling.linear.lpfOrder = pDevice->resampling.linear.lpfOrder;
        converterConfig.resampling.speex.quality   = pDevice->resampling.speex.quality;

        result = ma_data_converter_init(&converterConfig, &pDevice->playback.converter);
        if (result != MA_SUCCESS) {
            return result;
        }
    }

    return MA_SUCCESS;
}


static ma_thread_result MA_THREADCALL ma_worker_thread(void* pData)
{
    ma_device* pDevice = (ma_device*)pData;
    MA_ASSERT(pDevice != NULL);

#ifdef MA_WIN32
    ma_CoInitializeEx(pDevice->pContext, NULL, MA_COINIT_VALUE);
#endif

    /*
    When the device is being initialized it's initial state is set to MA_STATE_UNINITIALIZED. Before returning from
    ma_device_init(), the state needs to be set to something valid. In miniaudio the device's default state immediately
    after initialization is stopped, so therefore we need to mark the device as such. miniaudio will wait on the worker
    thread to signal an event to know when the worker thread is ready for action.
    */
    ma_device__set_state(pDevice, MA_STATE_STOPPED);
    ma_event_signal(&pDevice->stopEvent);

    for (;;) {  /* <-- This loop just keeps the thread alive. The main audio loop is inside. */
        ma_stop_proc onStop;

        /* We wait on an event to know when something has requested that the device be started and the main loop entered. */
        ma_event_wait(&pDevice->wakeupEvent);

        /* Default result code. */
        pDevice->workResult = MA_SUCCESS;

        /* If the reason for the wake up is that we are terminating, just break from the loop. */
        if (ma_device__get_state(pDevice) == MA_STATE_UNINITIALIZED) {
            break;
        }

        /*
        Getting to this point means the device is wanting to get started. The function that has requested that the device
        be started will be waiting on an event (pDevice->startEvent) which means we need to make sure we signal the event
        in both the success and error case. It's important that the state of the device is set _before_ signaling the event.
        */
        MA_ASSERT(ma_device__get_state(pDevice) == MA_STATE_STARTING);

        /* Make sure the state is set appropriately. */
        ma_device__set_state(pDevice, MA_STATE_STARTED);
        ma_event_signal(&pDevice->startEvent);

        if (pDevice->pContext->onDeviceMainLoop != NULL) {
            pDevice->pContext->onDeviceMainLoop(pDevice);
        } else {
            ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "No main loop implementation.", MA_API_NOT_FOUND);
        }

        /*
        Getting here means we have broken from the main loop which happens the application has requested that device be stopped. Note that this
        may have actually already happened above if the device was lost and miniaudio has attempted to re-initialize the device. In this case we
        don't want to be doing this a second time.
        */
        if (ma_device__get_state(pDevice) != MA_STATE_UNINITIALIZED) {
            if (pDevice->pContext->onDeviceStop) {
                pDevice->pContext->onDeviceStop(pDevice);
            }
        }

        /* After the device has stopped, make sure an event is posted. */
        onStop = pDevice->onStop;
        if (onStop) {
            onStop(pDevice);
        }

        /*
        A function somewhere is waiting for the device to have stopped for real so we need to signal an event to allow it to continue. Note that
        it's possible that the device has been uninitialized which means we need to _not_ change the status to stopped. We cannot go from an
        uninitialized state to stopped state.
        */
        if (ma_device__get_state(pDevice) != MA_STATE_UNINITIALIZED) {
            ma_device__set_state(pDevice, MA_STATE_STOPPED);
            ma_event_signal(&pDevice->stopEvent);
        }
    }

    /* Make sure we aren't continuously waiting on a stop event. */
    ma_event_signal(&pDevice->stopEvent);  /* <-- Is this still needed? */



( run in 0.782 second using v1.01-cache-2.11-cpan-df04353d9ac )