unit clientmain; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls, IAX, IAXSnd, AppEvent, MMSYSTEM, ExtCtrls, Zseg, zGauge, Mystd, Std2, zAnimate, SlideBar, Menus, ActnList, OleCtrls, SHDocVw, Buttons, clientcaller; type TIAXThread = class; PWHOUT = ^WHOUT; WHOUT = record w: WAVEHDR; data: array [0..160] of word; next: pwhout; end; TFrmClientMain = class(TForm) StatusBar1: TStatusBar; PageControl1: TPageControl; TabBrowser: TTabSheet; TabCalls: TTabSheet; GroupBox1: TGroupBox; Button2: TButton; Button3: TButton; Panel1: TPanel; zcShapeColorBtn13: TzcShapeColorBtn; zcShapeColorBtn14: TzcShapeColorBtn; zcShapeColorBtn15: TzcShapeColorBtn; zcShapeColorBtn16: TzcShapeColorBtn; zcShapeColorBtn17: TzcShapeColorBtn; zcShapeColorBtn18: TzcShapeColorBtn; zcShapeColorBtn19: TzcShapeColorBtn; zcShapeColorBtn20: TzcShapeColorBtn; zcShapeColorBtn21: TzcShapeColorBtn; zcShapeColorBtn22: TzcShapeColorBtn; zcShapeColorBtn23: TzcShapeColorBtn; zcShapeColorBtn24: TzcShapeColorBtn; Panel2: TPanel; Panel3: TPanel; VoiceOutput: TGroupBox; Bar1: TzcPeakOmeter; zSlideBar1: TzSlideBar; Bar: TzcPeakOmeter; MainMenu1: TMainMenu; Test1: TMenuItem; Memo1: TListBox; GnoPhonecom1: TMenuItem; Preferences1: TMenuItem; ListBox1: TListBox; Audio1: TMenuItem; Video1: TMenuItem; Telefony1: TMenuItem; ActionList1: TActionList; AudioEditProperties: TAction; BrsBack: TBitBtn; BrsForward: TBitBtn; BrsReload: TBitBtn; BrsHome: TBitBtn; BrsStop: TBitBtn; Label1: TLabel; BrowserAdress: TEdit; Panel4: TPanel; WebBrowser: TWebBrowser; frCaller1: TfrCaller; procedure FormCreate(Sender: TObject); procedure Button3Click(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormDestroy(Sender: TObject); procedure Button2Click(Sender: TObject); procedure SendDtmfClick(Sender: TObject); procedure BrowserAdressKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure BrsForwardClick(Sender: TObject); procedure BrsHomeClick(Sender: TObject); procedure BrsStopClick(Sender: TObject); procedure BrsBackClick(Sender: TObject); private { Private-Deklarationen } history: Double; wout: HWAVEOUT; win : HWAVEIN; outqueue: PWHOUT; paused_xmit: Boolean; gsm: Pointer; gsm2: Pointer; OutBuf: TIAXAudio; F: TFileStream; procedure IAXDebug(Text: String); procedure IAXEvent(e: Riax_event); function loudness(level: Integer): Double; public { Public-Deklarationen } Session: Piax_session; IAXThread: TIAXThread; procedure OnData(Sender: TObject); end; TIAXEvent = procedure (Event: Riax_event) of object; TIAXThread = class(TThread) private EventHandler: TIAXEvent; event: Piax_event; public constructor Create(Handler: TIAXEvent); virtual; procedure Execute; override; procedure HandleEvent; end; var FrmClientMain: TFrmClientMain; const // parameters for audio in NWHIN = 8; // number of input buffer entries */ { NOTE the OUT_INTERVAL parameter *SHOULD* be more around 18 to 20 or so, since the packets should be spaced by 20 milliseconds. However, in practice, especially in Windoze-95, setting it that high caused underruns. 10 is just ever so slightly agressive, and the receiver has to chuck a packet every now and then. Thats about the way it should be to be happy. } OUT_INTERVAL = 10; // number of ms to wait before sending more data to peer */ // parameters for audio out OUT_DEPTH = 20; // number of outbut buffer entries */ OUT_PAUSE_THRESHOLD = 10; // number of active entries needed to start output (for smoothing) */ implementation {$R *.DFM} procedure Debug(Text: PChar);cdecl; begin FrmClientMain.IAXDebug(StrPas(Text)); end; procedure TFrmClientMain.FormCreate(Sender: TObject); var wf: TWaveFormatEx; T: THandle; P: THandle; I: Integer; begin // Setup Priority T := GetCurrentThread; P := GetCurrentProcess; if not SetThreadPriority(T, THREAD_PRIORITY_TIME_CRITICAL ) then ShowMessage('Thread Error'); if not SetPriorityClass(P, REALTIME_PRIORITY_CLASS) then ShowMessage('Process Error'); // Setup Browser BrowserAdress.Text:='http://www.gnophone.com/directory'; WebBrowser.Navigate(BrowserAdress.Text); // setup the format for opening audio channels wf.wFormatTag := WAVE_FORMAT_PCM; wf.nChannels := 1; wf.nSamplesPerSec := 8000; wf.nAvgBytesPerSec := 16000; wf.nBlockAlign := 2; wf.wBitsPerSample := 16; wf.cbSize := 0; OutBuf := TIAXAudio.Create(Self); OutBuf.Format := @wf; OutBuf.OnUpdate := OnData; for I := 0 to OutBuf.InputDrivers.Count-1 do begin ListBox1.Items.Add(OutBuf.InputDrivers[i].Description); end; // // open the audio out channel // if (waveOutOpen(@wout,0,@wf,0,0,CALLBACK_NULL) <> MMSYSERR_NOERROR) then // begin // ShowMessage('Fatal Error: Failed to open wave output device'); // Exit; // end; // open the audio in channel // if (waveInOpen(@win,0,@wf,0,0,CALLBACK_NULL) <> MMSYSERR_NOERROR) then // begin // ShowMessage('Fatal Error: Failed to open wave input device'); // waveOutReset(wout); // waveOutClose(wout); // Exit; // end; iax_debug_callback(Debug); iax_set_formats(AST_FORMAT_GSM); StatusBar1.SimpleText := Format('IAX gestartet auf port %d',[iax_init(0)]); Session := 0; IAXThread := TIAXThread.Create(IAXEvent); end; procedure TFrmCLientMain.IAXDebug(Text: String); begin Memo1.Items.Insert(0,Text); end; procedure TFrmClientMain.IAXEvent(e: Riax_event); var len,n: Integer; wh,wh1: PWHOUT; fr: array [0..159] of word; begin case e.etype of IAX_EVENT_HANGUP: begin IAXDebug('HANGUP'); OutBuf.Stop; end; IAX_EVENT_REJECT: IAXDebug('Reject'); IAX_EVENT_ACCEPT: begin IAXDebug('ACCEPT'); OutBuf.Start; end; IAX_EVENT_ANSWER: IAXDebug('ANSWER'); IAX_EVENT_VOICE: begin case (e.event.voice.Format) of AST_FORMAT_GSM: begin if (e.event.voice.datalen mod 33)<>0 then begin ShowMessage('Weird gsm frame, not a multiple of 33.'); Exit; end; if not Assigned(gsm) then gsm := gsm_create(); len := 0; while (len < e.event.voice.datalen) do begin if (gsm_decode(gsm, e.event.voice.data, @fr)<>0) then begin ShowMessage('Bad GSM data'); Exit; end else // its an audio packet to be output to user begin OutBuf.WriteBlock(@fr); end; Inc(len,33); end; end else ShowMessage(Format('Don''t know how to handle that format %d\n', [e.event.voice.Format])); end; end; else IAXDebug('Event '+IntToStr(e.etype)); end; end; constructor TIAXThread.Create(Handler: TIAXEvent); begin EventHandler := Handler; Priority := tpTimeCritical; inherited Create(false); end; procedure TIAXThread.Execute; begin Debug('ThreadStarted'); while True do begin iax_time_to_next_event; event:=iax_get_event(1); if (event<>nil) then begin if Assigned(EventHandler) then begin Synchronize(HandleEvent); iax_event_free(event); end; end; end; end; procedure TIAXThread.HandleEvent; begin EventHandler(Event^); end; procedure TFrmClientMain.Button3Click(Sender: TObject); var CallerID: array [0..255] of char; CallTo : array [0..255] of Char; begin StrPCopy(CallerID,'Caller ID'); StrPCopy(CallTo,'192.168.0.10'); Session := iax_session_new; iax_call(session, CallerId, CallTo, 'de', 0); end; procedure TFrmClientMain.OnData(Sender: TObject); var Item: Pointer; fr: array [0..32] of char; begin // lblwp.Caption := IntToStr(OutBuf.WriteBufPos); // lblpp.Caption := IntToStr(OutBuf.PlayBufPos); // lblbt.Caption := IntToStr(OutBuf.BufferedTime); // Form1.Memo1.Items.Insert(0,IntToStr(OutBuf.BlocksLoad)); repeat Item := OutBuf.ReadBlock; if Assigned(Item) then begin if not Assigned(gsm2) then gsm2 := gsm_create(); gsm_encode(gsm2, Item, @fr); iax_send_voice( Session, AST_FORMAT_GSM, fr,33); end; until not Assigned(item); Bar.Value := Outbuf.OutputLevel; Bar1.Value := Outbuf.InputLevel; // lblfr.Caption := IntToStr(OutBuf.Frequency); // lblps.Caption := IntToStr(OutBuf.PlayedSize); // lblws.Caption := IntToStr(OutBuf.WritedSize); { if OutBuf.PlayedSize history then history := Result else history := Result/4 + 3.0 * history/4.0; if history > 1 then history := 1; Result := history * 3; if Result > 1.0 then Result := 1.0; end; procedure TFrmClientMain.BrowserAdressKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key = VK_RETURN then WebBrowser.Navigate(BrowserAdress.Text); end; procedure TFrmClientMain.BrsForwardClick(Sender: TObject); begin WebBrowser.GoForward; end; procedure TFrmClientMain.BrsHomeClick(Sender: TObject); begin WebBrowser.GoHome; end; procedure TFrmClientMain.BrsStopClick(Sender: TObject); begin WebBrowser.Stop; end; procedure TFrmClientMain.BrsBackClick(Sender: TObject); begin WebBrowser.GoBack; end; end.