Exemplo n.º 1
0
// This should probably move to another c file but for now ...
ALCAPI ALCdevice* ALCAPIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei SampleSize)
{
    ALCboolean DeviceFound = ALC_FALSE;
    ALCdevice *pDevice = NULL;
    ALCint i;

    if(SampleSize <= 0)
    {
        alcSetError(ALC_INVALID_VALUE);
        return NULL;
    }

    if(deviceName && !deviceName[0])
        deviceName = NULL;

    pDevice = malloc(sizeof(ALCdevice));
    if (pDevice)
    {
        //Initialise device structure
        memset(pDevice, 0, sizeof(ALCdevice));

        //Validate device
        pDevice->Connected = ALC_TRUE;
        pDevice->IsCaptureDevice = AL_TRUE;

        pDevice->szDeviceName = NULL;

        pDevice->Frequency = frequency;
        pDevice->Format = format;
        pDevice->UpdateSize = SampleSize;
        pDevice->NumUpdates = 1;

        SuspendContext(NULL);
        for(i = 0;BackendList[i].Init;i++)
        {
            pDevice->Funcs = &BackendList[i].Funcs;
            if(ALCdevice_OpenCapture(pDevice, deviceName))
            {
                pDevice->next = g_pDeviceList;
                g_pDeviceList = pDevice;
                g_ulDeviceCount++;

                DeviceFound = ALC_TRUE;
                break;
            }
        }
        ProcessContext(NULL);

        if(!DeviceFound)
        {
            alcSetError(ALC_INVALID_VALUE);
            free(pDevice);
            pDevice = NULL;
        }
    }
    else
        alcSetError(ALC_OUT_OF_MEMORY);

    return pDevice;
}
Exemplo n.º 2
0
ALCAPI ALCboolean ALCAPIENTRY alcCaptureCloseDevice(ALCdevice *pDevice)
{
    ALCboolean bReturn = ALC_FALSE;
    ALCdevice **list;

    if(IsDevice(pDevice) && pDevice->IsCaptureDevice)
    {
        SuspendContext(NULL);

        list = &g_pDeviceList;
        while(*list != pDevice)
            list = &(*list)->next;

        *list = (*list)->next;
        g_ulDeviceCount--;

        ProcessContext(NULL);

        ALCdevice_CloseCapture(pDevice);

        free(pDevice->szDeviceName);
        pDevice->szDeviceName = NULL;

        free(pDevice);

        bReturn = ALC_TRUE;
    }
    else
        alcSetError(ALC_INVALID_DEVICE);

    return bReturn;
}
Exemplo n.º 3
0
/*
    alcIsExtensionPresent

    Determines if there is support for a particular extension
*/
ALCAPI ALCboolean ALCAPIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
{
    ALCboolean bResult = ALC_FALSE;

    (void)device;

    if (extName)
    {
        const char *ptr;
        size_t len;

        len = strlen(extName);
        ptr = alcExtensionList;
        while(ptr && *ptr)
        {
            if(strncasecmp(ptr, extName, len) == 0 &&
               (ptr[len] == '\0' || isspace(ptr[len])))
            {
                bResult = ALC_TRUE;
                break;
            }
            if((ptr=strchr(ptr, ' ')) != NULL)
            {
                do {
                    ++ptr;
                } while(isspace(*ptr));
            }
        }
    }
    else
        alcSetError(ALC_INVALID_VALUE);

    return bResult;
}
Exemplo n.º 4
0
ALCAPI void ALCAPIENTRY alcCaptureSamples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCsizei lSamples)
{
    if(IsDevice(pDevice) && pDevice->IsCaptureDevice)
        ALCdevice_CaptureSamples(pDevice, pBuffer, lSamples);
    else
        alcSetError(ALC_INVALID_DEVICE);
}
Exemplo n.º 5
0
/*
    alcMakeContextCurrent

    Makes the given Context the active Context
*/
ALCAPI ALCboolean ALCAPIENTRY alcMakeContextCurrent(ALCcontext *context)
{
    ALCcontext *ALContext;
    ALboolean bReturn = AL_TRUE;

    SuspendContext(NULL);

    // context must be a valid Context or NULL
    if(context == NULL || IsContext(context))
    {
        if((ALContext=GetContextSuspended()) != NULL)
        {
            ALContext->InUse=AL_FALSE;
            ProcessContext(ALContext);
        }

        if((ALContext=context) != NULL && ALContext->Device)
        {
            SuspendContext(ALContext);
            ALContext->InUse=AL_TRUE;
            ProcessContext(ALContext);
        }

        tls_set(LocalContext, NULL);
    }
    else
    {
        alcSetError(ALC_INVALID_CONTEXT);
        bReturn = AL_FALSE;
    }

    ProcessContext(NULL);

    return bReturn;
}
Exemplo n.º 6
0
static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName)
{
    DSoundData *pData = NULL;
    LPGUID guid = NULL;
    HRESULT hr;

    if(!DSoundLoad())
        return ALC_FALSE;

    if(!deviceName)
        deviceName = dsDevice;
    else if(strcmp(deviceName, dsDevice) != 0)
    {
        ALuint i;

        if(!DeviceList)
        {
            hr = pDirectSoundEnumerateA(DSoundEnumDevices, NULL);
            if(FAILED(hr))
                AL_PRINT("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr);
        }

        for(i = 0; i < NumDevices; i++)
        {
            if(strcmp(deviceName, DeviceList[i].name) == 0)
            {
                if(i > 0)
                    guid = &DeviceList[i].guid;
                break;
            }
        }
        if(i == NumDevices)
            return ALC_FALSE;
    }

    //Initialise requested device
    pData = calloc(1, sizeof(DSoundData));
    if(!pData)
    {
        alcSetError(device, ALC_OUT_OF_MEMORY);
        return ALC_FALSE;
    }

    //DirectSound Init code
    hr = pDirectSoundCreate(guid, &pData->lpDS, NULL);
    if(SUCCEEDED(hr))
        hr = IDirectSound_SetCooperativeLevel(pData->lpDS, GetForegroundWindow(), DSSCL_PRIORITY);
    if(FAILED(hr))
    {
        if(pData->lpDS)
            IDirectSound_Release(pData->lpDS);
        free(pData);
        AL_PRINT("Device init failed: 0x%08lx\n", hr);
        return ALC_FALSE;
    }

    device->szDeviceName = strdup(deviceName);
    device->ExtraData = pData;
    return ALC_TRUE;
}
Exemplo n.º 7
0
ALCAPI void ALCAPIENTRY alcCaptureStop(ALCdevice *pDevice)
{
    if(IsDevice(pDevice) && pDevice->IsCaptureDevice)
        ALCdevice_StopCapture(pDevice);
    else
        alcSetError(ALC_INVALID_DEVICE);
}
Exemplo n.º 8
0
static void pa_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint samples)
{
    pa_data *data = device->ExtraData;
    if(samples <= (ALCuint)RingBufferSize(data->ring))
        ReadRingBuffer(data->ring, buffer, samples);
    else
        alcSetError(device, ALC_INVALID_VALUE);
}
Exemplo n.º 9
0
static void oss_capture_samples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples)
{
    oss_data *data = (oss_data*)pDevice->ExtraData;
    if(lSamples <= (ALCuint)RingBufferSize(data->ring))
        ReadRingBuffer(data->ring, pBuffer, lSamples);
    else
        alcSetError(pDevice, ALC_INVALID_VALUE);
}
Exemplo n.º 10
0
static void pulse_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint samples) //{{{
{
    pulse_data *data = device->ExtraData;
    ALCuint available = RingBufferSize(data->ring);
    const void *buf;
    size_t length;

    available *= data->frame_size;
    samples *= data->frame_size;

    ppa_threaded_mainloop_lock(data->loop);
    if(available+ppa_stream_readable_size(data->stream) < samples)
    {
        ppa_threaded_mainloop_unlock(data->loop);
        alcSetError(device, ALC_INVALID_VALUE);
        return;
    }

    available = min(available, samples);
    if(available > 0)
    {
        ReadRingBuffer(data->ring, buffer, available/data->frame_size);
        buffer = (ALubyte*)buffer + available;
        samples -= available;
    }

    /* Capture is done in fragment-sized chunks, so we loop until we get all
     * that's requested */
    while(samples > 0)
    {
        if(ppa_stream_peek(data->stream, &buf, &length) < 0)
        {
            AL_PRINT("pa_stream_peek() failed: %s\n",
                     ppa_strerror(ppa_context_errno(data->context)));
            break;
        }
        available = min(length, samples);

        memcpy(buffer, buf, available);
        buffer = (ALubyte*)buffer + available;
        buf = (const ALubyte*)buf + available;
        samples -= available;
        length -= available;

        /* Any unread data in the fragment will be lost, so save it */
        length /= data->frame_size;
        if(length > 0)
        {
            if(length > data->samples)
                length = data->samples;
            WriteRingBuffer(data->ring, buf, length);
        }

        ppa_stream_drop(data->stream);
    }
    ppa_threaded_mainloop_unlock(data->loop);
} //}}}
Exemplo n.º 11
0
static void alsa_capture_samples(ALCdevice *Device, ALCvoid *Buffer, ALCuint Samples)
{
    alsa_data *data = (alsa_data*)Device->ExtraData;

    if(Samples <= alsa_available_samples(Device))
        ReadRingBuffer(data->ring, Buffer, Samples);
    else
        alcSetError(Device, ALC_INVALID_VALUE);
}
Exemplo n.º 12
0
static void WinMMCaptureSamples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples)
{
    WinMMData *pData = (WinMMData*)pDevice->ExtraData;

    if(WinMMAvailableSamples(pDevice) >= lSamples)
        ReadRingBuffer(pData->pRing, pBuffer, lSamples);
    else
        alcSetError(pDevice, ALC_INVALID_VALUE);
}
Exemplo n.º 13
0
static void pulse_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint samples) //{{{
{
    pulse_data *data = device->ExtraData;
    ALCuint available = RingBufferSize(data->ring);

    if(available < samples)
        alcSetError(ALC_INVALID_VALUE);
    else
        ReadRingBuffer(data->ring, buffer, samples);
} //}}}
Exemplo n.º 14
0
static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName)
{
    DSoundData *pData = NULL;
    LPGUID guid = NULL;
    HRESULT hr;

    if(!deviceName)
        deviceName = dsDevice;
    else if(strcmp(deviceName, dsDevice) != 0)
    {
        ALuint i;
        for(i = 0;i < NumDevices;i++)
        {
            if(strcmp(deviceName, DeviceList[i].name) == 0)
            {
                guid = &DeviceList[i].guid;
                break;
            }
        }
        if(i == NumDevices)
            return ALC_FALSE;
    }

    DSoundLoad();
    if(ds_handle == NULL)
        return ALC_FALSE;

    //Initialise requested device

    pData = calloc(1, sizeof(DSoundData));
    if(!pData)
    {
        alcSetError(ALC_OUT_OF_MEMORY);
        DSoundUnload();
        return ALC_FALSE;
    }

    //DirectSound Init code
    hr = pDirectSoundCreate(guid, &pData->lpDS, NULL);
    if(SUCCEEDED(hr))
        hr = IDirectSound_SetCooperativeLevel(pData->lpDS, GetForegroundWindow(), DSSCL_PRIORITY);
    if(FAILED(hr))
    {
        if(pData->lpDS)
            IDirectSound_Release(pData->lpDS);
        free(pData);
        DSoundUnload();
        return ALC_FALSE;
    }

    device->szDeviceName = strdup(deviceName);
    device->ExtraData = pData;
    return ALC_TRUE;
}
static void pulse_capture_samples( ALCdevice* device, ALCvoid* buffer, ALCuint samples ) //{{{
{
	pulse_data* data = device->ExtraData;

	if ( pulse_available_samples( device ) >= samples )
	{
		ReadRingBuffer( data->ring, buffer, samples );
	}
	else
	{
		alcSetError( device, ALC_INVALID_VALUE );
	}
} //}}}
Exemplo n.º 16
0
/*
    alcGetContextsDevice

    Returns the Device that a particular Context is attached to
*/
ALCAPI ALCdevice* ALCAPIENTRY alcGetContextsDevice(ALCcontext *pContext)
{
    ALCdevice *pDevice = NULL;

    SuspendContext(NULL);
    if (IsContext(pContext))
        pDevice = pContext->Device;
    else
        alcSetError(ALC_INVALID_CONTEXT);
    ProcessContext(NULL);

    return pDevice;
}
Exemplo n.º 17
0
/*
    alcGetEnumValue

    Get the value for a particular ALC Enumerated Value
*/
ALCAPI ALCenum ALCAPIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
{
    ALsizei i = 0;
    ALCenum val;

    (void)device;

    while ((enumeration[i].enumName)&&(strcmp(enumeration[i].enumName,enumName)))
        i++;
    val = enumeration[i].value;

    if(!enumeration[i].enumName)
        alcSetError(ALC_INVALID_VALUE);

    return val;
}
Exemplo n.º 18
0
/*
    alcGetProcAddress

    Retrieves the function address for a particular extension function
*/
ALCAPI ALCvoid *  ALCAPIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
{
    ALCvoid *pFunction = NULL;
    ALsizei i = 0;

    (void)device;

    if (funcName)
    {
        while(alcFunctions[i].funcName &&
              strcmp(alcFunctions[i].funcName,funcName) != 0)
            i++;
        pFunction = alcFunctions[i].address;
    }
    else
        alcSetError(ALC_INVALID_VALUE);

    return pFunction;
}
Exemplo n.º 19
0
static void WinMMCaptureSamples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples)
{
    WinMMData *pData = (WinMMData*)pDevice->ExtraData;
    ALuint ulSamples = (unsigned long)lSamples;
    ALuint ulBytes, ulBytesToCopy;
    ALuint ulCapturedSamples;
    ALuint ulReadOffset;
    ALuint frameSize = aluFrameSizeFromFormat(pDevice->Format);

    // Check that we have the requested numbers of Samples
    ulCapturedSamples = (pData->ulWriteCapturedDataPos -
                         pData->ulReadCapturedDataPos) /
                        frameSize;
    if(ulSamples > ulCapturedSamples)
    {
        alcSetError(pDevice, ALC_INVALID_VALUE);
        return;
    }

    ulBytes = ulSamples * frameSize;

    // Get Read Offset
    ulReadOffset = (pData->ulReadCapturedDataPos % pData->ulCapturedDataSize);

    // Check for wrap-around condition
    if ((ulReadOffset + ulBytes) > pData->ulCapturedDataSize)
    {
        // Copy data from last Read position to end of data
        ulBytesToCopy = pData->ulCapturedDataSize - ulReadOffset;
        memcpy(pBuffer, pData->pCapturedSampleData + ulReadOffset, ulBytesToCopy);

        // Copy rest of the data from the start of the captured data
        memcpy(((char *)pBuffer) + ulBytesToCopy, pData->pCapturedSampleData, ulBytes - ulBytesToCopy);
    }
    else
    {
        // Copy data from the read position in the captured data
        memcpy(pBuffer, pData->pCapturedSampleData + ulReadOffset, ulBytes);
    }

    // Update Read Position
    pData->ulReadCapturedDataPos += ulBytes;
}
Exemplo n.º 20
0
/*
    alcMakeCurrent

    Makes the given Context the active Context for the current thread
*/
ALCboolean ALCAPIENTRY alcMakeCurrent(ALCcontext *context)
{
    ALboolean bReturn = AL_TRUE;

    SuspendContext(NULL);

    // context must be a valid Context or NULL
    if(context == NULL || IsContext(context))
        tls_set(LocalContext, context);
    else
    {
        alcSetError(ALC_INVALID_CONTEXT);
        bReturn = AL_FALSE;
    }

    ProcessContext(NULL);

    return bReturn;
}
Exemplo n.º 21
0
/*
    alcGetString

    Returns information about the Device, and error strings
*/
ALCAPI const ALCchar* ALCAPIENTRY alcGetString(ALCdevice *pDevice,ALCenum param)
{
    const ALCchar *value = NULL;

    switch (param)
    {
    case ALC_NO_ERROR:
        value = alcNoError;
        break;

    case ALC_INVALID_ENUM:
        value = alcErrInvalidEnum;
        break;

    case ALC_INVALID_VALUE:
        value = alcErrInvalidValue;
        break;

    case ALC_INVALID_DEVICE:
        value = alcErrInvalidDevice;
        break;

    case ALC_INVALID_CONTEXT:
        value = alcErrInvalidContext;
        break;

    case ALC_OUT_OF_MEMORY:
        value = alcErrOutOfMemory;
        break;

    case ALC_DEVICE_SPECIFIER:
        if(IsDevice(pDevice))
            value = pDevice->szDeviceName;
        else
        {
            ProbeDeviceList();
            value = alcDeviceList;
        }
        break;

    case ALC_ALL_DEVICES_SPECIFIER:
        ProbeAllDeviceList();
        value = alcAllDeviceList;
        break;

    case ALC_CAPTURE_DEVICE_SPECIFIER:
        if(IsDevice(pDevice))
            value = pDevice->szDeviceName;
        else
        {
            ProbeCaptureDeviceList();
            value = alcCaptureDeviceList;
        }
        break;

    /* Default devices are always first in the list */
    case ALC_DEFAULT_DEVICE_SPECIFIER:
        free(alcDefaultDeviceSpecifier);
        alcDefaultDeviceSpecifier = strdup(alcDeviceList ? alcDeviceList : "");
        if(!alcDefaultDeviceSpecifier)
            alcSetError(ALC_OUT_OF_MEMORY);
        value = alcDefaultDeviceSpecifier;
        break;

    case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
        free(alcDefaultAllDeviceSpecifier);
        alcDefaultAllDeviceSpecifier = strdup(alcAllDeviceList ?
                                              alcAllDeviceList : "");
        if(!alcDefaultAllDeviceSpecifier)
            alcSetError(ALC_OUT_OF_MEMORY);
        value = alcDefaultAllDeviceSpecifier;
        break;

    case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
        free(alcCaptureDefaultDeviceSpecifier);
        alcCaptureDefaultDeviceSpecifier = strdup(alcCaptureDeviceList ?
                                                  alcCaptureDeviceList : "");
        if(!alcCaptureDefaultDeviceSpecifier)
            alcSetError(ALC_OUT_OF_MEMORY);
        value = alcCaptureDefaultDeviceSpecifier;
        break;

    case ALC_EXTENSIONS:
        value = alcExtensionList;
        break;

    default:
        alcSetError(ALC_INVALID_ENUM);
        break;
    }

    return value;
}
Exemplo n.º 22
0
static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName)
{
    WAVEFORMATEX wfexCaptureFormat;
    DWORD ulCapturedDataSize;
    WinMMData *pData = NULL;
    UINT lDeviceID = 0;
    ALbyte *BufferData;
    ALint lBufferSize;
    MMRESULT res;
    ALuint i;

    if(!CaptureDeviceList)
        ProbeCaptureDevices();

    // Find the Device ID matching the deviceName if valid
    if(deviceName)
    {
        for(i = 0;i < NumCaptureDevices;i++)
        {
            if(CaptureDeviceList[i] &&
               strcmp(deviceName, CaptureDeviceList[i]) == 0)
            {
                lDeviceID = i;
                break;
            }
        }
    }
    else
    {
        for(i = 0;i < NumCaptureDevices;i++)
        {
            if(CaptureDeviceList[i])
            {
                lDeviceID = i;
                break;
            }
        }
    }
    if(i == NumCaptureDevices)
        return ALC_FALSE;

    pData = calloc(1, sizeof(*pData));
    if(!pData)
    {
        alcSetError(pDevice, ALC_OUT_OF_MEMORY);
        return ALC_FALSE;
    }
    pDevice->ExtraData = pData;

    if((pDevice->FmtChans != DevFmtMono && pDevice->FmtChans != DevFmtStereo) ||
       (pDevice->FmtType != DevFmtUByte && pDevice->FmtType != DevFmtShort))
    {
        alcSetError(pDevice, ALC_INVALID_ENUM);
        goto failure;
    }

    memset(&wfexCaptureFormat, 0, sizeof(WAVEFORMATEX));
    wfexCaptureFormat.wFormatTag = WAVE_FORMAT_PCM;
    wfexCaptureFormat.nChannels = ChannelsFromDevFmt(pDevice->FmtChans);
    wfexCaptureFormat.wBitsPerSample = BytesFromDevFmt(pDevice->FmtType) * 8;
    wfexCaptureFormat.nBlockAlign = wfexCaptureFormat.wBitsPerSample *
                                    wfexCaptureFormat.nChannels / 8;
    wfexCaptureFormat.nSamplesPerSec = pDevice->Frequency;
    wfexCaptureFormat.nAvgBytesPerSec = wfexCaptureFormat.nSamplesPerSec *
                                        wfexCaptureFormat.nBlockAlign;
    wfexCaptureFormat.cbSize = 0;

    if((res=waveInOpen(&pData->hWaveHandle.In, lDeviceID, &wfexCaptureFormat, (DWORD_PTR)&WaveInProc, (DWORD_PTR)pDevice, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR)
    {
        AL_PRINT("waveInOpen failed: %u\n", res);
        goto failure;
    }

    pData->hWaveHdrEvent = CreateEvent(NULL, AL_TRUE, AL_FALSE, "WaveInAllHeadersReturned");
    pData->hWaveThreadEvent = CreateEvent(NULL, AL_TRUE, AL_FALSE, "WaveInThreadDestroyed");
    if(pData->hWaveHdrEvent == NULL || pData->hWaveThreadEvent == NULL)
    {
        AL_PRINT("CreateEvent failed: %lu\n", GetLastError());
        goto failure;
    }

    pData->Frequency = pDevice->Frequency;

    // Allocate circular memory buffer for the captured audio
    ulCapturedDataSize = pDevice->UpdateSize*pDevice->NumUpdates;

    // Make sure circular buffer is at least 100ms in size
    if(ulCapturedDataSize < (wfexCaptureFormat.nSamplesPerSec / 10))
        ulCapturedDataSize = wfexCaptureFormat.nSamplesPerSec / 10;

    pData->pRing = CreateRingBuffer(wfexCaptureFormat.nBlockAlign, ulCapturedDataSize);
    if(!pData->pRing)
        goto failure;

    pData->lWaveBuffersCommitted = 0;

    // Create 4 Buffers of 50ms each
    lBufferSize = wfexCaptureFormat.nAvgBytesPerSec / 20;
    lBufferSize -= (lBufferSize % wfexCaptureFormat.nBlockAlign);

    BufferData = calloc(4, lBufferSize);
    if(!BufferData)
        goto failure;

    for(i = 0;i < 4;i++)
    {
        memset(&pData->WaveBuffer[i], 0, sizeof(WAVEHDR));
        pData->WaveBuffer[i].dwBufferLength = lBufferSize;
        pData->WaveBuffer[i].lpData = ((i==0) ? (LPSTR)BufferData :
                                       (pData->WaveBuffer[i-1].lpData +
                                        pData->WaveBuffer[i-1].dwBufferLength));
        pData->WaveBuffer[i].dwFlags = 0;
        pData->WaveBuffer[i].dwLoops = 0;
        waveInPrepareHeader(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR));
        waveInAddBuffer(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR));
        InterlockedIncrement(&pData->lWaveBuffersCommitted);
    }

    pData->hWaveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CaptureThreadProc, (LPVOID)pDevice, 0, &pData->ulWaveThreadID);
    if (pData->hWaveThread == NULL)
        goto failure;

    pDevice->szDeviceName = strdup(CaptureDeviceList[lDeviceID]);
    return ALC_TRUE;

