2025-04-27 07:49:33 -04:00

144 lines
5.7 KiB
Plaintext

___________________________________________________
Copyright (C) 1999 Microsoft Corporation. All rights reserved.
___________________________________________________
TAPI 3.0 TAPIRecv Media Streaming Terminal Sample Application
Overview:
The purpose of TAPIRecv sample is to illustrate the use of Media Streaming
Terminal (MST) for retrieving audio data from a TAPI media stream.
TAPIRecv is the receiving side of the call. It accepts a call and uses the MST
to get incoming audio data, which it saves to a local audio file,
recording.wav. When the remote side disconnects the call, the application exits.
TAPIRecv is a command line application.
To run the sample, run TAPIRecv.exe. There are no command line arguments. When
started, the application begins waiting for an incoming call.
The applicarion produces extensive logging to the console window.
Note that while detailed logging is useful for observing sequence of events and
monitoring state of the application, on a slow machine it can impair
performance to the point where it affects quality of the recorded sound.
Minimizing the console window while the application is running, or removing
logging calls from the code will solve this problem.
The application can be terminated by pressing ctrl+break, closing the
application's window, logging off, or shutting down the system.
Refer to the TAPISend sample for information on using the Media Streaming
Terminal for introducing data into a TAPI media stream.
Building the Sample
To build the sample, set the Platform SDK build environment, then run nmake
from the sample's directory. This will build TAPIRecv.exe.
Asynchronous Event Processing
The TAPIRecv performs asynchronous event processing. It subscribes to receive
TAPI notifications by
- registering CTAPIEventNotification (which implements
ITTAPIEventNotification interface)
- calling ITTAPI::put_EventFilter()
- calling ITTAPI::RegisterCallNotifications for listening addresses
When TAPI has an event to be processed by the application, it calls
ITTAPIEventNotification::Event() on the registered callback object and passes
in event data. It is recommended that this call returns as quickly as
possible, so our implementation of the interface does nothing more than posting
the event to worker thread (implemented by CWorkerThread) for asynchronous
processing.
When the worker thread receives the message, it passes it along to
OnTapiEvent(), the event handler where all event processing is happening.
Application Flow
On startup, TAPIRecv starts listening on all addresses available that support
audio and Media Streaming Terminal.
When the application is notified of an incoming call (by a TE_CALLNOTIFICATION
message), the event handler verifies that there is not already an active call,
and that the application is the owner of the call. If so, we keep a pointer
to the call's ITBasicCallControl interface. From now on this is assumed to be
the currently active call.
Once we have an active call, we are ready to receive notifications of the
call's state (TE_CALLSTATE). If the call is in the offering state
(CS_OFFERING), before answering the call, we create a rendering Media
Streaming Terminal and select it on one of the call's incoming audio streams.
When the audio stream becomes active (and the application receives
CME_STREAM_ACTIVE TE_CALLMEDIA event), the event handler starts
recording incoming audio data into a file. See "Writing Media Streaming
Terminal Data to a file" section of this document for more details.
Writing stream to a file is a "blocking" operation, and it does not return
until the call disconnects. Since this sample performs recording on the the
event handler's thread, messages will queued but not processed until recording
stops.
Some time after recording is completed, event handler will receive
CS_DISCONNECTED call state event. At this time we disconnect the call and
signal the main thread.
The main thread wakes up, performs clean up, and the application exits.
Writing Media Streaming Terminal Data to a File
Function WriteStreamToFile contains the logic for extracting audio data from
the media streaming terminal and writing it out to a file.
The Media Streaming Terminal has a number of samples of certain sizes
(configured through the terminal's ITAllocatorProperties interface).
The application repeatedly calls AllocateSample() on the terminal's
IMediaStream interface to get the terminal's samples (AllocateStreamSamples),
and associates each sample with an event by passing the event to the sample's
IStreamSample::Update() (see AssociateEventsWithSamples).
An event is signaled when the corresponding sample is filled with data by the
Media Streaming Terminal and is ready for the application to be processed
(written to a file). A call to IStreamSample::CompletionStatus assures that the
sample has valid data and is ready to be used.
The sample's data (accessed via sample's IMemoryData interface, see
WriteSampleToFile) is written to a file.
When the application is finished with the sample, it returns the sample to the
MST and asks it to be notified when the sample gets new portion of data for the
application to process. This is done by calling Update() on the sample's
IStreamSample interface and passing it the event to be signaled on completion.
At this point the applications goes back to waiting for the next sample to be
completed.
Note that samples are aborted and IStreamSample::CompletionStatus() returns
E_ABORT when call disconnects. TAPIRecv uses this error code as an indirect
sign that the connection was broken and it is time to stop streaming.