Example #1
0
void HRIR::update (double azimuth, double elevation)
{
    int nAzimuth = (int) azimuth;
    int nElevation = (int) elevation;
    int taps = mit_hrtf_availability (nAzimuth, nElevation, sampleRate, diffused);

    if (taps)
    {
        leftEar.setSize (1, taps);
        rightEar.setSize (1, taps);

        AudioBuffer<short> leftShort (1, taps);
        AudioBuffer<short> rightShort (1, taps);

        short* const writeLeft = leftShort.getWritePointer (0);
        short* const writeRight = rightShort.getWritePointer (0);

        taps = mit_hrtf_get (&nAzimuth, &nElevation, sampleRate, diffused, writeLeft, writeRight);

        float* const leftEarWrite = leftEar.getWritePointer (0);
        float* const rightEarWrite = rightEar.getWritePointer (0);

        const short* const readLeft = leftShort.getReadPointer (0);
        const short* const readRight = rightShort.getReadPointer (0);

        for (int n = 0; n < taps; ++n)
        {
            leftEarWrite[n] = readLeft[n] / 32768.0f;
            rightEarWrite[n] = readRight[n] / 32768.0f;
        }
    }
}
unsigned int mit_hrtf_get(int* pAzimuth, int* pElevation, unsigned int samplerate, unsigned int diffused, short* psLeft, short* psRight)
{
	int nInternalElevation = 0;
	float fAzimuthIncrement = 0;
	int nInternalAzimuth = 0;
	int nSwitchLeftRight = 0;
	int nAzimuthIndex = 0;
	const mit_hrtf_filter_set_44* pFilter44 = 0;
	const mit_hrtf_filter_set_48* pFilter48 = 0;
	const mit_hrtf_filter_set_88* pFilter88 = 0;
	const mit_hrtf_filter_set_96* pFilter96 = 0;
	const short* psLeftTaps = 0;
	const short* psRightTaps = 0;
	const short* psTempTaps = 0;
	unsigned int nTotalTaps = 0;
	unsigned int niTap = 0;

	//Check if the requested HRTF exists
	if(!mit_hrtf_availability(*pAzimuth, *pElevation, samplerate, diffused)){
	  printf("****************************AVAILABILITY === 0*******************\r\n");
	  return 0;
	}
	//Snap elevation to the nearest available elevation in the filter set
	if(*pElevation < 0)
		nInternalElevation = ((*pElevation - 5) / 10) * 10;
	else
		nInternalElevation = ((*pElevation + 5) / 10) * 10;

	// Elevation of 50 has a maximum 176 in the azimuth plane so we need to handle that.
	if(nInternalElevation == 50)
	{
		if(*pAzimuth < 0)
			*pAzimuth = *pAzimuth < -176 ? -176 : *pAzimuth;
		else
			*pAzimuth = *pAzimuth > 176 ? 176 : *pAzimuth;
	}

	//Snap azimuth to the nearest available azimuth in the filter set.
	switch(nInternalElevation)
	{
	case 0:		fAzimuthIncrement = 180.f / (MIT_HRTF_AZI_POSITIONS_00 - 1);		break;	// 180 5
	case 10:	
	case -10:	fAzimuthIncrement = 180.f / (MIT_HRTF_AZI_POSITIONS_10 - 1);		break;	// 180 5
	case 20:	
	case -20:	fAzimuthIncrement = 180.f / (MIT_HRTF_AZI_POSITIONS_20 - 1);		break;	// 180 5
	case 30:	
	case -30:	fAzimuthIncrement = 180.f / (MIT_HRTF_AZI_POSITIONS_30 - 1);		break;	// 180 6
	case 40:	
	case -40:	fAzimuthIncrement = 180.f / (MIT_HRTF_AZI_POSITIONS_40 - 1);		break;	// 180 6.43
	case 50:	fAzimuthIncrement = 176.f / (MIT_HRTF_AZI_POSITIONS_50 - 1);		break;	// 176 8
	case 60:	fAzimuthIncrement = 180.f / (MIT_HRTF_AZI_POSITIONS_60 - 1);		break;	// 180 10
	case 70:	fAzimuthIncrement = 180.f / (MIT_HRTF_AZI_POSITIONS_70 - 1);		break;	// 180 15
	case 80:	fAzimuthIncrement = 180.f / (MIT_HRTF_AZI_POSITIONS_80 - 1);		break;	// 180 30
	case 90:	fAzimuthIncrement = 0;												break;	// 0   1
	};

	if(*pAzimuth < 0)
	{
		nInternalAzimuth = (int)((int)((-*pAzimuth + fAzimuthIncrement / 2.f) / fAzimuthIncrement) * fAzimuthIncrement + 0.5f);
		nSwitchLeftRight = 1;
	}
	else
	{
		nInternalAzimuth = (int)((int)((*pAzimuth + fAzimuthIncrement / 2.f) / fAzimuthIncrement) * fAzimuthIncrement + 0.5f);
	}

	//Determine array index for azimuth based on elevation
	switch(nInternalElevation)
	{
	case 0:		nAzimuthIndex = (int)((nInternalAzimuth / 180.f) * (MIT_HRTF_AZI_POSITIONS_00 - 1));	break;
	case 10: 
	case -10:	nAzimuthIndex = (int)((nInternalAzimuth / 180.f) * (MIT_HRTF_AZI_POSITIONS_10 - 1));	break;
	case 20:	
	case -20:	nAzimuthIndex = (int)((nInternalAzimuth / 180.f) * (MIT_HRTF_AZI_POSITIONS_20 - 1));	break;
	case 30:	
	case -30:	nAzimuthIndex = (int)((nInternalAzimuth / 180.f) * (MIT_HRTF_AZI_POSITIONS_30 - 1));	break;
	case 40:	
	case -40:	nAzimuthIndex = (int)((nInternalAzimuth / 180.f) * (MIT_HRTF_AZI_POSITIONS_40 - 1));	break;
	case 50:	nAzimuthIndex = (int)((nInternalAzimuth / 176.f) * (MIT_HRTF_AZI_POSITIONS_50 - 1));	break;
	case 60:	nAzimuthIndex = (int)((nInternalAzimuth / 180.f) * (MIT_HRTF_AZI_POSITIONS_60 - 1));	break;
	case 70:	nAzimuthIndex = (int)((nInternalAzimuth / 180.f) * (MIT_HRTF_AZI_POSITIONS_70 - 1));	break;
	case 80:	nAzimuthIndex = (int)((nInternalAzimuth / 180.f) * (MIT_HRTF_AZI_POSITIONS_80 - 1));	break;
	case 90:	nAzimuthIndex = (int)((nInternalAzimuth / 180.f) * (MIT_HRTF_AZI_POSITIONS_90 - 1));	break;
	};

	//The azimuths for +/- elevations need special handling
	if(nInternalElevation == 40 || nInternalElevation == -40)
	{
		nInternalAzimuth = mit_hrtf_findAzimuthFor40Elev(nInternalAzimuth);
		nAzimuthIndex = mit_hrtf_findIndexFor40Elev(nInternalAzimuth);
	}

	//Assign pointer to appropriate array depending on saple rate, normal or diffused filters, elevation, and azimuth index.
	switch(samplerate)
	{
	case 44100:
		if(diffused)
			pFilter44 = &diffuse_44;
		else
			pFilter44 = &normal_44;

		switch(nInternalElevation)
		{	
		case -10:	psLeftTaps = pFilter44->e_10[nAzimuthIndex].left;
					psRightTaps = pFilter44->e_10[nAzimuthIndex].right;		break;
		case -20:	psLeftTaps = pFilter44->e_20[nAzimuthIndex].left;
					psRightTaps = pFilter44->e_20[nAzimuthIndex].right;		break;
		case -30:	psLeftTaps = pFilter44->e_30[nAzimuthIndex].left;
					psRightTaps = pFilter44->e_30[nAzimuthIndex].right;		break;
		case -40:	psLeftTaps = pFilter44->e_40[nAzimuthIndex].left;
					psRightTaps = pFilter44->e_40[nAzimuthIndex].right;		break;
		case 0:		psLeftTaps = pFilter44->e00[nAzimuthIndex].left;
					psRightTaps = pFilter44->e00[nAzimuthIndex].right;		break;
		case 10:	psLeftTaps = pFilter44->e10[nAzimuthIndex].left;
					psRightTaps = pFilter44->e10[nAzimuthIndex].right;		break;
		case 20:	psLeftTaps = pFilter44->e20[nAzimuthIndex].left;
					psRightTaps = pFilter44->e20[nAzimuthIndex].right;		break;
		case 30:	psLeftTaps = pFilter44->e30[nAzimuthIndex].left;
					psRightTaps = pFilter44->e30[nAzimuthIndex].right;		break;
		case 40:	psLeftTaps = pFilter44->e40[nAzimuthIndex].left;
					psRightTaps = pFilter44->e40[nAzimuthIndex].right;		break;
		case 50:	psLeftTaps = pFilter44->e50[nAzimuthIndex].left;
					psRightTaps = pFilter44->e50[nAzimuthIndex].right;		break;
		case 60:	psLeftTaps = pFilter44->e60[nAzimuthIndex].left;
					psRightTaps = pFilter44->e60[nAzimuthIndex].right;		break;
		case 70:	psLeftTaps = pFilter44->e70[nAzimuthIndex].left;
					psRightTaps = pFilter44->e70[nAzimuthIndex].right;		break;
		case 80:	psLeftTaps = pFilter44->e80[nAzimuthIndex].left;
					psRightTaps = pFilter44->e80[nAzimuthIndex].right;		break;
		case 90:	psLeftTaps = pFilter44->e90[nAzimuthIndex].left;
					psRightTaps = pFilter44->e90[nAzimuthIndex].right;		break;
		};
		
		//How many taps to copy later to user's buffers
		nTotalTaps = MIT_HRTF_44_TAPS;
		break;
	case 48000:
		if(diffused)
			pFilter48 = &diffuse_48;
		else
			pFilter48 = &normal_48;

		switch(nInternalElevation)
		{	
		case -10:	psLeftTaps = pFilter48->e_10[nAzimuthIndex].left;
					psRightTaps = pFilter48->e_10[nAzimuthIndex].right;		break;
		case -20:	psLeftTaps = pFilter48->e_20[nAzimuthIndex].left;
					psRightTaps = pFilter48->e_20[nAzimuthIndex].right;		break;
		case -30:	psLeftTaps = pFilter48->e_30[nAzimuthIndex].left;
					psRightTaps = pFilter48->e_30[nAzimuthIndex].right;		break;
		case -40:	psLeftTaps = pFilter48->e_40[nAzimuthIndex].left;
					psRightTaps = pFilter48->e_40[nAzimuthIndex].right;		break;
		case 0:		psLeftTaps = pFilter48->e00[nAzimuthIndex].left;
					psRightTaps = pFilter48->e00[nAzimuthIndex].right;		break;
		case 10:	psLeftTaps = pFilter48->e10[nAzimuthIndex].left;
					psRightTaps = pFilter48->e10[nAzimuthIndex].right;		break;
		case 20:	psLeftTaps = pFilter48->e20[nAzimuthIndex].left;
					psRightTaps = pFilter48->e20[nAzimuthIndex].right;		break;
		case 30:	psLeftTaps = pFilter48->e30[nAzimuthIndex].left;
					psRightTaps = pFilter48->e30[nAzimuthIndex].right;		break;
		case 40:	psLeftTaps = pFilter48->e40[nAzimuthIndex].left;
					psRightTaps = pFilter48->e40[nAzimuthIndex].right;		break;
		case 50:	psLeftTaps = pFilter48->e50[nAzimuthIndex].left;
					psRightTaps = pFilter48->e50[nAzimuthIndex].right;		break;
		case 60:	psLeftTaps = pFilter48->e60[nAzimuthIndex].left;
					psRightTaps = pFilter48->e60[nAzimuthIndex].right;		break;
		case 70:	psLeftTaps = pFilter48->e70[nAzimuthIndex].left;
					psRightTaps = pFilter48->e70[nAzimuthIndex].right;		break;
		case 80:	psLeftTaps = pFilter48->e80[nAzimuthIndex].left;
					psRightTaps = pFilter48->e80[nAzimuthIndex].right;		break;
		case 90:	psLeftTaps = pFilter48->e90[nAzimuthIndex].left;
					psRightTaps = pFilter48->e90[nAzimuthIndex].right;		break;
		};
		
		//How many taps to copy later to user's buffers
		nTotalTaps = MIT_HRTF_48_TAPS;
		break;
	case 88200:
		if(diffused)
			pFilter88 = &diffuse_88;
		else
			pFilter88 = &normal_88;

		switch(nInternalElevation)
		{	
		case -10:	psLeftTaps = pFilter88->e_10[nAzimuthIndex].left;
					psRightTaps = pFilter88->e_10[nAzimuthIndex].right;		break;
		case -20:	psLeftTaps = pFilter88->e_20[nAzimuthIndex].left;
					psRightTaps = pFilter88->e_20[nAzimuthIndex].right;		break;
		case -30:	psLeftTaps = pFilter88->e_30[nAzimuthIndex].left;
					psRightTaps = pFilter88->e_30[nAzimuthIndex].right;		break;
		case -40:	psLeftTaps = pFilter88->e_40[nAzimuthIndex].left;
					psRightTaps = pFilter88->e_40[nAzimuthIndex].right;		break;
		case 0:		psLeftTaps = pFilter88->e00[nAzimuthIndex].left;
					psRightTaps = pFilter88->e00[nAzimuthIndex].right;		break;
		case 10:	psLeftTaps = pFilter88->e10[nAzimuthIndex].left;
					psRightTaps = pFilter88->e10[nAzimuthIndex].right;		break;
		case 20:	psLeftTaps = pFilter88->e20[nAzimuthIndex].left;
					psRightTaps = pFilter88->e20[nAzimuthIndex].right;		break;
		case 30:	psLeftTaps = pFilter88->e30[nAzimuthIndex].left;
					psRightTaps = pFilter88->e30[nAzimuthIndex].right;		break;
		case 40:	psLeftTaps = pFilter88->e40[nAzimuthIndex].left;
					psRightTaps = pFilter88->e40[nAzimuthIndex].right;		break;
		case 50:	psLeftTaps = pFilter88->e50[nAzimuthIndex].left;
					psRightTaps = pFilter88->e50[nAzimuthIndex].right;		break;
		case 60:	psLeftTaps = pFilter88->e60[nAzimuthIndex].left;
					psRightTaps = pFilter88->e60[nAzimuthIndex].right;		break;
		case 70:	psLeftTaps = pFilter88->e70[nAzimuthIndex].left;
					psRightTaps = pFilter88->e70[nAzimuthIndex].right;		break;
		case 80:	psLeftTaps = pFilter88->e80[nAzimuthIndex].left;
					psRightTaps = pFilter88->e80[nAzimuthIndex].right;		break;
		case 90:	psLeftTaps = pFilter88->e90[nAzimuthIndex].left;
					psRightTaps = pFilter88->e90[nAzimuthIndex].right;		break;
		};
		
		//How many taps to copy later to user's buffers
		nTotalTaps = MIT_HRTF_88_TAPS;
		break;
	case 96000:
		if(diffused)
			pFilter96 = &diffuse_96;
		else
			pFilter96 = &normal_96;

		switch(nInternalElevation)
		{	
		case -10:	psLeftTaps = pFilter96->e_10[nAzimuthIndex].left;
					psRightTaps = pFilter96->e_10[nAzimuthIndex].right;		break;
		case -20:	psLeftTaps = pFilter96->e_20[nAzimuthIndex].left;
					psRightTaps = pFilter96->e_20[nAzimuthIndex].right;		break;
		case -30:	psLeftTaps = pFilter96->e_30[nAzimuthIndex].left;
					psRightTaps = pFilter96->e_30[nAzimuthIndex].right;		break;
		case -40:	psLeftTaps = pFilter96->e_40[nAzimuthIndex].left;
					psRightTaps = pFilter96->e_40[nAzimuthIndex].right;		break;
		case 0:		psLeftTaps = pFilter96->e00[nAzimuthIndex].left;
					psRightTaps = pFilter96->e00[nAzimuthIndex].right;		break;
		case 10:	psLeftTaps = pFilter96->e10[nAzimuthIndex].left;
					psRightTaps = pFilter96->e10[nAzimuthIndex].right;		break;
		case 20:	psLeftTaps = pFilter96->e20[nAzimuthIndex].left;
					psRightTaps = pFilter96->e20[nAzimuthIndex].right;		break;
		case 30:	psLeftTaps = pFilter96->e30[nAzimuthIndex].left;
					psRightTaps = pFilter96->e30[nAzimuthIndex].right;		break;
		case 40:	psLeftTaps = pFilter96->e40[nAzimuthIndex].left;
					psRightTaps = pFilter96->e40[nAzimuthIndex].right;		break;
		case 50:	psLeftTaps = pFilter96->e50[nAzimuthIndex].left;
					psRightTaps = pFilter96->e50[nAzimuthIndex].right;		break;
		case 60:	psLeftTaps = pFilter96->e60[nAzimuthIndex].left;
					psRightTaps = pFilter96->e60[nAzimuthIndex].right;		break;
		case 70:	psLeftTaps = pFilter96->e70[nAzimuthIndex].left;
					psRightTaps = pFilter96->e70[nAzimuthIndex].right;		break;
		case 80:	psLeftTaps = pFilter96->e80[nAzimuthIndex].left;
					psRightTaps = pFilter96->e80[nAzimuthIndex].right;		break;
		case 90:	psLeftTaps = pFilter96->e90[nAzimuthIndex].left;
					psRightTaps = pFilter96->e90[nAzimuthIndex].right;		break;
		};
		
		//How many taps to copy later to user's buffers
		nTotalTaps = MIT_HRTF_96_TAPS;
		break;
	};

	//Switch left and right ear if the azimuth is to the left of front centre (azimuth < 0)
	if(nSwitchLeftRight)
	{
		psTempTaps = psRightTaps;
		psRightTaps = psLeftTaps;
		psLeftTaps = psTempTaps;
	}
	
	//Copy taps to user's arrays
	for(niTap = 0; niTap < nTotalTaps; niTap++)
	{
		psLeft[niTap] = psLeftTaps[niTap];
		psRight[niTap] = psRightTaps[niTap];
	}

	//Assign the real azimuth and elevation used
	*pAzimuth = nInternalAzimuth;
	*pElevation = nInternalElevation;

	return nTotalTaps;	
}