📄 dupcarddevice.cxx
字号:
case '7': event->type = DeviceEventDtmf7; break; case '8': event->type = DeviceEventDtmf8; break; case '9': event->type = DeviceEventDtmf9; break; case 'u': if( hookStateOffhook ) { cout << "\nEnter URL: "; cout.flush(); myEntryState = EntryStateEnterUrl; } else { cpLog( LOG_ERR, "Enter 'a' first" ); } break; case '\n': // ignore break; default: // no events cpLog( LOG_ERR, "Unknown keyboard input" ); break; } } // send the event if( event->type != DeviceEventUndefined ) { assert( sessionQ != 0 ); event->callId = callId;#ifndef WIN32 sessionQ->add( event );#else Sptr <SipProxyEvent> proxyEvent; proxyEvent.dynamicCast( event ); sessionQ->add( proxyEvent );#endif } deviceMutex.unlock(); return 0;} // end DupCardDevice::process()voidDupCardDevice::processIncomingAudio(){ int incomingFd = -1; RtpReceiver* recv = audioStack->getRtpRecv(); if(recv) { incomingFd = recv->getSocketFD(); } int count = 0; while(incomingFd > 0) { fd_set netFD; FD_ZERO (&netFD); FD_SET(incomingFd, &netFD); struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 0; int selret = select(incomingFd + 1, &netFD, 0, 0, &timeout); if(selret > 0) { RtpSessionState sessionState = audioStack->getSessionState(); if ( sessionState == rtp_session_undefined ) { return; } // receive audio if( sessionState == rtp_session_recvonly || sessionState == rtp_session_sendrecv ) { RtpPacket* packet = audioStack->receive(); if( packet ) { if( packet->getPayloadType() != rtpPayloadPCMU || packet->getPayloadUsage() != NETWORK_RTP_RATE ) { cpLog(LOG_ERR, "Received from RTP stack incorrect payload type"); }#ifdef HAS_SPHINX //Give the RTP to recognizer speechHandler.recognize((unsigned char*) packet->getPayloadLoc() , packet->getPayloadUsage() );#else // send to play thread mySoundCard.write( (unsigned char*) packet->getPayloadLoc(), packet->getPayloadUsage() );#endif delete packet; } } } else {// cout << "readpackets: " << count << endl; return; } count++; }}voidDupCardDevice::processOutgoingAudio(){ RtpSessionState sessionState = audioStack->getSessionState(); if ( sessionState == rtp_session_undefined ) { return; } // transmit audio if( sessionState == rtp_session_sendonly || sessionState == rtp_session_sendrecv ) { int cc; if( audioStack->getRtcpTran() ) { if( sendRingback ) { cc = getRingbackTone( dataBuffer, RESID_RTP_RATE );#ifdef WIN32 Sleep(15);#endif } else { cc = mySoundCard.read( dataBuffer, RESID_RTP_RATE ); } if ((cc > 0) && audioStack) { audioStack->transmitRaw( (char*)dataBuffer, cc );// bNothingDo = false; } else { cpLog(LOG_DEBUG, "failed to read data from sound card"); } } }}//***************************************************************************// DupCardDevice::processRTP// description: main processing loop for RTP//***************************************************************************voidDupCardDevice::processRTP (){ deviceMutex.lock(); if( audioStack == 0 ) { deviceMutex.unlock(); vusleep( 1000 ); return; } // do something here to make sure we only process incoming if we need to. int incomingFd = -1; RtpReceiver* recv = audioStack->getRtpRecv(); if(recv) { incomingFd = recv->getSocketFD(); } fd_set netFD; FD_ZERO (&netFD); if(incomingFd > 0) { FD_SET(incomingFd, &netFD); } int myFD = mySoundCard.getFd(); if(myFD >= 0) { FD_SET(myFD, &netFD); } int maxfd = (incomingFd > myFD) ? incomingFd : myFD; if (maxfd == -1) { deviceMutex.unlock(); return; } struct timeval timeout; timeout.tv_sec = 1; timeout.tv_usec = 0; int selret = select(maxfd + 1, &netFD, 0, 0, &timeout); if(selret > 0) { if((incomingFd >= 0) && FD_ISSET(incomingFd, &netFD)) { processIncomingAudio(); } if((myFD >= 0) && FD_ISSET(myFD, &netFD)) { processOutgoingAudio(); } } //AND:BUGFIX:? if (audioStack == 0) { deviceMutex.unlock(); vusleep( 1000 ); return; }#ifdef WIN32 bool bNothingDo = true; if (bNothingDo) { //AND: Prevent processor from 100% load Sleep(2); }#endif // process RTCP //if( audioStack && sessionState != rtp_session_inactive ) //{ // audioStack->processRTCP(); //} deviceMutex.unlock(); return;}intDupCardDevice::addToFdSet( fd_set* fd ){ if( ( audioActive || audioHalfActive ) && audioStack ) { RtpSessionState sessionState = audioStack->getSessionState(); if( sessionState == rtp_session_recvonly || sessionState == rtp_session_sendrecv ) { FD_SET( ( audioStack->getRtpRecv() )->getSocketFD(), fd ); FD_SET( ( audioStack->getRtcpRecv() )->getSocketFD(), fd ); } } FD_SET( myFD, fd ); return 0;} // end DupCardDevice::addToFdSet()//***************************************************************************// DupCardDevice::getRtpPort()//// description: creates a new rtp session and reserves a rtp port//***************************************************************************intDupCardDevice::getRtpPort(){ deviceMutex.lock(); //this is an arbitrarily defined number const int MAX_RTP_PORT = UaConfiguration::instance()->getMaxRtpPort(); const int MIN_RTP_PORT = UaConfiguration::instance()->getMinRtpPort(); int port = 0; int minPort = MIN_RTP_PORT; // create a rtp session if there is no existing session alread // this Rtp session will be idle if( audioStack == 0 ) { audioStack = new RtpSession(0); } while( 1 ) { // reserve a rtp port port = audioStack->reserveRtpPort(minPort, MAX_RTP_PORT); minPort = (port > minPort) ? port : minPort; // attempt to reserve a rtcp port on port number higher than // the rtp port if ( port != 0 && audioStack->reserveRtcpPort(port + 1, 0) != 0 ) { break; } // if not successful allocating rtcp port, increment the minimum rtp // port and try again. If minPort reaches MAX_RTP_PORT, return 0 // to indicate port allocation failed. minPort += 2; if ( minPort > MAX_RTP_PORT ) { port = 0; break; } } deviceMutex.unlock(); return port;}//***************************************************************************// DupCardDevice::releaseRtpPort()//// description: destroy the rtp session and release the rtp port//***************************************************************************voidDupCardDevice::releaseRtpPort(){ deviceMutex.lock(); // destroy the rtp session if one exists if ( audioStack != 0 ) { //AND:BUGFIX: swap 2x2 bottom 4 lines // (or releaseRtcpPort() try use _rtp_ stack when his already // destroy releaseRtpPort) may be Unix to be able use class // after his ~destroy, but WIN32 close thread :) int port = audioStack->releaseRtcpPort(); cpLog( LOG_DEBUG, "rtcp port %d released", port ); port = audioStack->releaseRtpPort(); cpLog( LOG_DEBUG, "rtp port %d released", port ); delete audioStack; audioStack = 0; } deviceMutex.unlock();}//***************************************************************************// DupCardDevice::audioStart//// description: creates a new rtp session and also allocates memory for// incoming and outgoing rtp packet. ioctl calls to initialize// the quicknet card.//***************************************************************************intDupCardDevice::audioStart( const HardwareAudioRequest& request ){ deviceMutex.lock(); cerr << "%%% Establishing duplex 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 << " ms" << endl; // create new audioStack for this audio session // 0 is rtpPayloadPCUM // last paramter, -1, disables jitter buffer if( audioStack == 0 ) { int remoteRtcpPort = (request.remotePort > 0) ? request.remotePort + 1 : 0; int localRtcpPort = (request.localPort > 0) ? request.localPort + 1 : 0; cerr << "%%% Remote rtcp port : " << remoteRtcpPort << "\n"; cerr << "%%% Local rtcp port : " << localRtcpPort << "\n\n"; const char* remoteHost = 0; if ( request.remotePort != 0 ) remoteHost = request.remoteHost; audioStack = new RtpSession( remoteHost, request.remotePort, request.localPort, remoteRtcpPort, localRtcpPort, rtpPayloadPCMU, rtpPayloadPCMU, 0 ); } else { cerr << "%%% Turn half duplex into full duplex" << endl; //need to determine what mode RtpSession is in RtpSessionState sessionState = audioStack->getSessionState(); switch ( sessionState ) { case rtp_session_sendonly: //turn on the receive cerr << "%%% Turn on receive" << endl; cerr << "%%% local host " << request.localPort << endl; cerr << "%%% local port " << request.localPort << endl; if ( request.localPort != 0 ) { audioStack->setSessionState( rtp_session_sendrecv ); audioStack->setReceiver( request.localPort, request.localPort + 1, 0, rtpPayloadPCMU, rtpPayloadPCMU, 0); } break; case rtp_session_recvonly: //turn on the send cerr << "%%% Turn on send" << endl; cerr << "%%% remote host " << request.remoteHost << endl; cerr << "%%% remote port " << request.remotePort << endl; if ( request.remotePort != 0 ) { audioStack->setSessionState(rtp_session_sendrecv); audioStack->setTransmiter(request.remoteHost, request.remotePort, request.remotePort + 1, rtpPayloadPCMU, rtpPayloadPCMU); } break; case rtp_session_sendrecv: cpLog(LOG_DEBUG, "full duplex already"); return 0; break; default: cpLog(LOG_DEBUG, "turning on both send and receive"); //turn on the send if ( request.remotePort != 0 ) { audioStack->setSessionState( rtp_session_sendonly ); audioStack->setTransmiter(request.remoteHost, request.remotePort, request.remotePort + 1, rtpPayloadPCMU, rtpPayloadPCMU); } //turn on the receive if ( request.localPort != 0 ) { if( request.remotePort != 0 ) { audioStack->setSessionState( rtp_session_sendrecv ); } else { audioStack->setSessionState( rtp_session_recvonly ); } audioStack->setReceiver(request.localPort, request.localPort + 1, 0, rtpPayloadPCMU, rtpPayloadPCMU, 0); } 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 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -