2016-01-16 4 views
0

Я просто возился с библиотекой alsa и не могу понять, как делать воспроизведение с прямой записью. Я использую interleave mmap доступа. Я пытаюсь написать квадратную волну.Alsalib mmap direct write

Я создал буфер шорт, чтобы провести квадратную волну. Я тестировал его с помощью 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. Я замечаю, что limit_frames остается равным 0, даже если есть frames_available.

EDIT: Я использовал memcpy() вместо цикла for, и это решило шаткость. Тем не менее все же обрезается. Теперь мне любопытно, почему memcpy() решает неряшливость. Должен ли цикл for и memcpy и цикл циклически копировать по памяти?

ответ

0

Использование mmap не имеет смысла, если все, что вы делаете, копирует образцы из другого буфера; это точно то же самое, что и snd_pcm_writei().

Во всяком случае, перед вызовом snd_pcm_mmap_begin(), вы необходимо установить свой последний параметр на количество кадров вы собираетесь писать, и когда она возвращает меньшее число, вы должны написать это число, вместо 0.

Когда у вас более одного канала, кадр больше одного образца.