예제 #1
0
static ALCenum pa_open_capture(ALCdevice *device, const ALCchar *deviceName)
{
    ALuint frame_size;
    pa_data *data;
    PaError err;

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

    data = (pa_data*)calloc(1, sizeof(pa_data));
    if(data == NULL)
        return ALC_OUT_OF_MEMORY;

    frame_size = FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
    data->ring = CreateRingBuffer(frame_size, device->UpdateSize*device->NumUpdates);
    if(data->ring == NULL)
        goto error;

    data->params.device = -1;
    if(!ConfigValueInt("port", "capture", &data->params.device) ||
       data->params.device < 0)
        data->params.device = Pa_GetDefaultOutputDevice();
    data->params.suggestedLatency = 0.0f;
    data->params.hostApiSpecificStreamInfo = NULL;

    switch(device->FmtType)
    {
        case DevFmtByte:
            data->params.sampleFormat = paInt8;
            break;
        case DevFmtUByte:
            data->params.sampleFormat = paUInt8;
            break;
        case DevFmtShort:
            data->params.sampleFormat = paInt16;
            break;
        case DevFmtInt:
            data->params.sampleFormat = paInt32;
            break;
        case DevFmtFloat:
            data->params.sampleFormat = paFloat32;
            break;
        case DevFmtUInt:
        case DevFmtUShort:
            ERR("%s samples not supported\n", DevFmtTypeString(device->FmtType));
            goto error;
    }
    data->params.channelCount = ChannelsFromDevFmt(device->FmtChans);

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

    device->DeviceName = strdup(deviceName);

    device->ExtraData = data;
    return ALC_NO_ERROR;

error:
    DestroyRingBuffer(data->ring);
    free(data);
    return ALC_INVALID_VALUE;
}
예제 #2
0
static ALCenum pa_open_playback(ALCdevice *device, const ALCchar *deviceName)
{
    pa_data *data;
    PaError err;

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

    data = (pa_data*)calloc(1, sizeof(pa_data));
    data->update_size = device->UpdateSize;

    data->params.device = -1;
    if(!ConfigValueInt("port", "device", &data->params.device) ||
       data->params.device < 0)
        data->params.device = Pa_GetDefaultOutputDevice();
    data->params.suggestedLatency = (device->UpdateSize*device->NumUpdates) /
                                    (float)device->Frequency;
    data->params.hostApiSpecificStreamInfo = NULL;

    data->params.channelCount = ((device->FmtChans == DevFmtMono) ? 1 : 2);

    switch(device->FmtType)
    {
        case DevFmtByte:
            data->params.sampleFormat = paInt8;
            break;
        case DevFmtUByte:
            data->params.sampleFormat = paUInt8;
            break;
        case DevFmtUShort:
            /* fall-through */
        case DevFmtShort:
            data->params.sampleFormat = paInt16;
            break;
        case DevFmtUInt:
            /* fall-through */
        case DevFmtInt:
            data->params.sampleFormat = paInt32;
            break;
        case DevFmtFloat:
            data->params.sampleFormat = paFloat32;
            break;
    }

retry_open:
    err = Pa_OpenStream(&data->stream, NULL, &data->params, device->Frequency,
                        device->UpdateSize, paNoFlag, pa_callback, device);
    if(err != paNoError)
    {
        if(data->params.sampleFormat == paFloat32)
        {
            data->params.sampleFormat = paInt16;
            goto retry_open;
        }
        ERR("Pa_OpenStream() returned an error: %s\n", Pa_GetErrorText(err));
        free(data);
        return ALC_INVALID_VALUE;
    }

    device->ExtraData = data;
    device->DeviceName = strdup(deviceName);

    return ALC_NO_ERROR;
}
예제 #3
0
int MOB_File_ConfigValueInt(const char *blockName, const char *keyName, int *ret)
{
	char buffer[ 64 ];
	return ConfigValueInt( ConvertBlockName( blockName ), ConvertKeyName( buffer, keyName ), ret );
}
예제 #4
0
void aluInitRenderer(ALCdevice *device, ALint hrtf_id, enum HrtfRequestMode hrtf_appreq, enum HrtfRequestMode hrtf_userreq)
{
    const char *mode;
    bool headphones;
    int bs2blevel;
    size_t i;

    device->Hrtf = NULL;
    al_string_clear(&device->Hrtf_Name);
    device->Render_Mode = NormalRender;

    memset(&device->Dry.Ambi, 0, sizeof(device->Dry.Ambi));
    device->Dry.CoeffCount = 0;
    device->Dry.NumChannels = 0;

    if(device->FmtChans != DevFmtStereo)
    {
        ALuint speakermap[MAX_OUTPUT_CHANNELS];
        const char *devname, *layout = NULL;
        AmbDecConf conf, *pconf = NULL;

        if(hrtf_appreq == Hrtf_Enable)
            device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;

        ambdec_init(&conf);

        devname = al_string_get_cstr(device->DeviceName);
        switch(device->FmtChans)
        {
            case DevFmtQuad: layout = "quad"; break;
            case DevFmtX51: layout = "surround51"; break;
            case DevFmtX51Rear: layout = "surround51rear"; break;
            case DevFmtX61: layout = "surround61"; break;
            case DevFmtX71: layout = "surround71"; break;
            /* Mono, Stereo, and B-Fornat output don't use custom decoders. */
            case DevFmtMono:
            case DevFmtStereo:
            case DevFmtBFormat3D:
                break;
        }
        if(layout)
        {
            const char *fname;
            if(ConfigValueStr(devname, "decoder", layout, &fname))
            {
                if(!ambdec_load(&conf, fname))
                    ERR("Failed to load layout file %s\n", fname);
                else
                {
                    if(conf.ChanMask > 0xffff)
                        ERR("Unsupported channel mask 0x%04x (max 0xffff)\n", conf.ChanMask);
                    else
                    {
                        if(MakeSpeakerMap(device, &conf, speakermap))
                            pconf = &conf;
                    }
                }
            }
        }

        if(pconf && GetConfigValueBool(devname, "decoder", "hq-mode", 0))
        {
            if(!device->AmbiDecoder)
                device->AmbiDecoder = bformatdec_alloc();
        }
        else
        {
            bformatdec_free(device->AmbiDecoder);
            device->AmbiDecoder = NULL;
        }

        if(!pconf)
            InitPanning(device);
        else if(device->AmbiDecoder)
            InitHQPanning(device, pconf, speakermap);
        else
            InitCustomPanning(device, pconf, speakermap);

        ambdec_deinit(&conf);
        return;
    }

    bformatdec_free(device->AmbiDecoder);
    device->AmbiDecoder = NULL;

    headphones = device->IsHeadphones;
    if(device->Type != Loopback)
    {
        const char *mode;
        if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "stereo-mode", &mode))
        {
            if(strcasecmp(mode, "headphones") == 0)
                headphones = true;
            else if(strcasecmp(mode, "speakers") == 0)
                headphones = false;
            else if(strcasecmp(mode, "auto") != 0)
                ERR("Unexpected stereo-mode: %s\n", mode);
        }
    }

    if(hrtf_userreq == Hrtf_Default)
    {
        bool usehrtf = (headphones && hrtf_appreq != Hrtf_Disable) ||
                       (hrtf_appreq == Hrtf_Enable);
        if(!usehrtf) goto no_hrtf;

        device->Hrtf_Status = ALC_HRTF_ENABLED_SOFT;
        if(headphones && hrtf_appreq != Hrtf_Disable)
            device->Hrtf_Status = ALC_HRTF_HEADPHONES_DETECTED_SOFT;
    }
    else
    {
        if(hrtf_userreq != Hrtf_Enable)
        {
            if(hrtf_appreq == Hrtf_Enable)
                device->Hrtf_Status = ALC_HRTF_DENIED_SOFT;
            goto no_hrtf;
        }
        device->Hrtf_Status = ALC_HRTF_REQUIRED_SOFT;
    }

    if(VECTOR_SIZE(device->Hrtf_List) == 0)
    {
        VECTOR_DEINIT(device->Hrtf_List);
        device->Hrtf_List = EnumerateHrtf(device->DeviceName);
    }

    if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf_List))
    {
        const HrtfEntry *entry = &VECTOR_ELEM(device->Hrtf_List, hrtf_id);
        if(GetHrtfSampleRate(entry->hrtf) == device->Frequency)
        {
            device->Hrtf = entry->hrtf;
            al_string_copy(&device->Hrtf_Name, entry->name);
        }
    }

    for(i = 0;!device->Hrtf && i < VECTOR_SIZE(device->Hrtf_List);i++)
    {
        const HrtfEntry *entry = &VECTOR_ELEM(device->Hrtf_List, i);
        if(GetHrtfSampleRate(entry->hrtf) == device->Frequency)
        {
            device->Hrtf = entry->hrtf;
            al_string_copy(&device->Hrtf_Name, entry->name);
        }
    }

    if(device->Hrtf)
    {
        device->Render_Mode = HrtfRender;
        if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf-mode", &mode))
        {
            if(strcasecmp(mode, "full") == 0)
                device->Render_Mode = HrtfRender;
            else if(strcasecmp(mode, "basic") == 0)
                device->Render_Mode = NormalRender;
            else
                ERR("Unexpected hrtf-mode: %s\n", mode);
        }

        TRACE("HRTF enabled, \"%s\"\n", al_string_get_cstr(device->Hrtf_Name));
        InitHrtfPanning(device);
        return;
    }
    device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;

