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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user