alsa: use audio_pcm_hw_clip_out
Signed-off-by: malc <av1474@comtv.ru>
This commit is contained in:
parent
ddabec73e6
commit
541ba4e709
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user