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

📄 callaudio.cpp

📁 KphoneSI (kpsi) is a SIP (Session Initiation Protocol) user agent for Linux, with which you can in
💻 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 + -