Link to home
Start Free TrialLog in
Avatar of IUFITS
IUFITS

asked on

TAPI Dial/Send .WAV or SAPI speak command

Alright, I've read lots of questions on here, and lots of white papers over the Web but I cannot find one good example of integrating the two of these things together.  All answers are spoken in theory which I'm having a hard time tieing together.  I can play a .WAV file, I can use the SAPI to speak, I can dial a phone number multiple ways (using MSCOMM, TAPI and actually opening a directory connection to the COM port and sending the ATDT command) but I can't marry the two together.

The only code snippet that I found promising used SPVOICE and SpObjectToken but alas failed on the voice output... This was that snippet:

    Dim v As SpVoice
    Dim t As SpObjectToken
   
   
    'create voice object
    Set v = New SpVoice
   
    'enumerate available audio output devices and set the voice object to the Voice modem
    For Each t In v.GetAudioOutputs
        'I just look for the phrase "odem" to locate the voice modem, but you could use other means
        If InStr(1, t.GetDescription, "odem") Then
            'prevent changing modem's format to default SpVoice format
            v.AllowAudioOutputFormatChangesOnNextSet = False
            Set v.AudioOutput = t
            Exit For
        End If
    Next
     
    'set format of voice object to that compatible with voice modem
    v.AllowAudioOutputFormatChangesOnNextSet = False
    v.AudioOutputStream.Format.Type = SAFT8kHz16BitMono
    'this extra step is needed to force the voice object to recognize the new Format
    Set v.AudioOutputStream = v.AudioOutputStream
   
    'Now, you use TAPI to answer or place the call using the voice modem, and
    'once connected, the simple Speak method of the voice object will talk to
    'the other party, e.g.:

    ' fails on this line
    v.Speak "Hello, this is a test to see if this is working."    ', SVSFlagsAsync

I also tried this but my noob status with getting device ID's halted my progress here... I felt this one was promising:

    Dim MMSysAudioOut As ISpeechMMSysAudio
    Dim voiceobj As SpVoice
    Set voiceobj = New SpVoice

           'Create SpMMAudioOut object
    Set MMSysAudioOut = New SpMMAudioOut
       
    'Get the device identifier and set it to audio out
    '  the lineGetID doesn't work here, can't get the call correct
    '
    MMSysAudioOut.DeviceId = lineGetID(0, 0, 0, 0, "", "wave/out")
       
    'Find the supported wav format and set it to audio out object
    MMSysAudioOut.Format.Type = SAFT8kHz16BitMono
   
    'Prevent format changes
    voiceobj.AllowAudioOutputFormatChangesOnNextSet = False
   
    'Set the object as the audio output
    Set voiceobj.AudioOutputStream = MMSysAudioOut
    voiceobj.Speak "test"


I would greatly appreciate any specific coding snippets or help (aside from links to white papers) on how to dial, then send either a .WAV or the SAPI voice (preferably the SAPI voice).

Avatar of codeconqueror
codeconqueror

Here's how I do it in my project:

I have a form called frmLine, on it I have 2 objects declared:

Public WithEvents Voice As SpeechLib.SpVoice
Public VoiceStream As SpeechLib.SpMMAudioOut

Then I use it here:
<CODE SNIPPET>
Set frmLine.VoiceStream = New SpeechLib.SpMMAudioOut
If lLineWaveOut >= 0 Then
    frmLine.VoiceStream.DeviceId = lLineWaveOut
Else
    frmLine.VoiceStream.DeviceId = frmLine.amtpLine.LineWaveOutID
End If
frmLine.Voice.AllowAudioOutputFormatChangesOnNextSet = False
frmLine.VoiceStream.Format.Type = lapLineAudioProperties.OutputQuality
Set frmLine.Voice.AudioOutputStream = frmLine.VoiceStream
If LenB(sTTSVoice) > 0 Then
    Set frmLine.Voice.Voice = frmLine.Voice.GetVoices.Item(GetVoiceIndex(sTTSVoice))
Else
    Set frmLine.Voice.Voice = frmLine.Voice.GetVoices.Item(0)
End If
frmLine.Voice.Rate = lSpeechRate
frmLine.Voice.Volume = lVolume
frmLine.Voice.AlertBoundary = SVEPhoneme
frmLine.Voice.Speak sTextToSpeak, SVSFIsXML + SVSFPurgeBeforeSpeak + SVSFlagsAsync
</CODE SNIPPET>
This is done after the call has been established.  For me, the client calls into the system so I just react when I answer the call.  In your case, just use this code after you have dialed and established that someone has answered.
By default:

