I have an array of doubles which is the result of the FFT applied on an array, that contains the audio data of a Wav audio file in which i have added a 1000Hz tone.
I obtained this array thought the DREALFT defined in "Numerical Recipes".(I must use it).
(The original array has a length that is power of two.)
Mine array has this structure:
array[0] = first real valued component of the complex transform
array[1] = last real valued component of the complex transform
array[2] = real part of the second element
array[3] = imaginary part of the second element
etc......
Now, i know that this array represent the frequency domain.
I want to determine and kill the 1000Hz frequency.
I have tried this formula for finding the index of the array which should contain the 1000Hz frequency:
index = 1000. * NElements /44100;
Also, since I assume that this index refers to an array with real values only, i have determined the correct(?) position in my array, that contains imaginary values too:
int correctIndex=2;
for(k=0;k<index;k++){
correctIndex+=2;
}
(I know that surely there is a way easier but it is the first that came to mind)
Then, i find this value: 16275892957.123705, which i suppose to be the real part of the 1000Hz frequency.(Sorry if this is an imprecise affermation but at the moment I do not care to know more about it)
So i have tried to suppress it:
array[index]=-copy[index]*0.1f;
I don't know exactly why i used this formula but is the only one that gives some results, in fact the 1000hz tone appears to decrease slightly.
This is the part of the code in question:
double *copy = malloc( nCampioni * sizeof(double));
int nSamples;
/*...Fill copy with audio data...*/
/*...Apply ZERO PADDING and reach the length of 8388608 samples,
or rather 8388608 double values...*/
/*Apply the FFT (Sure this works)*/
drealft(copy - 1, nSamples, 1);
/*I determine the REAL(?) array index*/
i= 1000. * nSamples /44100;
/*I determine MINE(?) array index*/
int j=2;
for(k=0;k<i;k++){
j+=2;
}
/*I reduce the array value, AND some other values aroud it as an attempt*/
for(i=-12;i<12;i+=2){
copy[j-i]=-copy[i-j]*0.1f;
printf("%d\n",j-i);
}
/*Apply the inverse FFT*/
drealft(copy - 1, nSamples, -1);
/*...Write the audio data on the file...*/
NOTE: for simplicity I omitted the part where I get an array of double from an array of int16_t
How can i determine and totally kill the 1000Hz frequency?
Thank you!
As Oli Charlesworth writes, because your target frequency is not exactly one of the FFT bins (your index, TargetFrequency * NumberOfElements / SamplingRate, is not exactly an integer), the energy of the target frequency will be spread across all bins. For a start, you can eliminate some of the frequency by zeroing the bin closest to the target frequency. This will of course affect other frequencies somewhat too, since it is slightly off target. To better suppress the target frequency, you will need to consider a more sophisticated filter.
However, for educational purposes: To suppress the frequency corresponding to a bin, simply set that bin to zero. You must set both the real and the imaginary components of the bin to zero, which you can do with:
copy[index*2 + 0] = 0;
copy[index*2 + 1] = 1;
Some notes about this:
You had this code to calculate the position in the array:
int correctIndex = 2;
for (k = 0; k < index; k++) {
correctIndex += 2;
}
That is equivalent to:
correctIndex = 2*(index+1);
I believe you want 2*index, not 2*(index+1). So you were likely reducing the wrong bin.
At one point in your question, you wrote array[index] = -copy[index]*0.1f;. I do not know what array is. You appeared to be working in place in copy. I also do not know why you multiplied by 1/10. If you want to eliminate a frequency, just set it to zero. Multiplying it by 1/10 only reduces it to 10% of its original magnitude.
I understand that you must pass copy-1 to drealft because the Numerical Recipes code uses one-based indexing. However, the C standard does not support the way you are doing it. The behavior of the expression copy-1 is not defined by the standard. It will work in most C implementations. However, to write supported portable code, you should do this instead:
// Allocate one extra element.
double *memory = malloc((nCampioni+1) * sizeof *memory);
// Make a pointer that is convenient for your work.
double *copy = memory+1;
…
// Pass the necessary base address to drealft.
drealft(memory, nSamples, 1);
// Suppress a frequency.
copy[index*2 + 0] = 0;
copy[index*2 + 1] = 0;
…
// Free the memory.
free(memory);
One experiment I suggest you consider is to initialize an array with just a sine wave at the desired frequency:
for (i = 0; i < nSamples; ++i)
copy[i] = sin(TwoPi * Frequency / SampleRate * i);
(TwoPi is of course 2*3.1415926535897932384626433.) Then apply drealft and look at the results. You will see that much of the energy is at a peak in the closest bin to the target frequency, but much of it has also spread to other bins. Clearly, zeroing a single bin and performing the inverse FFT cannot eliminate all of the frequency. Also, you should see that the peak is in the same bin you calculated for index. If it is not, something is wrong.
Related
I'm looking for a "cannonical" name of a data structure with the characteristics below. I can implement it with a little thought given my application, but I'm curious if there's a matching data structure type or algorithm that's been studied in the past.
Requirements:
Fixed size array backing
Writing uses monotonically increasing strides in the following sense:
The array is filled from start to finish with single index increases until the array is filled. E.g. given an integer i = 0 and an unchanging fixed size integer n, the array is filled with i++ until i = n.
The index is then reset to the second element (index 1), so i = 1. The stride thus increases by a value of 1; in general the stride will increase by 1 each time the array bound is met or overshot. For the first time the stride is increased, instead of i++ we have i = i + 2 until i >= n.
int sRes=0;
template<T>
void addElement(T* element)
{
if(i >= n)
{
if (stride > 2*n)
{
sRes++;
// keep stride from overflowing the integer type
stride = (stride mod n);
}
stride += 1;
i = stride mod n;
}
// array of AR type, AR defined in #3 below
array[i] = new AR(element, stride);
i += stride;
}
Array elements include the "stride value" when the entry was written/overwritten. Thus I can determine what stride the current element was written under. Thus we may define an array element as:
template<T> struct AR
{
T* value;
int stride;
}
Array reads respect the random-access model (e.g. any index may be read at anytime, due to the under-laying array).
To me, this has a few issues; if I want to know the current stride, I can look it up in the array. But at some point I will have strides that vary between n and 2*n. While this seems suited to the task above, I'm wondering about the implications. I'm operating on an embedded device, with little memory. I want some notion on how long I've gone updating the array. I could save the number of times I've modded, with further logic to reduce the necessary meta information on the stride value, like making the current mod count a static; the mod count being the number of times I've increased the stride.
Thus the interest I have in a name might include observations like the mod issue as presented. I can store the current number of stride increases in an int32. Under my constraints, this is acceptable; though I like using the proper name of an idea if it exists and I like reading about observations I may have missed.
I hope this presentation of the issue is understandable! If not, let me know and I'll update accordingly.
Thank you!
I want to generate all permutations of 32 card deck, I represent cards as numbers 0-7, so I don´t care about color of the card. The game is very simple (divide deck into two gropus, compare two cards, add both cards to group of bigger card). I have already code this part of game, but deck is now generating randomly, and I want to look to all possibilities of cards, and make some statistics about it. How can I code this card generating? I totaly don´t know, how to code it.
Because I was just studying Aaron Williams 2009 paper "Loopless Generation of Multiset Permutations by Prefix Shifts", I'll contribute a version of his algorithm, which precisely solves this problem. I believe it to be faster than the standard C++ next_permutation which is usually cited for this problem, because it doesn't rely on searching the input vector for the pivot point. But more extensive benchmarking would be required to produce a definitive answer; it is quite possible that it ends up moving more data around.
Williams' implementation of the algorithm avoids data movement by storing the permutation in a linked list, which allows the "prefix shift" (rotate a prefix of the vector by one position) to be implemented by just modifying two next pointers. That makes the algorithm loopless.
My version here differs in a couple of ways.
First, it uses an ordinary array to store the values, which means that the shift does require a loop. On the other hand, it avoids having to implement a linked-list datatype, and many operations are faster on arrays.
Second, it uses suffix shifts rather than prefix shifts; in effect, it produces the reverse of each permutation (compared with Williams' implementation). I did that because it simplifies the description of the starting condition.
Finally, it just does one permutation step. One of the great things about Williams' algorithm is that the state of the permutation sequence can be encapsulated in a single index value (as well as the permutation itself, of course). This implementation returns the state to be provided to the next call. (Since the state variable will be 0 at the end, the return value doubles as a termination indicator.)
Here's the code:
/* Do a single permutation of v in reverse coolex order, using
* a modification of Aaron Williams' loopless shift prefix algorithm.
* v must have length n. It may have repeated elements; the permutations
* generated will be unique.
* For the first call, v must be sorted into non-descending order and the
* third parameter must be 1. For subsequent calls, the third parameter must
* be the return value of the previous call. When the return value is 0,
* all permutations have been generated.
*/
unsigned multipermute_step(int* v, unsigned n, unsigned state) {
int old_end = v[n - 1];
unsigned pivot = state < 2 || v[state - 2] > v[state] ? state - 1 : state - 2;
int new_end = v[pivot];
for (; pivot < n - 1; ++pivot) v[pivot] = v[pivot + 1];
v[pivot] = new_end;
return new_end < old_end ? n - 1 : state - 1;
}
In case that comment was unclear, you could use the following to produce all shuffles of a deck of 4*k cards without regard to suit:
unsigned n = 4 * k;
int v[n];
for (unsigned i = 0; i < k; ++i)
for (unsigned j = 0; j < 4; ++j)
v[4 * i + j] = i;
unsigned state = 1;
do {
/* process the permutation */
} while ((state = multipermute_step(v, n, state);
Actually trying to do that for k == 8 will take a while, since there are 32!/(4!)8 possible shuffles. That's about 2.39*1024. But I did do all the shuffles of decks of 16 cards in 0.3 seconds, and I estimate that I could have done 20 cards in half an hour.
I have this snippet of code with some pointer math that I'm having trouble understanding:
#include <stdlib.h>
#include <complex.h>
#include <fftw3.h>
int main(void)
{
int i, j, k;
int N, N2;
fftwf_complex *box;
fftwf_plan plan;
float *smoothed_box;
// Allocate memory for arrays (Ns are set elsewhere and properly,
// I've just left it out for clarity)
box = (fftwf_complex *)fftwf_malloc(N * sizeof(fftwf_complex));
smoothed_box = (float *)malloc(N2 * sizeof(float));
// Create complex data and fill box with it. Do FFT. Box has the
// Hermitian symmetry that complex data has when doing FFTs with
// real data
plan = fftwf_plan_dft_c2r_3d(N,N,N,box,(float *)box,
FFTW_ESTIMATE);
...
// end fft
// Now do the loop I don't understand
for(i = 0; i < N2; i++)
{
for(j = 0; j < N2; j++)
{
for(k = 0; k < N2; k++)
{
smoothed_box[R_INDEX(i,j,k)] = *((float *)box +
R_FFT_INDEX(i*f + 0.5, j*f + 0.5, k*f +0.5))/V;
}
}
}
// Do other stuff
...
return 0;
}
Where f and V are just some numbers that are set elsewhere in the code and don't matter for this particular question. Additionally, the functions R_FFT_INDEX and R_INDEX don't really matter, either. What's important is that, for the first loop iteration ,when i=j=k=0, R_INDEX = 0 and R_FFT_INDEX=45. smoothed_box has 8 elements and box has 320.
So, in gdb, when I print smoothed_box[0] after the loop, I get smoothed_box[0] = some number. Now, I understand that, for an array of normal types, say floats, array + integer will give array[integer], assuming that integer is within the bounds of the array.
However, fftwf_complex is defined as typedef float fftw_complex[2], as you need to hold both the real and imaginary parts of the complex number. It's also being casted to a float * from a fftwf_complex *, and I'm unsure what this does, given the typedef.
All I know is that when I print box[45] in gdb, I get box[45] = some complex number that is not smoothed_box[0] * V. Even when I print *((float *)box + 45)/V, I get a different number than smoothed_box[0].
So, I was just wondering if anyone could explain to me the pointer math that is being done in the above loop? Thank you, and I appreciate your time!
box is allocated as an array of N fftwf_complex. Then a backward 3D c2r fftw transform using N,N,N is performed on box, requiring N*N*(N/2+1) fftwf_complex. See http://www.fftw.org/fftw3_doc/Real_002ddata-DFT-Array-Format.html#Real_002ddata-DFT-Array-Format Therefore, this code might trigger undefined behavior, such as segmentation fault, before reaching the pointer arithmetics...
It is practical to cast back box to an array of float because the DFT is performed in place. Indeed, box is used twice as the fftwf_plan is created. box is both the input array of complex and the output array of real:
plan = fftwf_plan_dft_c2r_3d(N,N,N,box,(float *)box,
FFTW_ESTIMATE);
Once fftwf_execute(plan); is called, box is better seen as an array of real. Nevertheless, this array is of size N*N*2*(N/2+1), where the items located at positions i,j,k where k>N-1 are meaningless. See FFTW's Real-data DFT Array Format:
For an in-place transform, some complications arise since the complex data is slightly larger than the real data. In this case, the final dimension of the real data must be padded with extra values to accommodate the size of the complex data—two extra if the last dimension is even and one if it is odd. That is, the last dimension of the real data must physically contain 2 * (nd-1/2+1) double values (exactly enough to hold the complex data). This physical array size does not, however, change the logical array size—only nd-1 values are actually stored in the last dimension, and nd-1 is the last dimension passed to the planner.
This is the reason why the real array smoothed_box is introduced, though an N*N*N array would be expected. If smoothed_box were an array of size N*N*N, then the following conversion could have been performed:
for(i=0;i<N;i++){
for(j=0;j<N;j++){
for(k=0;k<N;k++){
smoothed_box[(i*N+j)*N+k]=((float *)box)[(i*N+j)*(2*(N/2+1))+k]
}
}
}
I am trying to implement a low pass filter in OpenCL and the theory behind all this has me confused a bit. I have attached my code at the bottom after my explanation of the scenario.
First off, let me try to explain the whole scenario in point form.
For the input, we have a cos signal with a sample size, frequency (Frequency sample obtained by multiplying sample size with frequency) and a step size.
The value of at each step size is stored in an array with the frequency and step size multiplied to the function
This array is then passed into the kernel, which then will execute the low pass filter function.
Kernel returns an output array with the new filtered values.
The cos function is always returning a value from (-1,1), the only thing that modifies this value is the frequency. So it may repeat faster or slower depending on the frequency BUT it is always between (-1,1).
This is where I am confused, I am not sure how to apply a low pass filter to these values. Let say the cutoff was 100Hz for the filter. I can't just say:
if(array[i] > 100 ) { //delete or ignore this value. Else store in a array }
The reason this won't work is because the value of array[i] ranges from (-1,1). So how then would I apply this filter? What values am I going to compare?
From a physical perspective, I can see how it works, a capacitor and a resistor to calculate the cut-off frequency and send the input through the circuit. But programmatically, I do not see how I can implement this. I have seen many implementations of this on-line but the code wasn't documented enough to get a good understanding of what was going on.
Here is the code on my host side:
//Array to hold the information of signal
float *Array;
//Number of sampling points
int sampleSize = 100;
float h = 0;
//Signal Frequency in Hz
float signalFreq = 10;
//Number of points between 0 and max val (T_Sample)
float freqSample = sampleSize*signalFreq;
//Step = max value or T_Sample
float stepSize = 1.0 / freqSample;
//Allocate enough memory for the array
Array = (float*)malloc(sampleSize*sizeof(float));
//Populate the array with modified cosine
for (int i = 0; i < sampleSize; i++) {
Array[0] = cos(2*CL_M_PI*signalFreq*h);
h = h + stepSize;
printf("Value of current sample for cos is: %f \n", Array[0]);
}
My kernel is only as follows: (Obviously this is not the code for the filter, this is where I am confused).
__kernel void lowpass(__global int *Array, __local float *cutOffValue, __global int *Output) {
int idx = get_global_id(0);
Output[idx] = Array[idx];
};
I found this PDF that implements a lot of filters. Near the end of the document you can find a float implementation of the Low Pass Filter.
http://scholar.uwindsor.ca/cgi/viewcontent.cgi?article=6242&context=etd
In the filter implementation in that pdf, the compare data[j] to value. Also I have no idea what numItems or workItems is.
If someone can provide some insight on this that would be great. I have searched a lot of other examples on low pass filters but I just can't wrap my head around the implementation. I hope I made this question clear. Again, I know how/what the low pass filter does. I just have no idea as to what values I need to compare in order for the filtering to take place.
Found this question aswell:
Low Pass filter in C
I have a possible solution. What I am attempting will be a moving average fir (which I am told is the easiest form of a lowpass filter that one can implement).
What is required:
FIFO buffer
Coefficient values (I generated and obtained mine from matlab for a specific cut-off frequency)
Input and Output arrays for the program
I have not implemented this code wise, but I do understand how to use it on a theoretical level. I have created a diagram below to try and explain the process.
Essentially, from another input array values will be passed into the FIFO buffer one at a time. Every time a value is passed in, the kernel will do a multiplication across the FIFO buffer that has 'n' taps. Each tap has a coefficient value associated with it. So the input at a particular element gets multiplied with the coefficient value and all the values are then accumulated and stored in one element of the output buffer.
Note that the coefficients were generated in Matlab. I didn't know how else to grab these values. At first I was going to just use the coefficient of 1/n, but I am pretty sure that is just going to distort the values of the signal.
And that should do the trick, I am going to implement this in the code now, but if there is anything wrong with this theory feel free to correct it.
I've implemented a signal processing FFT algorithm in Python using np.fft (too easy). Now I'm working on doing this in C using an integer algorithm. After some research, I found that one of the most popular integer FFT libraries in C on the internet is the one by Roberts, Slaney, and Bouras which can be found in many places including the second entry here.fft,
There are a few concepts I don't understand and am hoping for guidance.
Specifically, the example script included in the library linked above separates the input signal into two bins, real and imaginary, by putting all of the even indexes of the signal in the first half and the odd indexes in the second half of the signal.
for (i=0; i<N; i++){
x[i] = AMPLITUDE*cos(i*FREQUENCY*(2*3.1415926535)/N);
if (i & 0x01) // only odd index
fx[(N+i)>>1] = x[i]; // N+i >> 1 is len(input)+i/2
else // only even index
fx[i>>1] = x[i];
}
fix_fftr(fx, log2N, 0);
The signal array has not changed length but now contains two of almost the same signal. Then FFT driver function (fix_fftr) takes the entire input signal as an argument and does the exact same thing
if (inverse)
scale = fix_fft(fr, fi, m-1, inverse);
for (int i=1; i<n; i+=2) {
tt = f[n+i-1]; // even index
f[n+i-1] = f[i]; // odd index into the second half
f[i] = tt; // even index into the first half
}
if (!inverse)
scale = fix_fft(fr, fi, m-1, inverse);
return scale;
whats the reason for this?
The first part is computing the twiddle factors, which are constants for a given length FFT and independent of the data.
The second part appears to be part of the data shuffling based on recursive bit-reversed addressing, which is a component within an in-place FFT.