mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-10 14:42:13 +00:00
------------------------------------------------------------------------
r4191 | acceptthis | 2013-02-10 17:19:47 +0000 (Sun, 10 Feb 2013) | 1 line Try to fix alsa latencies. Again. ------------------------------------------------------------------------ git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4189 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
c23206fefd
commit
051a32d742
1 changed files with 64 additions and 34 deletions
|
@ -53,9 +53,11 @@ int (*psnd_pcm_sw_params_set_stop_threshold) (snd_pcm_t *pcm, snd_pcm_sw_params_
|
||||||
int (*psnd_pcm_sw_params) (snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
|
int (*psnd_pcm_sw_params) (snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
|
||||||
int (*psnd_pcm_hw_params_get_buffer_size) (const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
|
int (*psnd_pcm_hw_params_get_buffer_size) (const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
|
||||||
int (*psnd_pcm_hw_params_set_buffer_size_near) (snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
|
int (*psnd_pcm_hw_params_set_buffer_size_near) (snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
|
||||||
|
int (*psnd_pcm_set_params) (snd_pcm_t *pcm, snd_pcm_format_t format, snd_pcm_access_t access, unsigned int channels, unsigned int rate, int soft_resample, unsigned int latency);
|
||||||
snd_pcm_sframes_t (*psnd_pcm_avail_update) (snd_pcm_t *pcm);
|
snd_pcm_sframes_t (*psnd_pcm_avail_update) (snd_pcm_t *pcm);
|
||||||
snd_pcm_state_t (*psnd_pcm_state) (snd_pcm_t *pcm);
|
snd_pcm_state_t (*psnd_pcm_state) (snd_pcm_t *pcm);
|
||||||
int (*psnd_pcm_start) (snd_pcm_t *pcm);
|
int (*psnd_pcm_start) (snd_pcm_t *pcm);
|
||||||
|
int (*psnd_pcm_recover) (snd_pcm_t *pcm, int err, int silent);
|
||||||
|
|
||||||
size_t (*psnd_pcm_hw_params_sizeof) (void);
|
size_t (*psnd_pcm_hw_params_sizeof) (void);
|
||||||
size_t (*psnd_pcm_sw_params_sizeof) (void);
|
size_t (*psnd_pcm_sw_params_sizeof) (void);
|
||||||
|
@ -113,6 +115,12 @@ static unsigned int ALSA_RW_GetDMAPos (soundcardinfo_t *sc)
|
||||||
{
|
{
|
||||||
int frames;
|
int frames;
|
||||||
frames = psnd_pcm_avail_update(sc->handle);
|
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)
|
if (frames >= 0)
|
||||||
{
|
{
|
||||||
sc->sn.samplepos = (sc->snd_sent + frames) * sc->sn.numchannels;
|
sc->sn.samplepos = (sc->snd_sent + frames) * sc->sn.numchannels;
|
||||||
|
@ -121,45 +129,47 @@ static unsigned int ALSA_RW_GetDMAPos (soundcardinfo_t *sc)
|
||||||
}
|
}
|
||||||
static void ALSA_RW_Submit (soundcardinfo_t *sc, int start, int end)
|
static void ALSA_RW_Submit (soundcardinfo_t *sc, int start, int end)
|
||||||
{
|
{
|
||||||
int state;
|
// int state;
|
||||||
unsigned int frames, offset, ringsize;
|
unsigned int frames, offset, ringsize;
|
||||||
unsigned chunk;
|
unsigned chunk;
|
||||||
int result;
|
int result;
|
||||||
int stride = sc->sn.numchannels * (sc->sn.samplebits/8);
|
int stride = sc->sn.numchannels * (sc->sn.samplebits/8);
|
||||||
|
|
||||||
/*we can't change the data that was already written*/
|
while(1)
|
||||||
frames = end - sc->snd_sent;
|
|
||||||
if (!frames)
|
|
||||||
return;
|
|
||||||
|
|
||||||
state = psnd_pcm_state (sc->handle);
|
|
||||||
|
|
||||||
ringsize = sc->sn.samples / sc->sn.numchannels;
|
|
||||||
|
|
||||||
chunk = frames;
|
|
||||||
offset = sc->snd_sent % ringsize;
|
|
||||||
|
|
||||||
if (offset + chunk >= ringsize)
|
|
||||||
chunk = ringsize - offset;
|
|
||||||
result = psnd_pcm_writei(sc->handle, sc->sn.buffer + offset*stride, chunk);
|
|
||||||
if (result < chunk)
|
|
||||||
{
|
{
|
||||||
if (result >= 0)
|
/*we can't change the data that was already written*/
|
||||||
sc->snd_sent += result;
|
frames = end - sc->snd_sent;
|
||||||
return;
|
if (frames <= 0)
|
||||||
}
|
return;
|
||||||
sc->snd_sent += chunk;
|
|
||||||
|
|
||||||
chunk = frames - chunk;
|
// state = psnd_pcm_state (sc->handle);
|
||||||
if (chunk)
|
|
||||||
{
|
|
||||||
result = psnd_pcm_writei(sc->handle, sc->sn.buffer, chunk);
|
|
||||||
if (result > 0)
|
|
||||||
sc->snd_sent += result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state == SND_PCM_STATE_PREPARED)
|
ringsize = sc->sn.samples / sc->sn.numchannels;
|
||||||
psnd_pcm_start (sc->handle);
|
|
||||||
|
chunk = frames;
|
||||||
|
offset = sc->snd_sent % ringsize;
|
||||||
|
|
||||||
|
if (offset + chunk >= ringsize)
|
||||||
|
chunk = ringsize - offset;
|
||||||
|
result = psnd_pcm_writei(sc->handle, sc->sn.buffer + offset*stride, chunk);
|
||||||
|
if (result < chunk)
|
||||||
|
{
|
||||||
|
if (result < 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sc->snd_sent += chunk;
|
||||||
|
|
||||||
|
chunk = frames - chunk;
|
||||||
|
if (chunk)
|
||||||
|
{
|
||||||
|
result = psnd_pcm_writei(sc->handle, sc->sn.buffer, chunk);
|
||||||
|
if (result > 0)
|
||||||
|
sc->snd_sent += result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (state == SND_PCM_STATE_PREPARED)
|
||||||
|
// psnd_pcm_start (sc->handle);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ALSA_Shutdown (soundcardinfo_t *sc)
|
static void ALSA_Shutdown (soundcardinfo_t *sc)
|
||||||
|
@ -221,6 +231,8 @@ static qboolean Alsa_InitAlsa(void)
|
||||||
psnd_pcm_avail_update = dlsym(alsasharedobject, "snd_pcm_avail_update");
|
psnd_pcm_avail_update = dlsym(alsasharedobject, "snd_pcm_avail_update");
|
||||||
psnd_pcm_state = dlsym(alsasharedobject, "snd_pcm_state");
|
psnd_pcm_state = dlsym(alsasharedobject, "snd_pcm_state");
|
||||||
psnd_pcm_start = dlsym(alsasharedobject, "snd_pcm_start");
|
psnd_pcm_start = dlsym(alsasharedobject, "snd_pcm_start");
|
||||||
|
psnd_pcm_recover = dlsym(alsasharedobject, "snd_pcm_recover");
|
||||||
|
psnd_pcm_set_params = dlsym(alsasharedobject, "snd_pcm_set_params");
|
||||||
psnd_pcm_hw_params_sizeof = dlsym(alsasharedobject, "snd_pcm_hw_params_sizeof");
|
psnd_pcm_hw_params_sizeof = dlsym(alsasharedobject, "snd_pcm_hw_params_sizeof");
|
||||||
psnd_pcm_sw_params_sizeof = dlsym(alsasharedobject, "snd_pcm_sw_params_sizeof");
|
psnd_pcm_sw_params_sizeof = dlsym(alsasharedobject, "snd_pcm_sw_params_sizeof");
|
||||||
psnd_pcm_hw_params_set_buffer_size_near = dlsym(alsasharedobject, "snd_pcm_hw_params_set_buffer_size_near");
|
psnd_pcm_hw_params_set_buffer_size_near = dlsym(alsasharedobject, "snd_pcm_hw_params_set_buffer_size_near");
|
||||||
|
@ -314,8 +326,24 @@ static int ALSA_InitCard (soundcardinfo_t *sc, int cardnum)
|
||||||
}
|
}
|
||||||
Con_Printf ("ALSA: Using PCM %s.\n", pcmname);
|
Con_Printf ("ALSA: Using PCM %s.\n", pcmname);
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
err = psnd_pcm_set_params(pcm, ((sc->sn.samplebits==8)?SND_PCM_FORMAT_U8:SND_PCM_FORMAT_S16), (mmap?SND_PCM_ACCESS_MMAP_INTERLEAVED:SND_PCM_ACCESS_RW_INTERLEAVED), sc->sn.numchannels, sc->sn.speed, true, 0.04*1000000);
|
||||||
|
if (0 > err)
|
||||||
|
{
|
||||||
|
Con_Printf (CON_ERROR "ALSA: error setting params. %s\n",
|
||||||
|
psnd_strerror (err));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sc->sn.numchannels = stereo;
|
||||||
|
// sc->sn.samplepos = 0;
|
||||||
|
// sc->sn.samplebits = bps;
|
||||||
|
|
||||||
|
sc->samplequeue = buffer_size = 2048;
|
||||||
|
#else
|
||||||
err = psnd_pcm_hw_params_any (pcm, hw);
|
err = psnd_pcm_hw_params_any (pcm, hw);
|
||||||
if (0 > err) {
|
if (0 > err)
|
||||||
|
{
|
||||||
Con_Printf (CON_ERROR "ALSA: error setting hw_params_any. %s\n",
|
Con_Printf (CON_ERROR "ALSA: error setting hw_params_any. %s\n",
|
||||||
psnd_strerror (err));
|
psnd_strerror (err));
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -401,7 +429,8 @@ static int ALSA_InitCard (soundcardinfo_t *sc, int cardnum)
|
||||||
frag_size = 8 * bps;
|
frag_size = 8 * bps;
|
||||||
|
|
||||||
err = psnd_pcm_hw_params_set_period_size_near (pcm, hw, &frag_size, 0);
|
err = psnd_pcm_hw_params_set_period_size_near (pcm, hw, &frag_size, 0);
|
||||||
if (0 > err) {
|
if (0 > err)
|
||||||
|
{
|
||||||
Con_Printf (CON_ERROR "ALSA: unable to set period size near %i. %s\n",
|
Con_Printf (CON_ERROR "ALSA: unable to set period size near %i. %s\n",
|
||||||
(int) frag_size, psnd_strerror (err));
|
(int) frag_size, psnd_strerror (err));
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -458,9 +487,10 @@ static int ALSA_InitCard (soundcardinfo_t *sc, int cardnum)
|
||||||
psnd_strerror (err));
|
psnd_strerror (err));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
sc->sn.speed = rate;
|
||||||
|
#endif
|
||||||
|
|
||||||
sc->sn.samples = buffer_size * sc->sn.numchannels; // mono samples in buffer
|
sc->sn.samples = buffer_size * sc->sn.numchannels; // mono samples in buffer
|
||||||
sc->sn.speed = rate;
|
|
||||||
sc->handle = pcm;
|
sc->handle = pcm;
|
||||||
|
|
||||||
sc->Lock = ALSA_LockBuffer;
|
sc->Lock = ALSA_LockBuffer;
|
||||||
|
|
Loading…
Reference in a new issue