Reply by nobby_trussin July 22, 20062006-07-22
Many thanks for your reply, that's a great help. I hadn't even 
considered doing it that way

kind regards

Dan

William C Bonner <wbonner@wimsworld.com> wrote:
> If you use the arrays the same size, your source array only has half > the number of points filled in, and the rest of the points padded with > zeros I think you'll get the effect that you want. I've used this to > interpolate data in the past. It increases your uncertainty, but can > smoth some curves. > > > Here's a FFT Interpolate function that I wrote a few years ago using a > mixed radix FFT routine I had turned into a DLL a few years before > that. > > bool FFTInterpolate(int numSourcePoints, double * SourcePoints, int > numDestinationPoints, double * DestinationPoints, bool ComplexData/* = > false*/) > // Destination size must be at least twice the the source size. > // inverse fft of 256 points > // split results to top and bottom of destination points > // fft new data > { > bool rval = false; > if (ComplexData) > { > /* Try linking and loading the Fortran FFT DLL */ > HINSTANCE hFFTLib = LoadLibrary(TEXT ("MRFFT.DLL")); > if (hFFTLib != NULL) > { > int (__stdcall * FFTMIXED)(double A[], double B[], int& NSEG, int& > N, int& NSPN, int& ISN); > FFTMIXED = (int (__stdcall *)(double [],double [],int &,int &,int > &,int &))GetProcAddress(hFFTLib,"FFTMIXED"); > if (FFTMIXED != NULL) > { > // copy the data to the destination space > for (int index = 0; index < numSourcePoints * 2; index++) > { > DestinationPoints[index] = SourcePoints[index]; > } > // zero out the remaining destination space > for (; index < numDestinationPoints * 2; index++) > { > DestinationPoints[index] = 0.0; > } > int isign = 2; > int nseg = 1; > int nspn = 1; > int n = numSourcePoints; > // fft the data > FFTMIXED(DestinationPoints, DestinationPoints + 1, nseg, n, nspn, > isign); > // move the second half of the fft'd source data to the end of the > array > for (index = (numSourcePoints * 2) - 1; index > (numSourcePoints - > 1); index--) > { > DestinationPoints[(2 * (numDestinationPoints - numSourcePoints)) + > index] = DestinationPoints[index]; > DestinationPoints[index] = 0.0; > } > isign = -2; > nseg = 1; > nspn = 1; > n = numDestinationPoints; > // reverse fft the data > FFTMIXED(DestinationPoints, DestinationPoints + 1, nseg, n, nspn, > isign); > rval = true; > } > FreeLibrary(hFFTLib); > } > } > else > { > // Do stuff to allocate memory, and copy the data to bigger memory > double * newSourcePoints = new double[numSourcePoints*2]; > for (int index = 0; index < numSourcePoints; index++) > { > newSourcePoints[index*2] = SourcePoints[index]; > newSourcePoints[index*2+1] = 0.0; > } > double * newDestinationPoints = new double[numDestinationPoints*2]; > rval = FFTInterpolate(numSourcePoints, newSourcePoints, > numDestinationPoints, newDestinationPoints, true); > // do stuff to get real data back out from the complex data > delete[] newSourcePoints; > for (index = 0; index < numDestinationPoints; index++) > { > // Absolute Value of complex data > DestinationPoints[index] = sqrt(newDestinationPoints[index*2] * > newDestinationPoints[index*2] + > newDestinationPoints[index*2+1] * newDestinationPoints[index*2+1]); > } > delete[] newDestinationPoints; > } > return(rval); > } > > > > nobby_trussin wrote: >> Hi, >> >> I am using FFTW to obtain freq values from an audio signal.The input and >> output arrays are the same size. However, I need more precision (i need >> to detect frequencies which aren't whole numbers) therefore as i >> understand it i need a larger output array than my input one. >> >> i am using the real-to-real fftw_plan_r2r_1d function as follows: >> fftw_plan_r2r_1d (numSamples, in, out, FFTW_R2HC, FFTW_FORWARD); >> >> The fftw manual states that when using this function the input and >> output arrays must be of the same size so i am assuming i should use a >> different function. I have read the documentation for the other >> functions but none seem to really match my requirements. Has anyone come >> across anything like this before? >> >> Any suggestions are most welcome >> >> Thank you >> >> Dan >
Reply by William C Bonner July 21, 20062006-07-21
If you use the arrays the same size, your source array only has half
the number of points filled in, and the rest of the points padded with
zeros I think you'll get the effect that you want.  I've used this to
interpolate data in the past.  It increases your uncertainty, but can
smoth some curves.


Here's a FFT Interpolate function that I wrote a few years ago using a
mixed radix FFT routine I had turned into a DLL a few years before
that.