failure:
    if(pData->hWaveThread)
        CloseHandle(pData->hWaveThread);

    for(i = 0;i < 4;i++)
    {
        if(pData->WaveBuffer[i].lpData)
        {
            waveInUnprepareHeader(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR));
            if(i == 0)
                free(pData->WaveBuffer[i].lpData);
        }
    }

    if(pData->pRing)
        DestroyRingBuffer(pData->pRing);

    if(pData->hWaveThreadEvent)
        CloseHandle(pData->hWaveThreadEvent);
    if(pData->hWaveHdrEvent)
        CloseHandle(pData->hWaveHdrEvent);

    if(pData->hWaveHandle.In)
        waveInClose(pData->hWaveHandle.In);

    free(pData);
    pDevice->ExtraData = NULL;
    return ALC_FALSE;
}
Exemplo n.º 23
0
static ALCboolean WinMMOpenPlayback(ALCdevice *pDevice, const ALCchar *deviceName)
{
    WAVEFORMATEX wfexFormat;
    WinMMData *pData = NULL;
    UINT lDeviceID = 0;
    MMRESULT res;
    ALuint i = 0;

    // Find the Device ID matching the deviceName if valid
    if(!deviceName || strcmp(deviceName, woDefault) == 0)
        lDeviceID = WAVE_MAPPER;
    else
    {
        if(!PlaybackDeviceList)
            ProbePlaybackDevices();

        for(i = 0;i < NumPlaybackDevices;i++)
        {
            if(PlaybackDeviceList[i] &&
               strcmp(deviceName, PlaybackDeviceList[i]) == 0)
            {
                lDeviceID = i;
                break;
            }
        }
        if(i == NumPlaybackDevices)
            return ALC_FALSE;
    }

    pData = calloc(1, sizeof(*pData));
    if(!pData)
    {
        alcSetError(pDevice, ALC_OUT_OF_MEMORY);
        return ALC_FALSE;
    }
    pDevice->ExtraData = pData;

    if(pDevice->FmtChans != DevFmtMono)
        pDevice->FmtChans = DevFmtStereo;
    switch(pDevice->FmtType)
    {
        case DevFmtByte:
            pDevice->FmtType = DevFmtUByte;
            break;
        case DevFmtUShort:
        case DevFmtFloat:
            pDevice->FmtType = DevFmtShort;
            break;
        case DevFmtUByte:
        case DevFmtShort:
            break;
    }

    memset(&wfexFormat, 0, sizeof(WAVEFORMATEX));
    wfexFormat.wFormatTag = WAVE_FORMAT_PCM;
    wfexFormat.nChannels = ChannelsFromDevFmt(pDevice->FmtChans);
    wfexFormat.wBitsPerSample = BytesFromDevFmt(pDevice->FmtType) * 8;
    wfexFormat.nBlockAlign = wfexFormat.wBitsPerSample *
                             wfexFormat.nChannels / 8;
    wfexFormat.nSamplesPerSec = pDevice->Frequency;
    wfexFormat.nAvgBytesPerSec = wfexFormat.nSamplesPerSec *
                                 wfexFormat.nBlockAlign;
    wfexFormat.cbSize = 0;

    if((res=waveOutOpen(&pData->hWaveHandle.Out, lDeviceID, &wfexFormat, (DWORD_PTR)&WaveOutProc, (DWORD_PTR)pDevice, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR)
    {
        AL_PRINT("waveInOpen failed: %u\n", res);
        goto failure;
    }

    pData->hWaveHdrEvent = CreateEvent(NULL, AL_TRUE, AL_FALSE, "WaveOutAllHeadersReturned");
    pData->hWaveThreadEvent = CreateEvent(NULL, AL_TRUE, AL_FALSE, "WaveOutThreadDestroyed");
    if(pData->hWaveHdrEvent == NULL || pData->hWaveThreadEvent == NULL)
    {
        AL_PRINT("CreateEvent failed: %lu\n", GetLastError());
        goto failure;
    }

    pData->Frequency = pDevice->Frequency;

    pDevice->szDeviceName = strdup((lDeviceID==WAVE_MAPPER) ? woDefault :
                                   PlaybackDeviceList[lDeviceID]);
    return ALC_TRUE;

failure:
    if(pData->hWaveThreadEvent)
        CloseHandle(pData->hWaveThreadEvent);
    if(pData->hWaveHdrEvent)
        CloseHandle(pData->hWaveHdrEvent);

    if(pData->hWaveHandle.Out)
        waveOutClose(pData->hWaveHandle.Out);

    free(pData);
    pDevice->ExtraData = NULL;
    return ALC_FALSE;
}
Exemplo n.º 24
0
/*
    alcCreateContext

    Create and attach a Context to a particular Device.
*/
ALCAPI ALCcontext* ALCAPIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
{
    ALuint attrIdx, reqStereoSources;
    ALCcontext *ALContext;
    void *temp;
    ALuint i;

    SuspendContext(NULL);

    if(!IsDevice(device) || device->IsCaptureDevice || !device->Connected)
    {
        alcSetError(ALC_INVALID_DEVICE);
        ProcessContext(NULL);
        return NULL;
    }

    // Reset Context Last Error code
    g_eLastContextError = ALC_NO_ERROR;

    // If a context is already running on the device, stop playback so the
    // device attributes can be updated
    if(device->NumContexts > 0)
    {
        ProcessContext(NULL);
        ALCdevice_StopPlayback(device);
        SuspendContext(NULL);
    }

    // Check for attributes
    if(attrList)
    {
        ALCint level = device->Bs2bLevel;
        ALCuint freq = device->Frequency;
        ALCint numMono = device->lNumMonoSources;
        ALCint numStereo = device->lNumStereoSources;
        ALCuint numSends = device->NumAuxSends;

        attrIdx = 0;
        while(attrList[attrIdx])
        {
            if(attrList[attrIdx] == ALC_FREQUENCY)
            {
                freq = attrList[attrIdx + 1];
                if(freq == 0)
                    freq = device->Frequency;
            }

            if(attrList[attrIdx] == ALC_STEREO_SOURCES)
            {
                reqStereoSources = attrList[attrIdx + 1];
                if(reqStereoSources > device->MaxNoOfSources)
                    reqStereoSources = device->MaxNoOfSources;

                numStereo = reqStereoSources;
                numMono = device->MaxNoOfSources - numStereo;
            }

            if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
            {
                numSends = attrList[attrIdx + 1];
                if(numSends > MAX_SENDS)
                    numSends = MAX_SENDS;
            }

            attrIdx += 2;
        }

        device->Bs2bLevel = GetConfigValueInt(NULL, "cf_level", level);
        device->Frequency = GetConfigValueInt(NULL, "frequency", freq);
        device->lNumMonoSources = numMono;
        device->lNumStereoSources = numStereo;
        device->NumAuxSends = GetConfigValueInt(NULL, "sends", numSends);
    }

    if(ALCdevice_ResetPlayback(device) == ALC_FALSE)
    {
        alcSetError(ALC_INVALID_DEVICE);
        aluHandleDisconnect(device);
        ProcessContext(NULL);
        return NULL;
    }

    for(i = 0;i < device->NumContexts;i++)
    {
        ALCcontext *context = device->Contexts[i];
        ALeffectslot *slot;
        ALsource *source;

        SuspendContext(context);
        for(slot = context->AuxiliaryEffectSlot;slot != NULL;slot = slot->next)
        {
            if(!slot->EffectState)
                continue;

            if(ALEffect_DeviceUpdate(slot->EffectState, device) == AL_FALSE)
            {
                alcSetError(ALC_INVALID_DEVICE);
                aluHandleDisconnect(device);
                ProcessContext(context);
                ProcessContext(NULL);
                ALCdevice_StopPlayback(device);
                return NULL;
            }
            ALEffect_Update(slot->EffectState, context, &slot->effect);
        }

        for(source = context->Source;source != NULL;source = source->next)
        {
            ALuint s = device->NumAuxSends;
            while(s < MAX_SENDS)
            {
                if(source->Send[s].Slot)
                    source->Send[s].Slot->refcount--;
                source->Send[s].Slot = NULL;
                source->Send[s].WetFilter.type = 0;
                source->Send[s].WetFilter.filter = 0;
                s++;
            }
        }
        ProcessContext(context);
    }

    if(device->Bs2bLevel > 0 && device->Bs2bLevel <= 6)
    {
        if(!device->Bs2b)
        {
            device->Bs2b = calloc(1, sizeof(*device->Bs2b));
            bs2b_clear(device->Bs2b);
        }
        bs2b_set_srate(device->Bs2b, device->Frequency);
        bs2b_set_level(device->Bs2b, device->Bs2bLevel);
    }
    else
    {
        free(device->Bs2b);
        device->Bs2b = NULL;
    }

    temp = realloc(device->Contexts, (device->NumContexts+1) * sizeof(*device->Contexts));
    if(!temp)
    {
        alcSetError(ALC_OUT_OF_MEMORY);
        ProcessContext(NULL);
        return NULL;
    }
    device->Contexts = temp;

    ALContext = calloc(1, sizeof(ALCcontext));
    if(!ALContext)
    {
        alcSetError(ALC_OUT_OF_MEMORY);
        ProcessContext(NULL);
        return NULL;
    }

    device->Contexts[device->NumContexts++] = ALContext;
    ALContext->Device = device;

    InitContext(ALContext);

    ALContext->next = g_pContextList;
    g_pContextList = ALContext;
    g_ulContextCount++;

    ProcessContext(NULL);

    return ALContext;
}
Exemplo n.º 25
0
static ALCboolean pa_open_capture(ALCdevice *device, const ALCchar *deviceName)
{
    PaStreamParameters inParams;
    ALuint frame_size;
    pa_data *data;
    PaError err;

    if(!deviceName)
        deviceName = pa_device;
    else if(strcmp(deviceName, pa_device) != 0)
        return ALC_FALSE;

    if(!pa_load())
        return ALC_FALSE;

    data = (pa_data*)calloc(1, sizeof(pa_data));
    if(data == NULL)
    {
        alcSetError(device, ALC_OUT_OF_MEMORY);
        return ALC_FALSE;
    }

    frame_size = aluFrameSizeFromFormat(device->Format);
    data->ring = CreateRingBuffer(frame_size, device->UpdateSize*device->NumUpdates);
    if(data->ring == NULL)
    {
        alcSetError(device, ALC_OUT_OF_MEMORY);
        goto error;
    }

    inParams.device = GetConfigValueInt("port", "capture", -1);
    if(inParams.device < 0)
        inParams.device = pPa_GetDefaultOutputDevice();
    inParams.suggestedLatency = 0.0f;
    inParams.hostApiSpecificStreamInfo = NULL;

    switch(aluBytesFromFormat(device->Format))
    {
        case 1:
            inParams.sampleFormat = paUInt8;
            break;
        case 2:
            inParams.sampleFormat = paInt16;
            break;
        case 4:
            inParams.sampleFormat = paFloat32;
            break;
        default:
            AL_PRINT("Unknown format: 0x%x\n", device->Format);
            goto error;
    }
    inParams.channelCount = aluChannelsFromFormat(device->Format);

    err = pPa_OpenStream(&data->stream, &inParams, NULL, device->Frequency,
                         paFramesPerBufferUnspecified, paNoFlag, pa_capture_cb, device);
    if(err != paNoError)
    {
        AL_PRINT("Pa_OpenStream() returned an error: %s\n", pPa_GetErrorText(err));
        goto error;
    }

    device->szDeviceName = strdup(deviceName);

    device->ExtraData = data;
    return ALC_TRUE;

error:
    DestroyRingBuffer(data->ring);
    free(data);
    return ALC_FALSE;
}
Exemplo n.º 26
0
static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName)
{
    WAVEFORMATEX wfexCaptureFormat;
    WinMMData *pData = NULL;
    ALint lDeviceID = 0;
    ALint lBufferSize;
    ALuint i;

    if(!CaptureDeviceList)
        ProbeDevices();

    // Find the Device ID matching the deviceName if valid
    if(deviceName)
    {
        for(i = 0;i < NumCaptureDevices;i++)
        {
            if(CaptureDeviceList[i] &&
               strcmp(deviceName, CaptureDeviceList[i]) == 0)
            {
                lDeviceID = i;
                break;
            }
        }
    }
    else
    {
        for(i = 0;i < NumCaptureDevices;i++)
        {
            if(CaptureDeviceList[i])
            {
                lDeviceID = i;
                break;
            }
        }
    }
    if(i == NumCaptureDevices)
        return ALC_FALSE;

    pData = calloc(1, sizeof(*pData));
    if(!pData)
    {
        alcSetError(pDevice, ALC_OUT_OF_MEMORY);
        return ALC_FALSE;
    }

    memset(&wfexCaptureFormat, 0, sizeof(WAVEFORMATEX));
    wfexCaptureFormat.wFormatTag = WAVE_FORMAT_PCM;
    wfexCaptureFormat.nChannels = aluChannelsFromFormat(pDevice->Format);
    wfexCaptureFormat.wBitsPerSample = aluBytesFromFormat(pDevice->Format) * 8;
    wfexCaptureFormat.nBlockAlign = wfexCaptureFormat.wBitsPerSample *
                                    wfexCaptureFormat.nChannels / 8;
    wfexCaptureFormat.nSamplesPerSec = pDevice->Frequency;
    wfexCaptureFormat.nAvgBytesPerSec = wfexCaptureFormat.nSamplesPerSec *
                                        wfexCaptureFormat.nBlockAlign;
    wfexCaptureFormat.cbSize = 0;

    if (waveInOpen(&pData->hWaveInHandle, lDeviceID, &wfexCaptureFormat, (DWORD_PTR)&WaveInProc, (DWORD_PTR)pDevice, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
        goto failure;

    pData->hWaveInHdrEvent = CreateEvent(NULL, AL_TRUE, AL_FALSE, "WaveInAllHeadersReturned");
    if (pData->hWaveInHdrEvent == NULL)
        goto failure;

    pData->hWaveInThreadEvent = CreateEvent(NULL, AL_TRUE, AL_FALSE, "WaveInThreadDestroyed");
    if (pData->hWaveInThreadEvent == NULL)
        goto failure;

    // Allocate circular memory buffer for the captured audio
    pData->ulCapturedDataSize = pDevice->UpdateSize*pDevice->NumUpdates *
                                wfexCaptureFormat.nBlockAlign;

    // Make sure circular buffer is at least 100ms in size (and an exact multiple of
    // the block alignment
    if (pData->ulCapturedDataSize < (wfexCaptureFormat.nAvgBytesPerSec / 10))
    {
        pData->ulCapturedDataSize = wfexCaptureFormat.nAvgBytesPerSec / 10;
        pData->ulCapturedDataSize -= (pData->ulCapturedDataSize % wfexCaptureFormat.nBlockAlign);
    }

    pData->pCapturedSampleData = (ALCchar*)malloc(pData->ulCapturedDataSize);
    pData->lWaveInBuffersCommitted=0;

    // Create 4 Buffers of 50ms each
    lBufferSize = wfexCaptureFormat.nAvgBytesPerSec / 20;
    lBufferSize -= (lBufferSize % wfexCaptureFormat.nBlockAlign);

    for (i=0;i<4;i++)
    {
        memset(&pData->WaveInBuffer[i], 0, sizeof(WAVEHDR));
        pData->WaveInBuffer[i].dwBufferLength = lBufferSize;
        pData->WaveInBuffer[i].lpData = calloc(1,pData->WaveInBuffer[i].dwBufferLength);
        pData->WaveInBuffer[i].dwFlags = 0;
        pData->WaveInBuffer[i].dwLoops = 0;
        waveInPrepareHeader(pData->hWaveInHandle, &pData->WaveInBuffer[i], sizeof(WAVEHDR));
        waveInAddBuffer(pData->hWaveInHandle, &pData->WaveInBuffer[i], sizeof(WAVEHDR));
        pData->lWaveInBuffersCommitted++;
    }

    pData->ulReadCapturedDataPos = 0;
    pData->ulWriteCapturedDataPos = 0;

    pDevice->ExtraData = pData;

    pData->hWaveInThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CaptureThreadProc, (LPVOID)pDevice, 0, &pData->ulWaveInThreadID);
    if (pData->hWaveInThread == NULL)
        goto failure;

    pDevice->szDeviceName = strdup(CaptureDeviceList[lDeviceID]);
    return ALC_TRUE;

failure:
    for (i=0;i<4;i++)
    {
        if(pData->WaveInBuffer[i].lpData)
        {
            waveInUnprepareHeader(pData->hWaveInHandle, &pData->WaveInBuffer[i], sizeof(WAVEHDR));
            free(pData->WaveInBuffer[i].lpData);
        }
    }

    free(pData->pCapturedSampleData);
    if(pData->hWaveInHandle)
        waveInClose(pData->hWaveInHandle);
    if(pData->hWaveInThread)
        CloseHandle(pData->hWaveInThread);
    if (pData->hWaveInHdrEvent)
        CloseHandle(pData->hWaveInHdrEvent);
    if (pData->hWaveInThreadEvent)
        CloseHandle(pData->hWaveInThreadEvent);

    free(pData);
    pDevice->ExtraData = NULL;
    return ALC_FALSE;
}
Exemplo n.º 27
0
/*
    alcDestroyContext

    Remove a Context
*/
ALCAPI ALCvoid ALCAPIENTRY alcDestroyContext(ALCcontext *context)
{
    ALCcontext **list;
    ALuint i;

    if (IsContext(context))
    {
        ALCdevice *Device = context->Device;

        if(Device->NumContexts == 1)
            ALCdevice_StopPlayback(Device);

        SuspendContext(NULL);

        for(i = 0;i < Device->NumContexts-1;i++)
        {
            if(Device->Contexts[i] == context)
            {
                memmove(&Device->Contexts[i], &Device->Contexts[i+1],
                        (Device->NumContexts-i-1) * sizeof(*Device->Contexts));
                break;
            }
        }
        Device->NumContexts--;

        // Lock context
        SuspendContext(context);

        if(context->SourceCount > 0)
        {
#ifdef _DEBUG
            AL_PRINT("alcDestroyContext(): deleting %d Source(s)\n", context->SourceCount);
#endif
            ReleaseALSources(context);
        }
        if(context->AuxiliaryEffectSlotCount > 0)
        {
#ifdef _DEBUG
            AL_PRINT("alcDestroyContext(): deleting %d AuxiliaryEffectSlot(s)\n", context->AuxiliaryEffectSlotCount);
#endif
            ReleaseALAuxiliaryEffectSlots(context);
        }

        list = &g_pContextList;
        while(*list != context)
            list = &(*list)->next;

        *list = (*list)->next;
        g_ulContextCount--;

        // Unlock context
        ProcessContext(context);
        ProcessContext(NULL);

        ExitContext(context);

        // Free memory (MUST do this after ProcessContext)
        memset(context, 0, sizeof(ALCcontext));
        free(context);
    }
    else
        alcSetError(ALC_INVALID_CONTEXT);
}
Exemplo n.º 28
0
/*
    alcGetIntegerv

    Returns information about the Device and the version of Open AL
*/
ALCAPI ALCvoid ALCAPIENTRY alcGetIntegerv(ALCdevice *device,ALCenum param,ALsizei size,ALCint *data)
{
    if(IsDevice(device) && device->IsCaptureDevice)
    {
        SuspendContext(NULL);

        // Capture device
        switch (param)
        {
        case ALC_CAPTURE_SAMPLES:
            if ((size) && (data))
                *data = ALCdevice_AvailableSamples(device);
            else
                alcSetError(ALC_INVALID_VALUE);
            break;

        case ALC_CONNECTED:
            if(size <= 0)
                alcSetError(ALC_INVALID_VALUE);
            else
                *data = device->Connected;
            break;

        default:
            alcSetError(ALC_INVALID_ENUM);
            break;
        }

        ProcessContext(NULL);
    }
    else
    {
        if(data)
        {
            // Playback Device
            switch (param)
            {
                case ALC_MAJOR_VERSION:
                    if(size <= 0)
                        alcSetError(ALC_INVALID_VALUE);
                    else
                        *data = alcMajorVersion;
                    break;

                case ALC_MINOR_VERSION:
                    if(size <= 0)
                        alcSetError(ALC_INVALID_VALUE);
                    else
                        *data = alcMinorVersion;
                    break;

                case ALC_EFX_MAJOR_VERSION:
                    if(size <= 0)
                        alcSetError(ALC_INVALID_VALUE);
                    else
                        *data = alcEFXMajorVersion;
                    break;

                case ALC_EFX_MINOR_VERSION:
                    if(size <= 0)
                        alcSetError(ALC_INVALID_VALUE);
                    else
                        *data = alcEFXMinorVersion;
                    break;

                case ALC_MAX_AUXILIARY_SENDS:
                    if(size <= 0)
                        alcSetError(ALC_INVALID_VALUE);
                    else
                        *data = (device?device->NumAuxSends:MAX_SENDS);
                    break;

                case ALC_ATTRIBUTES_SIZE:
                    if(!IsDevice(device))
                        alcSetError(ALC_INVALID_DEVICE);
                    else if(size <= 0)
                        alcSetError(ALC_INVALID_VALUE);
                    else
                        *data = 13;
                    break;

                case ALC_ALL_ATTRIBUTES:
                    if(!IsDevice(device))
                        alcSetError(ALC_INVALID_DEVICE);
                    else if (size < 13)
                        alcSetError(ALC_INVALID_VALUE);
                    else
                    {
                        int i = 0;

                        SuspendContext(NULL);
                        data[i++] = ALC_FREQUENCY;
                        data[i++] = device->Frequency;

                        data[i++] = ALC_REFRESH;
                        data[i++] = device->Frequency / device->UpdateSize;

                        data[i++] = ALC_SYNC;
                        data[i++] = ALC_FALSE;

                        data[i++] = ALC_MONO_SOURCES;
                        data[i++] = device->lNumMonoSources;

                        data[i++] = ALC_STEREO_SOURCES;
                        data[i++] = device->lNumStereoSources;

                        data[i++] = ALC_MAX_AUXILIARY_SENDS;
                        data[i++] = device->NumAuxSends;

                        data[i++] = 0;
                        ProcessContext(NULL);
                    }
                    break;

                case ALC_FREQUENCY:
                    if(!IsDevice(device))
                        alcSetError(ALC_INVALID_DEVICE);
                    else if(size <= 0)
                        alcSetError(ALC_INVALID_VALUE);
                    else
                        *data = device->Frequency;
                    break;

                case ALC_REFRESH:
                    if(!IsDevice(device))
                        alcSetError(ALC_INVALID_DEVICE);
                    else if(size <= 0)
                        alcSetError(ALC_INVALID_VALUE);
                    else
                        *data = device->Frequency / device->UpdateSize;
                    break;

                case ALC_SYNC:
                    if(!IsDevice(device))
                        alcSetError(ALC_INVALID_DEVICE);
                    else if(size <= 0)
                        alcSetError(ALC_INVALID_VALUE);
                    else
                        *data = ALC_FALSE;
                    break;

                case ALC_MONO_SOURCES:
                    if(!IsDevice(device))
                        alcSetError(ALC_INVALID_DEVICE);
                    else if(size <= 0)
                        alcSetError(ALC_INVALID_VALUE);
                    else
                        *data = device->lNumMonoSources;
                    break;

                case ALC_STEREO_SOURCES:
                    if(!IsDevice(device))
                        alcSetError(ALC_INVALID_DEVICE);
                    else if(size <= 0)
                        alcSetError(ALC_INVALID_VALUE);
                    else
                        *data = device->lNumStereoSources;
                    break;

                case ALC_CONNECTED:
                    if(!IsDevice(device))
                        alcSetError(ALC_INVALID_DEVICE);
                    else if(size <= 0)
                        alcSetError(ALC_INVALID_VALUE);
                    else
                        *data = device->Connected;
                    break;

                default:
                    alcSetError(ALC_INVALID_ENUM);
                    break;
            }
        }
        else if(size)
            alcSetError(ALC_INVALID_VALUE);
    }

    return;
}
Exemplo n.º 29
0
/*
    alcOpenDevice

    Open the Device specified.
*/
ALCAPI ALCdevice* ALCAPIENTRY alcOpenDevice(const ALCchar *deviceName)
{
    ALboolean bDeviceFound = AL_FALSE;
    ALCdevice *device;
    ALint i;

    if(deviceName && !deviceName[0])
        deviceName = NULL;

    device = malloc(sizeof(ALCdevice));
    if (device)
    {
        const char *fmt;

        //Initialise device structure
        memset(device, 0, sizeof(ALCdevice));

        //Validate device
        device->Connected = ALC_TRUE;
        device->IsCaptureDevice = AL_FALSE;

        device->Bs2b = NULL;
        device->szDeviceName = NULL;

        device->Contexts = NULL;
        device->NumContexts = 0;

        //Set output format
        device->Frequency = GetConfigValueInt(NULL, "frequency", SWMIXER_OUTPUT_RATE);
        if(device->Frequency == 0)
            device->Frequency = SWMIXER_OUTPUT_RATE;

        fmt = GetConfigValue(NULL, "format", "AL_FORMAT_STEREO16");
        device->Format = GetFormatFromString(fmt);

        device->NumUpdates = GetConfigValueInt(NULL, "periods", 4);
        if(device->NumUpdates < 2)
            device->NumUpdates = 4;

        i = GetConfigValueInt(NULL, "refresh", 4096);
        if(i <= 0) i = 4096;

        device->UpdateSize = GetConfigValueInt(NULL, "period_size", i/device->NumUpdates);
        if(device->UpdateSize <= 0)
            device->UpdateSize = i/device->NumUpdates;

        device->MaxNoOfSources = GetConfigValueInt(NULL, "sources", 256);
        if((ALint)device->MaxNoOfSources <= 0)
            device->MaxNoOfSources = 256;

        device->AuxiliaryEffectSlotMax = GetConfigValueInt(NULL, "slots", 4);
        if((ALint)device->AuxiliaryEffectSlotMax <= 0)
            device->AuxiliaryEffectSlotMax = 4;

        device->lNumStereoSources = 1;
        device->lNumMonoSources = device->MaxNoOfSources - device->lNumStereoSources;

        device->NumAuxSends = GetConfigValueInt(NULL, "sends", MAX_SENDS);
        if(device->NumAuxSends > MAX_SENDS)
            device->NumAuxSends = MAX_SENDS;

        device->Bs2bLevel = GetConfigValueInt(NULL, "cf_level", 0);

        // Find a playback device to open
        SuspendContext(NULL);
        for(i = 0;BackendList[i].Init;i++)
        {
            device->Funcs = &BackendList[i].Funcs;
            if(ALCdevice_OpenPlayback(device, deviceName))
            {
                device->next = g_pDeviceList;
                g_pDeviceList = device;
                g_ulDeviceCount++;

                bDeviceFound = AL_TRUE;
                break;
            }
        }
        ProcessContext(NULL);

        if (!bDeviceFound)
        {
            // No suitable output device found
            alcSetError(ALC_INVALID_VALUE);
            free(device);
            device = NULL;
        }
    }
    else
        alcSetError(ALC_OUT_OF_MEMORY);

    return device;
}
Exemplo n.º 30
0
/*
    alcCloseDevice

    Close the specified Device
*/
ALCAPI ALCboolean ALCAPIENTRY alcCloseDevice(ALCdevice *pDevice)
{
    ALCboolean bReturn = ALC_FALSE;
    ALCdevice **list;

    if(IsDevice(pDevice) && !pDevice->IsCaptureDevice)
    {
        SuspendContext(NULL);

        list = &g_pDeviceList;
        while(*list != pDevice)
            list = &(*list)->next;

        *list = (*list)->next;
        g_ulDeviceCount--;

        ProcessContext(NULL);

        if(pDevice->NumContexts > 0)
        {
#ifdef _DEBUG
            AL_PRINT("alcCloseDevice(): destroying %u Context(s)\n", pDevice->NumContexts);
#endif
            while(pDevice->NumContexts > 0)
                alcDestroyContext(pDevice->Contexts[0]);
        }
        ALCdevice_ClosePlayback(pDevice);

        if(pDevice->BufferCount > 0)
        {
#ifdef _DEBUG
            AL_PRINT("alcCloseDevice(): deleting %d Buffer(s)\n", pDevice->BufferCount);
#endif
            ReleaseALBuffers(pDevice);
        }
        if(pDevice->EffectCount > 0)
        {
#ifdef _DEBUG
            AL_PRINT("alcCloseDevice(): deleting %d Effect(s)\n", pDevice->EffectCount);
#endif
            ReleaseALEffects(pDevice);
        }
        if(pDevice->FilterCount > 0)
        {
#ifdef _DEBUG
            AL_PRINT("alcCloseDevice(): deleting %d Filter(s)\n", pDevice->FilterCount);
#endif
            ReleaseALFilters(pDevice);
        }
        if(pDevice->DatabufferCount > 0)
        {
#ifdef _DEBUG
            AL_PRINT("alcCloseDevice(): deleting %d Databuffer(s)\n", pDevice->DatabufferCount);
#endif
            ReleaseALDatabuffers(pDevice);
        }

        free(pDevice->Bs2b);
        pDevice->Bs2b = NULL;

        free(pDevice->szDeviceName);
        pDevice->szDeviceName = NULL;

        free(pDevice->Contexts);
        pDevice->Contexts = NULL;

        //Release device structure
        memset(pDevice, 0, sizeof(ALCdevice));
        free(pDevice);

        bReturn = ALC_TRUE;
    }
    else
        alcSetError(ALC_INVALID_DEVICE);

    return bReturn;
}