2015-05-16 4 views
2

В настоящее время я использую snd_pcm_writei для воспроизведения звукового файла, который ранее был загружен в массив коротких (16-битный формат PCM). Чтобы воспроизвести этот звук, я создаю буфер (короткий *), содержащий период (или фрагмент). Затем я использую время цикла для вызова snd_pcm_writei, который дает мне эту строку:Alsa api: как использовать mmap в c?

int err = snd_pcm_writei(handle, buffer, frames); 

Это довольно просто, чтобы понять, как это работает, и все работает отлично, я могу услышать звук. Тем не менее, я хотел бы попытаться использовать mmap вместо writei, но я действительно не понимаю. Я столкнулся с отсутствием документации и ясных примеров. Может ли кто-нибудь объяснить, как mmap работает с alsa, и как преобразовать мой код в то, что использует mmap? В принципе, я все равно хотел бы воспроизвести то, что находится в моем массиве, используя буфер (так что массив короткий, размер которого равен одному периоду). Благодарю.

+0

Что вы ожидаете получить от использования mmap? –

+0

Первая причина в том, что мне любопытно, и я хотел бы понять разницу и уметь заставить ее работать. Я также надеюсь, что это может уменьшить задержку (наглядный более короткий буфер), но я не уверен, что это будет так ...? – Spin

ответ

1

Сначала вам необходимо установить тип доступа одного из типов MMAP (обычно SND_PCM_ACCESS_MMAP_INTERLEAVED вместо SND_PCM_ACCESS_RW_INTERLEAVED).

Если вы хотите записать в буфер, позвоните по номеру snd_pcm_mmap_begin() с количеством кадров, которое вы хотите записать. Если эта функция завершается успешно, она возвращает указатель на буфер (areas[0].addr или несколько указателей на неперемещенные или сложные типы доступа), смещение в буфер (offset) и количество кадров, которые вы действительно можете записать.

После написания образцов позвоните по номеру snd_pcm_mmap_commit() с фактическим количеством кадров, которые вы написали.


Пожалуйста, обратите внимание, что использование ММАПА не имеет смысла, когда вы копируете образец из своего собственного буфера в буфер устройства (это точно то же самое, что snd_pcm_writei() уже делает). Вы можете уменьшить задержку только в том случае, если вы создаете образцы «на лету» и можете записывать их непосредственно в буфер устройства.

+0

Хорошо, что мне очень помогло, спасибо. Было бы неплохо добавить несколько вещей к вашему объяснению. Быстрая строка, которая объясняет, как заполнять буфер, так же: short * data = (short *) (области [0] .addr + (области [0] .first + offset * areas [0] .step)/8). На самом деле, я думаю, что короткий код, который показывает, как использовать mmap с alsa, будет большим. Что-то вроде этого: http://freewebmaster.fr/up/cpp/alsaTest.c. – Spin

Смежные вопросы