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

📄 jvoipsimplelocalisation.cpp

📁 使用VOIP进行网络传输声音的类库
💻 CPP
字号:
/*    This file is a part of JVOIPLIB, a library designed to facilitate    the use of Voice over IP (VoIP).    Copyright (C) 2000-2004  Jori Liesenborgs (jori@lumumba.luc.ac.be)    This library (JVOIPLIB) is based upon work done for my thesis at    the School for Knowledge Technology (Belgium/The Netherlands)    This file was developed at the 'Expertise Centre for Digital    Media' (EDM) in Diepenbeek, Belgium (http://www.edm.luc.ac.be).    The EDM is a research institute of the 'Limburgs Universitair    Centrum' (LUC) (http://www.luc.ac.be).    The full GNU Library General Public License can be found in the    file LICENSE.LGPL which is included in the source code archive.    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Library General Public    License as published by the Free Software Foundation; either    version 2 of the License, or (at your option) any later version.    This library is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    Library General Public License for more details.    You should have received a copy of the GNU Library General Public    License along with this library; if not, write to the Free    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307    USA*/#include "jvoipconfig.h"#ifndef JVOIPDISABLE_LOCALISATION_SIMPLE#include "jvoipsimplelocalisation.h"#include <math.h>#include "debugnew.h"#define JVOIPSIMPLELOCALISATION_HEADRADIUS				0.15#define JVOIPSIMPLELOCALISATION_SPEEDOFSOUND				343.0 // meters/secondJVOIPSimpleLocalisation::JVOIPSimpleLocalisation(JVOIPSession *sess):JVOIPSessionLocalisation(sess){	init = false;}JVOIPSimpleLocalisation::~JVOIPSimpleLocalisation(){	Cleanup();}int JVOIPSimpleLocalisation::Init(int outputsamprate,int outputbytespersample,const JVOIPComponentParams *componentparams){	if (init)		return ERR_JVOIPLIB_GENERAL_COMPONENTALREADYINIT;	samplerate = outputsamprate;	bytespersample = outputbytespersample;	init = true;	return 0;}int JVOIPSimpleLocalisation::Cleanup(){	if (!init)		return ERR_JVOIPLIB_GENERAL_COMPONENTNOTINIT;	init = false;	return 0;}int JVOIPSimpleLocalisation::Create3DEffect(double local_x,double local_y,double local_z,                                            double righteardir_x,double righteardir_y,double righteardir_z,        		                    double frontdir_x,double frontdir_y,double frontdir_z,					    double updir_x,double updir_y,double updir_z,                                            double remote_x,double remote_y,double remote_z,                                            VoIPFramework::VoiceBlock *vb,                                            VoIPFramework::VOIPuint64 sourceid){	double vectlen;	int status,len,newlen,maxsampoff;	int rightadd,leftadd;	int i,val;	if (!init)		return ERR_JVOIPLIB_GENERAL_COMPONENTNOTINIT;	if (vb->IsStereo()) // we can't handle this (and it shouldn't happen either	{		// Silence!		vb->Clear();		return 0;	}	// First, we'll get the necessary data	data = vb->GetSamples(false);	if (data == NULL)		return 0;	datalen = vb->GetNumBytes();	if (datalen <= 0)		return 0;	vblock = vb;	localpos[0] = local_x;	localpos[1] = local_y;	localpos[2] = local_z;	vectlen = sqrt(righteardir_x*righteardir_x + righteardir_y*righteardir_y + righteardir_z*righteardir_z);	righteardir[0] = righteardir_x/vectlen;	righteardir[1] = righteardir_y/vectlen;	righteardir[2] = righteardir_z/vectlen;	remotepos[0] = remote_x;	remotepos[1] = remote_y;	remotepos[2] = remote_z;	// Calculate distance to each ear (also time-distance)	CalculateDistances();	// Calculate the Interaural Time Difference (ITD), expressed in samples	leftearsampleoffset = (int)((lefteartimedist*(double)samplerate)+0.5);	rightearsampleoffset = (int)((righteartimedist*(double)samplerate)+0.5);	// Calculate the amplitude factors, used to calculate the Interaural Intensity Difference (IID)	leftearampfactor = JVOIPSIMPLELOCALISATION_HEADRADIUS/lefteardist;	rightearampfactor = JVOIPSIMPLELOCALISATION_HEADRADIUS/righteardist;	// Allocate a new buffer	if ((status = AllocateNewBuffer()) < 0)	{		vb->Clear();		return status;	}	// Convert the original data to the right samplerate and bytes per sample	sampconv.SetConversionParams((int)vb->GetSampleRate(),false,(int)vb->GetBytesPerSample(),false,false,	                             samplerate,true,bytespersample,false,false);	maxsampoff = (leftearsampleoffset > rightearsampleoffset)?leftearsampleoffset:rightearsampleoffset;	newlen = newdatalen-maxsampoff*bytespersample*2; // the '2' is for stereo	len = sampconv.Convert(data,datalen,newdata,newlen);	if (len < 2)	{		vb->Clear();		return 0;	}	if (len < newlen)	{		if (bytespersample == 1)		{			unsigned char copybyte;			copybyte = newdata[len-1];			while (len < newlen)				newdata[len++] = copybyte;		}		else // two bytes per sample		{			unsigned char copybyte1,copybyte2;			copybyte1 = newdata[len-2];			copybyte2 = newdata[len-1];			while (len < newlen)			{				newdata[len++] = copybyte1;				newdata[len++] = copybyte2;			}		}	}	// Insert the right offsets and apply the amplitude factors	rightadd = rightearsampleoffset*2*bytespersample;	leftadd = leftearsampleoffset*2*bytespersample;	if (bytespersample == 1)	{		for (i = newlen-1 ; i >= 0 ; i -= 2)		{			// for the right ear			val = ((int)newdata[i])-127;			val = (int)((((double)val)*rightearampfactor)+0.5);			val += 127;			if (val > 255)				val = 255;			else if (val < 0)				val = 0;			newdata[i+rightadd] = (unsigned char)val;			// for the left ear			val = ((int)newdata[i-1])-127;			val = (int)((((double)val)*leftearampfactor)+0.5);			val += 127;			if (val > 255)				val = 255;			else if (val < 0)				val = 0;			newdata[i-1+leftadd] = (unsigned char)val;		}		// set some stuff to silence		for (i = newlen+leftadd ; i < newdatalen ; i += 2)			newdata[i] = 127;		for (i = newlen+1+rightadd ; i < newdatalen ; i += 2)			newdata[i] = 127;		for (i = 0 ; i < leftadd ; i += 2)			newdata[i] = 127;		for (i = 1 ; i < rightadd+1 ; i += 2)			newdata[i] = 127;	}	else // two bytes per sample	{		for (i = newlen-2 ; i >= 0 ; i -= 4)		{			// for the right ear			val = (((int)newdata[i+1])|(((int)newdata[i])<<8))-32767;			val = (int)((((double)val)*rightearampfactor)+0.5);			val += 32767;			if (val > 65535)				val = 65535;			else if (val < 0)				val = 0;			newdata[i+rightadd] = (unsigned char)((val>>8)&255);			newdata[i+rightadd+1] = (unsigned char)(val&255);			// for the left ear			val = (((int)newdata[i-1])|(((int)newdata[i-2])<<8))-32767;			val = (int)((((double)val)*rightearampfactor)+0.5);			val += 32767;			if (val > 65535)				val = 65535;			else if (val < 0)				val = 0;			newdata[i-2+leftadd] = (unsigned char)((val>>8)&255);			newdata[i-1+leftadd] = (unsigned char)(val&255);		}		// set some stuff to silence		for (i = newlen+leftadd ; i < newdatalen ; i += 4)		{			newdata[i] = 127;			newdata[i+1] = 255;		}		for (i = newlen+2+rightadd ; i < newdatalen ; i += 4)		{			newdata[i] = 127;			newdata[i+1] = 255;		}		for (i = 0 ; i < leftadd ; i += 4)		{			newdata[i] = 127;			newdata[i+1] = 255;		}		for (i = 2 ; i < rightadd+2 ; i += 4)		{			newdata[i] = 127;			newdata[i+1] = 255;		}	}	vb->SetSamples(newdata,newdatalen);	vb->SetNumSamples(newnumsamples);	vb->SetStereo(true);	vb->SetSampleRate(samplerate);	vb->SetBytesPerSample(bytespersample);	return 0;}bool JVOIPSimpleLocalisation::SupportsOutputSamplingRate(int orate){	if (!init)		return false;	return true;}int JVOIPSimpleLocalisation::SetOutputSamplingRate(int orate){	if (!init)		return ERR_JVOIPLIB_GENERAL_COMPONENTNOTINIT;	samplerate = orate;	return 0;}bool JVOIPSimpleLocalisation::SupportsOutputBytesPerSample(int outputbytespersample){	if (!init)		return false;	return true;}int JVOIPSimpleLocalisation::SetOutputBytesPerSample(int outputbytespersample){	if (!init)		return ERR_JVOIPLIB_GENERAL_COMPONENTNOTINIT;	bytespersample = outputbytespersample;	return 0;}int JVOIPSimpleLocalisation::GetComponentState(JVOIPComponentState **compstate){	// NOTE: nothing to do...	*compstate = NULL;	return 0;}int JVOIPSimpleLocalisation::SetComponentState(JVOIPComponentState *compstate){	// NOTE: nothing to do...	return 0;}std::string JVOIPSimpleLocalisation::GetComponentName(){	return std::string("JVOIPSimpleLocalisation");}std::string JVOIPSimpleLocalisation::GetComponentDescription(){	return std::string("JVOIPLIB Internal basic localisation module");}std::vector<JVOIPCompParamInfo> *JVOIPSimpleLocalisation::GetComponentParameters() throw (JVOIPException){	return NULL;}void JVOIPSimpleLocalisation::CalculateDistances(){	double pos[3];	double diff;	int i;	// calculate the right ear distance to the sound source	for (i = 0 ; i < 3 ; i++)		pos[i] = localpos[i]+righteardir[i]*JVOIPSIMPLELOCALISATION_HEADRADIUS;	righteardist = 0;        for (i = 0 ; i < 3 ; i++)	{		diff = pos[i]-remotepos[i];		righteardist += diff*diff;	}	righteardist = sqrt(righteardist);	if (righteardist < JVOIPSIMPLELOCALISATION_HEADRADIUS)		righteardist = JVOIPSIMPLELOCALISATION_HEADRADIUS;	// calculate the left ear distance to the sound source	for (i = 0 ; i < 3 ; i++)		pos[i] = localpos[i]-righteardir[i]*JVOIPSIMPLELOCALISATION_HEADRADIUS;	lefteardist = 0;        for (i = 0 ; i < 3 ; i++)	{		diff = pos[i]-remotepos[i];		lefteardist += diff*diff;	}	lefteardist = sqrt(lefteardist);	if (lefteardist < JVOIPSIMPLELOCALISATION_HEADRADIUS)		lefteardist = JVOIPSIMPLELOCALISATION_HEADRADIUS;	// calculate the time distance	lefteartimedist = lefteardist/JVOIPSIMPLELOCALISATION_SPEEDOFSOUND;	righteartimedist = righteardist/JVOIPSIMPLELOCALISATION_SPEEDOFSOUND;}int JVOIPSimpleLocalisation::AllocateNewBuffer(){	int maxaddsamples;	double rateratio;	rateratio = ((double)samplerate)/((double)vblock->GetSampleRate());	newnumsamples = (int)((((double)vblock->GetNumSamples())*rateratio)+0.5);        maxaddsamples = (rightearsampleoffset > leftearsampleoffset)?rightearsampleoffset:leftearsampleoffset;	newnumsamples += maxaddsamples;	newdatalen = newnumsamples*2; // we'll be using stereo	if (bytespersample != 1)		newdatalen *= 2;	newdata = new unsigned char[newdatalen];	if (newdata == NULL)		return ERR_JVOIPLIB_GENERAL_OUTOFMEM;	return 0;}#endif // JVOIPDISABLE_LOCALISATION_SIMPLE

⌨️ 快捷键说明

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