Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Голосовой чат. Нужна помощь [D7, XP]


Archi ©   (2010-06-04 15:22:00) 

Пишу голосовой чат на делфи при помощи acm components. Вообщем записываю звук в буфер и передаю его на сервер, который передаёт этот звук всем подключённым клиентам, которые потом воспроизводят этот звук.  Суть проблемы в том, что на месте стыковки буферов звук пропадает и заново воспроизводится - из за этого слышны хлопки. Как можно этого избежать?
P.S. Прошу только попонятнее если что писать, потому что я только начал изучать делфи^^


Va-Bank   (2010-08-03 21:52:00) [1]

Вообще компоненты TServerSocket и TClientSocket для передачи звука не совсем подходят. Они работаю по протоколу TCP. А для передачи звука лучше воспользоваться протоколом UDP. Для этого можно к примеру взять компоненты от Indy (сам пишу на одних TidUDPServer без TidUDPCLient). Дело в том что TCP ожидает прихода всех данных, а UDP пофиг, пришли они или нет. Просто если пара байт затеряется в сети ничего страшного не произойдет, на слух не определишь. Зато скорость передачи возрастет. Я сам пишу программу, в которую надо встроить групповой аудио чат. Один на один я сделал. А вот совместный никак не получается. Сделал два модуля для захвата и воспроизведения звука на основе ACM компонентов, но с использованием callback функции.
Вообще по теме аудиочата налито много воды. Инфы вообще нет в инете. Все жилят не то чтобы поделиться исходниками (я понимаю), но даже подсказать алгоритм (тут не понимаю).


RWolf   (2010-06-05 22:21:00) [2]


> Archi   (05.06.10 00:33) [10]
> тестировал в сети на 100мб и в интернете. особой разницы
> не заметил

тестировал на канале ~4 кбит, ничего не трещало.


Сергей М.   (2010-06-05 16:54:00) [3]


> Archi   (04.06.10 20:21) [2]


Этов боевых условиях работать не будет - ни с треском ни без треска.


Германн   (2010-06-05 01:43:00) [4]


> > даже когда на сервере сидит всего 2 человека
>
> у которых скорость соединения должна быть настолько быстрой,
>  что бы пауза, которая образовывается у одного, пока идет
> отсылка второму, была настолько маленькая, что можно пренебречь.
>  Опять же, учитывая какой-то TACMComponent.
>


> тестировал в сети на 100мб и в интернете. особой разницы
> не заметил

Тестирование "на стенде" и "тестирование на реальных объектах" очень часто дают весьма разные результаты!


Archi   (2010-06-05 00:33:00) [5]

дело в том, что сервер не воспроизводит а всего лишь передаёт звук.
а про скорость - тестировал в сети на 100мб и в интернете. особой разницы не заметил


KilkennyCat   (2010-06-04 23:46:00) [6]

и еще нужно учесть какой-то компонент TACMComponent.

> даже когда на сервере сидит всего 2 человека

у которых скорость соединения должна быть настолько быстрой, что бы пауза, которая образовывается у одного, пока идет отсылка второму, была настолько маленькая, что можно пренебречь. Опять же, учитывая какой-то TACMComponent.

Вопрос: если один человек на сервере, все хорошо?


Archi   (2010-06-04 22:44:00) [7]

Честно - незнаю =\
но ведь оно "трещит" даже когда на сервере сидит всего 2 человека, а я думаю что это не так уж и много и всё это будет выполнятся довольно таки быстро


Демо   (2010-06-04 22:20:00) [8]

1. socket.ReceiveBuf(buf^,l); //принимаем данные

2. for i:=0 to Server.Socket.ActiveConnections-1 do
if server.Socket.Connections[i]=socket
then
  continue
else
  Server.Socket.Connections[i].SendBuf(buf^,l);
FreeMem(buf); //освобождаем память;
end;


Как ты думаешь, насколько долго выполняется код (2)?

И насколько часто у тебя считывается буфер (1)?

Ещё нужно учесть, что всё это выполняется в основном потоке.


Archi   (2010-06-04 21:55:00) [9]

извеняюсь за дабл пост, завис компьютер=\


Archi   (2010-06-04 21:39:00) [10]

TACMComponent - компонент, который записывает\воспроизводит звук.

Что в коде непонятно? клиент записывает звук, отпровляет его на сервер. Сервер пересылает поочерёдно всем клиентам этот пакет. Клиент воспроизводит его. Задержки между пакетами вроде бы нету.. звук практически не отстаёт (около полусекунды), но на месте стыковки пакетов(как мне обьяснили) происходит вот что: пакет закончился, воспроизведение остановилось, началось воспроизведение нового пакета. В момент когда останавливается воспроизведение пакета из за того, что звук останавливается слышен как бе треск.


Archi   (2010-06-04 21:39:00) [11]

TACMComponent - компонент, который записывает\воспроизводит звук.

Что в коде непонятно? клиент записывает звук, отпровляет его на сервер. Сервер пересылает поочерёдно всем клиентам этот пакет. Клиент воспроизводит его. Задержки между пакетами вроде бы нету.. звук практически не отстаёт (около полусекунды), но на месте стыковки пакетов(как мне обьяснили) происходит вот что: пакет закончился, воспроизведение остановилось, началось воспроизведение нового пакета. В момент когда останавливается воспроизведение пакета из за того, что звук останавливается слышен как бе треск.


KilkennyCat   (2010-06-04 21:09:00) [12]

TACMComponent - это что?

и вообще, приведенный код ничего не демонстрирует.


Archi   (2010-06-04 20:21:00) [13]

сервер:

procedure TfServer.ServerClientRead(Sender: TObject;
 Socket: TCustomWinSocket);
var l:integer;   //размер буфера
 buf:pointer;//буфер
 i:integer;
begin
l:=socket.ReceiveLength;//получаем длину буфера
getmem(buf,l+1); //резервируем память
socket.ReceiveBuf(buf^,l); //принимаем данные
//пересылаем данные всем кроме источника
for i:=0 to Server.Socket.ActiveConnections-1 do
 if server.Socket.Connections[i]=socket
 then
   continue
 else
   Server.Socket.Connections[i].SendBuf(buf^,l);
FreeMem(buf); //освобождаем память;
end;


клиент

procedure TfClient.ACMIn1Data(Sender: TACMComponent; aDataPtr: Pointer;
 aDataSize: Cardinal);
begin
//посылаем буфер данных
clientsocket1.Socket.SendBuf(adataptr^,adatasize);
end;


KilkennyCat   (2010-06-04 17:20:00) [14]

Смотря что происходит. Если есть задержка между пакетами (что тут обозвано буферами), то необходимо действительно буфер делать, т.е. сначала накопить несколько пакетов, затем воспроизводить. Если причина не в задержке, то не видя кода сложно сказать, при правильных действиях на месте стыковки ничего не хлопает.


Наверх

Титульная страница Поиск, карта сайта Написать письмо