alsa: use audio_pcm_hw_clip_out

Signed-off-by: malc <av1474@comtv.ru>
This commit is contained in:
malc 2009-09-18 10:59:50 +04:00
parent ddabec73e6
commit 541ba4e709

View File

@ -42,6 +42,8 @@ struct pollhlp {
typedef struct ALSAVoiceOut { typedef struct ALSAVoiceOut {
HWVoiceOut hw; HWVoiceOut hw;
int wpos;
int pending;
void *pcm_buf; void *pcm_buf;
snd_pcm_t *handle; snd_pcm_t *handle;
struct pollhlp pollhlp; struct pollhlp pollhlp;
@ -592,7 +594,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
goto err; goto err;
} }
if ((req->override_mask & 1) && (obt - req->period_size)) if (((req->override_mask & 1) && (obt - req->period_size)))
dolog ("Requested period %s %u was rejected, using %lu\n", dolog ("Requested period %s %u was rejected, using %lu\n",
size_in_usec ? "time" : "size", req->period_size, obt); size_in_usec ? "time" : "size", req->period_size, obt);
} }
@ -698,13 +700,73 @@ static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle)
return avail; return avail;
} }
static void alsa_write_pending (ALSAVoiceOut *alsa)
{
HWVoiceOut *hw = &alsa->hw;
while (alsa->pending) {
int left_till_end_samples = hw->samples - alsa->wpos;
int len = audio_MIN (alsa->pending, left_till_end_samples);
char *src = advance (alsa->pcm_buf, alsa->wpos << hw->info.shift);
while (len) {
snd_pcm_sframes_t written;
written = snd_pcm_writei (alsa->handle, src, len);
if (written <= 0) {
switch (written) {
case 0:
if (conf.verbose) {
dolog ("Failed to write %d frames (wrote zero)\n", len);
}
return;
case -EPIPE:
if (alsa_recover (alsa->handle)) {
alsa_logerr (written, "Failed to write %d frames\n",
len);
return;
}
if (conf.verbose) {
dolog ("Recovering from playback xrun\n");
}
continue;
case -ESTRPIPE:
/* stream is suspended and waiting for an
application recovery */
if (alsa_resume (alsa->handle)) {
alsa_logerr (written, "Failed to write %d frames\n",
len);
return;
}
if (conf.verbose) {
dolog ("Resuming suspended output stream\n");
}
continue;
case -EAGAIN:
return;
default:
alsa_logerr (written, "Failed to write %d frames from %p\n",
len, src);
return;
}
}
alsa->wpos = (alsa->wpos + written) % hw->samples;
alsa->pending -= written;
len -= written;
}
}
}
static int alsa_run_out (HWVoiceOut *hw) static int alsa_run_out (HWVoiceOut *hw)
{ {
ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
int rpos, live, decr; int live, decr;
int samples;
uint8_t *dst;
struct st_sample *src;
snd_pcm_sframes_t avail; snd_pcm_sframes_t avail;
live = audio_pcm_hw_get_live_out (hw); live = audio_pcm_hw_get_live_out (hw);
@ -719,73 +781,9 @@ static int alsa_run_out (HWVoiceOut *hw)
} }
decr = audio_MIN (live, avail); decr = audio_MIN (live, avail);
samples = decr; decr = audio_pcm_hw_clip_out (hw, alsa->pcm_buf, decr, alsa->pending);
rpos = hw->rpos; alsa->pending += decr;
while (samples) { alsa_write_pending (alsa);
int left_till_end_samples = hw->samples - rpos;
int len = audio_MIN (samples, left_till_end_samples);
snd_pcm_sframes_t written;
src = hw->mix_buf + rpos;
dst = advance (alsa->pcm_buf, rpos << hw->info.shift);
hw->clip (dst, src, len);
while (len) {
written = snd_pcm_writei (alsa->handle, dst, len);
if (written <= 0) {
switch (written) {
case 0:
if (conf.verbose) {
dolog ("Failed to write %d frames (wrote zero)\n", len);
}
goto exit;
case -EPIPE:
if (alsa_recover (alsa->handle)) {
alsa_logerr (written, "Failed to write %d frames\n",
len);
goto exit;
}
if (conf.verbose) {
dolog ("Recovering from playback xrun\n");
}
continue;
case -ESTRPIPE:
/* stream is suspended and waiting for an
application recovery */
if (alsa_resume (alsa->handle)) {
alsa_logerr (written, "Failed to write %d frames\n",
len);
goto exit;
}
if (conf.verbose) {
dolog ("Resuming suspended output stream\n");
}
continue;
case -EAGAIN:
goto exit;
default:
alsa_logerr (written, "Failed to write %d frames to %p\n",
len, dst);
goto exit;
}
}
rpos = (rpos + written) % hw->samples;
samples -= written;
len -= written;
dst = advance (dst, written << hw->info.shift);
src += written;
}
}
exit:
hw->rpos = rpos;
return decr; return decr;
} }