no_hrtf:
    TRACE("HRTF disabled\n");

    bs2blevel = ((headphones && hrtf_appreq != Hrtf_Disable) ||
                 (hrtf_appreq == Hrtf_Enable)) ? 5 : 0;
    if(device->Type != Loopback)
        ConfigValueInt(al_string_get_cstr(device->DeviceName), NULL, "cf_level", &bs2blevel);
    if(bs2blevel > 0 && bs2blevel <= 6)
    {
        device->Bs2b = al_calloc(16, sizeof(*device->Bs2b));
        bs2b_set_params(device->Bs2b, bs2blevel, device->Frequency);
        device->Render_Mode = StereoPair;
        TRACE("BS2B enabled\n");
        InitPanning(device);
        return;
    }

    TRACE("BS2B disabled\n");

    device->Render_Mode = NormalRender;
    if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "stereo-panning", &mode))
    {
        if(strcasecmp(mode, "paired") == 0)
            device->Render_Mode = StereoPair;
        else if(strcasecmp(mode, "uhj") != 0)
            ERR("Unexpected stereo-panning: %s\n", mode);
    }
    if(device->Render_Mode == NormalRender)
    {
        device->Uhj_Encoder = al_calloc(16, sizeof(Uhj2Encoder));
        TRACE("UHJ enabled\n");
        InitUhjPanning(device);
        return;
    }

    TRACE("UHJ disabled\n");
    InitPanning(device);
}
예제 #5
0
static ALCenum pa_open_playback(ALCdevice *device, const ALCchar *deviceName)
{
    PaStreamParameters outParams;
    pa_data *data;
    PaError err;

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

    data = (pa_data*)calloc(1, sizeof(pa_data));
    data->update_size = device->UpdateSize;

    device->ExtraData = data;

    outParams.device = -1;
    if(!ConfigValueInt("port", "device", &outParams.device) || outParams.device < 0)
        outParams.device = Pa_GetDefaultOutputDevice();
    outParams.suggestedLatency = (device->UpdateSize*device->NumUpdates) /
                                 (float)device->Frequency;
    outParams.hostApiSpecificStreamInfo = NULL;

    switch(device->FmtType)
    {
        case DevFmtByte:
            outParams.sampleFormat = paInt8;
            break;
        case DevFmtUByte:
            outParams.sampleFormat = paUInt8;
            break;
        case DevFmtUShort:
            device->FmtType = DevFmtShort;
            /* fall-through */
        case DevFmtShort:
            outParams.sampleFormat = paInt16;
            break;
        case DevFmtFloat:
            outParams.sampleFormat = paFloat32;
            break;
    }
    outParams.channelCount = ((device->FmtChans == DevFmtMono) ? 1 : 2);

    SetDefaultChannelOrder(device);

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

    device->szDeviceName = strdup(deviceName);

    if((ALuint)outParams.channelCount != ChannelsFromDevFmt(device->FmtChans))
    {
        if(outParams.channelCount != 1 && outParams.channelCount != 2)
        {
            ERR("Unhandled channel count: %u\n", outParams.channelCount);
            Pa_CloseStream(data->stream);
            device->ExtraData = NULL;
            free(data);
            return ALC_INVALID_VALUE;
        }
        if((device->Flags&DEVICE_CHANNELS_REQUEST))
            ERR("Failed to set %s, got %u channels instead\n", DevFmtChannelsString(device->FmtChans), outParams.channelCount);
        device->Flags &= ~DEVICE_CHANNELS_REQUEST;
        device->FmtChans = ((outParams.channelCount==1) ? DevFmtMono : DevFmtStereo);
    }

    return ALC_NO_ERROR;
}