Welcome to
Steven A. Frare's
GeoCities Web Page

 

 Download the MSJ Voice Code

Home

MSJ Voice

In August 1996 Charles Mirho authored the article "To Learn About the Voice Modem Extensions for Windows 95, Press 1 Now!" for Microsoft Systems Journal.  Since then time has eroded it a bit, so I have made a few corrections, documented them here and re-archived the sample.  I  found the sample pretty valuable in learning TAPI but even with the fixes it is still just a sample, not a robust application.

In total there are 21 changes from the original source, though not all changes were needed to get the sample working properly again.  Until the release of Windows 2000 it compiled and ran, though not well.  With the inclusion of TAPI 3.0 and H.323 in Windows 2000 that pretty much broke it all together.  The new media types offered confused the application enough that it shut down almost immediately in telephonyInitialize.

To fix it I first applied the two changes mentioned in Bruce Pennypacker's Unofficial TAPI FAQ.  The first in Comdial.c in the TTYWndProc the two lines:

mytapi.dwWaveInID = mylineGetWaveID(LINECALLSELECT_LINE, "wave/in");
recordMessage (mytapi.dwWaveInID);

were commented out.  The second in mytapi_.c -> LineCallBackProc two debugging lines needed to be commented out.

mytapi.dwWaveOutID = 0;
mytapi.dwWaveInID = 0;

In comdial.h the function prototype playSound was changed to match the function in sound.c as follows:

From:
HWAVE playSound(DWORD, char *, HWND);
To:
HWAVEOUT playSound(DWORD, char *, HWND);

With the above changes, and deleting the Tapi32.lib that was included in the original archive it would now compile. 

The following are the changes I made to mytapi_.c

In Windows 2000 it exited almost immediately in telephonyInitialize.The dwLine member of the mytapi structure was not getting set properly so I set it just before the call to mylineGetDevCaps since it is used in that function.  Now it would at least show the main window.  However if your TAPI device was after the H.323 or IPCONF TAPI lines, the sample would attempt to use those lines instead of a voice card.  I am unsure of the proper way to get around that so I hacked in another check of the pLineDevCaps structure:

mytapi.pLinedevcaps->dwMonitorToneMaxNumFreq

With my voice cards this value is always greater than 0, with the H.323 stuff it was always 0.  This will probably fail in time, but it works for now.

In mylineGetWaveID and LineCallBackProc I changed two NULL's to 0 to avoid type conversion warnings, so now the sample should compile with MSVC at warning level 3 and produce no warnings.

Also changed in the LineCallBackProc:

Modified the handling of the LINECALLSTATE_CONNECTED message so that lineMonitorDigits was called before playSound.  The order change was neccassary for my Dialogic 160/SC as the other way produced an error from lineMonitorDigits stating that the device was unavailable.  It worked without the re-ordering with my Creative Labs Modem Blaster (DI5630).

Added the LINECALLSTATE_DISCONNECTED case and the following code to make sure the call was dropped and the wave devices freed.

waveOutClose(mytapi.h_waveout) ;
waveInReset(mytapi.h_wavein) ;
waveInClose(mytapi.h_wavein) ;
lineDrop (mytapi.hCall, NULL, 0) ;
lineDeallocateCall(mytapi.hCall) ;
mytapi.hCall = 0 ;

In LINEDEVSTATE_RINGING I changed the ring count check from == to >= since it is possible to miss a ring.

In this sample you press '2' to record a message.  After pressing two Record.wav is played then the sample is supposed to record your message, however the call to record the message came before the prompt was finished and so it would fail to open the device if you weren't using a Full-Duplex TSP and voice card.  Since Unimodem/V and Unimodem 5 are both Half-Duplex this would always fail with standard voice cards.  This was fixed by moving the recordMessage call to the COMDIAL.C MM_WOM_DONE message.

This sample also provides for getting your messages over the phone by pressing '1' then the entering the password '6727'.  This also failed since in the case PLAYSUBSTATE_PASSWORD3 the mytapi.nPlayCnt was set to start at zero instead of one.  That is the final change to mytapi_.c .

In comdial.c the following changes were made:

In TTYWndProc for the MM_WOM_DONE message a check was added to see if mytapi.iPlayState == PLAYSTATE_RECORD and if so to call the recordMessage function.  Also the mytapi.h_wavein member was set so that the wave in device could be closed properly in the MM_WIM_DATA message.

No matter which operating system I ran under the application used 100% of the C.P.U. and failed to show error dialogs.  This was caused by improperly handling the WM_PAINT message so I added code to the PaintTTY function as follows:

PAINTSTRUCT ps;
HDC hdc;
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);

That is all the fixes for comdial.c .

For sound.c the only functional change made was in the saveMessage function.  The CreateFile function would fail if the file didn't already exist so the dwCreationDisposition flag was changed from OPEN_EXISTING to CREATE_ALWAYS.  Other than that I simply added WAVE_MAPPED flags to the appropriate wavein/out calls and changed the CODEC from PCM 16bit to u-Law 8bit since that is the only format that works on all my voice cards, and it is the recommended format for TAPI compatibility as per Microsoft Knowledge Base Article ID: Q142745.

That's it!  I have included the four wave files required to run the application in this archive (only added 8k to the size) to get you started until you record your own.  Thanks to http://www.elantts.com/ for providing the wave files.  Maybe the sample will be good for another couple of years now...  With TAPI 3.0 it is surely on borrowed time.

 

[email protected]

 

Hosted by www.Geocities.ws

1