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

📄 soundcarddevice.cxx

📁 Vovida 社区开源的 SIP 协议源码
💻 CXX
📖 第 1 页 / 共 3 页
字号:
            }            break;        case rtp_session_sendrecv:             cpLog(LOG_DEBUG, "full duplex already");            deviceMutex.unlock();            return 0;            break;        default:            if ( request.localPort != 0 )            {                cpLog( LOG_DEBUG, "Turning on RTP receive" );                audioStack->setSessionState( rtp_session_recvonly );                audioStack->setReceiver( request.localPort,                                         request.localPort + 1,                                         0,                                         rtpPayloadPCMU,                                         rtpPayloadPCMU,                                         0 );            }            if ( request.remotePort != 0 )            {                cpLog( LOG_DEBUG, "Turning on RTP transmit" );                if( request.localPort != 0 )                {                    audioStack->setSessionState( rtp_session_sendrecv );                }                else                {                    audioStack->setSessionState( rtp_session_sendonly );                }                audioStack->setTransmiter( request.remoteHost,                                           request.remotePort,                                           request.remotePort + 1,                                           rtpPayloadPCMU,                                           rtpPayloadPCMU );            }            break;        }    }    if( request.sendRingback )        startSendRingback();    else        stopSendRingback();    RtpSessionState sessionState = audioStack->getSessionState();    if( sessionState == rtp_session_sendonly ||        sessionState == rtp_session_recvonly)    {        audioActive = false;        audioHalfActive = true;    }    else    {        audioActive = true;        audioHalfActive = false;    }    audioStack->setApiFormat( rtpPayloadPCMU, request.rtpPacketSize*8 );    audioStack->setNetworkFormat( rtpPayloadPCMU, request.rtpPacketSize*8 );    deviceMutex.unlock();    reopenAudioHardware();    return 0;} // end SoundCardDevice::audioStart()//***************************************************************************// SoundCardDevice::audioStop//// description:  tears down audio.  cleans up by delete objects created when//               audioStart was called...  audioStack, rtp packets.//***************************************************************************intSoundCardDevice::audioStop(){    if( !audioActive )    {        return 1;    }    cerr << "%%% Stopping audio" << endl;    // mark audio as deactivated.    audioActive = false;    audioHalfActive = false;    vusleep( 200 );#ifdef WIN32    deviceMutex.lock(); //AND: or thread must die !!!#endif    // should lock here, but seg faults application when unlocking below - kle    // close RTP session    if( audioStack )    {        RtpSessionState sessionState = audioStack->getSessionState();        if( sessionState == rtp_session_sendonly ||            sessionState == rtp_session_sendrecv )        {            audioStack->transmitRTCPBYE();        }    }    if( inRtpPkt )    {        delete inRtpPkt;        inRtpPkt = 0;    }    if( audioStack )    {        delete audioStack;        audioStack = 0;    }#ifdef WIN32    deviceMutex.unlock();#endif    reopenAudioHardware();    return 0;} // end SoundCardDevice::audioStop()//***************************************************************************// SoundCardDevice::audioSuspend//// description: suspend the RTP transmit and receive, and also stop the////***************************************************************************intSoundCardDevice::audioSuspend (){    deviceMutex.lock();    cerr << "%%% Suspending audio" << endl;    cerr << "Setting all RTP / RTCP ports to 0" << endl;     if ( audioStack != 0 )    {        //set rtp session to inactive        audioStack->setSessionState( rtp_session_inactive );        audioStack->setReceiver( 0, 0, 0, rtpPayloadPCMU, rtpPayloadPCMU, 0 );        audioStack->setTransmiter( 0, 0, 0, rtpPayloadPCMU, rtpPayloadPCMU );    }    deviceMutex.unlock();    reopenAudioHardware();    return 0;} // end SoundCardDevice::audioSuspend()//***************************************************************************// SoundCardDevice::audioResume//// description:  resume the rtp session using the new sdp information//               enable the quicknet card audio//***************************************************************************intSoundCardDevice::audioResume( const HardwareAudioRequest& request ){    deviceMutex.lock();    if ( audioStack == 0 )    {        cpLog( LOG_ERR, "Try to resume an existing audio channel" );        cpLog( LOG_ERR, "No existing audio channel" );        deviceMutex.unlock();        return 0;    }    cerr << "Resuming audio" << endl;    cerr << "Listening on port: " << request.localPort << endl;    cerr << "Sending to host: " << request.remoteHost << endl;    cerr << "Sending to port: " << request.remotePort << endl;    cerr << "RTP packet size: " << request.rtpPacketSize << endl;    //resuming audio channel    //int remoteRtcpPort = (request.remotePort > 0) ? request.remotePort + 1 : 0;    //int localRtcpPort = (request.localPort > 0) ? request.localPort + 1 : 0;    const char* remoteHost = 0;    if( request.remotePort != 0 )        remoteHost = request.remoteHost;    if( request.localPort != 0 && request.remotePort != 0 )    {        //full duplex audio        audioStack->setSessionState(rtp_session_sendrecv);        audioStack->setReceiver(request.localPort, request.localPort + 1, 0,                                rtpPayloadPCMU, rtpPayloadPCMU, 0);        audioStack->setTransmiter(request.remoteHost, request.remotePort,                                  request.remotePort + 1, rtpPayloadPCMU,                                  rtpPayloadPCMU);    }    else if ( request.localPort != 0 )    {        //receive only        audioStack->setSessionState(rtp_session_sendrecv);        audioStack->setReceiver(request.localPort, request.localPort + 1, 0,                                rtpPayloadPCMU, rtpPayloadPCMU, 0);    }    else if ( request.remotePort != 0 )    {        //transmit only        audioStack->setSessionState( rtp_session_sendrecv );        audioStack->setTransmiter( request.remoteHost, request.remotePort,                                   request.remotePort + 1, rtpPayloadPCMU,                                   rtpPayloadPCMU );    }    audioStack->setApiFormat( rtpPayloadPCMU, request.rtpPacketSize*8 );    audioStack->setNetworkFormat( rtpPayloadPCMU, request.rtpPacketSize*8 );    if( request.sendRingback )        startSendRingback();    else        stopSendRingback();    deviceMutex.unlock();    reopenAudioHardware();    return 0;} // end SoundCardDevice::audioResume()//***************************************************************************// SoundCardDevice::provideTone//// description:  provide the tone for the soundcard by playing//               a sound file of that particular tone.//***************************************************************************voidSoundCardDevice::provideTone( const ToneEmulation tone ){    // open ULAW encoded sound file    int toneFD;    switch( tone )    {    case DialToneEmulation:        cpLog( LOG_DEBUG, "*** Provide dial tone emulation ***" );        toneFD = open( "Tone/dialtone", O_RDONLY );        break;    case RingbackToneEmulation:        cpLog( LOG_DEBUG, "*** Provide ringback tone emulation ***" );        toneFD = open( "Tone/ringback", O_RDONLY );        break;    default:        cpLog( LOG_ERR, "Unsupported tone requested" );        toneFD = -1;        break;    }    if( toneFD < 0 )    {        cpLog( LOG_ERR, "Cannot open tone file" );        return;    }    // play until file ends or hardware event    reopenAudioHardware();    bool provideToneLoop = true;    while( provideToneLoop )    {        int cc = read( toneFD, dataBuffer, NETWORK_RTP_RATE );        if( cc != NETWORK_RTP_RATE )        {            // end of file reached            provideToneLoop = false;        }        deviceMutex.lock();        // play tone sample        writeToSoundCard( dataBuffer, NETWORK_RTP_RATE );#ifndef WIN32        // watch for a key press on stdinFD        fd_set readFdSet;        struct timeval tv;        tv.tv_sec = 0;        tv.tv_usec = 0;        FD_ZERO( &readFdSet );        FD_SET(stdinFD, &readFdSet );        select( stdinFD+1, &readFdSet, 0, 0, &tv );        if( FD_ISSET( stdinFD, &readFdSet ) )        {            // something in the keyboard buffer            provideToneLoop = false;        }#else        HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);        INPUT_RECORD        inputRecord;        DWORD        nRecords;        if (PeekConsoleInput( hStdin, &inputRecord, 1, &nRecords)            && nRecords)        {            if (inputRecord.Event.KeyEvent.bKeyDown)             {                // something in the keyboard buffer                provideToneLoop = false;            }        }#endif                if( myQ->size() > 0 )        {            // need to stop tone and process endpoint msg            provideToneLoop = false;        }        deviceMutex.unlock();    }    reopenAudioHardware();    close( toneFD );} // end provideTone()intSoundCardDevice::getRingbackTone( unsigned char *ringData, const int samples ){    // open tone file if first time    if( ringbackFd == -1 )    {        cpLog( LOG_DEBUG, "Opening remote ringback tone file" );        if( ( ringbackFd = open( "Tone/ringback", O_RDONLY ) ) == -1 )        {            cpLog( LOG_ERR, "Fail to open Tone/ringback" );            return 0;        }    }    // read from tone file    int cc = read( ringbackFd, (char*)ringData, samples );    if( cc != samples )    {        //AND:may be need close file for reopen at next read() ?        close(ringbackFd);        ringbackFd = -1;        // end of file reached        return cc;    }    return cc;}//***************************************************************************// SoundCardDevice::onhookOrFlash//// THIS FEATURE IS TURNED OFF IN THE PHONECARDDEVICE UNTIL QUICKNET// RELEASES THE SMARTCABLE.// description:  quicknet does not implement a flash function on their cards.//               so, we have to implement our own, by checking the hook state//               of the phone.  this function will tell us whether the phone//               is being flashed or being placed onhook.//***************************************************************************voidSoundCardDevice::onhookOrFlash(){    cpLog( LOG_DEBUG, "We know this isn't a flash!" );}voidSoundCardDevice::provideDialToneStart(){    cpLog( LOG_DEBUG, "***  Start dial tone  ***" );    provideTone( DialToneEmulation );}voidSoundCardDevice::provideDialToneStop(){    cpLog( LOG_DEBUG, "***  Stop dial tone  ***" );    if( playDialTone == true )    {        playDialTone = false;        reopenAudioHardware();    }}voidSoundCardDevice::provideRingStart(){    cpLog( LOG_DEBUG, "***  Start Ringing  ***" );    cout << "Incoming call..." << endl << endl;    //TODO play some ringing sound to speaker?    //provideTone( RingbackToneEmulation );}voidSoundCardDevice::provideRingStop(){    cpLog( LOG_DEBUG, "***  Stop Ringing  ***" );    reopenAudioHardware();}voidSoundCardDevice::provideLocalRingbackStart(){    cpLog( LOG_DEBUG, "***  Start local ringback  ***" );    provideTone( RingbackToneEmulation );}voidSoundCardDevice::provideLocalRingbackStop(){    cpLog( LOG_DEBUG, "***  Stop local ringback  ***" );    reopenAudioHardware();}voidSoundCardDevice::provideBusyToneStart(){    cpLog( LOG_DEBUG, "***  Start busy tone  ***" );}voidSoundCardDevice::provideBusyToneStop(){    cpLog( LOG_DEBUG, "***  Stop busy tone  ***" );}voidSoundCardDevice::provideFastBusyToneStart(){    cpLog( LOG_DEBUG, "***  Start fast busy tone  ***" );}voidSoundCardDevice::provideFastBusyToneStop(){    cpLog( LOG_DEBUG, "***  Stop fast busy tone  ***" );}voidSoundCardDevice::provideDtmf( DeviceSignalType signal ){    char digit = ' ';    if ( signal >= DeviceSignalDigit0 && signal <= DeviceSignalDigit9 )    {        digit = '0' + signal - DeviceSignalDigit0;    }    else if ( signal == DeviceSignalDigitHash )    {        digit = '#';    }    else if ( signal == DeviceSignalDigitStar )    {        digit = '*';    }    cpLog( LOG_DEBUG, "***  DTMF %c  ***", digit );}voidSoundCardDevice::provideCallInfo(string, string, string){}#if 0voidSoundCardDevice::killDialTone(){    if( playDialTone == true )    {        playDialTone = false;        cpLog( LOG_DEBUG, "*** Stopping tone emulation ***" );#ifndef WIN32  //AND:Construction fall on WIN32        deviceMutex.unlock();        reopenAudioHardware();        deviceMutex.unlock();#endif    }}#endifvoidSoundCardDevice::provideCallWaitingBeepStart(){    // Not yet implemented    cpLog( LOG_DEBUG, "in provideCallWaitingBeepStart() - not completed" );}voidSoundCardDevice::provideCallWaitingBeepStop(){    // Not yet implemented    cpLog( LOG_DEBUG, "in provideCallWaitingBeepStop() - not completed" );}/* Local Variables: *//* c-file-style: "stroustrup" *//* indent-tabs-mode: nil *//* c-file-offsets: ((access-label . -) (inclass . ++)) *//* c-basic-offset: 4 *//* End: */

⌨️ 快捷键说明

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