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

📄 tapisend.cpp

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

        }

        
        //
        // the sample was submitted successfully. update count
        //

        nSampleCount++;

        if (nSampleCount == 300)
        {
            
            LogError("ReadFileIntoTerminal: sleeping 10 seconds");

            Sleep(30000);

            LogError("ReadFileIntoTerminal: woke up");
        }

        //
        // keep the sample we have just submitted. on exit, we will wait 
        // for it to be processed by mst
        //

        SampleQ.push_back(pStreamSample);

    } // file reading/sample-filling loop


    LogMessage("ReadFileIntoTerminal: processed %lu samples", nSampleCount);

    
    //
    // walk through the list of all the samples we have submitted and wait for 
    // each sample to be done
    //
    
    while (!SampleQ.empty())
    {

        //
        // get and remove a sample from the queue 
        //

        IStreamSample *pStreamSample = SampleQ.front();

        SampleQ.pop_front();


        //
        // wait for the Media Streaming Terminal to finish 
        // processing the sample
        //

        pStreamSample->CompletionStatus(COMPSTAT_WAIT, INFINITE);


        //
        // ignore the error code -- release the sample in any case
        //

        pStreamSample->Release();
        pStreamSample = NULL;

    }


    LogMessage("ReadFileIntoTerminal: released all submitted samples");

    
    //
    // tell media streaming terminal's stream that there is no more data
    //

    pTerminalMediaStream->SendEndOfStream(0);


    //
    // ignore the error code
    //

    pTerminalMediaStream->Release();
    pTerminalMediaStream = NULL;


    //
    // if we disconnect the call right away, the call may be dropped before
    // receiver gets all the samples. An application should wait for 
    // STREAM_INACTIVE media event before disconnecting the call.
    //
    // Since, for simplicity, we are not processing events in this sample,
    // wait several seconds to give the receiver a little time to complete
    // processing.
    //

    LogMessage("ReadFileIntoTerminal: Sleeping to give the receiver time "
               "to process everything we have sent.");

    Sleep(7500);


    LogMessage("ReadFileIntoTerminal: completed");
   
    return hr;
}


///////////////////////////////////////////////////////////////////////////////
//
// CreateAndSelectTerminal
//
// creates a media streaming terminal for capture, sets requested format,
// sets allocator properties, and selects the terminal on the call's first 
// outgoing audio stream.
//
// returns S_OK and terminal if success
// error if failure
//
///////////////////////////////////////////////////////////////////////////////

HRESULT CreateAndSelectTerminal(IN ITBasicCallControl *pCall,
                                IN WAVEFORMATEX *pWaveFormat,
                                OUT ITTerminal **ppTerminal)
{

    HRESULT hr = E_FAIL;

    
    //
    // don't return garbage
    //

    *ppTerminal = NULL;



    //
    // find an outgoing audio stream on the call
    //

    ITStream *pStream = NULL;

    hr = FindAudioStream(pCall, &pStream);

    if (FAILED(hr))
    {
        LogError("CreateAndSelectTerminal: failed to find an outgoing audio stream");

        return hr;
    }


    //
    // create media streaming terminal
    //
    
    ITTerminal *pTerminal = NULL;

    pTerminal = CreateCaptureMediaStreamingTerminal(pCall);


    if (NULL == pTerminal)
    {

        LogError("CreateAndSelectTerminal: Failed to create media streaming terminal");

        pStream->Release();
        pStream = NULL;

        return hr;

    }


    //
    // tell media streaming terminal format of the data 
    // we are going to send. If the terminal cannot handle this format
    // return an error
    //

    hr = SetTerminalFormat(pTerminal, pWaveFormat);

    if (FAILED(hr))
    {
        LogMessage("CreateAndSelectTerminal: "
                   "terminal does not support requested format");
    
        pStream->Release();
        pStream = NULL;

        pTerminal->Release();
        pTerminal = NULL;

        return hr;
    }


    //
    // set allocator properties. 
    //
    // calling ITAllocatorProperties::SetAllocatorProperties with the 
    // properties that are not optimal for the MSP in use can result
    // in loss of sound quality.
    //
    // So make sure that you only call this function if you know you
    // need it.
    // 
    // Do not use ITAllocatorProperties::SetAllocatorProperties to set
    // the size of the buffer you want to get when you fill samples, 
    // ITAllocatorProperties::SetBufferSize will accomplish that without
    // affecting terminal's allocator properties.
    //

    // hr = SetAllocatorProperties(pTerminal);

    if (FAILED(hr))
    {

        //
        // not fatal -- we are still likely to successfully stream data
        //

        LogMessage("CreateAndSelectTerminal: "
                   "failed to set allocator properties. continuing.");
    }


    //
    // select the terminal on the stream
    //

    hr = pStream->SelectTerminal(pTerminal);


    //
    // don't need the stream anymore
    //

    pStream->Release();
    pStream = NULL;
    

    if (FAILED(hr))
    {
        LogError("CreateAndSelectTerminal: Failed to select terminal on the stream");

        pTerminal->Release();
        pTerminal = NULL;

    }

    
    //
    // if everything went smoothly pTerminal has a pointer to configured 
    // and selected terminal. otherwise pTerminal is null and all resources 
    // have been released
    //

    *ppTerminal = pTerminal;

    
    return hr;

}


