static snd_pcm_sframes_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas, snd_pcm_uframes_t offset, snd_pcm_uframes_t size) { snd_pcm_uframes_t xfer = 0; if (snd_pcm_mmap_capture_avail(pcm) < size) { SNDMSG("too short avail %ld to size %ld", snd_pcm_mmap_capture_avail(pcm), size); return -EPIPE; } while (size > 0) { const snd_pcm_channel_area_t *pcm_areas; snd_pcm_uframes_t pcm_offset; snd_pcm_uframes_t frames = size; snd_pcm_sframes_t result; snd_pcm_mmap_begin(pcm, &pcm_areas, &pcm_offset, &frames); snd_pcm_areas_copy(areas, offset, pcm_areas, pcm_offset, pcm->channels, frames, pcm->format); result = snd_pcm_mmap_commit(pcm, pcm_offset, frames); if (result < 0) return xfer > 0 ? (snd_pcm_sframes_t)xfer : result; offset += result; xfer += result; size -= result; } return (snd_pcm_sframes_t)xfer; }
static snd_pcm_uframes_t snd_pcm_mmap_avail(snd_pcm_t *pcm) { if (pcm->stream == SND_PCM_STREAM_PLAYBACK) return snd_pcm_mmap_playback_avail(pcm); else return snd_pcm_mmap_capture_avail(pcm); }
static int snd_pcm_dsnoop_status(snd_pcm_t *pcm, snd_pcm_status_t * status) { snd_pcm_direct_t *dsnoop = pcm->private_data; snd_pcm_state_t state; switch(dsnoop->state) { case SNDRV_PCM_STATE_DRAINING: case SNDRV_PCM_STATE_RUNNING: snd_pcm_dsnoop_sync_ptr(pcm); break; default: break; } memset(status, 0, sizeof(*status)); state = snd_pcm_state(dsnoop->spcm); status->state = state == SND_PCM_STATE_RUNNING ? dsnoop->state : state; status->trigger_tstamp = dsnoop->trigger_tstamp; status->tstamp = dsnoop->update_tstamp; status->avail = snd_pcm_mmap_capture_avail(pcm); status->avail_max = status->avail > dsnoop->avail_max ? status->avail : dsnoop->avail_max; dsnoop->avail_max = 0; return 0; }