Beispiel #1
0
static ALCboolean ALCnullBackend_start(ALCnullBackend *self)
{
    ATOMIC_STORE(&self->killNow, AL_FALSE, almemory_order_release);
    if(althrd_create(&self->thread, ALCnullBackend_mixerProc, self) != althrd_success)
        return ALC_FALSE;
    return ALC_TRUE;
}
Beispiel #2
0
static ALCboolean WinMMStartPlayback(ALCdevice *device)
{
    WinMMData *data = (WinMMData*)device->ExtraData;
    ALbyte *BufferData;
    ALint BufferSize;
    ALuint i;

    data->killNow = AL_FALSE;
    if(althrd_create(&data->thread, PlaybackThreadProc, device) != althrd_success)
        return ALC_FALSE;

    InitRef(&data->WaveBuffersCommitted, 0);

    // Create 4 Buffers
    BufferSize  = device->UpdateSize*device->NumUpdates / 4;
    BufferSize *= FrameSizeFromDevFmt(device->FmtChans, device->FmtType);

    BufferData = calloc(4, BufferSize);
    for(i = 0; i < 4; i++)
    {
        memset(&data->WaveBuffer[i], 0, sizeof(WAVEHDR));
        data->WaveBuffer[i].dwBufferLength = BufferSize;
        data->WaveBuffer[i].lpData = ((i==0) ? (CHAR*)BufferData :
                                      (data->WaveBuffer[i-1].lpData +
                                       data->WaveBuffer[i-1].dwBufferLength));
        waveOutPrepareHeader(data->WaveHandle.Out, &data->WaveBuffer[i], sizeof(WAVEHDR));
        waveOutWrite(data->WaveHandle.Out, &data->WaveBuffer[i], sizeof(WAVEHDR));
        IncrementRef(&data->WaveBuffersCommitted);
    }

    return ALC_TRUE;
}
Beispiel #3
0
static ALCboolean ALCwinmmPlayback_start(ALCwinmmPlayback *self)
{
    ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
    ALbyte *BufferData;
    ALint BufferSize;
    ALuint i;

    ATOMIC_STORE(&self->killNow, AL_FALSE, almemory_order_release);
    if(althrd_create(&self->thread, ALCwinmmPlayback_mixerProc, self) != althrd_success)
        return ALC_FALSE;

    InitRef(&self->WaveBuffersCommitted, 0);

    // Create 4 Buffers
    BufferSize  = device->UpdateSize*device->NumUpdates / 4;
    BufferSize *= FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder);

    BufferData = calloc(4, BufferSize);
    for(i = 0;i < 4;i++)
    {
        memset(&self->WaveBuffer[i], 0, sizeof(WAVEHDR));
        self->WaveBuffer[i].dwBufferLength = BufferSize;
        self->WaveBuffer[i].lpData = ((i==0) ? (CHAR*)BufferData :
                                      (self->WaveBuffer[i-1].lpData +
                                       self->WaveBuffer[i-1].dwBufferLength));
        waveOutPrepareHeader(self->OutHdl, &self->WaveBuffer[i], sizeof(WAVEHDR));
        waveOutWrite(self->OutHdl, &self->WaveBuffer[i], sizeof(WAVEHDR));
        IncrementRef(&self->WaveBuffersCommitted);
    }

    return ALC_TRUE;
}
Beispiel #4
0
static ALCboolean ALCsolarisBackend_start(ALCsolarisBackend *self)
{
    ATOMIC_STORE_SEQ(&self->killNow, AL_FALSE);
    if(althrd_create(&self->thread, ALCsolarisBackend_mixerProc, self) != althrd_success)
        return ALC_FALSE;
    return ALC_TRUE;
}
Beispiel #5
0
static ALCboolean qsa_start_playback(ALCdevice* device)
{
    qsa_data *data = (qsa_data*)device->ExtraData;

    data->killNow = 0;
    if(althrd_create(&data->thread, qsa_proc_playback, device) != althrd_success)
        return ALC_FALSE;

    return ALC_TRUE;
}
Beispiel #6
0
static ALCboolean sndio_start_playback(ALCdevice *device)
{
    sndio_data *data = device->ExtraData;

    if(!sio_start(data->sndHandle))
    {
        ERR("Error starting playback\n");
        return ALC_FALSE;
    }

    data->data_size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
    data->mix_data = calloc(1, data->data_size);

    data->killNow = 0;
    if(althrd_create(&data->thread, sndio_proc, device) != althrd_success)
    {
        sio_stop(data->sndHandle);
        free(data->mix_data);
        data->mix_data = NULL;
        return ALC_FALSE;
    }

    return ALC_TRUE;
}
Beispiel #7
0
static ALCenum WinMMOpenCapture(ALCdevice *Device, const ALCchar *deviceName)
{
    const al_string *iter, *end;
    ALbyte *BufferData = NULL;
    DWORD CapturedDataSize;
    WinMMData *data = NULL;
    ALint BufferSize;
    UINT DeviceID;
    MMRESULT res;
    ALuint i;

    if(VECTOR_SIZE(CaptureDevices) == 0)
        ProbeCaptureDevices();

    // Find the Device ID matching the deviceName if valid
    iter = VECTOR_ITER_BEGIN(CaptureDevices);
    end = VECTOR_ITER_END(CaptureDevices);
    for(; iter != end; iter++)
    {
        if(!al_string_empty(*iter) &&
                (!deviceName || al_string_cmp_cstr(*iter, deviceName) == 0))
        {
            DeviceID = (UINT)(iter - VECTOR_ITER_BEGIN(CaptureDevices));
            break;
        }
    }
    if(iter == end)
        return ALC_INVALID_VALUE;

    switch(Device->FmtChans)
    {
    case DevFmtMono:
    case DevFmtStereo:
        break;

    case DevFmtQuad:
    case DevFmtX51:
    case DevFmtX51Side:
    case DevFmtX61:
    case DevFmtX71:
        return ALC_INVALID_ENUM;
    }

    switch(Device->FmtType)
    {
    case DevFmtUByte:
    case DevFmtShort:
    case DevFmtInt:
    case DevFmtFloat:
        break;

    case DevFmtByte:
    case DevFmtUShort:
    case DevFmtUInt:
        return ALC_INVALID_ENUM;
    }

    data = calloc(1, sizeof(*data));
    if(!data)
        return ALC_OUT_OF_MEMORY;
    Device->ExtraData = data;

    memset(&data->Format, 0, sizeof(WAVEFORMATEX));
    data->Format.wFormatTag = ((Device->FmtType == DevFmtFloat) ?
                               WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM);
    data->Format.nChannels = ChannelsFromDevFmt(Device->FmtChans);
    data->Format.wBitsPerSample = BytesFromDevFmt(Device->FmtType) * 8;
    data->Format.nBlockAlign = data->Format.wBitsPerSample *
                               data->Format.nChannels / 8;
    data->Format.nSamplesPerSec = Device->Frequency;
    data->Format.nAvgBytesPerSec = data->Format.nSamplesPerSec *
                                   data->Format.nBlockAlign;
    data->Format.cbSize = 0;

    if((res=waveInOpen(&data->WaveHandle.In, DeviceID, &data->Format, (DWORD_PTR)&WaveInProc, (DWORD_PTR)Device, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR)
    {
        ERR("waveInOpen failed: %u\n", res);
        goto failure;
    }

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

    // Make sure circular buffer is at least 100ms in size
    if(CapturedDataSize < (data->Format.nSamplesPerSec / 10))
        CapturedDataSize = data->Format.nSamplesPerSec / 10;

    data->Ring = CreateRingBuffer(data->Format.nBlockAlign, CapturedDataSize);
    if(!data->Ring)
        goto failure;

    InitRef(&data->WaveBuffersCommitted, 0);

    // Create 4 Buffers of 50ms each
    BufferSize = data->Format.nAvgBytesPerSec / 20;
    BufferSize -= (BufferSize % data->Format.nBlockAlign);

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

    for(i = 0; i < 4; i++)
    {
        memset(&data->WaveBuffer[i], 0, sizeof(WAVEHDR));
        data->WaveBuffer[i].dwBufferLength = BufferSize;
        data->WaveBuffer[i].lpData = ((i==0) ? (CHAR*)BufferData :
                                      (data->WaveBuffer[i-1].lpData +
                                       data->WaveBuffer[i-1].dwBufferLength));
        data->WaveBuffer[i].dwFlags = 0;
        data->WaveBuffer[i].dwLoops = 0;
        waveInPrepareHeader(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR));
        waveInAddBuffer(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR));
        IncrementRef(&data->WaveBuffersCommitted);
    }

    if(althrd_create(&data->thread, CaptureThreadProc, Device) != althrd_success)
        goto failure;

    al_string_copy(&Device->DeviceName, VECTOR_ELEM(CaptureDevices, DeviceID));
    return ALC_NO_ERROR;

failure:
    if(BufferData)
    {
        for(i = 0; i < 4; i++)
            waveInUnprepareHeader(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR));
        free(BufferData);
    }

    if(data->Ring)
        DestroyRingBuffer(data->Ring);

    if(data->WaveHandle.In)
        waveInClose(data->WaveHandle.In);

    free(data);
    Device->ExtraData = NULL;
    return ALC_INVALID_VALUE;
}
Beispiel #8
0
static ALCenum ALCwinmmCapture_open(ALCwinmmCapture *self, const ALCchar *name)
{
    ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
    const al_string *iter;
    ALbyte *BufferData = NULL;
    DWORD CapturedDataSize;
    ALint BufferSize;
    UINT DeviceID;
    MMRESULT res;
    ALuint i;

    if(VECTOR_SIZE(CaptureDevices) == 0)
        ProbeCaptureDevices();

    // Find the Device ID matching the deviceName if valid
#define MATCH_DEVNAME(iter) (!alstr_empty(*(iter)) && (!name || alstr_cmp_cstr(*iter, name) == 0))
    VECTOR_FIND_IF(iter, const al_string, CaptureDevices, MATCH_DEVNAME);
    if(iter == VECTOR_END(CaptureDevices))
        return ALC_INVALID_VALUE;
#undef MATCH_DEVNAME

    DeviceID = (UINT)(iter - VECTOR_BEGIN(CaptureDevices));

    switch(device->FmtChans)
    {
        case DevFmtMono:
        case DevFmtStereo:
            break;

        case DevFmtQuad:
        case DevFmtX51:
        case DevFmtX51Rear:
        case DevFmtX61:
        case DevFmtX71:
        case DevFmtAmbi3D:
            return ALC_INVALID_ENUM;
    }

    switch(device->FmtType)
    {
        case DevFmtUByte:
        case DevFmtShort:
        case DevFmtInt:
        case DevFmtFloat:
            break;

        case DevFmtByte:
        case DevFmtUShort:
        case DevFmtUInt:
            return ALC_INVALID_ENUM;
    }

    memset(&self->Format, 0, sizeof(WAVEFORMATEX));
    self->Format.wFormatTag = ((device->FmtType == DevFmtFloat) ?
                               WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM);
    self->Format.nChannels = ChannelsFromDevFmt(device->FmtChans, device->AmbiOrder);
    self->Format.wBitsPerSample = BytesFromDevFmt(device->FmtType) * 8;
    self->Format.nBlockAlign = self->Format.wBitsPerSample *
                               self->Format.nChannels / 8;
    self->Format.nSamplesPerSec = device->Frequency;
    self->Format.nAvgBytesPerSec = self->Format.nSamplesPerSec *
                                   self->Format.nBlockAlign;
    self->Format.cbSize = 0;

    if((res=waveInOpen(&self->InHdl, DeviceID, &self->Format, (DWORD_PTR)&ALCwinmmCapture_waveInProc, (DWORD_PTR)self, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR)
    {
        ERR("waveInOpen failed: %u\n", res);
        goto failure;
    }

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

    // Make sure circular buffer is at least 100ms in size
    if(CapturedDataSize < (self->Format.nSamplesPerSec / 10))
        CapturedDataSize = self->Format.nSamplesPerSec / 10;

    self->Ring = ll_ringbuffer_create(CapturedDataSize, self->Format.nBlockAlign, false);
    if(!self->Ring) goto failure;

    InitRef(&self->WaveBuffersCommitted, 0);

    // Create 4 Buffers of 50ms each
    BufferSize = self->Format.nAvgBytesPerSec / 20;
    BufferSize -= (BufferSize % self->Format.nBlockAlign);

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

    for(i = 0;i < 4;i++)
    {
        memset(&self->WaveBuffer[i], 0, sizeof(WAVEHDR));
        self->WaveBuffer[i].dwBufferLength = BufferSize;
        self->WaveBuffer[i].lpData = ((i==0) ? (CHAR*)BufferData :
                                      (self->WaveBuffer[i-1].lpData +
                                       self->WaveBuffer[i-1].dwBufferLength));
        self->WaveBuffer[i].dwFlags = 0;
        self->WaveBuffer[i].dwLoops = 0;
        waveInPrepareHeader(self->InHdl, &self->WaveBuffer[i], sizeof(WAVEHDR));
        waveInAddBuffer(self->InHdl, &self->WaveBuffer[i], sizeof(WAVEHDR));
        IncrementRef(&self->WaveBuffersCommitted);
    }

    ATOMIC_STORE(&self->killNow, AL_FALSE, almemory_order_release);
    if(althrd_create(&self->thread, ALCwinmmCapture_captureProc, self) != althrd_success)
        goto failure;

    alstr_copy(&device->DeviceName, VECTOR_ELEM(CaptureDevices, DeviceID));
    return ALC_NO_ERROR;

failure:
    if(BufferData)
    {
        for(i = 0;i < 4;i++)
            waveInUnprepareHeader(self->InHdl, &self->WaveBuffer[i], sizeof(WAVEHDR));
        free(BufferData);
    }

    ll_ringbuffer_free(self->Ring);
    self->Ring = NULL;

    if(self->InHdl)
        waveInClose(self->InHdl);
    self->InHdl = NULL;

    return ALC_INVALID_VALUE;
}