Форум: "Система";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.02.18;
Скачать: [xml.tar.bz2];




Вниз

Логическая задачка (не могу справиться) 


REL   (2001-11-09 11:37) [0]

Народ, помогите вот с таким алгоритмом.

Есть 2 компа, соединённые по модему. На первом работает цикл, который в равные!!! интервалы времени выдаёт массивы разной длины (в моём случае - это сжатый речевой сигнал от 2 до 256 значений - но это не принципиально). На приёмном конце также работает алгоритм, который в равные интервалы времени принимает вышеуказанные массивы и обрабатывет их. Как синхронизировать приёмник и передатчик, чтобы нехватка времени на передачу больших массивов компенсировалась избытком времени при передаче малых массивов. Т.е. у меня скорость передачи должна подбираться под массив средней длины (например 100).

Замечание: не должно возникать такой ситуации, что на приёмном конце массив запросится, но ещё не успеет считаться. В двух словах алгоритм такой же как в сотовых телефонах: на малых скоростях передаётся достаточно большие объёиы данных за счёт того, что та информация, которая не успевает передаваться во время разговора, передаётся во время пауз между фразами.

Заранее благодарен за любую помощь.



savva   (2001-11-09 12:26) [1]

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

или я чего то не понимаю....



savva   (2001-11-09 12:30) [2]

и вообще...
>равные интервалы времени принимает вышеуказанные массивы
а если нет этих самых массивов? что он принимает?....



REL   (2001-11-12 16:16) [3]

Привет, savva. Огромное спасибо, что откликнулся. Смотря что ты подразумеваешь под протоколом.

У меня есть возможность через равные моменты времени отправлять данные в порт, я также могу предварительно накапливать данные в буфере, а уж затем оттправлять. Что ты подразумеваешь под идентификатором пакета: начало и конец каждого массива у меня, конечно, отмечается.

Давай я поясню суть проблемы, чтобы тебе стало понятнее.

Представь: оцифровываю данные со звуовухи и, скажем, в интервале времени (условно) 1 сек. получаю массив данных из 200 знач. Затем я сжимаю данный массив и из 200 значений получаю, скажем, 100 зн., но могу получить и 190 и 50 и т.д. (смотря как сожмётся). Именно эти данные я и пересылаю по модему (естественно отметив начало и конец каждого уже сжатого массива). На приёмном конце я эти данные принимаю, восстанавливаю до 200 значений и воспроизвожу (понятно, что тоже в равные промежутки времени - как иначе?).
Так вот мне необходимо придумать такой алгоритм, чтобы скорость передачи определять не длиной самого длиннго (плохо сжатого в моём случае) массива, а длиной среднесжатого массива. Т.е., чтобы избыток времени при передаче малых массивов компенсировал недостачу времени при передаче больших массивов.

Я пробовал реализовать сл. алгоритм: перед посылкой накапливал буфер фиксированной длины, затем отсылал, а на приёмном конце разбирал буфер, восстанавливал массивы и воспроизводил их. Но здесь возникла вполне объяснимая ситуация: из-за различной степени сжатия в буфер могло попадать, например, от 2 до 10 массивов. Соответственно, такой буфер мог воспроизводиться звуковухой от 2 до 10 сек (в зависимости от кол-ва содержащихся в нём массивов), что приводило к сл: пусть вначале отослался буфер, в который попало 2 массива (на приёмном конце он восстанавливается и воспроизводится 2 сек). В это время на источнике накапливается новый буфер, в который попало 10 массивов (т.к. они хорошо сжались)- данный буфер будет накапливаться 10 сек. Т.е. получется, что из-за разности длин сжатых массивов и, следовательно, из-за разности в кол-ве массивов, попавших в буфер (в приведённом выше случае) приёмник будет вынужден 8 сек ждать, пока 2-ой буфер заполнится и отошлётся.

Пока, savva, может я всё слишком усложняю, может ты увидишь более простое решение. Сильно не грузись - просто может быть ты влёт сможешь придумать что-нибудь простое и эффективное.

Ещё раз спасибо, Евгений.



Владислав   (2001-11-13 08:05) [4]

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



Stranger   (2001-11-13 09:35) [5]

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