///////////////////////////////////////////////////////////////////////////////
//
// StreamFile
//
// use TAPI to connect to the remote machine to stream file
//
///////////////////////////////////////////////////////////////////////////////

HRESULT StreamFile(IN char *szFileName, 
                   IN char *szAddressString, 
                   IN char *szAddressType)
{

    HRESULT hr = E_FAIL;


    LogMessage("StreamFile: file [%s] address [%s] address type [%s]", 
                szFileName, szAddressString, szAddressType);


    //
    // check if the file is valid
    //

    if (!IsValidAudioFile(szFileName))
    {

        LogError("StreamFile: file not valid [%s]", szFileName);

        return E_FAIL;
    }


    //
    // initialize COM libraries -- used by TAPI
    //

    hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);

    if ( FAILED(hr))
    {
        LogError("StreamFile: Failed to CoInitialize");

        return hr;
    }


    //
    // create and initialize TAPI
    //

    hr = InitializeTAPI();

    if (SUCCEEDED(hr))
    {

        //
        // try to make a call
        //

        ITBasicCallControl *pCall = NULL;

        hr = Call(szAddressString, szAddressType, &pCall);

        if (SUCCEEDED(hr))
        {

            //
            // construct the file reader object
            // to be used to read file's data
            //
            // note: If you want to play more than one file in one call, reuse 
            // the same terminal for the duration of the call. Under 
            // Windows 2000, all data submitted via the Media Streaming Terminal
            // during the call must have the same format. Changing a Media 
            // Streaming Terminal's format after it is initially configured will 
            // always return an error code, regardless of the OS version. 
            // Unselecting a Media Streaming Terminal and creating and selecting
            // a new terminal on the same stream from the same call with a 
            // different format is not supported on Windows 2000. This may, 
            // however, be supported on other versions of Windows. For the latest 
            // information on which versions of Windows support this, please 
            // refer to the latest Platform SDK documentation.
            //

            CAVIFileReader FileReader;

            hr =  FileReader.Initialize(szFileName);


            //
            // get the file's format. remember to deallocate when done.
            //

            WAVEFORMATEX *pWaveFormat = NULL;

            if (SUCCEEDED(hr) && 
                SUCCEEDED(hr = FileReader.GetFormat(&pWaveFormat)))
            {

                //
                // create and configure a media streaming terminal and select it on this call
                //
                //

                ITTerminal *pPlaybackTerminal = NULL;

                hr = CreateAndSelectTerminal(pCall, pWaveFormat, &pPlaybackTerminal);


                if (SUCCEEDED(hr))
                {

                    //
                    // use the terminal to send the file
                    //

                    hr = ReadFileIntoTerminal(&FileReader, pPlaybackTerminal);

                    if (FAILED(hr))
                    {
                        LogError("StreamFile: failed to ReadFileIntoTerminal");
                    }
                    else
                    {
                        LogError("StreamFile: succeeded");
                    }



                    //
                    // release the terminal, we no longer need it
                    //

                    pPlaybackTerminal->Release();
                    pPlaybackTerminal = NULL;

                }
                else
                {
                    LogError("StreamFile: failed to create and select terminal");

                }


                //
                // no longer need wave format. free memory.
                //

                FreeMemory(pWaveFormat);
                pWaveFormat = NULL;

            }  // got file format
            else
            {
                LogError("StreamFile: failed to get file's format");

            }


            //
            // there is not much we can do if disconnect fails, 
            // so ignore its return code
            //

            pCall->Disconnect(DC_NORMAL);

            pCall->Release();
            pCall = NULL;

        }   // call connected
        else
        {
        
            LogError("StreamFile: failed to connect to %s", szAddressString);

        }


        //
        // tapi has been initialized. shutdown now.
        //

        ShutdownTAPI();

    } // initialized tapi
    else
    {

        LogError("StreamFile: Failed to initialize TAPI");

    }


    CoUninitialize();
        
    return hr;
}



