четверг, 21 октября 2010 г.

Передача аудио по COM порту в голосовом модеме

В задачах автоматического обзвона абонентов, аудиосообщение можно передать через аппаратный аудиоканал, подключив выход аудиокарты к линейному входу модема (можно и микрофонный вход любого мобильного телефона, но со схемой нормализации уровня сигнала). Однако при наличии специализированного голосового модема можно воспользоваться специфичными AT командами производителя модема и передавать записи в формате WAV PCM через последовательный порт как обычный набор байтов. Как? Об этом под катом...

Не растекаясь мыслию по древу сразу код:

var Com: THandle = 0;

function SetCommTiming: Boolean;
var Timeouts: TCommTimeOuts;
begin
 with TimeOuts do begin
  ReadIntervalTimeout := 1;
  ReadTotalTimeoutMultiplier := 0;
  ReadTotalTimeoutConstant := 1;
  WriteTotalTimeoutMultiplier := 2;
  WriteTotalTimeoutConstant := 2;
 end;
 Result:= SetCommTimeouts(Com,Timeouts)
end;

function SetCommBuffer(InQueue, OutQueue: LongInt): Boolean;
begin
 Result:= SetupComm(Com, InQueue, OutQueue)
end;

function SetCommStatus(Baud: Integer): Boolean;
var DCB: TDCB;
begin
 with DCB do begin
  DCBlength:=SizeOf(Tdcb);
  BaudRate := Baud;
  Flags:=12305;
  wReserved:=0;
  XonLim:=600;
  XoffLim:=150;
  ByteSize:=8;
  Parity:=0;
  StopBits:=0;
  XonChar:=#17;
  XoffChar:=#19;
  ErrorChar:=#0;
  EofChar:=#0;
  EvtChar:=#0;
  wReserved1:=65;
 end;
 Result:= SetCommState(Com, DCB)
end;

procedure closecom;
begin
 CloseHandle(Com)
end;

function opencom(comPort:string; InQueue,OutQueue,Baud: LongInt): Boolean;
begin
 comport:= uppercase(comport);
 if Com > 0 then closecom;
 Com:= CreateFile(PChar(comPort),
  GENERIC_READ or GENERIC_WRITE,
  0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
 Result:= (Com > 0) and SetCommTiming and
 SetCommBuffer(InQueue,OutQueue) and
 SetCommStatus(Baud)
end;

procedure sendcom(s: string);
var TempArray: array[1..255] of Byte;
    Count    : Integer;
    TX_Count : cardinal;
begin
 for Count:= 1 to Length(S) do TempArray[Count]:= Ord(S[Count]);
 WriteFile(Com, TempArray,Length(S),TX_Count,nil)
end;

function readcom: string;
var RX_Count : cardinal;
    TempArray: array[1..255] of Byte;
    Count    : Integer;
begin
 result:= '';
 ReadFile(Com, TempArray, 255, RX_Count, nil);
 for Count:= 1 to RX_Count do result:= result + Chr(TempArray[Count])
end;


//- идентификация вызова
function ring: boolean;
begin
 result:= false;
 if trim(readcom)='RING' then result:= true
  else result:= false;
end;

// ОТСЫЛКА WAV НА ГОЛОСОВОЙ МОДЕМ --------------------
// sleep - следует заменить буфером отсылки по таймеру
// с проверкой ответа модема
// ---------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
var fname, nomer: string;
    fl: textfile;
    
    TempArray: array[1..255] of Byte;
    Count    : Integer;
    TX_Count : cardinal;
begin
 // открываем порт-
 opencom('\\.\COM4', 8, 8, 115200);

 // инициализация модема-
 sendcom('AT+FCLASS=8');
 sleep(10);
 sendcom('AT+VSM=130,8000,0,0');
 sleep(10);
 sendcom('AT+VSD=128,50');
 sleep(10);
 sendcom('AT+VLS=1');
 sleep(10);
 // набираем номер в тональном режиме-
 nomer:= '+380504341593';
 sendcom('ATDT '+ nomer + ';'+ #13 + #10 + 'ATH1'+ #13 + #10);
 sleep(100);

 //режим передачи голоса-
 sendcom('AT+VTX'#13#10); // ответом будет - CONNECT

 // открываем WAV-файл в формате PCM и побайтно отсылаем-
 fname:= ExtractFilePath(paramstr(0))+'golos_pcm.wav';
 AssignFile(fl, fname);
 if fileexists(fname) then begin
  Reset(fl); fname:= '';
  repeat
   ReadLn(fl, fname);

   for Count:= 1 to Length(fname) do TempArray[Count]:= Ord(fname[Count]);
   WriteFile(Com, TempArray,Length(fname),TX_Count,nil)
  until eof(fl);
  CloseFile(fl);
 end;

 // завершить передачу, ответ - VCON
 sendcom(''#10#03);
 sleep(100);
 // положить трубку
 sendcom('ATH0')
end;

end.

забрать добро

Комментариев нет:

Отправить комментарий

В комментариях уважайте собеседника, внимательно читайте посты и не додумывайте. Просьбы и предложения из разряда: «можно ваш Skype/Viber/телефон», «напишите мне в vk/FB», а также другие им подобные — игнорируются. Выход новых версий ПО, внешняя ссылка, переставшая работать с течением времени и т.п. не является основанием для претензий. Желающие спокойно подискутировать и высказаться — Welcome. Желающие спонсировать блог — Donate. Нарушение этих простых правил ведет к бану и удалению комментариев без предупреждения.