📄 soundcarddevice.cxx
字号:
} 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 + -