我只是搞乱了alsa库,并且无法真正弄清楚如何使用直接写入进行播放。我正在使用访问类型mmap interleave。 我正在尝试写一个方波。
我创建了一个短裤缓冲区来保持方波。我用snd_pcm_writei对它进行了测试,结果正常。
然后我调用snd_pcm_begin并使用区域给出的指针写入设备:
while(1){
int msg;
frames_available = snd_pcm_avail_update(handle);
snd_pcm_mmap_begin(handle,&areas,&offset,&limit_frames);
frames_to_write = frames;//frames is the size of the buffer in frames
if(frames_to_write > limit_frames)
frames_to_write = 0;
int offset_frames = (areas[0].first + offset*areas[0].step)/16;
short* write_ptr = (short*)areas[0].addr + offset_frames;
//fill the buffer with stuff
for(int i =0; i < frames_to_write;i++){
write_ptr[i] = buffer[i];
}
msg = snd_pcm_mmap_commit(handle,offset,frames_to_write);
}
产生的声音很不稳定,很快就会被切断。由于limit_frame达到0,它会被切断。我注意到即使有frames_available,limit_frames也会保持为0。编辑: 我使用memcpy()而不是for循环,这解决了紊乱。仍然被切断了。现在我很好奇为什么memcpy()解决了这些不稳定因素。不应该for循环和memcpy和for循环复制内存连续吗?
答案 0 :(得分:0)
如果您所做的只是从另一个缓冲区复制样本,那么使用mmap是没有意义的;这与snd_pcm_writei()
完全相同。
无论如何,在调用snd_pcm_mmap_begin()
之前,必须将其最后一个参数设置为您要写入的帧数,当它返回较小的数字时,您应该写出该数字,而不是0。
当您有多个频道时,一个帧大于一个样本。