bool FFTInterpolate(int numSourcePoints, double * SourcePoints, int
numDestinationPoints, double * DestinationPoints, bool ComplexData/* =
false*/)
// Destination size must be at least twice the the source size.
// inverse fft of 256 points
// split results to top and bottom of destination points
// fft new data
{
	bool rval = false;
	if (ComplexData)
	{
		/* Try linking and loading the Fortran FFT DLL */
		HINSTANCE hFFTLib = LoadLibrary(TEXT ("MRFFT.DLL"));
		if (hFFTLib != NULL)
		{
			int (__stdcall * FFTMIXED)(double A[], double B[], int& NSEG, int&
N, int& NSPN, int& ISN);
			FFTMIXED = (int (__stdcall *)(double [],double [],int &,int &,int
&,int &))GetProcAddress(hFFTLib,"FFTMIXED");
			if (FFTMIXED != NULL)
			{
				// copy the data to the destination space
				for (int index = 0; index < numSourcePoints * 2; index++)
				{
					DestinationPoints[index] = SourcePoints[index];
				}
				// zero out the remaining destination space
				for (; index < numDestinationPoints * 2; index++)
				{
					DestinationPoints[index] = 0.0;
				}
				int isign = 2;
				int nseg = 1;
				int nspn = 1;
				int n = numSourcePoints;
				// fft the data
				FFTMIXED(DestinationPoints, DestinationPoints + 1, nseg, n, nspn,
isign);
				// move the second half of the fft'd source data to the end of the
array
				for (index = (numSourcePoints * 2) - 1; index > (numSourcePoints -
1); index--)
				{
					DestinationPoints[(2 * (numDestinationPoints - numSourcePoints)) +
index] = DestinationPoints[index];
					DestinationPoints[index] = 0.0;
				}
				isign = -2;
				nseg = 1;
				nspn = 1;
				n = numDestinationPoints;
				// reverse fft the data
				FFTMIXED(DestinationPoints, DestinationPoints + 1, nseg, n, nspn,
isign);
				rval = true;
			}
			FreeLibrary(hFFTLib);
		}
	}
	else
	{
		// Do stuff to allocate memory, and copy the data to bigger memory
		double * newSourcePoints = new double[numSourcePoints*2];
		for (int index = 0; index < numSourcePoints; index++)
		{
			newSourcePoints[index*2] = SourcePoints[index];
			newSourcePoints[index*2+1] = 0.0;
		}
		double * newDestinationPoints = new double[numDestinationPoints*2];
		rval = FFTInterpolate(numSourcePoints, newSourcePoints,
numDestinationPoints, newDestinationPoints, true);
		// do stuff to get real data back out from the complex data
		delete[] newSourcePoints;
		for (index = 0; index < numDestinationPoints; index++)
		{
			// Absolute Value of complex data
			DestinationPoints[index] = sqrt(newDestinationPoints[index*2] *
newDestinationPoints[index*2] +
				newDestinationPoints[index*2+1] * newDestinationPoints[index*2+1]);
		}
		delete[] newDestinationPoints;
	}
	return(rval);
}



nobby_trussin wrote:
> Hi, > > I am using FFTW to obtain freq values from an audio signal.The input and > output arrays are the same size. However, I need more precision (i need > to detect frequencies which aren't whole numbers) therefore as i > understand it i need a larger output array than my input one. > > i am using the real-to-real fftw_plan_r2r_1d function as follows: > fftw_plan_r2r_1d (numSamples, in, out, FFTW_R2HC, FFTW_FORWARD); > > The fftw manual states that when using this function the input and > output arrays must be of the same size so i am assuming i should use a > different function. I have read the documentation for the other > functions but none seem to really match my requirements. Has anyone come > across anything like this before? > > Any suggestions are most welcome > > Thank you > > Dan
Reply by Anton July 21, 20062006-07-21
nobby_trussin <nobby_trussin@yahoo.com> writes:

> Hi, > > I am using FFTW to obtain freq values from an audio signal.The input > and output arrays are the same size. However, I need more precision (i > need to detect frequencies which aren't whole numbers) therefore as i > understand it i need a larger output array than my input one. >
Hi, Do you really need more precision or could you maybe just interpolate between the values of the bins (e.g. by zero padding before you take the fft)? I think that if you really need more precision, the fft cannot help you. Maybe with a chirp-z transform you can get more precise information for a given range of frequencies that you want to examine. Or with a very sharp bandpass filter at the wanted frequency. gr. Anton
Reply by Jerry Avins July 21, 20062006-07-21
nobby_trussin wrote:
> Hi, > > I am using FFTW to obtain freq values from an audio signal.The input and > output arrays are the same size. However, I need more precision (i need > to detect frequencies which aren't whole numbers) therefore as i > understand it i need a larger output array than my input one. > > i am using the real-to-real fftw_plan_r2r_1d function as follows: > fftw_plan_r2r_1d (numSamples, in, out, FFTW_R2HC, FFTW_FORWARD); > > The fftw manual states that when using this function the input and > output arrays must be of the same size so i am assuming i should use a > different function. I have read the documentation for the other > functions but none seem to really match my requirements. Has anyone come > across anything like this before? > > Any suggestions are most welcome
It's true that you need a larger output array. The way to get it is with a larger input array. You can pad the input with fake information (zeros) and make the output look prettier, or gather more real information (sample longer) and make the output meaningful. Jerry -- Engineering is the art of making what you want from things you can get. &#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;
Reply by nobby_trussin July 21, 20062006-07-21
Hi,

I am using FFTW to obtain freq values from an audio signal.The input and 
output arrays are the same size. However, I need more precision (i need 
to detect frequencies which aren't whole numbers) therefore as i 
understand it i need a larger output array than my input one.

i am using the real-to-real fftw_plan_r2r_1d function as follows:
fftw_plan_r2r_1d (numSamples, in, out, FFTW_R2HC, FFTW_FORWARD);

The fftw manual states that when using this function the input and 
output arrays must be of the same size so i am assuming i should use a 
different function. I have read the documentation for the other 
functions but none seem to really match my requirements. Has anyone come 
across anything like this before?

Any suggestions are most welcome

Thank you

Dan