Exemplo n.º 1
0
static void ALSA_MMap_Submit (soundcardinfo_t *sc, int start, int end)
{
	int			state;
	int			count = end - start;
	const snd_pcm_channel_area_t *areas;
	snd_pcm_uframes_t nframes;
	snd_pcm_uframes_t offset;

	nframes = count / sc->sn.numchannels;

	psnd_pcm_avail_update (sc->handle);
	psnd_pcm_mmap_begin (sc->handle, &areas, &offset, &nframes);

	state = psnd_pcm_state (sc->handle);

	switch (state) {
		case SND_PCM_STATE_PREPARED:
			psnd_pcm_mmap_commit (sc->handle, offset, nframes);
			psnd_pcm_start (sc->handle);
			break;
		case SND_PCM_STATE_RUNNING:
			psnd_pcm_mmap_commit (sc->handle, offset, nframes);
			break;
		default:
			break;
	}
}
Exemplo n.º 2
0
static unsigned int ALSA_MMap_GetDMAPos (soundcardinfo_t *sc)
{
	const snd_pcm_channel_area_t *areas;
	snd_pcm_uframes_t offset;
	snd_pcm_uframes_t nframes = sc->sn.samples / sc->sn.numchannels;

	psnd_pcm_avail_update (sc->handle);
	psnd_pcm_mmap_begin (sc->handle, &areas, &offset, &nframes);
	offset *= sc->sn.numchannels;
	nframes *= sc->sn.numchannels;
	sc->sn.samplepos = offset;
	sc->sn.buffer = areas->addr;
	return sc->sn.samplepos;
}
Exemplo n.º 3
0
static ALuint ALSAProc(ALvoid *ptr)
{
    ALCdevice *pDevice = (ALCdevice*)ptr;
    alsa_data *data = (alsa_data*)pDevice->ExtraData;
    const snd_pcm_channel_area_t *areas = NULL;
    snd_pcm_sframes_t avail, commitres;
    snd_pcm_uframes_t offset, frames;
    char *WritePtr;
    int err;

    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;
        }

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

        // make sure there's frames to process
        if(avail >= 0 && avail < (snd_pcm_sframes_t)pDevice->UpdateSize)
        {
            if(state != SND_PCM_STATE_RUNNING)
            {
                err = psnd_pcm_start(data->pcmHandle);
                if(err < 0)
                {
                    AL_PRINT("start failed: %s\n", psnd_strerror(err));
                    continue;
                }
            }
            if(psnd_pcm_wait(data->pcmHandle, 1000) == 0)
                AL_PRINT("Wait timeout... buffer size too low?\n");
            continue;
        }
        avail -= avail%pDevice->UpdateSize;

        // it is possible that contiguous areas are smaller, thus we use a loop
        while(avail > 0)
        {
            frames = avail;

            err = psnd_pcm_mmap_begin(data->pcmHandle, &areas, &offset, &frames);
            if(err < 0)
            {
                AL_PRINT("mmap begin error: %s\n", psnd_strerror(err));
                break;
            }

            WritePtr = (char*)areas->addr + (offset * areas->step / 8);
            aluMixData(pDevice, WritePtr, frames);

            commitres = psnd_pcm_mmap_commit(data->pcmHandle, offset, frames);
            if(commitres < 0 || (commitres-frames) != 0)
            {
                AL_PRINT("mmap commit error: %s\n",
                         psnd_strerror(commitres >= 0 ? -EPIPE : commitres));
                break;
            }

            avail -= frames;
        }
    }

    return 0;
}