savva   (2001-11-13 12:02) [6]

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



MegaVolt   (2001-11-13 14:32) [7]

Послушай Stranger`a! А скорость обмена поставь максимальную например 56000 или скока потянешь. Буфер для сжатой инфы на приёмной стороне. А дальше всё очень просто например раз в секунду из буфера на приёмной стороне выбираешь кусок соответствующий 1 сек. декодируешь его и воспроизводишь его в течении 1 сек. за это время к тебе приходит другой кусок и ты его воспроизвоишь и.т.д.



Mikhail   (2001-11-14 07:15) [8]

Мне кажется, что надо создать DCOM сервер и клиент.



Exception   (2001-11-14 09:48) [9]

Вообще, проблема мне кажется несколько надуманной. Особенно интересен ответ о DCOM сервере и клиенте - Mikhail, ты решил просто свои знания в этой области показать ? Ведь совершенно не принципиально в этой ситуации - вопрос стоит не в том, через что передавать данные, а как обеспечить работу приемника без задержек, и при этом передеветь максимум аудиоданных при существенно ограниченной пропускной способности канала.

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

Клиент:
- получает данные от сервера
- каждую 1/10 секунды воспроизводит очередной пакет.

Результат: задержка востроизведения мажду клиентом и сервером - 1/10 секунды, либо больше - если наступит такой момент, когда не хватит пропускной способности канала. Для решения этой проблемы достаточно (если передаем именно разговор) иногда пропускать "тишину" - т.е. не востроизводить пакеты "с молчанием" на клиенте, если он в данный момент "не успевает". Кроме того, можно изменить значение "0.1 сек" - чем больше, тем больше степень сжатия, естественно, но и задержка - тоже.

Вроде-бы все.



Exception   (2001-11-14 09:58) [10]

К сожалению, я не прочитал то, что написал, до того, как отправил.
Еще раз, и более подробно:

Использовать или не использовать DCOM - cовершенно не принципиально в этой ситуации (на самом деле даже нежелательно). Вопрос стоит не в том, через что передавать данные, а как обеспечить работу приемника без задержек и при этом передеветь максимум аудиоданных при существенно ограниченной пропускной способности канала.

Одно из решений, на мой взгляд, таково:
Сервер делает следующее:
- оцыфровывает аудиоданные порциями, скажем, по 0.1 сек.
- сжимет порции
- накапливает сжатые порции в буфере (скажем на 10-100 порций - т.е. 1-10 сек.) - это необходимо, если возникнет задержка, вызванная ограниченной проп. способностью канала.
- паралельно с этим непрерывным потоком посылает сжатые порции из буфера, если они там есть, конечно. Если это принципиально, то он может начинать посылку пакета порций (т.е. столько порций, сколько необходимо набрать до некоторой суммарной длины - она определяется по интервалу между посылками и проп. способности канала) через равные интервалы времени.

Клиент:
- получает данные от сервера
- каждую 1/10 секунды воспроизводит очередной пакет.

Результат: задержка востроизведения мажду клиентом и сервером - 1/10 секунды, либо больше - если наступит такой момент, когда не хватит пропускной способности канала. Для решения этой проблемы достаточно (если передаем именно разговор) иногда пропускать "тишину" - т.е. не востроизводить пакеты "с молчанием" на клиенте. Вернее, сервер вообще должен их пропускать при посылке, если в данный момент клиент "не успевает". Кроме того, можно изменить значение "0.1 сек." - чем больше, тем больше степень сжатия, естественно, но и задержка - тоже.

Вроде-бы все.




Форум: "Система";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.02.18;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.77 MB
Время: 0.045 c
1-57073           Злой_Гном             2002-02-01 18:23  2002.02.18  
Все, про ProgressBar дотумкал :-)))


3-57026           Romul                 2002-01-24 17:25  2002.02.18  
Как организовать поиск по полю в DBGrid?


3-56997           Beer                  2002-01-23 05:28  2002.02.18  
Как достать значение из TDBGrid.SelectedRows


7-57227           Valera_S              2001-11-15 08:52  2002.02.18  
Мастера?


1-57053           Vitek                 2002-02-01 13:53  2002.02.18  
Шрифты