I got the code here:
https://naudio.codeplex.com/discussions/270762.
The goertzel algorithm goes like this:
public double goertzel(List<double> sngData, long N, float frequency, int samplerate)
{
double skn, skn1, skn2;
skn = skn1 = skn2 = 0;
samplerate = this.sampleRate;
frequency = this.freq;
double c = 2 * pi * frequency / samplerate;
double cosan = Math.Cos(c);
for (int i = 0; i < N; i++)
{
skn2 = skn1;
skn1 = skn;
skn = 2 * cosan * skn1 - skn2 + sngData[i];
}
return skn - Math.Exp(-c) * skn1;
}
I want to transform the audio data (from wave file reader in the link above) by using that algorithm. How can i do that? Thanks
If you're doing DTMF detection, try "phoneToneDecoder" COM. it detects DTMF tones from your sound card. (i think it's proprietary)
Related
I've got an input signal and I calculated its FFT. After that, I need to calculate its RMS ONLY at a bandwith of frequencies, not for all spectrum.
I solved RMS calculation of the entire spectrum applying Parseval's theorem, but how do I calculate this kind of RMS "selective"? I've got the indexes correctly calculated to get the three frecuencies of interest (F0, FC, F1), but when applying RMS to this bandwith, it seems Parseval's theorem is not holded.
I receive an unique 10 KHz frequency, the RMS from FFT total spectrum is correct, but its RMS selective at 10 KHz frequency gives me a wrong result (-0.4V from RMS correct one) and should give me almost the same result as I only got one frecuency in the spectrum. Here you can see my RMS selective calculation:
public static double RMSSelectiveCalculation(double[] trama, double samplingFreq, double F0, double Fc, double F1)
{
//Frequency of interest
double fs = samplingFreq; // Sampling frequency
double t1 = 1 / fs; // Sample time
int l = trama.Length; // Length of signal
double rmsSelective = 0;
double ParsevalB = 0;
double scalingFactor = fs;
double dt = 1 / fs;
// We just use half of the data as the other half is simetric. The middle is found in NFFT/2 + 1
int nFFT = (int)Math.Pow(2, NextPow2(l));
double df = fs / nFFT;
if (nFFT > 655600)
{ }
// Create complex array for FFT transformation. Use 0s for imaginary part
Complex[] samples = new Complex[nFFT];
Complex[] reverseSamples = new Complex[nFFT];
double[] frecuencies = new double[nFFT];
for (int i = 0; i < nFFT; i++)
{
frecuencies[i] = i * (fs / nFFT);
if (i >= trama.Length)
{
samples[i] = new MathNet.Numerics.Complex(0, 0);
}
else
{
samples[i] = new MathNet.Numerics.Complex(trama[i], 0);
}
}
ComplexFourierTransformation fft = new ComplexFourierTransformation(TransformationConvention.Matlab);
fft.TransformForward(samples);
ComplexVector s = new ComplexVector(samples);
//The indexes will get the index of each frecuency
int f0Index, fcIndex, f1Index;
double k = nFFT / fs;
f0Index = (int)Math.Floor(k * F0);
fcIndex = (int)Math.Floor(k * Fc);
f1Index = (int)Math.Ceiling(k * F1);
for (int i = f0Index; i <= f1Index; i++)
{
ParsevalB += Math.Pow(Math.Abs(s[i].Modulus / scalingFactor), 2.0);
}
ParsevalB = ParsevalB * df;
double ownSF = fs / l; //This is a own scale factor used to take the square root after
rmsSelective = Math.Sqrt(ParsevalB * ownSF);
samples = null;
s = null;
return rmsSelective;
}
An estimate of the power spectral density PSD is given by the square of magnitude of the FFT.
The RMS of a section with a certain bandwidth is the root of the area of the PSD of that section.
So practically, just integrate the absolute value of the FFT between the lower and upper frequency.
MATLAB example
I am trying too have my C# console application make a beep sound. Yes I know I can use Console.Beep but I also want to lower the volume etc.
But the error I am getting is this:
Method name expected
on this line:
binaryWriter.Write(hdr(i));
This is my code:
private bool Beep(int volume, int frequency, int duration)
{
try
{
double amplitude = volume * 1.27;
double a = ((amplitude * (System.Math.Pow(2, 15))) / 1000) - 1;
double deltaFt = 2 * System.Math.PI * frequency / 8000;
double samples = 441 * (duration / 100);
int bytes = Convert.ToInt32(samples) * 4;
int[] hdr = {
0x46464952,
36 + bytes,
0x45564157,
0x20746d66,
16,
0x20001,
8000,
176400,
0x100004,
0x61746164,
bytes
};
using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(44 + bytes))
{
using (System.IO.BinaryWriter binaryWriter = new System.IO.BinaryWriter(memoryStream))
{
for (int i = 0; i <= hdr.Length - 1; i++)
{
binaryWriter.Write(hdr(i));
}
for (int T = 0; T <= Convert.ToInt32(samples) - 1; T++)
{
short sample = Convert.ToInt16(a * System.Math.Sin(deltaFt * T));
binaryWriter.Write(sample);
binaryWriter.Write(sample);
}
binaryWriter.Flush();
memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
using (System.Media.SoundPlayer sp = new System.Media.SoundPlayer(memoryStream))
{
sp.PlaySync();
}
}
}
}
catch
{
return false;
}
return true;
}
Your hdr is an array, you need to get the entry by putting the square brackets and then passing the index
binaryWriter.Write(hdr[i]);
I am writing an application for procedural audiofiles, I have to analyze my new file, get its frequency spectrum and change it in its calculated.
I want to do this with the Fast Fourier Transform (FFT). This is my recursive C# FFT:
void ft(float n, ref Complex[] f)
{
if (n > 1)
{
Complex[] g = new Complex[(int) n / 2];
Complex[] u = new Complex[(int) n / 2];
for (int i = 0; i < n / 2; i++)
{
g[i] = f[i * 2];
u[i] = f[i * 2 + 1];
}
ft(n / 2, ref g);
ft(n / 2, ref u);
for (int i = 0; i < n / 2; i++)
{
float a = i;
a = -2.0f * Mathf.PI * a / n;
float cos = Mathf.Cos(a);
float sin = Mathf.Sin(a);
Complex c1 = new Complex(cos, sin);
c1 = Complex.Multiply(u[i], c1);
f[i] = Complex.Add(g[i], c1);
f[i + (int) n / 2] = Complex.Subtract(g[i], c1);
}
}
}
The inspiring example was
I then compared my results with those from wolframalpha for the same input 0.6,0.7,0.8,0.9 but the results aren't be the same. My results are twice as big than Wolfram's and the imaginary part are the -2 times of Wolfram's.
Also, wiki indicates that the inverse of FFT can be computed with
But I compare inputs and outputs and they are different.
Has anyone an idea what's wrong?
Different implementations often use different definitions of the Discrete Fourier Transform (DFT), with correspondingly different results. The correspondence between implementations is usually fairly trivial (such as a scaling factor).
More specifically, your implementation is based on the following definition of the DFT:
On the other hand, Wolfram alpha by default uses a definition, which after adjusting to 0-based indexing looks like:
Correspondingly, it is possible to transform the result of your implementation to match Wolfram alpha's with:
void toWolframAlphaDefinition(ref Complex[] f)
{
float scaling = (float)(1.0/Math.Sqrt(f.Length));
for (int i = 0; i < f.Length; i++)
{
f[i] = scaling * Complex.Conjugate(f[i]);
}
}
Now as far as computing the inverse DFT using the forward transform, a direct implementation of the formula
you provided would be:
void inverseFt(ref Complex[] f)
{
for (int i = 0; i < f.Length; i++)
{
f[i] = Complex.Conjugate(f[i]);
}
ft(f.Length, ref f);
float scaling = (float)(1.0 / f.Length);
for (int i = 0; i < f.Length; i++)
{
f[i] = scaling * Complex.Conjugate(f[i]);
}
}
Calling ft on the original sequence 0.6, 0.7, 0.8, 0.9 should thus get you the transformed sequence 3, -0.2+0.2j, -0.2, -0.2-0.2j.
Further calling inverseFt on this transform sequence should then bring you back to your original sequence 0.6, 0.7, 0.8, 0.9 (within some reasonable floating point error), as shown in this live demo.
I have a working FFT, but my question is how do I convert it into an IFFT?
I was told that an IFFT should be just like the FFT that you are using.
so how do I make an ifft from a fft i c#?
I was told there should only be a few changes made to get the ifft.
I tried to do it myself, but I am not getting the same values back that I put in...
so I made an array of values and put it in to the fft and then the ifft and I can not getting the same values I put in...
so I do not think I changed it the right way.
this is the FFT I have:
public Complex[] FFT(Complex[] x )
{
int N2 = x.Length;
Complex[] X = new Complex[N2];
if (N2 == 1)
{
return x;
}
Complex[] odd = new Complex[N2 / 2];
Complex[] even = new Complex[N2 / 2];
Complex[] Y_Odd = new Complex[N2 / 2];
Complex[] Y_Even = new Complex[N2 / 2];
for (int t = 0; t < N2 / 2; t++)
{
even[t] = x[t * 2];
odd[t] = x[(t * 2) + 1];
}
Y_Even = FFT(even);
Y_Odd = FFT(odd);
Complex temp4;
for (int k = 0; k < (N2 / 2); k++)
{
temp4 = Complex1(k, N2);
X[k] = Y_Even[k] + (Y_Odd[k] * temp4);
X[k + (N2 / 2)] = Y_Even[k] - (Y_Odd[k] * temp4);
}
return X;
}
public Complex Complex1(int K, int N3)
{
Complex W = Complex.Pow((Complex.Exp(-1 * Complex.ImaginaryOne * (2.0 * Math.PI / N3))), K);
return W;
}
Depending on the FFT, you may have to scale the entire complex vector (multiply either the input or result vector, not both) by 1/N (the length of the FFT). But this scale factor differs between FFT libraries (some already include a 1/sqrt(N) factor).
Then take the complex conjugate of the input vector, FFT it, and do another complex conjugate to get the IFFT result. This is equivalent to doing an FFT using -i instead of i for the basis vector exponent.
Also, normally, one does not get the same values out of a computed IFFT(FFT()) as went in, as arithmetic rounding adds at least some low level numerical noise to the result.
I'm working on some code where I have a Time object with a member time. Time.time gives
me the time since my application started in seconds (float value). Now I want to create a pulsating value between 0 and 1 and then from 1 to 0 again, which continues doing thins untill the application stops.
I was thinking to use sin() but don't know what to pass to it as paramters to create this pulsing value.
How would I create this pulsating value?
Kind regards,
Pollux
You mention using sin(), so I guess you want it to pulse continuously between 0 and 1.
Something like this will do:
float pulse(float time) {
const float pi = 3.14;
const float frequency = 10; // Frequency in Hz
return 0.5*(1+sin(2 * pi * frequency * time));
}
1/frequency = 0.1 second is the period, which is the time between 1's.
How about x = 1 - x?
Or if you want it to be time based use Timer % 2
Oh, you wanted the values between 0 and 1 as well.
how about Math.Abs(100 - (Timer % 200)) / 100
Where timer is something like DateTime.Now.TimeOfDay.TotalMilliseconds
Edit:
My tests indicate that this is more than twice as fast as the Sin method. For 1 million iterations, the sin method takes .048 seconds while the Abs method takes about .023 seconds. Also, you get different waveforms out of the two, of course. Sin produces a Sine wave, while Abs produces a triangular wave.
static void Main(string[] args)
{
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
const int count = 1000000;
float[] results = new float[count];
for (int i = 0; i < count; i++)
{
results[i] = AbsPulse(i/1000000F);
//results[i] = SinPulse(i / 1000000F);
}
sw.Stop();
Console.WriteLine("Time Elapsed: {0} seconds", sw.Elapsed.TotalSeconds);
char[,] graph = new char[80, 20];
for (int y = 0; y <= graph.GetUpperBound(1); y++)
for (int x = 0; x <= graph.GetUpperBound(0); x++)
graph[x, y] = ' ';
for (int x = 0; x < count; x++)
{
int col = x * 80 / count;
graph[col, (int)(results[x] * graph.GetUpperBound(1))] = 'o';
}
for (int y = 0; y <= graph.GetUpperBound(1); y++)
{
for (int x = 0; x < graph.GetUpperBound(0); x++)
Console.Write(graph[x, y]);
Console.WriteLine();
}
}
static float AbsPulse(float time)
{
const int frequency = 10; // Frequency in Hz
const int resolution = 1000; // How many steps are there between 0 and 1
return Math.Abs(resolution - ((int)(time * frequency * 2 * resolution) % (resolution * 2))) / (float)resolution;
}
static float SinPulse(float time)
{
const float pi = 3.14F;
const float frequency = 10; // Frequency in Hz
return 0.5F * (1 + (float)Math.Sin(2 * pi * frequency * time));
}
A sine function would be ideal I think, but you need to adjust the period and the scale.
The sine function produces results between -1 and 1, but you want to go between 0 and 1. To scale it properly you want (sin(x)+1)/2.
The sine function starts at zero, goes to 1 at pi/2, zero again at pi, -1 at 3*pi/2, and back to zero at 2*pi. Scaled, the first zero will happen at 3*pi/2 and the first maximum after that will be at 5/2*pi. So x in the previous formula is (2*time + 3) * pi/2.
Putting it all together: (sin((2*time.time + 3) * pi/2) + 1) / 2
How often do you want it to pulse?
Let's say you want to go from 0 to 1 over 10 seconds.
float pulseValueForTime(int sec) {
int pulsePoint = sec % 10;
float pulsePercent = (float)pulsePoint / (float)10;
float pulseInTermsOfPI = (pulsePercent * 2 * PI) - PI;
float sinVal = MagicalSinFunction(pulseInTermsOfPI); // what framework you use to compute sin is up to you... I'm sure you can google that!
return (sinVal + 1) / 2; // sin is between 1 and -1, translate to between 0 and 1
}
Look into Ease functions. They do this sort of thing in all sorts of manners - linear, poly, exp, sin, etc.