///////////////////////////////////////////////////////////////////////////////
//
// HelpScreen
//
// this function displays usage information
//
///////////////////////////////////////////////////////////////////////////////

void HelpScreen()
{

    printf("Usage:\n\n"
               "  TAPISend filename address addresstype\n\n"
               "  where addresstype is [ ");


    for (int i = 0; i < g_nNumberOfAddressTypes - 1; ++i)
    {
        printf("%s | ", g_szAddressTypes[i]);
    }

    printf("%s ]\n", g_szAddressTypes[i]);

}


///////////////////////////////////////////////////////////////////////////////
// 
// CtrlHandler
//
// handler for ctrl+break, close, logoff and shutdown. 
//
// sets g_bExitRequested flag signaling shutdown. this ensures graceful exit
// 
///////////////////////////////////////////////////////////////////////////////

BOOL CtrlHandler(DWORD nEventType) 
{

    //
    // are we in the middle of shutting down?
    //

    if (TRUE == g_bExitRequested)
    {
        LogMessage("CtrlHandler: shutdown is already in progress");

        return TRUE;
    }


    //
    // any exit event (close, ctrl+break/C, logoff, shutdown)
    // is a signal for the application to exit.
    //

    switch (nEventType) 
    { 
 
        case CTRL_C_EVENT: 
        case CTRL_CLOSE_EVENT:
        case CTRL_BREAK_EVENT:
        case CTRL_LOGOFF_EVENT:
        case CTRL_SHUTDOWN_EVENT:

            LogMessage("CtrlHandler: Initiating shutdown.");


            //
            // signal shutdown
            //

            g_bExitRequested = TRUE;


    }

    return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
//
// main 
//
// usage: TAPISend filename address addresstype
// 
// returns 0 if success, 1 if failure
//
///////////////////////////////////////////////////////////////////////////////

int __cdecl main(int argc, char* argv[])
{

    LogMessage("main: started");


    //
    // validate arguments
    //

    if (argc != 4)
    {
        HelpScreen();

        LogMessage("main: invalid arguments, exiting.");

        return 1;
    }


    //
    // we want to handle ctrl+c and ctrl+break events so we can cleanup on exit
    // proceed even in case of failure
    //

    SetConsoleCtrlHandler( (PHANDLER_ROUTINE)CtrlHandler, TRUE);


    //
    // open the file, connect to the remote machine and stream the file over
    //

    HRESULT hr = StreamFile(argv[1], argv[2], argv[3]);


    //
    // exiting... we no longer want to handle ctrl+c and ctrl+break
    //
    
    SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, FALSE);


    //
    // was file streaming successful?
    //

    if (FAILED(hr))
    {
        LogError("main: Failed to stream file");

        return 1;
    }


    LogMessage("main: completed");

    return 0;

}

⌨️ 快捷键说明

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