📄 callaudio.cpp
字号:
//// C++ Implementation: callaudio2//// Description:////// Author: root <root@papa>, (C) 2004//// Copyright: See COPYING file that comes with this distribution////#include <stdio.h>#include <sys/types.h>#include <unistd.h>#include <signal.h>#include <math.h>#include <sys/ioctl.h>#include "../config.h"#include "../dissipate2/sipprotocol.h"#include "../dissipate2/sipcall.h"#include "../dissipate2/sdpbuild.h"#include "kstatics.h"#include "dspaudioout.h"#include "dspaudioin.h"#include "dspoutrtp.h"#include "dspoutoss.h"#ifdef ALSA_SUPPORT#include "dspoutalsa.h"#endif#include "callaudio.h"CallAudio::CallAudio(SessionControl *sessionC, const char *name ){ sc = sessionC; outrtp = 0; inrtp = 0; inoss = 0; outoss = 0; inalsa = 0; outalsa = 0; output = 0; input = 0; useoss = true; payload = sc->getPayload(); useStun = false; audio_fd = -1; charDTMF[0]='0'; charDTMF[1]='1'; charDTMF[2]='2'; charDTMF[3]='3'; charDTMF[4]='4'; charDTMF[5]='5'; charDTMF[6]='6'; charDTMF[7]='7'; charDTMF[8]='8'; charDTMF[9]='9'; charDTMF[10]='*'; charDTMF[11]='#'; dtmfCount = 0; dtmfSize = 0; dtmfTimer = new QTimer(); connect( dtmfTimer, SIGNAL( timeout() ), this, SLOT( handleDTMFSeq() ) ); debug = KStatics::debugLevel; audioUser=0; printf(":::::: Callaudio start\n");}CallAudio::~CallAudio(){if( output ) { if( output->running() ) { output->setCancel(); output->wait(); } delete output; } if( input ) { if( input->running() ) { input->setCancel(); input->wait(); } delete input; };if(dtmfTimer) { delete dtmfTimer; dtmfTimer=0;} printf(":::::: Callaudio end\n");}void CallAudio::audioIn( SdpBuild *call, int aU ){ bool ok; audioUser=aU; int min, max; min = sc->getMinMediaPort(); max = sc->getMaxMediaPort(); if(debug >= 2) printf("=====CallAudio audioIn: %d\n",(int) sc->getAudioSys() ); QString hostname = call->getExtHost(); unsigned int portnum = call->getAudioPort().toInt( &ok, 10 );; if(debug >= 2) printf( "=====CallAudio audioIn: Sending to remote site %s:%d\n", hostname.latin1(), portnum ); if( input ) { stopListeningAudio(aU); } if( sc->getAudioSys() == SessionControl::isOSS ) { if(debug >= 2) printf("=====CallAudio audioIn: OSS used: codec = %d payload size %d\n",call->getRtpCodecNum(),call->getResponsePay()); if (sc->getSymMediaMode()) { outrtp = new DspOutRtp(call->getRtpCodec(), call->getRtpCodecNum(), min, max, hostname, &socket ); if(debug >= 2) printf( "=====CallAudio audioIn: sym media\n" ); } else { outrtp = new DspOutRtp( call->getRtpCodec(), call->getRtpCodecNum(), min, max, hostname ); } outrtp->setPortNum( portnum); outrtp->openDevice( DspOut::WriteOnly ); outrtp->setPayload( call->getResponsePay() ); if(debug >= 2) printf( "=====CallAudio audioIn: RTP %s:%d %d\n", hostname.latin1(), portnum,outrtp->getPortNum() ); inoss = new DspOutOss( sc->getOSSFilename2() ); if( sc->isAudioRW()) { if(debug >= 2) printf( "=====CallAudio audioIn: OSS device already open (readwrite)\n" ); if( !inoss->openDevice( audio_fd ) ) { if(debug >= 2) printf( "=====CallAudio audioIn: openDevice Failed.\n" ); } } else { if(debug >= 2) printf( "=====CallAudio audioIn: Opening OSS device %s for Input \n", sc->getOSSFilename2().latin1() ); if( !inoss->openDevice( DspOut::ReadOnly ) ) { if(debug >= 2) printf( "=====CallAudio: audioIn openDevice Failed.\n" ); } } inoss->readBuffer(2); if(debug >= 2) printf( "=====CallAudio audioIn: Creating OSS->RTP Diverter\n" ); input = new DspAudioIn( inoss, outrtp ); output->setCodec(call->getRtpCodec(), call->getRtpCodecNum()); input->start(); output->start(); } else if( sc->getAudioSys() == SessionControl::isALSA ) { if(debug >= 2) printf("=====CallAudio audioIn: ALSA used codec = %d\n",call->getRtpCodecNum()); if (sc->getSymMediaMode()) { outrtp = new DspOutRtp( call->getRtpCodec(), call->getRtpCodecNum(), min, max, hostname, &socket ); if(debug >= 2) printf( "=====CallAudio audioIn: ALSA sym media\n" ); } else { outrtp = new DspOutRtp( call->getRtpCodec(), call->getRtpCodecNum(), min, max, hostname ); } outrtp->setPortNum( portnum); outrtp->openDevice( DspOut::WriteOnly ); outrtp->setPayload( call->getResponsePay() ); inalsa = new DspOutAlsa( sc->getALSAFilename() );//("default"); if(debug >= 2) printf( "=====CallAudio audioIn: we open the deviced\n" ); if( !inalsa->openDevice( DspOut::ReadOnly ) ) { if(debug >= 2) printf( "=====CallAudio audioIn: openDevice Failed.\n" ); } inalsa->readBuffer(2); if(debug >= 2) printf( "=====CallAudio: audioIn: Creating ALSA->RTP Diverter\n" ); input = new DspAudioIn( inalsa, outrtp ); output->setCodec(call->getRtpCodec(), call->getRtpCodecNum()); input->start(); output->start(); }}int CallAudio::audioOut( SdpBuild *call,int aU ){ audioUser=aU; useStun=sc->isStun(); int min, max; min =sc-> getMinMediaPort(); max = sc->getMaxMediaPort(); if( output ) { if(debug >= 2) printf( "=====CallAudio audioOut: stop sending audio\n" ); stopSendingAudio(aU); } if( sc->getAudioSys() == SessionControl::isOSS ) { if(debug >= 2) printf( "=====CallAudio audioOut: OSS used codec = %d payload size = %d \n",call->getRtpCodecNum(),call->getResponsePay()); if (sc->getSymMediaMode()) { if(debug >= 2) printf( "=====CallAudio audioOut: sym media\n" ); inrtp = new DspOutRtp( call->getRtpCodec(), call->getRtpCodecNum(), min, max, QString::null, &socket ); } else { inrtp = new DspOutRtp( call->getRtpCodec(), call->getRtpCodecNum() , min, max ); } inrtp->setPayload(call->getResponsePay() ); if( useStun ) { if(debug >= 2) printf( "=====CallAudio audioOut: use stun\n" ); inrtp->setStunSrv( sc->getStunSrv() ); } inrtp->openDevice( DspOut::ReadOnly ); int po = 0; po=inrtp->getPortNum(); if(debug >= 2) printf( "=====CallAudio audioOut: RTP %d\n", po ); outoss = new DspOutOss( sc->getOSSFilename() ); if( sc->isAudioRW() ) { if( !outoss->openDevice( DspOut::ReadWrite ) ) { if(debug >= 2) printf("=====CallAudio audioOut: openDevice Failed.\n" ); po=0; } else { audio_fd = outoss->audio_fd; } } else { if( !outoss->openDevice( DspOut::WriteOnly )){ if(debug >= 2) printf("=====CallAudio audioOut: openDevice Failed.\n" ); po=0; } } if(debug >= 2) printf( "=====CallAudio audioOut: Creating RTP->OSS Diverter\n" ); output = new DspAudioOut( inrtp, outoss ); return po; } else if( sc->getAudioSys() == SessionControl::isALSA ) { if(debug >= 2) printf( "=====CallAudio audioOut: ALSA used codec = %d\n",call->getRtpCodecNum()); if (sc->getSymMediaMode()) { if(debug >= 2) printf( "=====CallAudio: audioOut sym media\n" ); inrtp = new DspOutRtp( call->getRtpCodec(), call->getRtpCodecNum(), min, max,QString::null, &socket ); } else { inrtp = new DspOutRtp(call->getRtpCodec(), call->getRtpCodecNum() , min, max ); } inrtp->setPayload(call->getResponsePay() ); if( useStun ) { if(debug >= 2) printf( "=====CallAudio audioOut: use stun\n" ); inrtp->setStunSrv( sc->getStunSrv() ); } inrtp->openDevice( DspOut::ReadOnly ); int po = 0; po=inrtp->getPortNum(); if(debug >= 2) printf( "=====CallAudio audioOut: ALSA\n" ); outalsa = new DspOutAlsa( sc->getALSAFilename() );//default if( !outalsa->openDevice( DspOut::WriteOnly )){ if(debug >= 2) printf("=====CallAudio audioOut: openDevice Failed.\n" ); po=0; }// printf ("!!!!!!!!!!!!!!!!!!!---------------> %s \n",socket.getStunnedHost().latin1() ); if(debug >= 2) printf( "=====CallAudio audioOut: Creating RTP->ALSA Diverter\n" ); output = new DspAudioOut( inrtp, outalsa ); return po; }return 0;}void CallAudio::stopSendingAudio( int aU ) {if (aU == audioUser) { if(debug >= 2) printf("=====CallAudio: stopSendingAudio %d\n",audioUser); if( output ) { if( output->running() ) { output->setCancel(); output->wait(); } if(debug >= 2) printf("=====CallAudio: stopSendingAudio output deleted %d\n",audioUser); delete output; output = 0; } if( input ) { if( input->running() ) { input->setCancel(); input->wait(); } if(debug >= 2) printf("=====CallAudio: stopSendingAudio input deleted %d\n",audioUser); delete input; input = 0; } clearMe(aU);}}void CallAudio::stopListeningAudio( int aU ){if (aU == audioUser) { if(debug >= 2) printf("=====CallAudio: stopListeningAudio %d\n",audioUser); if( input ) { if( input->running() ) { input->setCancel(); input->wait(); } delete input; input = 0; }}}bool CallAudio::isAudioOn( void ){ return (output || input );}void CallAudio::startDTMF(int tone){ if (outrtp) { outrtp->sendDTMF(tone); if(debug >= 2) printf( "tone %d \n",tone); } if (output) { output->startTone(charDTMF[tone]); } if (input) { input->startTone(charDTMF[tone]); }}void CallAudio::startDTMFSeq(QString string, int size){dtmfCount = 0;dtmfSize = size;dtmfString = string;dtmfTimer->start(500,TRUE);}void CallAudio::handleDTMFSeq() {int tone = 0, id =0; if(dtmfCount < dtmfSize) { id = (int)(*dtmfString.mid(dtmfCount,1)); switch(id) { case 0x30: tone = 0; break; case 0x31: tone = 1; break; case 0x32: tone = 2; break; case 0x33: tone = 3; break; case 0x34: tone = 4; break; case 0x35: tone = 5; break; case 0x36: tone = 6; break; case 0x37: tone = 7; break; case 0x38: tone = 8; break; case 0x39: tone = 9;break; case 0x2a: tone = 10; break; case 0x23: tone = 11;break; case 0x2c: dtmfCount ++; dtmfTimer->start(sc->getDTMFWait(),TRUE); return; default: tone = 0; } if (outrtp) outrtp->sendDTMF(tone); dtmfCount ++; dtmfTimer->start(500,TRUE); }}void CallAudio::stopDTMF(void){ if (output) { output->stopTone(); } if (input) { input->stopTone(); }}void CallAudio::ringOnce(int mul) { int audio_fd = ::open( sc->getRingtonedevice(), O_WRONLY | O_NONBLOCK ); if( audio_fd == -1 ) { printf( "!!!!!ERROR: %s\n", "Open Failed" ); return; } int flags = fcntl( audio_fd, F_GETFL ); flags &= ~O_NONBLOCK; fcntl( audio_fd, F_SETFL, flags ); int format = AFMT_S16_LE; if( ioctl( audio_fd, SNDCTL_DSP_SETFMT, &format ) == -1 ) { return; } if( format != AFMT_S16_LE ) { return; } int channels = 1; if( ioctl( audio_fd, SNDCTL_DSP_CHANNELS, &channels ) == -1 ) { return; } if( channels != 1 ) { return; } int rate = 8000; if( ioctl( audio_fd, SNDCTL_DSP_SPEED, &rate ) == -1 ) { return; } if( rate != 8000) { return; } int size = 1024*16; int samp = 1024*(mul-1)*4; int ampl = 1024*16; unsigned char devbuf[size]; int buf[samp]; int i, p=0; double arg1, arg2; arg1 = (double)2 * (double)M_PI * (double)941 / (double)samp; arg2 = (double)2 * (double)M_PI * (double)1336 / (double)samp; for(int i = 0; i < samp; i++) { buf[i] = (short)((double)(ampl) * sin(arg1 * i) + (double)(ampl) * sin(arg2 * i)); }; for (i=0; i<samp; i+=2) { devbuf[p++] = (unsigned char)(buf[i] & 0xff); devbuf[p++] = (unsigned char)((buf[i] >> 8) & 0xff); } for(;;) { if( write( audio_fd, devbuf, samp ) != -1 ) { break; } } ::close( audio_fd );}void CallAudio::clearMe(int cwuser) { if(audioUser==cwuser){ audioUser=0; }}bool CallAudio::audioOwner(int cwuser){ if(audioUser==cwuser) return true; else return false;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -