⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tapisend.cpp

📁 tapi3.0实现的数据发送程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:

/*

Copyright (c) 1999  Microsoft Corporation


Module Name:

    TAPISend.cpp


Abstract:

    This sample illustrates use of Media Streaming Terminal for sending audio.

    The application makes a TAPI call to the address specified in the command 
    line and uses Media Streaming Terminal to send the media content of a wav 
    file, also specified in the command line, to the remote machibe.
 
*/


#include "common.h"
#include "avifilereader.h"


//
// global TAPI object
//

ITTAPI *g_pTapi = NULL;


//
// a global flag, set true to request stop streaming
//

BOOL g_bExitRequested = FALSE;


//
// possible address types strings and corresponding LINEADDRESSTYPE_ constants
//

char *g_szAddressTypes[] = 
            {"PHONENUMBER", "CONFERENCE", "EMAIL", "MACHINE", "IP"};


long g_nAddressTypeConstants[] = 
            { LINEADDRESSTYPE_PHONENUMBER,
              LINEADDRESSTYPE_SDP,
              LINEADDRESSTYPE_EMAILNAME,
              LINEADDRESSTYPE_DOMAINNAME,
              LINEADDRESSTYPE_IPADDRESS };

//
// number of different address types
//

const UINT g_nNumberOfAddressTypes = 
                    sizeof(g_szAddressTypes)/sizeof(g_szAddressTypes[0]);


///////////////////////////////////////////////////////////////////////////////
// 
// LogMessage
//
//
// log a message using printf
//
///////////////////////////////////////////////////////////////////////////////

void LogMessage(IN CHAR *pszFormat, ... )
{
    
    //
    // output buffer -- note: hardcoded limit
    //

    static const BUFFER_SIZE = 1280;

    char szBuffer[BUFFER_SIZE]; 


    //
    // get current time
    //

    SYSTEMTIME SystemTime;

    GetLocalTime(&SystemTime);

    
    //
    // format thread id and time
    //

    StringCbPrintf( szBuffer, BUFFER_SIZE, "[%lx]:[%02u:%02u:%02u.%03u]::",
             GetCurrentThreadId(),
             SystemTime.wHour,
             SystemTime.wMinute,
             SystemTime.wSecond,
             SystemTime.wMilliseconds);


    size_t iStringLength = 0;

    HRESULT hr = StringCbLength(szBuffer, BUFFER_SIZE, &iStringLength);

    if (FAILED(hr))
    {
        // either this code is wrong, or someone else in the process corrupted 
        // our memory.
        return;
    }


    //
    // get the actual message
    //

    va_list vaArguments;

    va_start(vaArguments, pszFormat);


    size_t iBytesLeft = BUFFER_SIZE - iStringLength;


    //
    // not checking the return code of this function. even if it fails, we will
    // have a null-terminated string that we will be able to log.
    //

    StringCbVPrintf( &(szBuffer[iStringLength]), iBytesLeft, pszFormat, vaArguments);

    va_end(vaArguments);


    //
    // how big is the string now, and how many bytes do we have left?
    //

    hr = StringCbLength(szBuffer, BUFFER_SIZE, &iStringLength);

    if (FAILED(hr))
    {
        // either this code is wrong, or someone else in the process corrupted 
        // our memory.
        return;
    }

    iBytesLeft = BUFFER_SIZE - iStringLength;

    //
    // append a carriage return to the string. ignore the result code, the 
    // result string will be null-terminated no matter what.
    //

    StringCbCat(szBuffer, iBytesLeft, "\n");


    //
    // log the buffer 
    //

    printf(szBuffer);
}


#define LogError LogMessage


///////////////////////////////////////////////////////////////////////////////
// 
// LogFormat
//
// use LogMessage to log wave format
//
///////////////////////////////////////////////////////////////////////////////

void LogFormat(IN WAVEFORMATEX *pWaveFormat)
{
    LogMessage("    Format: ");
    LogMessage("        tag: %u", pWaveFormat->wFormatTag);
    LogMessage("        channels: %u", pWaveFormat->nChannels);
    LogMessage("        samples/sec: %lu", pWaveFormat->nSamplesPerSec);
    LogMessage("        align: %u", pWaveFormat->nBlockAlign);
    LogMessage("        bits/sample: %u", pWaveFormat->wBitsPerSample);

}


///////////////////////////////////////////////////////////////////////////////
//
// AllocateMemory
//
// use win32 heap api to allocate memory on the application's heap
// and zero the allocated memory
//
///////////////////////////////////////////////////////////////////////////////

void *AllocateMemory(SIZE_T nMemorySize)
{
    

    //
    // use HeapAlloc to allocate and clear memory
    //

    return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nMemorySize);
}


///////////////////////////////////////////////////////////////////////////////
//
// FreeMemory
//
// use win32 heap api to free memory previously allocated on the application's
// heap
//
///////////////////////////////////////////////////////////////////////////////

void FreeMemory(void *pMemory)
{
    
    //
    // get size of the allocated memory
    //

    SIZE_T nMemorySize = HeapSize(GetProcessHeap(), 0, pMemory);

    if (-1 == nMemorySize)
    {
        LogError("FreeMemory: failed to get size of the memory block %p",
                 pMemory);

        //
        // don't exit -- try freeing anyway
        //

    }
    else
    {
        //
        // fill memory with 0xdd's before freeing, so it is easier to debug 
        // failures caused by using pointer to deallocated memory
        //
        
        if (0 != pMemory)
        {
            FillMemory(pMemory, nMemorySize, 0xdd);
        }

    }


    //
    // use HeapFree to free memory. use return code to log the result, but
    // do not return it to the caller
    //
    
    BOOL bFreeSuccess = HeapFree(GetProcessHeap(), 0, pMemory);

    if (FALSE == bFreeSuccess)
    {
        LogError("FreeMemory: HeapFree failed");

        //
        // if this assertion fires, it is likely there is a problem with the 
        // memory we are trying to deallocate. Was it allocated using heapalloc
        // and on the same heap? Is this a valid pointer?
        //

        _ASSERTE(FALSE);
    }

}


///////////////////////////////////////////////////////////////////////////////
// 
// InitializeTAPI()
//
// create and initialize the TAPI object
//
///////////////////////////////////////////////////////////////////////////////

HRESULT InitializeTAPI()
{
    
    HRESULT hr = E_FAIL;

    LogMessage("InitializeTAPI: started");
    
    
    //
    // create the TAPI object
    //

    hr = CoCreateInstance(
                          CLSID_TAPI,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          IID_ITTAPI,
                          (LPVOID *)&g_pTapi
                         );

    if (FAILED(hr))
    {
        LogError("InitializeTAPI: CoCreateInstance on TAPI failed");

        return hr;
    }

    
    //
    // must initialize tapi object before using it
    //
    
    LogMessage("InitializeTAPI: calling ITTAPI::Initialize()");

    hr = g_pTapi->Initialize();

    if (FAILED(hr))
    {
        LogError("InitializeTAPI: TAPI failed to initialize");

        g_pTapi->Release();
        g_pTapi = NULL;
        
        return hr;
    }

    
    //
    // setting event filtering -- this is required for synchronous 
    // ITBasicCallControl->Connect to work
    //
    
    LogMessage("InitializeTAPI: calling ITTAPI::put_EventFilter()");

    hr = g_pTapi->put_EventFilter(TE_CALLSTATE);

    if (FAILED(hr))
    {
        LogError("InitializeTAPI: TAPI failed to put event filtering");

        g_pTapi->Shutdown();

        g_pTapi->Release();
        g_pTapi = NULL;
        
        return hr;
    }


    
    LogMessage("InitializeTAPI: succeeded");
    
    return S_OK;
}



///////////////////////////////////////////////////////////////////////////////
// 
// ShutdownTAPI
//
// shutdown and release the tapi object
// 
///////////////////////////////////////////////////////////////////////////////

void ShutdownTAPI()
{
    
    LogMessage("ShutdownTAPI: started");


    if (NULL != g_pTapi)
    {
        
        g_pTapi->Shutdown();
        
        g_pTapi->Release();
        g_pTapi = NULL;
    }

    
    LogMessage("ShutdownTAPI: completed");

}


///////////////////////////////////////////////////////////////////////////////
//
//  IsValidAudioFile
//
// returns TRUE if the file specified by pszFileName 
// exists and is a valid audio file
//
///////////////////////////////////////////////////////////////////////////////

BOOL IsValidAudioFile(IN char *pszFileName)
{

    //
    // open the file
    //
    
    CAVIFileReader FileReader;

    HRESULT hr = FileReader.Initialize(pszFileName);


    //
    // see if it is a valid audio file
    //

    if ((FAILED(hr)) || !FileReader.IsValidAudioFile())
    {
        LogError("IsValidAudioFile: file [%s] does not exist or is not "
                 "a valid wav file", pszFileName);

        return FALSE;
    }
    else
    {
        LogMessage("IsValidAudioFile: file [%s] is a valid audio file", 
                    pszFileName);

        return TRUE;
    }

}


///////////////////////////////////////////////////////////////////////////////
//
// FindAddress
//
// find an address of the requested type that supports audio. returns S_OK 
// if address found, failure otherwise
//
///////////////////////////////////////////////////////////////////////////////

HRESULT FindAddress(IN  long nAddressType,
                    OUT ITAddress **ppAddress)
{

    HRESULT hr = E_FAIL;


    //
    // don't return garbage even if we fail
    //
    
    *ppAddress = NULL;


    //
    // enumerate all available addresses
    //

    IEnumAddress *pEnumAddress = NULL;
    
    hr = g_pTapi->EnumerateAddresses(&pEnumAddress);
    
    if (FAILED(hr))
    {
        LogError("FindAddress: Failed to enumerate addresses");

        return hr;
    }


    //
    // walk through the enumeration of addresses and look for those which are
    // of requested type and supports audio 
    //

    while (TRUE)
    {
        //        
        // get the next address from the enumeration
        // 

        ITAddress *pAddress = NULL;

        hr = pEnumAddress->Next( 1, &pAddress, NULL );

        if (S_OK != hr)
        {

            //
            // no more addresses
            //

            LogMessage("FindAddress: no more addresses");

            break;
        }
        

        //
        // we got an address. check its capabilities
        //
        
        ITAddressCapabilities *pAddressCaps = NULL;

        hr = pAddress->QueryInterface( IID_ITAddressCapabilities, 
                                       (void**)&pAddressCaps );

        if (FAILED(hr))
        {

            LogError("FindAddress: "
                     "Failed to QI address for address capabilities");

            //
            // just continue to the next address
            // 

            pAddress->Release();
            pAddress = NULL;

            continue;
        }


        //
        // is this the right address type?
        //
    
        long nType = 0;

        hr = pAddressCaps->get_AddressCapability(AC_ADDRESSTYPES, &nType);
 

        pAddressCaps->Release();
        pAddressCaps = NULL;


        if (FAILED(hr))
        {
            LogError("FindAddress: Failed to get_AddressCapability");

            pAddress->Release();
            pAddress = NULL;

            continue;
        }


        if (nType & nAddressType)
        {
            
            //
            // this address is of the right type. does it support audio?
            //

            ITMediaSupport *pMediaSupport = NULL;

            hr = pAddress->QueryInterface(IID_ITMediaSupport,
                                           (void **)&pMediaSupport);

            if (FAILED(hr))
            {

                //
                // continue to the next address
                //

                LogError("FindAddress: "
                         "failed to qi address for ITMediaSupport");

                pAddress->Release();
                pAddress = NULL;

                continue;
            }

            
            VARIANT_BOOL bAudioSupported = VARIANT_FALSE;

            hr = pMediaSupport->QueryMediaType(TAPIMEDIATYPE_AUDIO, 
                                               &bAudioSupported);

            pMediaSupport->Release();
            pMediaSupport = NULL;
            
            if (SUCCEEDED(hr) && (VARIANT_TRUE == bAudioSupported))
            {

                LogMessage("FindAddress: address found");


                //
                // log the name of this address
                //
                
                BSTR bstrAddressName = NULL;
                
                hr = pAddress->get_AddressName(&bstrAddressName);

                if (FAILED(hr))
                {
                    LogError("FindAddress: failed to get address name");
                }
                else
                {
                    LogMessage("   %S\n", bstrAddressName);
                }

                SysFreeString(bstrAddressName);


                //
                // will use this address
                //

                *ppAddress = pAddress;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -