Alsalib mmap直接写

时间:2016-01-16 10:58:31

标签: linux audio mmap alsa

我只是搞乱了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循环复制内存连续吗?

1 个答案:

答案 0 :(得分:0)

如果您所做的只是从另一个缓冲区复制样本,那么使用mmap是没有意义的;这与snd_pcm_writei()完全相同。

无论如何,在调用snd_pcm_mmap_begin()之前,必须将其最后一个参数设置为您要写入的帧数,当它返回较小的数字时,您应该写出该数字,而不是0。

当您有多个频道时,一个帧大于一个样本。