Дело в том что вызов write(audio_dev,...) является блокирующим, нужно чтобы он был асинхронным, то есть ждать события, или мютекса после того как все тыграется. Как это сделать собстенно , если вообще OSS и RH 9.1 это позволяют?
Вы писали 27 апреля 2004 г., 10:14:51:
O> Дело в том что вызов write(audio_dev,...) является O> блокирующим, нужно чтобы он был асинхронным, то есть ждать события, O> или мютекса после того как все тыграется. Как это сделать собстенно O> , если вообще OSS и RH 9.1 это позволяют?
а в чём собственно разница — ждать готовности или быть в блокировке?
наверно стоит посмотреть в сторону select(2)..
Вы писали 27 апреля 2004 г., 10:14:51:
O> Дело в том что вызов write(audio_dev,...) является O> блокирующим, нужно чтобы он был асинхронным, то есть ждать события, O> или мютекса после того как все тыграется. Как это сделать собстенно O> , если вообще OSS и RH 9.1 это позволяют?
# man 2 write
...
When using non-blocking I/O on objects such as sockets that are subject
to flow control, write() and writev() may write fewer bytes than
requested; the return value must be noted, and the remainder of the oper-
ation should be retried when possible.
...
Я так понимаю audio_dev это "файл"?
# man 2 fcntl
..
O_NONBLOCK Non-blocking I/O; if no data is available to a read(2) call,
or if a write(2) operation would block, the read or write
call returns -1 with the error EAGAIN.
...
Здравствуйте, butcher, Вы писали:
B>Здравствуйте, OpenGL.
B>Вы писали 27 апреля 2004 г., 10:14:51:
O>> Дело в том что вызов write(audio_dev,...) является O>> блокирующим, нужно чтобы он был асинхронным, то есть ждать события, O>> или мютекса после того как все тыграется. Как это сделать собстенно O>> , если вообще OSS и RH 9.1 это позволяют?
B>а в чём собственно разница — ждать готовности или быть в блокировке?
В том что второй подход гораздо более правильный (если не сказать единственно верный ) для все клонов unix .
Да и код проще . B>наверно стоит посмотреть в сторону select(2)..
Здравствуйте, butcher, Вы писали:
B>Здравствуйте, OpenGL.
B>Вы писали 27 апреля 2004 г., 10:14:51:
O>> Дело в том что вызов write(audio_dev,...) является O>> блокирующим, нужно чтобы он был асинхронным, то есть ждать события, O>> или мютекса после того как все тыграется. Как это сделать собстенно O>> , если вообще OSS и RH 9.1 это позволяют?
B>
B># man 2 write
B>...
B>When using non-blocking I/O on objects such as sockets that are subject
B>to flow control, write() and writev() may write fewer bytes than
B>requested; the return value must be noted, and the remainder of the oper-
B>ation should be retried when possible.
B>...
B>
B>Я так понимаю audio_dev это "файл"? B>
B># man 2 fcntl
B>..
B>O_NONBLOCK Non-blocking I/O; if no data is available to a read(2) call,
B> or if a write(2) operation would block, the read or write
B> call returns -1 with the error EAGAIN.
B>...
B>
Нужно для того чтобы ни один кусок звука не пропал и не было шелчков.
Получактся что fctrl есть мое решение?
Тогда как синхронизоваться, после того как блок отыграет? B>-- B>С уважением, butcher
Вы писали 27 апреля 2004 г., 15:42:28:
O> Нужно для того чтобы ни один кусок звука не пропал и не было шелчков. O> Получактся что fctrl есть мое решение? O> Тогда как синхронизоваться, после того как блок отыграет?
я так понимаю вашу проблему: вы хотите одновременно записывать данные
в устройство и читать следующие данные?
Тогда вам наверно не поможет неблокирующая запись, она не так работает
как OVERLAPPED в винде..
Тут надо как-то по другому..
Здравствуйте, butcher, Вы писали:
B>я так понимаю вашу проблему: вы хотите одновременно записывать данные B>в устройство и читать следующие данные? B>Тогда вам наверно не поможет неблокирующая запись, она не так работает B>как OVERLAPPED в винде.. B>Тут надо как-то по другому..
B>-- B>С уважением, butcher
Да сначало считываю данные (звуковые) два буффера, затем посылаю 1 в аудио устройство, (затем меняю местами буфферы) 2 посылаю в аудио устройство. Между делом считываю данные в другом потоке и т.д.
Здравствуйте, OpenGL, Вы писали:
OGL>Да сначало считываю данные (звуковые) два буффера, затем посылаю 1 в аудио устройство, (затем меняю местами буфферы) 2 посылаю в аудио устройство. Между делом считываю данные в другом потоке и т.д.
мьютекс не подойдёт?
# man 3 pthread_mutex_init
Нет ничего невозможного..
Re: Асинхронный I/O со звуковым устройством.
От:
Аноним
Дата:
28.04.04 09:00
Оценка:
Здравствуйте, OpenGL, Вы писали:
OGL>Дело в том что вызов write(audio_dev,...) является блокирующим, нужно чтобы он был асинхронным, то есть ждать события, или мютекса после того как все тыграется. Как это сделать собстенно , если вообще OSS и RH 9.1 это позволяют?
А если так:
Два потока и защищённая от одновременного доступа очередь буфферов данных.
Перевый готовит данные и ставит их в очередь.
Второй поток пишет их в устройство (write).
Очередь можно защитить обычными семафорами.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, OpenGL, Вы писали:
OGL>>Дело в том что вызов write(audio_dev,...) является блокирующим, нужно чтобы он был асинхронным, то есть ждать события, или мютекса после того как все тыграется. Как это сделать собстенно , если вообще OSS и RH 9.1 это позволяют?
А>А если так: А> Два потока и защищённая от одновременного доступа очередь буфферов данных. А> Перевый готовит данные и ставит их в очередь. А> Второй поток пишет их в устройство (write). А> Очередь можно защитить обычными семафорами.
Я так и сделал, Все просто. Надо чтобы не один буффер ни улетел куда-нить. А то он где то через 1-2 минуты начинает пропускать блоки, идут щелчки. Нужен метод на подобие write только без блокировки, чтобы можно было точно дождаться конца проигрывания.
Здравствуйте, OpenGL, Вы писали:
OGL>>>Дело в том что вызов write(audio_dev,...) является блокирующим, нужно чтобы он был асинхронным, то есть ждать события, или мютекса после того как все тыграется. Как это сделать собстенно , если вообще OSS и RH 9.1 это позволяют?
А>>А если так: А>> Два потока и защищённая от одновременного доступа очередь буфферов данных. А>> Перевый готовит данные и ставит их в очередь. А>> Второй поток пишет их в устройство (write). А>> Очередь можно защитить обычными семафорами.
OGL>Я так и сделал, Все просто. Надо чтобы не один буффер ни улетел куда-нить. А то он где то через 1-2 минуты начинает пропускать блоки, идут щелчки. Нужен метод на подобие write только без блокировки, чтобы можно было точно дождаться конца проигрывания.
Я чего-то не понял.
Куда буфферы улетают?
OpenGL> чтобы можно было точно дождаться конца проигрывания.
Это и есть write.
Эта функция ждёт конца закачки (проигрывания) буффера в устройство (блокируется до конца проигрования).
Вы сами драйвер устройства писали?
Сдаётся мне что у вас либо с драйвером что-то либо с алгоритмом.
Если очередь реализована верно то в цыкле write потока (поток закачки) из очереди будут
извлекаться буффер за буффером в нужном порядке и с минимальной задержкой отправлятся в устройство.
Возможно так же, что данные просто не успевают закачиваться в устройство в нужном темпе.
Может устройство не правильно работает.
Устройство и драйвер вашей разработки или?
Здравствуйте, Click, Вы писали:
C>Здравствуйте, OpenGL, Вы писали:
OGL>>>>Дело в том что вызов write(audio_dev,...) является блокирующим, нужно чтобы он был асинхронным, то есть ждать события, или мютекса после того как все тыграется. Как это сделать собстенно , если вообще OSS и RH 9.1 это позволяют?
А>>>А если так: А>>> Два потока и защищённая от одновременного доступа очередь буфферов данных. А>>> Перевый готовит данные и ставит их в очередь. А>>> Второй поток пишет их в устройство (write). А>>> Очередь можно защитить обычными семафорами.
OGL>>Я так и сделал, Все просто. Надо чтобы не один буффер ни улетел куда-нить. А то он где то через 1-2 минуты начинает пропускать блоки, идут щелчки. Нужен метод на подобие write только без блокировки, чтобы можно было точно дождаться конца проигрывания.
C>Я чего-то не понял. C>Куда буфферы улетают? C>OpenGL> чтобы можно было точно дождаться конца проигрывания. C>Это и есть write. C>Эта функция ждёт конца закачки (проигрывания) буффера в устройство (блокируется до конца проигрования). C>Вы сами драйвер устройства писали? C>Сдаётся мне что у вас либо с драйвером что-то либо с алгоритмом. C>Если очередь реализована верно то в цыкле write потока (поток закачки) из очереди будут C>извлекаться буффер за буффером в нужном порядке и с минимальной задержкой отправлятся в устройство. C>Возможно так же, что данные просто не успевают закачиваться в устройство в нужном темпе. C>Может устройство не правильно работает. C>Устройство и драйвер вашей разработки или?
Да звук берется с моего устройства(ну нашего, не я его делал). Драйвер для него я писал,
Write передает управление мне чуть раньше чем блок отыграет или после того как отыграет?
Здравствуйте, OpenGL, Вы писали:
OGL>Да звук берется с моего устройства(ну нашего, не я его делал). Драйвер для него я писал, OGL>Write передает управление мне чуть раньше чем блок отыграет или после того как отыграет?
Это зависит от таго как вы реализовали драйвер.
Конкретно функцию write в драйвере.
Как вы пишите в устройство?
Вариант 1.
Если из write (в драйвере — kernel mode),
то процес не вернётся в user mode пока вы не отправите
последний байт в устройство.
Вариант 2.
Если вы пишите данные в обработчике прерывания,
то процесс необходимо усыплять в функции write (kernel mode).
Вы передаете буффер в устройство (write).
В драйвере его копируете во внутрений буффер.
Затем закачиваете кусок данных в устройство.
В фун. write в драйвере усыпляете процесс на очереди ожидания (wait_queue).
Ждёте когда оно запросит прерыванием новые данные.
В нижнем обработчике прерываний подсовываете новый кусок данных в устройство.
Если буффер исчерпан, то будите процесс.
Процесс просыпается и переходит из kernel mode в user mode.
Функция write завершается.
Возращаетесь к первому пункту.
Заметте пока вы будите выделять и передавть в драйвер новый буффер он будет проигровать последние переданые ему данные.
Поэтом если правильно выбрать размер буффера устройства, то разрыва в воспроизведении не будет.
Первый вариант проще.
Второй мне кажется более правильным.
Существует ещё третий вариант похожий на второй, но исключающий буффер в драйвере (устройство само забирает данные из памяти).
Третий вариант самый производительный, но реализовать его не просто.
В любом случае вам надо переписать драйвер.
Возможно переделать устройство.
Функция write работает так как она реализована в вашем драйвере.
На rsdn.ru в форумах и opennet.ru в форумах и статьях поищите более подробную инфу об этом.
Здравствуйте, Click, Вы писали:
C>Здравствуйте, OpenGL, Вы писали:
OGL>>Да звук берется с моего устройства(ну нашего, не я его делал). Драйвер для него я писал, OGL>>Write передает управление мне чуть раньше чем блок отыграет или после того как отыграет?
C>Это зависит от таго как вы реализовали драйвер. C>Конкретно функцию write в драйвере.
C>Как вы пишите в устройство?
C>Вариант 1. C>Если из write (в драйвере — kernel mode), C>то процес не вернётся в user mode пока вы не отправите C>последний байт в устройство.
C>Вариант 2. C>Если вы пишите данные в обработчике прерывания, C>то процесс необходимо усыплять в функции write (kernel mode).
C>Вы передаете буффер в устройство (write). C>В драйвере его копируете во внутрений буффер. C>Затем закачиваете кусок данных в устройство. C>В фун. write в драйвере усыпляете процесс на очереди ожидания (wait_queue). C>Ждёте когда оно запросит прерыванием новые данные. C>В нижнем обработчике прерываний подсовываете новый кусок данных в устройство. C>Если буффер исчерпан, то будите процесс. C>Процесс просыпается и переходит из kernel mode в user mode. C>Функция write завершается. C>Возращаетесь к первому пункту. C>Заметте пока вы будите выделять и передавть в драйвер новый буффер он будет проигровать последние переданые ему данные. C>Поэтом если правильно выбрать размер буффера устройства, то разрыва в воспроизведении не будет.
C>Первый вариант проще. C>Второй мне кажется более правильным. C>Существует ещё третий вариант похожий на второй, но исключающий буффер в драйвере (устройство само забирает данные из памяти). C>Третий вариант самый производительный, но реализовать его не просто.
C>В любом случае вам надо переписать драйвер. C>Возможно переделать устройство. C>Функция write работает так как она реализована в вашем драйвере.
C>На rsdn.ru в форумах и opennet.ru в форумах и статьях поищите более подробную инфу об этом.
Дак он в принципе не возможен чтоли? Асинхронный I/O со звуковым устройством? Какая же тогда Linux многозадачная система?
Здравствуйте, OpenGL, Вы писали:
OGL>Дак он в принципе не возможен чтоли? Асинхронный I/O со звуковым устройством? Какая же тогда Linux многозадачная система?
Вы просто запутались в понятиях.
Вы писали: >Дело в том что вызов write(audio_dev,...) является блокирующим, нужно чтобы он был асинхронным, то есть ждать события, или мютекса после т>ого как все тыграется. Как это сделать собстенно , если вообще OSS и RH 9.1 это позволяют?
"ЖДАТЬ СОБЫТИЯ", "ПОСЛЕ ТОГО КАК ВСЁ ТЫГРАЕТ" — ваши слова.
Вам предлагают вызвать в другом потоке блокирующию write и дождаться её завершения.
В основном потоке вы можите делать в это время другую работу.
Разве это не многозадачность.
Но ещё раз что бы это работало вы должны поддерживать блокировку из драйвера.
Здравствуйте, Click, Вы писали:
C>Здравствуйте, OpenGL, Вы писали:
OGL>>Дак он в принципе не возможен чтоли? Асинхронный I/O со звуковым устройством? Какая же тогда Linux многозадачная система?
C>Вы просто запутались в понятиях. C>Вы писали: >>Дело в том что вызов write(audio_dev,...) является блокирующим, нужно чтобы он был асинхронным, то есть ждать события, или мютекса после т>ого как все тыграется. Как это сделать собстенно , если вообще OSS и RH 9.1 это позволяют?
C>"ЖДАТЬ СОБЫТИЯ", "ПОСЛЕ ТОГО КАК ВСЁ ТЫГРАЕТ" — ваши слова. C>Вам предлагают вызвать в другом потоке блокирующию write и дождаться её завершения. C>В основном потоке вы можите делать в это время другую работу. C>Разве это не многозадачность.
Вообще то я так и сделал.
Нет это не многзадачность ОС в принципе должна поддерживать асинхронный обмен с устройствами, я уж не говорю про порты.
C>Но ещё раз что бы это работало вы должны поддерживать блокировку из драйвера.