Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.145.191.22] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
По сабжу. Звук пишется в буфер (буфер 1 сек) как буфер заполнился шлется через сокет типа Socket.SendBuffer(Buffer,sizeof(Buffer));
ну и принимается Socket.ReceiveBuffer(BufIn,sizeof(BufIn)); MS:=TMemoryStream.create; пишем заголовок wave файла(ну не слать же его !?) Ms.write(); Ms.writebuffer(bufIn,sizeof(BufIn)); sndPlaysound(MS.memory,snd_memory); Так вот проблемы такие: (сеть 100Mbit/s) 1. задержка (ну это не очень важно, но если есть возможности оптимизировать отправку с радостью выслушаю) 2. Щелчки при начале проигрывания и приокончнии, причем очень громкие. из-за них надо очень вслушиваться. вообще картина на приемнике такая: щелчок, звук на 1сек, щелчок, задержка и .т.д вообще кошмар, а если звук не 44100 то вообще ничего не разобрать из-за разрывов и щелчков. С радостью выслушаю любые советы по оптимизации. |
Сообщ.
#2
,
|
|
|
для начала надо бы все таки небольшую задержку внести - чтоб не было так что пришел кусок по сети и сразу его выводим - лучше выводить предыдущий, т.е. задержка чтоб была 1-2 сек...
и еще может воспроизводить не через sndPlaysound, а через какие-нить waveOut... (waveOutOpen, waveOutWrite, waveOutClose ... и т.п.) зы: это все было ИМХО |
Сообщ.
#3
,
|
|
|
а какой смысл не сразу проигрывать? мы же ведь полностью получили буфер зачем ждать следующего. А вот sndPlaySound мне и самому не нравиться, но это самое протое решение и темболее она из памяти читает. Будет ли лучше использование других функций -это большой вопрос.
|
Сообщ.
#4
,
|
|
|
А что если сеть затормозит ? - тогда у тя сразу дырка в звуке
|
Сообщ.
#5
,
|
|
|
а ты умнее ничего предложить не смог ? (извини не сдержадся), но считать то всетаки учись!
по 100Mbit/s сетке за 1 cек. передается до 12.5 Mb а у меня весь секундный буфер 40 Kb !! Разницу видишь ? |
Сообщ.
#6
,
|
|
|
Со своего опыта знаю что и 100 мегабит может затормозить ( особенно если сеть из виндов )
Извиняюсь за офф |
Сообщ.
#7
,
|
|
|
Да нет же, сеть незагруженная (2 компа (пока)) я смотрел загрузка сети при голосовом обмене 0.53%. Мне нужен совет по оптимизации кода.
|
Сообщ.
#8
,
|
|
|
А как ты в реал тайм отправляешь данные(звук) ?
|
Сообщ.
#9
,
|
|
|
У меня это вроде это написано... Ну да ладно повторю: заполнется секудный звуковой буфер (размер не важен) и шлется через сокет.
|
Сообщ.
#10
,
|
|
|
хе,хе,это я вроде увидел.Я имел ввиду,сам код что ли.Дело в том,что у меня таких как у тебя проблем нет, зато есть проблемы с выпаданием нескольких звуков(в частности букв\слогов).
Я делаю так,веду записьпотом по таймеру(еще не нашел оптимального промежутка)обрываю запись и посылаю сначала размер потока, а потом и сам поток через sendStream(). Но вот процедуры остановки и вновь запуска записи отнимаю как минимум пол секунды. Да еще думаю на той стороне теюе траблы, в итоге получаются как бы заикания.Вот если ставить буфер\таймер в 10 сек,то не так заметно,но задержка в 10 секунд это перебор... |
Сообщ.
#11
,
|
|
|
я senbufferом шлю, размер слать не надо так как буфер стандартного размера - 1сек.
|
Сообщ.
#12
,
|
|
|
Дык я вот думаю, может многопоточность придется прикрутить,типа:сначала отправляются первые несколько секунд,запускается втрой поток и в это время сразу же пишет звук дальше,на принимающей стороне таже картина,первые данные приняли,начинем играть и в тоже время принимаем следующую порцию.Но все это как-то сильно гиморно выглядит...
|
Сообщ.
#13
,
|
|
|
Так, может быть, проще сделать - в одном потоке пишется звук, потом каждые n секунд скидывается в глобальный буфер (объявленный в глобальных переменных) и ставит глобальный флаг, типа, готово, можно посылать, а основной поток на эту переменную реагирует и скидывает буфер (в это время запись идет дальше, кстати), лучше использовать двойную буферизацию, т.е. глобальный буфер переписывается в локальный и именно этот локальный отправляется, а в глобальный снова пишутся данные. Еще модификация - заводим охрененного размера буфер (на минуту, например) для устранения лагов. Первый поток в него пишет звук, а второй - отсылает в сеть. Если происходит override (т.е. указатель на отправку сравнялся с указателем на запись), то ждем новых голосовых данных (ИМХО, такого никогда не будет, но все же). При дохождении до конца буфера указатель ставится на начало и т.д. Уж за минуту максимум данные отправятся Если не хватает, то надо увеличивать буфер. Т.о. этот способ лишен всех недостатков двух других. Данные поступают и отправляются потоком, нет лагов, заиканий/щелчков.
На приемной стороне - то же самое. Большой буфер, данные поступают и проигрываются конвеером, тут уже overrid'ы неизбежны. Надо ждать дозаполнения буфера, а потом проигрывать, чтобы в буфере была хотя бы 1 секунда. ИМХО, для всего этого лучше использовать не компонентные сокеты, а WinSock в чистом виде (по крайней мере, он не выдает всякие ошибки в виде MessageBox'ов), используя асинхронные сокеты. |
Сообщ.
#14
,
|
|
|
Да но тут одна проблема(по крайней мере явная),в буфер нельзя одновременно писать и читать из него(переписывая в другой буфер на отправку), т.к. при чтении
stream.position:=0; // !! Как быть? |
Сообщ.
#15
,
|
|
|
О!!! Дошло, да? Надо, надо изучать низкоуровневые WinSock'еты, WSA рулит! Я уж давно не юзаю компоненты из-за их тупых, подчас, ограничений! Читайте доки по WSA, там все есть... А уж асинхронные сокеты - то, что доктор прописал.
|