int snd_pcm_area_silence(const struct snd_pcm_channel_area *dst_area, size_t dst_offset,
size_t samples, int format)
{
/* FIXME: sub byte resolution and odd dst_offset */
unsigned char *dst;
unsigned int dst_step;
int width;
const unsigned char *silence;
if (!dst_area->addr)
return 0;
dst = dst_area->addr + (dst_area->first + dst_area->step * dst_offset) / 8;
width = snd_pcm_format_physical_width(format);
if (width <= 0)
return -EINVAL;
if (dst_area->step == (unsigned int) width && width >= 8)
return snd_pcm_format_set_silence(format, dst, samples);
《浅析alsa声卡驱动snd_pcm_format_set_silence函数》
silence = snd_pcm_format_silence_64(format); // silence固定占用8字节空间
if (! silence)
return -EINVAL;
dst_step = dst_area->step / 8;
if (width == 4) {
/* Ima ADPCM */
int dstbit = dst_area->first % 8; // dst_area->first等于0或者4,这里假设等于0
int dstbit_step = dst_area->step % 8; // dst_area->step等于4
while (samples-- > 0) {
if (dstbit)
*dst &= 0xf0; // dstbit等于4,那么清低4bits有效位[luther.gliethttp]
else
*dst &= 0x0f; // dstbit等于0,那么清高4bits有效位[luther.gliethttp]
dst += dst_step; // dst_step应该等于0.
dstbit += dstbit_step; // 0+4=4或者4+4=8
if (dstbit == 8) {
dst++; // 指向下一个字节
dstbit = 0; // 重新从0bit开始[luther.gliethttp]
}
}
} else {
width /= 8; // width等于32, 而dst_area->step等于24的情况[luther.gliethttp]
while (samples-- > 0) { // 所以width = 32/8 = 4, dst_step = 24/8 = 3;
memcpy(dst, silence, width);// 拷贝4个字节[这里多拷贝的1个字节,应该不会出现最后1次拷贝内存越界问题,因为这是alsa]
dst += dst_step; // 步进3个字节
}
}
return 0;
}
阅读(1400) | 评论(0) | 转发(3) |