static void convert(struct snd_pcm_plugin *plugin, const struct snd_pcm_plugin_channel *src_channels, struct snd_pcm_plugin_channel *dst_channels, snd_pcm_uframes_t frames) { struct linear_priv *data = (struct linear_priv *)plugin->extra_data; int channel; int nchannels = plugin->src_format.channels; for (channel = 0; channel < nchannels; ++channel) { char *src; char *dst; int src_step, dst_step; snd_pcm_uframes_t frames1; if (!src_channels[channel].enabled) { if (dst_channels[channel].wanted) snd_pcm_area_silence(&dst_channels[channel].area, 0, frames, plugin->dst_format.format); dst_channels[channel].enabled = 0; continue; } dst_channels[channel].enabled = 1; src = src_channels[channel].area.addr + src_channels[channel].area.first / 8; dst = dst_channels[channel].area.addr + dst_channels[channel].area.first / 8; src_step = src_channels[channel].area.step / 8; dst_step = dst_channels[channel].area.step / 8; frames1 = frames; while (frames1-- > 0) { do_convert(data, dst, src); src += src_step; dst += dst_step; } } }
static snd_pcm_sframes_t copy_transfer(struct snd_pcm_plugin *plugin, const struct snd_pcm_plugin_channel *src_channels, struct snd_pcm_plugin_channel *dst_channels, snd_pcm_uframes_t frames) { unsigned int channel; unsigned int nchannels; snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO); if (frames == 0) return 0; nchannels = plugin->src_format.channels; for (channel = 0; channel < nchannels; channel++) { snd_assert(src_channels->area.first % 8 == 0 && src_channels->area.step % 8 == 0, return -ENXIO); snd_assert(dst_channels->area.first % 8 == 0 && dst_channels->area.step % 8 == 0, return -ENXIO); if (!src_channels->enabled) { if (dst_channels->wanted) snd_pcm_area_silence(&dst_channels->area, 0, frames, plugin->dst_format.format); dst_channels->enabled = 0; continue; } dst_channels->enabled = 1; snd_pcm_area_copy(&src_channels->area, 0, &dst_channels->area, 0, frames, plugin->src_format.format); src_channels++; dst_channels++; } return frames; }
static snd_pcm_sframes_t copy_transfer(struct snd_pcm_plugin *plugin, const struct snd_pcm_plugin_channel *src_channels, struct snd_pcm_plugin_channel *dst_channels, snd_pcm_uframes_t frames) { unsigned int channel; unsigned int nchannels; if (snd_BUG_ON(!plugin || !src_channels || !dst_channels)) return -ENXIO; if (frames == 0) return 0; nchannels = plugin->src_format.channels; for (channel = 0; channel < nchannels; channel++) { if (snd_BUG_ON(src_channels->area.first % 8 || src_channels->area.step % 8)) return -ENXIO; if (snd_BUG_ON(dst_channels->area.first % 8 || dst_channels->area.step % 8)) return -ENXIO; if (!src_channels->enabled) { if (dst_channels->wanted) snd_pcm_area_silence(&dst_channels->area, 0, frames, plugin->dst_format.format); dst_channels->enabled = 0; continue; } dst_channels->enabled = 1; snd_pcm_area_copy(&src_channels->area, 0, &dst_channels->area, 0, frames, plugin->src_format.format); src_channels++; dst_channels++; } return frames; }
static void resample_shrink(struct snd_pcm_plugin *plugin, const struct snd_pcm_plugin_channel *src_channels, struct snd_pcm_plugin_channel *dst_channels, int src_frames, int dst_frames) { unsigned int pos = 0; signed int val; signed short S1, S2; signed short *src, *dst; unsigned int channel; int src_step, dst_step; int src_frames1, dst_frames1; struct rate_priv *data = (struct rate_priv *)plugin->extra_data; struct rate_channel *rchannels = data->channels; for (channel = 0; channel < plugin->src_format.channels; ++channel) { pos = data->pos; S1 = rchannels->last_S1; S2 = rchannels->last_S2; if (!src_channels[channel].enabled) { if (dst_channels[channel].wanted) snd_pcm_area_silence(&dst_channels[channel].area, 0, dst_frames, plugin->dst_format.format); dst_channels[channel].enabled = 0; continue; } dst_channels[channel].enabled = 1; src = (signed short *)src_channels[channel].area.addr + src_channels[channel].area.first / 8 / 2; dst = (signed short *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8 / 2; src_step = src_channels[channel].area.step / 8 / 2; dst_step = dst_channels[channel].area.step / 8 / 2; src_frames1 = src_frames; dst_frames1 = dst_frames; while (dst_frames1 > 0) { S1 = S2; if (src_frames1-- > 0) { S2 = *src; src += src_step; } if (pos & ~R_MASK) { pos &= R_MASK; val = S1 + ((S2 - S1) * (signed int)pos) / BITS; if (val < -32768) val = -32768; else if (val > 32767) val = 32767; *dst = val; dst += dst_step; dst_frames1--; } pos += data->pitch; } rchannels->last_S1 = S1; rchannels->last_S2 = S2; rchannels++; } data->pos = pos; }
static void zero_areas(struct snd_pcm_plugin_channel *dvp, int ndsts, snd_pcm_uframes_t frames, int format) { int dst = 0; for (; dst < ndsts; ++dst) { if (dvp->wanted) snd_pcm_area_silence(&dvp->area, 0, frames, format); dvp->enabled = 0; dvp++; } }
int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset, unsigned int channels, snd_pcm_uframes_t frames, snd_pcm_format_t format) { while (channels > 0) { snd_pcm_area_silence(dst_areas, dst_offset, frames, format); dst_areas++; channels--; } return 0; }
static void do_silence(snd_pcm_t *pcm) { snd_pcm_direct_t *dshare = pcm->private_data; const snd_pcm_channel_area_t *dst_areas; unsigned int chn, dchn, channels; snd_pcm_format_t format; dst_areas = snd_pcm_mmap_areas(dshare->spcm); channels = dshare->channels; format = dshare->shmptr->s.format; for (chn = 0; chn < channels; chn++) { dchn = dshare->bindings ? dshare->bindings[chn] : chn; snd_pcm_area_silence(&dst_areas[dchn], 0, dshare->shmptr->s.buffer_size, format); } }
int snd_pcm_area_copy(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t dst_offset, const snd_pcm_channel_area_t *src_area, snd_pcm_uframes_t src_offset, unsigned int samples, snd_pcm_format_t format) { const char *src; char *dst; int width; int src_step, dst_step; if (!dst_area->addr) return 0; if (dst_area == src_area && dst_offset == src_offset) return 0; if (!src_area->addr) return snd_pcm_area_silence(dst_area, dst_offset, samples, format); width = snd_pcm_format_physical_width(format); if (width < 8) return area_copy_4bit(dst_area, dst_offset, src_area, src_offset, samples, format); src = snd_pcm_channel_area_addr(src_area, src_offset); dst = snd_pcm_channel_area_addr(dst_area, dst_offset); if (src_area->step == (unsigned int) width && dst_area->step == (unsigned int) width) { memcpy(dst, src, samples * width / 8); return 0; } src_step = src_area->step / 8; dst_step = dst_area->step / 8; width /= 8; while (samples-- > 0) { memcpy(dst, src, width); src += src_step; dst += dst_step; } return 0; }