lapLineAudioProperties.OutputQuality = SAFT8kHz16BitMono
Avatar of IUFITS

ASKER

Where are you getting the lLineWaveOut here?  Currently, after I dial-up and connect whenever I get it to say something with the voice, it comes through the speakers and not the modem.  I'm assume that's a fluke since lLineWaveOut's undefined value of 0 must be the speaker setting.

If lLineWaveOut >= 0 Then
    frmLine.VoiceStream.DeviceId = lLineWaveOut
Else
    frmLine.VoiceStream.DeviceId = frmLine.amtpLine.LineWaveOutID
End If
It's the index of the enumerated speech devices.  In my program I let the user select which device to use as output.  Here's an example of how you enumerate them:

<CODE SNIPPET>
Dim T As SpeechLib.SpObjectToken
Dim sAudio As String
Set T = Voice.AudioOutput
sCurrentAudio = T.GetDescription
For Each T In Voice.GetAudioOutputs
    sAudio = T.GetDescription
    If sAudio = sCurrentAudio Then
        sAudio = sAudio & "  (Current)  "
    End If
    cmbAudioDevices.AddItem sAudio
Next
</CODE SNIPPET>
I use the amTapiPro and amWavePro from Allen Martin for all the TAPI, I didn't feel like writing my own TAPI library, theirs is really complete, really easy, and not too badly priced (www.allen-martin-inc.com).  That's the type of object that amtpLine is.  It makes writing a TAPI based app really easy.
If you download and install the trial version of amTAPI and amWave, you can use my slapped together sample testing application so you can see how a lot of it is done.

http://www.securitysoftware.com/Downloads/hidden/codeconqueror/ee/IUFITS/TAPI_Tester_AMCtrls.exe

Let me know when you've downloaded the file so I can remove it from our server.  :)

The code is a just slapped together, it's just a tester application so don't expect to see the prettiest, most professional code in there, it's a little sloppy.  ;)
It's a self-extracting, virus scanned file so don't be scared.  ;)
Avatar of IUFITS

ASKER

Done.  ;)
Avatar of IUFITS

ASKER

I'm going to run this when I get home also, I noticed that when I remoted desktop the number of devices I have changed and the only output device available was "Microsoft RDP" which I can only assume is a special remote desktop audio setting.
Correct.  You need to run this via the local machine, not RDP'd.  MS does some hardware mapping stuff that will screw with it.  Let me know how it goes.  :)
Avatar of IUFITS

ASKER

Alright, I used your project but replaced the dial section with my dialing code since I didn't have the controls installed on this machine that you used.  I still receive this error once I change to the modem input instead of the sound blaster card:

Method 'Type' obj object 'ISpeechAudioFormat' failed  Error Number -2147201021


I used a seperate VB answering machine project to send a .WAV file over the phone line so I know the modem is at least capable (which I was beginning to doubt).  Any ideas on the above?  The above was setting the format type...  in another project I was working on I could set the type but got a failed error on the actual speak section.

Going through the sound card, the speaking works fine.

Thoughts?
On what line does this error occur?  Can you post the code snippet causing the error?  Also, make sure that your modem supports voice.  If it's just a regular data/fax modem, it won't work.  The best 2 I've found are the Zoom 2949 and the USR 5610B, but NOT 5610A.  They work really well in TAPI/SAPI applications unless you're willing to spend 500 or more for a Dialogic D/4 PCI or Brooktrout board.
Avatar of IUFITS

ASKER

The modem is a Conexant D850 56K V.9x DFVc Modem.  I was under the assumption it had telephony capabilities but I could be wrong.  It is capable of sending the sound from a .WAV file over the phone (I've got an answering machine VB application that does it).

1.)  Am I wrong in assuming that if it can send the sound of a .WAV file that it should be able to do this also?

2.)  Here is the line it failed on in the "Hear It" button with the "Modem #0 Line Playback" selected:

VoiceStream.Format.Type = SAFT11kHz8BitMono
Avatar of IUFITS

ASKER

If I can't get the SAPI to actually speak over the modem, I guess I could use it to write out a .WAV file and then send that .WAV file over the phone line... would prefer not to do it that way but I guess it's not that bad of a work around.
ASKER CERTIFIED SOLUTION
Avatar of codeconqueror
codeconqueror

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of IUFITS

ASKER

I found the following answering machine code also which uses TAPI and has a ton of stuff in it.  Thought I'd share the link since it was a huge help along with the advice here:

http://www.geocities.com/sfrare/index.html
Avatar of IUFITS

ASKER

Thanks for the help codeconqueror!