Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » RS232: опустошение буфера модема. Почему ?

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки

Открыть новую тему     Написать ответ в эту тему

j7



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Пишу маленький автоответчик  на Делфи. Модем – ZyXel OMNI 56K Plus. При установке драйвера, звуковое устройство Unimodem не появилось, поэтому использовать TAPI не могу. Если же подправить INF файл и добиться, чтобы появился sound unimodem, то звук – ужасный.  
 
Пытаюсь работать через COM порт AT командами. Вроде бы все получается, звук идет, но с каким-то треском.  
 
Пытался работать с COM портом Async Pro и TMS Async32 v1.2, результат примерно одинаковый.  
Делаю так:
1. Готовлю Adobe Audition WAV файл нужного формата (IMA ADCPM 4 * 8000 Гц), вырезаю аудиоданные (размер = 25 кБ), редактирую на предмет двойных <DLE> (это маркер управления потоком данных в модеме Zyxel) и дописываю <DLE><EXT>(признак конца потока аудиоданных)  в конец файла.
2. Бросаю на форму компонент, делаю ему исходящий буфер 50 кБ (больше размера файла, это пока экспериментирую, чтобы файл влез весь).
3. Пихаю файл в порт (в буфер порта). В начинает трубке говорить, но с треском.
4. Гляжу PortMon’ом, файл уходит в правильным размером, но до того как модем скажет OK, он валит «туеву хучу» сигналов <DLE>u (в Zyxel - это опустошение буфера модема без получения команды <DLE><EXT> (конец передачи данных).  
 
Сложилась ситуация, в которой я не могу разобраться: данные в буфере Com порта есть, но они почему-то в нужное время не отдаются в модем, и он сигнализирует, что у него буфер пуст. Подозреваю, что из-за этого и треск в трубке.
 
Подскажите, в чем я мог допустить ошибку.  
 
PS: VentaFax на модеме работает чудесно.
 
Спасибо.
 

Всего записей: 750 | Зарегистр. 14-12-2001 | Отправлено: 04:35 27-07-2007
dmka



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Какая скорость порта, какой используется flow control, какой размер буфера установлен для UART и в самом модеме? Данные шлются в порт по одному байту? Синхронно или асинхронно? На другом компьютере пробовал? Файл в правильном формате?

Цитата:
PS: VentaFax на модеме работает чудесно.

Ну так посмотри как она работает и сделай так же. Как минимум строку инициализации используй такую же.

Всего записей: 956 | Зарегистр. 23-04-2003 | Отправлено: 07:47 27-07-2007 | Исправлено: dmka, 08:02 27-07-2007
j7



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Работаю компонентом CommPort из TMS Async32, асинхронно. Оба буфера порта равны 8192. Контроль потока – Xon/Xoff. Скорость при инициализации 19200, при передаче звука – 57600. Строки инициализации в наглую стырил из Вентафакса.
Похоже, дело в формате данных, которые я запихиваю в модем. По документации на модем, он поддерживает формат IMA ADPCM 4, 9600. Беру Adobe Audition, открываю заготовленный файл, понижаю Sample Rate, сохраняю в формате IMA ADPCM. В своей программе открываю этот файл, смещаюсь на длину WAV заголовка, даю в модем +VTX, и после получения CONNECT передаю файл, обрабатывая <DLE>. Идет треск и опустошения буфера модема.  
В качестве эксперимента, запускаю ВенаФакс, настраиваю монитор порта, дозваниваюсь, Вента произносит приветственное сообщение, записываю перехваченные с COM порта данные, относящиеся ко звуку, в файл. Проигрываю этот файл своей программой (без обработки <DLE>), звучит отлично.
Вывод:  
-  беда либо в формате IMA ADPCM (в RFC2361 есть указание на код WAVE_FORMAT_ZYXEL_ADPCM в заглоовке WAV файла). Может есть алгоритм IMA ADPCM ZYXEL?
-  либо в моей обработке <DLE> (Если я её правильно понял и реализую).
 
Кто в теме, может гляньте:
 
Кусок кода, обработки маркера <DLE> (байта с кодом 0x10)
- Одиночный 0x10 заменяю на 0x10, 0x10
- двойной 0x10 – на 0x10, 0x1A
 
Код:
 
Const
   BufSz = 3000; // размер входного буфера
   Buf1Sz = 4000; // размер выходного буфера
 
Var
   fs : TFileStream;
   Buf, Buf1 : pByte;  
   PrevByte : Byte;
   Speaking : Boolean = False;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
   fs := TFileStream.Create ('e:\gre.bin',fmOpenRead    + fmShareDenyWrite);
   fs.Seek(60, soFromBeginning);
   PrevByte :=0;
   GetMem (Buf, BufSz);
   GetMem (Buf1, Buf1Sz);
end;
 
 
// эта процедура вызывается после получения строки CONNECT (в ответ на +VTX),  
// либо при получении сообщения, что буфер COM порта меньше либо равен XonLim
 
procedure TForm1.CopyBuf;
Var
   i : Integer;
   BufCnt, Buf1Cnt : Integer;
   pBuf,pBuf1 : pByte;
Begin
   // если размер  
   if vaComm1.WriteBufFree < BufSz then exit;
 
   // Зачитываю очередной блок из файлва в Buf
   BufCnt := fs.Read(buf^,BufSz);
 
   // Определяю, последний ли это блок из файла
   // True - нет
   Speaking := not (fs.Position = fs.Size);
 
   // Размер выходного буфера = размеру входного
   Buf1Cnt := BufCnt;
 
   // Указатели на начала буферов
   pBuf := Buf;
   pBuf1 := buf1;
 
   // Переписываю входной буфер в выходной, заменяя последовательности байтов:
   // любой_не_0x10, 0x10, любой_не_0x10 на любой_не_0x10, 0x10, 0x10, любой_не_0x10
   // любой_не_0x10, 0x10, 0x10, любой_не_0x10 на любой_не_0x10, 0x10, 0x1A, любой_не_0x10
   For i := 1 to BufCnt do
      Begin
         // Если предыдущий байт входного буфера был = 0x10
         if PrevByte = $10 then
            // и текущий байт = 0x10
            if pBuf^ = $10 then
               // Заменяю два идущих подряд 0x10 на 0x10, 0x1A
               pBuf1^ := $1A
            else
               // и текущий байт <> 0x10
               Begin
                 // Заменяю одиночный  0x10 на 0x10, 0x10, раздвигая выходной буфер
                  pBuf1^ := $10;
                  inc(Buf1Cnt);
                  inc(pBuf1);
                  pBuf1^ := pBuf^;
               End
         Else
            // Предыдущий байт <> 0x10
            pBuf1^ := pBuf^;
 
         PrevByte := pBuf1^;
         inc (pBuf);
         inc (pBuf1);
      End;
 
// Если это последний кусок файла, то обрабатываю, аналогичным образом,  
// последний байт потока данных.
if not Speaking then
   Begin
      if PrevByte = $10 then
         if pBuf^ = $10 then
            // Заменяю два идущих подряд 0x10 на 0x10, 0x1A
            pBuf1^ := $1A
         else
            Begin
               // Заменяю одиночный  0x10 на 0x10, 0x10, раздвигая выходной буфер
               pBuf1^ := $10;
               inc(Buf1Cnt);
               inc(pBuf1);
               pBuf1^ := pBuf^;
            End
      else
         pBuf1^ := pBuf^;
 
      // Дописываю в конец потока, маркер окончания потока 0x10, 0x03.
      Inc(Buf1Cnt);
      Inc(Buf1Cnt);
 
      pBuf1^ := $10;
      inc (pBuf1);
      pBuf1^ := $03;
   End;
 
   // вываливаю выходной буфер в COM порт
   vaComm1.WriteBuf(Buf1^, Buf1Cnt);
End;
 

 
Часть протокола PortMon’а при открытии порта

Код:
 
Options: Open                         
Rate: 19200                        
                        
StopBits: 1 Parity: NONE WordLength: 8                        
EOF:0 ERR:0 BRK:0 EVT:0 XON:11 XOFF:13                        
Shake:41 Replace:83 XonLimit:1024 XoffLimit:4096                        
InSize: 8192 OutSize: 8192                        
RI:-1 RM:0 RC:0 WM:0 WC:0                        
Mask: RXCHAR ERR                         
Purge: TXABORT TXCLEAR                         
Length 3: AT.                        
Length 6: ..OK..                        
Length 12: ATQ0V1E0&D2.                        
Length 6: ..OK..                        
Length 18: ATQ0V1E0&D2X4S0=0.                        
Length 6: ..OK..                        
Length 8: ATS7=50.                        
Length 6: ..OK..                        
Length 15: AT&H4+FCLASS=1.                        
Length 6: ..OK..                        
Length 6: AT&I0.                        
Length 6: ..OK..                        
Length 15: AT+FCLASS=8&H3.                        
Length 6: ..OK..                        
Length 17: AT+VRN=0;+VTD=10.                        
Length 6: ..OK..                        
Length 11: AT+VGT=130.                        
Length 6: ..OK..                        
Length 9: AT+FLO=1.                        
Length 6: ..OK..                        
                
Rate: 57600                        
                        
StopBits: 1 Parity: NONE WordLength: 8                        
EOF:0 ERR:0 BRK:0 EVT:0 XON:11 XOFF:13                        
Shake:41 Replace:83 XonLimit:1024 XoffLimit:4096                        
Length 14: AT+VSM=4,9600.                        
Length 6: ..OK..    
 

 
Спсибо.

Всего записей: 750 | Зарегистр. 14-12-2001 | Отправлено: 19:36 30-07-2007 | Исправлено: j7, 20:40 30-07-2007
j7



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Все, получилось.
 
dmka, спасибо за наводящие вопросы.
дело действительно было в формате.
 
Tech.support ZyXel - рулит.
 
Удачи.

Всего записей: 750 | Зарегистр. 14-12-2001 | Отправлено: 03:45 01-08-2007
loader1986

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Если можно поделитесь реализацией, а то проблемасхожая. А если запустить doom3, то тормаза нереальные.

Всего записей: 2 | Зарегистр. 13-02-2008 | Отправлено: 09:40 13-02-2008
loader1986

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
loader1986@uvaga.by

Всего записей: 2 | Зарегистр. 13-02-2008 | Отправлено: 12:32 14-02-2008
Открыть новую тему     Написать ответ в эту тему

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » RS232: опустошение буфера модема. Почему ?


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2025

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru