Example #1
0
static ALuint ALSANoMMapProc(ALvoid *ptr)
{
    ALCdevice *pDevice = (ALCdevice*)ptr;
    alsa_data *data = (alsa_data*)pDevice->ExtraData;
    snd_pcm_sframes_t avail;
    char *WritePtr;

    SetRTPriority();

    while(!data->killNow)
    {
        int state = verify_state(data->pcmHandle);
        if(state < 0)
        {
            AL_PRINT("Invalid state detected: %s\n", psnd_strerror(state));
            aluHandleDisconnect(pDevice);
            break;
        }

        WritePtr = data->buffer;
        avail = data->size / psnd_pcm_frames_to_bytes(data->pcmHandle, 1);
        aluMixData(pDevice, WritePtr, avail);

        while(avail > 0)
        {
            int ret = psnd_pcm_writei(data->pcmHandle, WritePtr, avail);
            switch (ret)
            {
            case -EAGAIN:
                continue;
            case -ESTRPIPE:
            case -EPIPE:
            case -EINTR:
                ret = psnd_pcm_recover(data->pcmHandle, ret, 1);
                if(ret >= 0)
                    psnd_pcm_prepare(data->pcmHandle);
                break;
            default:
                if (ret >= 0)
                {
                    WritePtr += psnd_pcm_frames_to_bytes(data->pcmHandle, ret);
                    avail -= ret;
                }
                break;
            }
            if (ret < 0)
            {
                ret = psnd_pcm_prepare(data->pcmHandle);
                if(ret < 0)
                    break;
            }
        }
    }

    return 0;
}
Example #2
0
static int xrun_recovery(snd_pcm_t *handle, int err)
{
    if(err == -EINTR || err == -EPIPE || err == -ESTRPIPE)
    {
        err = psnd_pcm_recover(handle, err, 1);
        if(err >= 0)
            err = psnd_pcm_prepare(handle);
        if(err < 0)
            AL_PRINT("recover failed: %s\n", psnd_strerror(err));
    }
    return err;
}
Example #3
0
static unsigned int ALSA_RW_GetDMAPos (soundcardinfo_t *sc)
{
	int frames;
	frames = psnd_pcm_avail_update(sc->handle);
	if (frames < 0)
	{
		psnd_pcm_start (sc->handle);
		psnd_pcm_recover(sc->handle, frames, true);
		frames = psnd_pcm_avail_update(sc->handle);
	}
	if (frames >= 0)
	{
		sc->sn.samplepos = (sc->snd_sent + frames) * sc->sn.numchannels;
	}
	return sc->sn.samplepos;
}
Example #4
0
static ALCuint alsa_available_samples(ALCdevice *Device)
{
    alsa_data *data = (alsa_data*)Device->ExtraData;
    snd_pcm_sframes_t avail;

    avail = (Device->Connected ? psnd_pcm_avail_update(data->pcmHandle) : 0);
    if(avail < 0)
    {
        AL_PRINT("avail update failed: %s\n", psnd_strerror(avail));

        if((avail=psnd_pcm_recover(data->pcmHandle, avail, 1)) >= 0 &&
           (avail=psnd_pcm_prepare(data->pcmHandle)) >= 0)
        {
            if(data->doCapture)
                avail = psnd_pcm_start(data->pcmHandle);
            if(avail >= 0)
                avail = psnd_pcm_avail_update(data->pcmHandle);
        }
        if(avail < 0)
        {
            AL_PRINT("restore error: %s\n", psnd_strerror(avail));
            aluHandleDisconnect(Device);
        }
    }
    while(avail > 0)
    {
        snd_pcm_sframes_t amt;

        amt = psnd_pcm_bytes_to_frames(data->pcmHandle, data->size);
        if(avail < amt) amt = avail;

        amt = psnd_pcm_readi(data->pcmHandle, data->buffer, amt);
        if(amt < 0)
        {
            AL_PRINT("read error: %s\n", psnd_strerror(amt));

            if(amt == -EAGAIN)
                continue;
            if((amt=psnd_pcm_recover(data->pcmHandle, amt, 1)) >= 0 &&
               (amt=psnd_pcm_prepare(data->pcmHandle)) >= 0)
            {
                if(data->doCapture)
                    amt = psnd_pcm_start(data->pcmHandle);
                if(amt >= 0)
                    amt = psnd_pcm_avail_update(data->pcmHandle);
            }
            if(amt < 0)
            {
                AL_PRINT("restore error: %s\n", psnd_strerror(amt));
                aluHandleDisconnect(Device);
                break;
            }
            avail = amt;
            continue;
        }

        WriteRingBuffer(data->ring, data->buffer, amt);
        avail -= amt;
    }

    return RingBufferSize(data->ring);
}