LINUX.ORG.RU

Надо одновременно играть и записывать.


0

0

Требуется примерно следующее. Есть два массива для РСМ звука. Надо звуковухе передать указатели на них, чтоб один проигрывать, а другой синхронно записывать c линейного входа, возможно с микшированием. При этом (optional) чтобы программа не тормозилась, а ловила сигнал по окончании иоперации.

В доке по Open Sound System что-то туманное на сей счёт написано. Кинте скелет кода, если не лень, pls.

Заранее спасибо,

Ростислав

anonymous

Требуется писать что-то в /dev/dsp, и все то время, пока идет запись, нужно его же читать? Если требуется именно это, то ниже некоторые рекомендации. Если будет непонятно, оформлю их в код (долго это, поэтому пока только словеса).


Файл устройства открываешь как обычно:
fd = open("/dev/dsp", O_RDWR);

Создаешь 2 треда: читателя из и писателя в этот файл.

В читающем треде используешь примерно такой код:
for (i = 0; i < SIZE; i += r) {
r = read(fd, buf + i, SIZE - i);
//error checking here
if (установлен_флаг_завершения_записи) break;
}

В пишущем треде можно использовать аналогичный код, но вместо чтения -- запись. По окончании записи тред-писатель изменяет глобальную переменную, указывающую на конец записи.

В main дожидаешься завершения обоих тредов. Потом имеешь считанные данные и делаешь с ними что хочешь.

Если объем читаемых/записываемых данных велик, значит нужно еще 2 треда: для чтения/записи данных с/на диск. Ну и плюс синхра "дисковых" тредов со "звуковыми". И буферов должно быть несколько: пока часть используется для общения с диском, другая их часть используется для звуковой карты. Из личного опыта: 4 буфера на одну операцию достаточно. Под "одной операцией" понимается либо чтение /dev/dsp, либо запись в него. То есть, в твоем случае, всего 8 буферов. Для каждого свой флаг "пуст/полон".


ЗЫ: именно твою задачу я лично не пробовал решать, но, судя по доке на OSS, должно работать.

nobody ★★
()

В идеале хотелось бы, чтоб на выходе получился массив, синхронизированный с исходным с точностью порядка периода дискретизации. В описанном подходе задержки каждого треда непредсказуемы. Кроме того, в доке по OSS предостерегают от такого подхода, поскольку, он, по их словам, не всегда работает.

Видимо надо делать mmap поотдельности для буферов чтения и записи, давать карте (драйверу?) зелёный свисток начать, а дальше дрюкаться с указателями и успевать выдёргивать данные из DMA буферов. Как я понял из доки, размер буфера ограничен 8k. Что это за ограничение мне не ясно. Это ограничение звуковухи, либо драйвера, либо архитектуры. Можно ли его обойти как-то проще?

Ростислав

anonymous
()

Синхронизация с точностью порядка периода дискретизации... И ты хочешь сделать это на персоналке? Подумай: частота 1 кГц -- это период 1 мс. Даже если у тебя верхняя регистрируемая частота = всего 4 кГц, то частота дискретизации должна быть минимум 8 кГц. А это = периоду 125 мкс. Я вижу здесь 2 варианта. Первый: плата с каким-нибудь контроллером попроще, на ноги ему ЦАП, АЦП (из тех что подешевле) и CompactFlash. Минус этого: трах с аналоговой частью. Другой вариант: работа с регистрами звуковой карты напрямую из-под DOS (или вообще без OS) при запрещенных прерываниях. Но для этого нужна очень древняя карта, чьи регистры ты знаешь. Возможно, это как-то реализуемо с уровня ядра linux (но вряд ли из user-space). Может быть, тебе стоит связаться с разработчиками alsы и их поспрошать? А вообще интересно, для чего тебе такая точность? Хочешь сделать измерительную систему на персоналке?:)

nobody ★★
()

Вдогонку: Ростислав, если ты хочешь измерить скорость распространения сигнала в какой-то среде, то это не такая тривиальная задача, как кажется на первый взгляд. Разработкой таких приборов занимаются целые фирмы (наша например), и стоят такие вещи весьма недешево. Обычная звуковуха за $30 здесь не катит -- главным образом, из-за отстойной реализации аналоговой части.

nobody ★★
()

Гы! До 10мс догнал. И без всяких ассемблеров и кернел-спейсов. На карточке за 7 баксов плохо работает, а на двадцатибаксовой -- супер. Ещё бы с шумами потом разобраться, но это, думаю, получится.

Дока, блин, по OSS отстойная. Всё методом тыка делать приходится.

А про скорость распространения -- не совсем так. Это попытка соорудить акустический локатор. Про распространение в среде я не уловил. Насколько я понял, надо просто цифровать принимаемый сигнал вместе с зондирующим.

Если интересно узнать подробнее или есть что предложить велкам вмыло.

roux СобакА ifaran ТочкА ru

Ростислав

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.