Use voice modem to implement telephone on demand and message function
Author: Chen Province
It hasn't updated the website for some time. I have been very busy recently, so the progress of the book is slow, I only write more than 10-page design mode related content in two weeks. I hope that the progress can be accelerated in the next few weeks and quickly finish. In the past two days, I was named the Borland Delphi product expert, plus the SARS situation in Beijing in the past two days, and it was very happy. For this purpose, an article written for a long time, share my happiness with you.
At the time of last year, I have been worried about what a gift for my girlfriend. I don't know what kind of gift can give her a surprise colleague. expensive. At this time, one of my good friends had a idea, saying that it is better to say the phone songs, it is more special. However, if it is passed through the radio song, then tell her if it is listening, there is no unexpected effect. Just when there is no good way, when I joined it on the Delphi Forum, the question raised by a person suddenly inspired me, the problem is about the record function of the voice message and the phone button. I suddenly wants why I can't write a program to control the phone, and then make a call to my girlfriend, let her call, when the phone is connected, my program will play a good time, prompting her to select by phone button. Song, and can provide a message. The idea must be sure, I have to check the information in this area, and my friends will tell you to implement these functions through the speech card, but the voice card is more expensive, and I bought it, I will not use it in addition to once. It is a bit a waste, and later, the netizen ccedent mentioned that the ASYNC Professional control of Turbopower has provided a set of TELEPHONE API-based controls to implement similar functions via voice MODEM. This seems to be much lower, my modem is just voice modem, so I downloaded Async Professional (Official Website www.turbower.com) Test, and there is different backspered, cheap and simple.
Start Design Let's take a look at how to use this set of controls to implement voice features, for our app, just need to use two TAPI controls TapdComport and TAPDTapidevice, where the TAPDComPort control is a serial communication control because MODEM is With the serial port, the serial communication control is required to control. TAPDTAPIDEVICE is a core control for providing voice features. First, create a program project, place a TAPDCOMPORT control on the form, set its properties to autoopen: = false; Tapimode = TMON; here Tapimode is set to TMON indicate that TapdComport will control the TAPDTAPIDEVICE. Control associated with it. Control, and will AutoOpen is set to false because the open and off of the serial port can now be controlled by TAPI. Then, place a TAPDTAPIDEVICE control on the form to set its Comport property as the front TAPDCOMPORT control. Set the answeronring attribute 1, indicating that the first ring is started to control the response to the phone by the program. Set ShowTapidevices To True Indicates that a dialog box for selecting a TAPI device is displayed when the selectDevice method of the control is called. The ShowPorts property is false, indicating that the call SelectDevice method does not display a list of serial ports. Next, this program mainly uses a finite state machine to control the process, let's define the enumeration status.
TypetCurrentState = (csidle, cswaiting, csconnected, csplaying, csrecording, sdisconnected); where the CSIdle status indicates that the phone is idle and is waiting for access. CSWAITING means that the phone is in the program control, waiting for access, if there is a phone to enter, the program will automatically answer. CSConnected indicates that the phone is inserted, in the connection status, CSRecording is used to indicate the current record phone message status. CSDisConnected means that the current connection is hung up.
The initialization of the program is that the ONCREATE handler of the program is very simple, it is set to set the current state csder, and set the TRIMSeconds attribute of the APDTapidevice control to 5, indicating that if there is 5 seconds of silence when there is a 5 second silent time when it is recorded. Procedure tfrmmain.formcreate (sender: Tobject); VARTELEINI: TiniFile; begincurrentState: = csder; APDTAPIDEVICE.TRIMSECONDS: = 5; // When the record is 5 seconds, it is hung up
CommandList: = TSTRINGLIST.CREATE;
Teleini: = tinifile.create (extramstr (0)) 'Tele.ini'); Teleini.ReadsectionValues ('Commands', CommandList); Teleini.Free; WindowsTate: = WSMaximized; END; then will define in Tele The voice list file directory to be played in the .ini file is loaded into the CommandList. Example of Tele.ini is as follows: [Commands] 1 # = 1.wav2 # = 2.wav3 # = 3.wav123 # = E: / Program files / APRO / EXAMPLES / Beep.wav where 1 #, indicating that when the user presses 1 and # 号, after the button, the program plays its corresponding 1.wav file. Next, we have to provide two commands, one is a monitor phone, one is a hanging phone, first add a TListBox on the form, name LBSysInfo, then add two menu items, and write, write, write Action's Onexecute Event Processing Function:
// Monitor phone procedure tfrmmain.Actionanswerexecute (sender: TOBJECT); beginTryApdtapideVice.enableVoice: = true; ExceptApplication.MessageBox ('Current device does not support voice extension', 'error', MB_OK); END;
If APDTapidevice.enablevoice damiAnpdtapide.com.autoanswer; lbsysinfo.items.add ('answer: answering each other phone'); currentState: = cswaiting;
Because not all modem supports voice function, it should be judged before the monitoring phone access should first determine the setttapidevice.enableVoice: = true; if an exception occurs, indicating that Modem does not support voice functions. If supported, call the Autoanswer method Wait for access at the same time to set the status as cswaiting, and write the log in the list box.
// Hang up the phone procedure tfrmmain.Actioncancelexecute (sender: TOBIECT); BeginApdtapidevice.cancelcall; lbsysinfo.items.add ('Cancel: Hanging each other); currentState: = csidle; end; hanging up the phone is simple, As long as the CancelCall method of the Tapdtapidevice control is called, you will also need to set the current state CSIDLE.
When there are multiple TAPI devices in the system, we can also choose which one to answer the phone, the following is the method of selecting the device:
// Select the device procedure tfrmmain.actionSeldeXecute (Sender: TOBJECT); beginapdtapidevice.selection; apcture;
Event Driver The Telephone API is an event-driven, so the core function needs to be implemented in the event handler, first to see the TAPDTAPIDEVICE of the program to handle the ONCONNECT event handler code:
procedure TFrmMain.ApdTapiDeviceTapiConnect (Sender: TObject); beginCurrentState: = csConnected; LBSysInfo.Items.Add ( 'Connect: Success connector'); ApdTapiDevice.PlayWaveFile ( 'Greeting.wav'); // prompt voice playback LBSysInfo.Items. Add ('Connect: Playing Greeting.wav'); END;
When the user is integrated into the monitored version, the program should play a prompt voice after the user access, prompting the user to sing or leave a message according to the different function keys. The program sets the current state to csconnected, then call the APDTapidevice PlayWaveFile method to play the prompt audio file. It should be noted that the format of different modem supports playback wave files is different, but they all support PCM 8-bit mono wave files, but this type of wave file is very poor, used to play song effect is really bad However, most voice modem supports better wave vendial format, but is usually a PCM format, such as my Lucent Voice Modem, supports playback of PCM 16-bit mono wave files. The song transformation is very simple to wave files. I use WINAMP to convert MP3 files directly into 44-bit wave files (usually 40-70m size) through WinAmp itself, and then use a goldwave Software (I forgot to download it) to 16-bit mono wave files (usually 4-7m size). As for the prompt voice, I will use the recorder program that comes with Windows through the microphone recorded. When the user listened to the prompt voice, they will call to sing or leave a message, and the user's button will inspire TapdTapidevice's OntTMF event, we can process the button in this event. Here is the processing code:
procedure TFrmMain.ApdTapiDeviceTapiDTMF (CP: TObject; Digit: Char; ErrorCode: Integer); beginif (Digit = '') or (Digit = '') thenExit; LBSysInfo.Items.Add ( 'dtmf: key =' Digit); CurrentCommand: = CurrentCommand Digit; {simple state machine} if Digit = '#' thenbeginif CurrentCommand = '* #' thenbeginCurrentCommand: = ''; ApdTapiDevice.MaxMessageLength: = 30; // longest recording time of 30 seconds ApdTapiDevice.InterruptWave: = False; // Press the key to interrupt the prompt voice to play APDTAPIDEVICE.PLAYWAVEFILE ('Recordhint.wav'); // Play Recording Tips Voice CURRENTSTATE: = CSRecording; exit;
if CommandList.values [CurrentCommand] <> '' thenbeginApdTapiDevice.PlayWaveFile (CommandList.values [CurrentCommand]); LBSysInfo.Items.Add (Format ( '% s% s being played% s', [ApdTapiDevice.calleridname, apdtapidevice.callerid CommandList.Values [currentCommand]]); endelsebegin // Play error prompt voice, and require the user to re-enter the command APDTapide.com; lbsysinfo.ientMs.Add (Format ('% s% s input The wrong number ', [APDTAPIDEVICE.CALLERIDNAME, APDTAPIDEVICE.CALLERID]); END; // The reset command is empty currentcommand: ='; end; end;
The program determines the button (the button corresponds to the DIGIT parameter). If the input is the '* #' button, enter the recording function, play the prompt voice before the recording, can tell the user to leave a message length of 30 seconds, then set the current state as CSrecording, some people may ask, did not see the code used to record, this is actually in another incident, and we will talk later. Take another part of the song, the same, according to the combination of the button, look up the matching song in the string list of the CommandList, if there is a corresponding song play, otherwise play the error prompt voice, prompt the user to re-enter the command, then Press the key to wait for re-enter. Also, pay attention to the event's logging I recorded the properties of APDTapidevice.calleridName and Callerid, which correspond to the number of the number of calls, but this feature is only valid for the phone number that has opened the caller ID function, through the input The processing of telephone numbers information, we can provide some additional features, but this is the topic. The previous referred to the recording feature we did not have a message in the button processing event, which is mainly because we have to ensure that the message prompts the voice not being interrupted (set InterruptWave: = false), so put the message recording function on the TAPDTAPIDEVICE onWavenotify In the event, this event can prompt the status of the wave file playback, such as playback end and recording the sound data preparation status, in this program, we need to start recording a message after prompting voice playback, and preparing in message sound data Ok, save it to disk files. Below is the process of processing procedures:
procedure TFrmMain.ApdTapiDeviceTapiWaveNotify (CP: TObject; Msg: TWaveMessage); varTimeStr: string; FileName: string; begin // never do time-consuming operation in case the outer case Msg ofwaPlayOpen: LBSysInfo.Items.Add ( 'wavnotify: Play Starts '); waPlayDone: beginLBSysInfo.Items.Add (' wavnotify: play end '); if CurrentState = csRecording thenbegintry // wait state wave device wsIdle start recording again while ApdTapiDevice.WaveState <> wsIdle doApplication.ProcessMessages; ApdTapiDevice.InterruptWave: = True; ApdTapiDevice.StartWaveRecord; LBSysInfo.Items.Add ( 'dtmf: recording the success'); exceptLBSysInfo.Items.Add (' dtmf: recording fail '); end; end; end; waPlayClose: LBSysInfo.Items.Add (' wavnotify: play off '); waRecordOpen: LBSysInfo.Items.Add (' wavnotify: start recording '); waDataReady: beginLBSysInfo.Items.Add (' wavnotify: data preparation '); TimeSeparator: =' - '; FileName: = DateTimeToStr (Now) '.wav'; tryApdTapiDevice.SaveWaveFile (ExtractFilePath (ParamStr (0)) 'record /' FileName, True); LBSysInfo.Items.Add ( 'wavNotify: voice files' FileName); exceptLBSysInfo. Items.add ('Wavnotify: Save Sound File Failed'); End; End; WarecordClose: Beginlbsysinfo.items.Add ('WAVN OTIFY: Record the end '); currentState: = cswaiting; actioncancelexecute (nil); timer1.enabled: = true; end; end; end; The whole process is to judge the current sound status through a case statement, if waplaydone (play is over ) If the colleague CurrentStatus is CSRecording, call the StartWaveRecord method to record the sound. When the MSG is a WADATAREADY state, the recording data is already available, and the file name is generated according to the current time and saves the data as a wave file. And when the recording is over, we need to call ActionCanceLexecute (nil) to hang up the phone and set the status to cswaiting to wait for the next access, pay attention to the final, and we activate a TTIMER control. This TTIMER control time interval is set to 8 seconds, and its ONTIMER event code is as follows:
procedure TFrmMain.Timer1Timer (Sender: TObject); begintry // answering telephone ActionAnswerExecute (nil); CurrentState: = csWaiting; Timer1.Enabled: = False; exceptend; end; The reason for this is that, when a call hang up method CancelCall After that, the TAPI device takes 8 seconds to return to normal state. If Autoanswer is executed immediately, this method will fail to monitor phone access, so use TTIMER to control the time of recovery phone response.
Exception handle, if the program is very robust, repetitive answering calls, we must have a sudden hanging phone to handle the phone, and the user-disconnected event will stimulate the Ontapistatus event of the control. When the user hangs up the phone, if we want to do if The current recording, stop recording, if you play a song, hang up the phone, then set the TTIMER to take effect, re-enter the phone response status. Below is the code of the entire process:
procedure TFrmMain.ApdTapiDeviceTapiStatus (CP: TObject; First, Last: Boolean; Device, Message, Param1, Param2, Param3: Cardinal); beginif (Message = Line_CallState) thenbegincase Param1 ofLineCallState_Disconnected: beginLBSysInfo.Items.Add ( 'status: disconnected from remote modem '); if CurrentState = csRecording thenbeginApdTapiDevice.StopWaveRecord; Exit; end; CurrentState: = csDisconnected; ActionCancelExecute (nil); Timer1.Enabled: = True; end; end; end; end;
Further improvement When the recording is completed, we want to listen to the phone message, you can place an open file dialog box on the form, implement it with the following code:
procedure TFrmMain.ActionPlayRecExecute (Sender: TObject); varFrmPlay: TFrmPlayRec; beginDlgOpenRec.InitialDir: = ExtractFilePath (ParamStr (0)) 'Record /'; if DlgOpenRec.Execute then // play sound recording files ShellExecute (Application.Handle, PChar ('Open'), Pchar (Dlgopenrec.FileName), NIL, NIL, SW_SHOW; END;
In addition, if you are confident that your own voice is not poor than those singers, you can record your own songs, then play to your girlfriend or friend, maybe the effect is better :). Finally, what I want to say is that the features that the Telephone API can provide more than those mentioned in this article, and interests of interest can be further referred to the relevant information.
Finally, what is going to say is that Turbo Power has no longer develops Async Pro, which puts all the sourceforge shares on the SourceForge, and everyone can download it on the SourceForge.