Exemple #1
0
/*
    InitContext

    Initialize Context variables
*/
static ALvoid InitContext(ALCcontext *pContext)
{
    int level;

    //Initialise listener
    pContext->Listener.Gain = 1.0f;
    pContext->Listener.MetersPerUnit = 1.0f;
    pContext->Listener.Position[0] = 0.0f;
    pContext->Listener.Position[1] = 0.0f;
    pContext->Listener.Position[2] = 0.0f;
    pContext->Listener.Velocity[0] = 0.0f;
    pContext->Listener.Velocity[1] = 0.0f;
    pContext->Listener.Velocity[2] = 0.0f;
    pContext->Listener.Forward[0] = 0.0f;
    pContext->Listener.Forward[1] = 0.0f;
    pContext->Listener.Forward[2] = -1.0f;
    pContext->Listener.Up[0] = 0.0f;
    pContext->Listener.Up[1] = 1.0f;
    pContext->Listener.Up[2] = 0.0f;

    //Validate pContext
    pContext->LastError = AL_NO_ERROR;
    pContext->InUse = AL_FALSE;

    //Set output format
    pContext->Frequency = pContext->Device->Frequency;

    //Set globals
    pContext->DistanceModel = AL_INVERSE_DISTANCE_CLAMPED;
    pContext->DopplerFactor = 1.0f;
    pContext->DopplerVelocity = 1.0f;
    pContext->flSpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;

    pContext->lNumStereoSources = 1;
    pContext->lNumMonoSources = pContext->Device->MaxNoOfSources - pContext->lNumStereoSources;

    pContext->ExtensionList = "AL_EXTX_buffer_sub_data AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_OFFSET AL_LOKI_quadriphonic";

    level = GetConfigValueInt(NULL, "cf_level", 0);
    if(level > 0 && level <= 6)
    {
        pContext->bs2b = calloc(1, sizeof(*pContext->bs2b));
        bs2b_set_srate(pContext->bs2b, pContext->Frequency);
        bs2b_set_level(pContext->bs2b, level);
    }
}
Exemple #2
0
// OpenAL {{{
static ALCboolean pulse_open_playback(ALCdevice *device, const ALCchar *device_name) //{{{
{
    if(!device_name)
        device_name = pulse_device;
    else if(strcmp(device_name, pulse_device) != 0)
        return ALC_FALSE;

    if(!pulse_load())
        return ALC_FALSE;

    if(pulse_open(device, device_name) != ALC_FALSE)
    {
        ALuint len = GetConfigValueInt("pulse", "buffer-length", 2048);
        if(len != 0)
        {
            device->UpdateSize = len;
            device->NumUpdates = 1;
        }
        return ALC_TRUE;
    }

    pulse_unload();
    return ALC_FALSE;
} //}}}
Exemple #3
0
static ALCboolean oss_open_playback(ALCdevice *device, const ALCchar *deviceName)
{
    int numFragmentsLogSize;
    int log2FragmentSize;
    unsigned int periods;
    audio_buf_info info;
    ALuint frameSize;
    char driver[64];
    int numChannels;
    oss_data *data;
    int ossFormat;
    int ossSpeed;
    char *err;
    int i;

    strncpy(driver, GetConfigValue("oss", "device", "/dev/dsp"), sizeof(driver)-1);
    driver[sizeof(driver)-1] = 0;
    if(deviceName)
    {
        if(strcmp(deviceName, oss_device))
            return ALC_FALSE;
        device->szDeviceName = oss_device;
    }
    else
        device->szDeviceName = oss_device;

    data = (oss_data*)calloc(1, sizeof(oss_data));
    data->killNow = 0;

    data->fd = open(driver, O_WRONLY);
    if(data->fd == -1)
    {
        free(data);
        AL_PRINT("Could not open %s: %s\n", driver, strerror(errno));
        return ALC_FALSE;
    }

    switch(aluBytesFromFormat(device->Format))
    {
        case 1:
            ossFormat = AFMT_U8;
            break;
        case 2:
            ossFormat = AFMT_S16_NE;
            break;
        default:
            ossFormat = -1;
            AL_PRINT("Unknown format?! %x\n", device->Format);
    }

    periods = GetConfigValueInt("oss", "periods", 4);
    if((int)periods <= 0)
        periods = 4;
    numChannels = aluChannelsFromFormat(device->Format);
    frameSize = numChannels * aluBytesFromFormat(device->Format);

    ossSpeed = device->Frequency;
    log2FragmentSize = log2i(device->UpdateSize * frameSize / periods);

    /* according to the OSS spec, 16 bytes are the minimum */
    if (log2FragmentSize < 4)
        log2FragmentSize = 4;
    numFragmentsLogSize = (periods << 16) | log2FragmentSize;

#define ok(func, str) (i=(func),((i<0)?(err=(str)),0:1))
    if (!(ok(ioctl(data->fd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize), "set fragment") &&
          ok(ioctl(data->fd, SNDCTL_DSP_SETFMT, &ossFormat), "set format") &&
          ok(ioctl(data->fd, SNDCTL_DSP_CHANNELS, &numChannels), "set channels") &&
          ok(ioctl(data->fd, SNDCTL_DSP_SPEED, &ossSpeed), "set speed") &&
          ok(ioctl(data->fd, SNDCTL_DSP_GETOSPACE, &info), "get space")))
    {
        AL_PRINT("%s failed: %s\n", err, strerror(errno));
        close(data->fd);
        free(data);
        return ALC_FALSE;
    }
#undef ok

    device->Frequency = ossSpeed;

    if((int)aluChannelsFromFormat(device->Format) != numChannels)
    {
        AL_PRINT("Could not set %d channels, got %d instead\n", aluChannelsFromFormat(device->Format), numChannels);
        close(data->fd);
        free(data);
        return ALC_FALSE;
    }

    if(!((ossFormat == AFMT_U8 && aluBytesFromFormat(device->Format) == 1) ||
         (ossFormat == AFMT_S16_NE && aluBytesFromFormat(device->Format) == 2)))
    {
        AL_PRINT("Could not set %d-bit output, got format %#x\n", aluBytesFromFormat(device->Format)*8, ossFormat);
        close(data->fd);
        free(data);
        return ALC_FALSE;
    }

    device->UpdateSize = info.fragsize / frameSize;

    data->data_size = device->UpdateSize * frameSize;
    data->mix_data = calloc(1, data->data_size);

    device->ExtraData = data;
    data->thread = StartThread(OSSProc, device);
    if(data->thread == NULL)
    {
        device->ExtraData = NULL;
        free(data->mix_data);
        free(data);
        return ALC_FALSE;
    }

    return ALC_TRUE;
}
Exemple #4
0
/*
    alcOpenDevice

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

    InitAL();

    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->IsCaptureDevice = AL_FALSE;

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

        fmt = GetConfigValue(NULL, "format", "AL_FORMAT_STEREO16");
        if(fmt[0])
            device->Format = alGetEnumValue(fmt);

        if(!aluChannelsFromFormat(device->Format))
            device->Format = AL_FORMAT_STEREO16;

        device->UpdateSize = GetConfigValueInt(NULL, "refresh", 4096);
        if((ALint)device->UpdateSize <= 0)
            device->UpdateSize = 4096;

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

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

                bDeviceFound = AL_TRUE;
                break;
            }
        }

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

    return device;
}
// OpenAL {{{
static ALCboolean pulse_open_playback( ALCdevice* device, const ALCchar* device_name ) //{{{
{
	char* pulse_name = NULL;
	pa_sample_spec spec;
	pulse_data* data;
	ALuint len;

	if ( !pulse_load() )
	{
		return ALC_FALSE;
	}

	if ( !device_name )
	{
		device_name = pulse_device;
	}
	else if ( strcmp( device_name, pulse_device ) != 0 )
	{
		ALuint i;

		if ( !allDevNameMap )
		{
			probe_devices( AL_FALSE );
		}

		for ( i = 0; i < numDevNames; i++ )
		{
			if ( strcmp( device_name, allDevNameMap[i].name ) == 0 )
			{
				pulse_name = allDevNameMap[i].device_name;
				break;
			}
		}

		if ( i == numDevNames )
		{
			return ALC_FALSE;
		}
	}

	if ( pulse_open( device, device_name ) == ALC_FALSE )
	{
		return ALC_FALSE;
	}

	data = device->ExtraData;

	ppa_threaded_mainloop_lock( data->loop );

	spec.format = PA_SAMPLE_S16NE;
	spec.rate = 44100;
	spec.channels = 2;

	data->device_name = pulse_name;
	pa_stream* stream = connect_playback_stream( device, 0, NULL, &spec, NULL );

	if ( !stream )
	{
		ppa_threaded_mainloop_unlock( data->loop );
		goto fail;
	}

	if ( ppa_stream_is_suspended( stream ) )
	{
		ppa_stream_disconnect( stream );
		ppa_stream_unref( stream );
		ppa_threaded_mainloop_unlock( data->loop );
		goto fail;
	}

	data->device_name = strdup( ppa_stream_get_device_name( stream ) );

	ppa_stream_disconnect( stream );
	ppa_stream_unref( stream );

	ppa_threaded_mainloop_unlock( data->loop );

	len = GetConfigValueInt( "pulse", "buffer-length", 2048 );

	if ( len != 0 )
	{
		device->UpdateSize = len;
		device->NumUpdates = 1;
	}

	return ALC_TRUE;

fail:
	pulse_close( device );
	return ALC_FALSE;
} //}}}
Exemple #6
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;
}
Exemple #7
0
static ALCboolean pa_open_playback(ALCdevice *device, const ALCchar *deviceName)
{
    const PaStreamInfo *streamInfo;
    PaStreamParameters outParams;
    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));
    data->update_size = device->UpdateSize;

    device->ExtraData = data;

    outParams.device = GetConfigValueInt("port", "device", -1);
    if(outParams.device < 0)
        outParams.device = pPa_GetDefaultOutputDevice();
    outParams.suggestedLatency = (device->UpdateSize*device->NumUpdates) /
                                 (float)device->Frequency;
    outParams.hostApiSpecificStreamInfo = NULL;

    switch(aluBytesFromFormat(device->Format))
    {
        case 1:
            outParams.sampleFormat = paUInt8;
            break;
        case 2:
            outParams.sampleFormat = paInt16;
            break;
        case 4:
            outParams.sampleFormat = paFloat32;
            break;
        default:
            AL_PRINT("Unknown format: 0x%x\n", device->Format);
            device->ExtraData = NULL;
            free(data);
            return ALC_FALSE;
    }
    outParams.channelCount = aluChannelsFromFormat(device->Format);

    SetDefaultChannelOrder(device);

    err = pPa_OpenStream(&data->stream, NULL, &outParams, device->Frequency,
                         device->UpdateSize, paNoFlag, pa_callback, device);
    if(err != paNoError)
    {
        AL_PRINT("Pa_OpenStream() returned an error: %s\n", pPa_GetErrorText(err));
        device->ExtraData = NULL;
        free(data);
        return ALC_FALSE;
    }
    streamInfo = pPa_GetStreamInfo(data->stream);

    device->szDeviceName = strdup(deviceName);
    device->Frequency = streamInfo->sampleRate;

    return ALC_TRUE;
}
Exemple #8
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;
}
Exemple #9
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;
}