/** * Gabor transform (complex values) */ public FloatComplex[][] TGabor(float[] signal, int nbSamplesPerBar) { int n = signal.Length; int nbBars = n / nbSamplesPerBar; FloatComplex[][] TG = new FloatComplex[nbSamplesPerBar][]; var fftFoward = new FloatComplexForward1DFFT(nbSamplesPerBar); for (int i = 0; i < nbSamplesPerBar; i++) { TG[i] = new FloatComplex[nbBars]; } for (int i = 0; i < nbBars; i++) { int iMin = i * nbSamplesPerBar; int iMax = (i + 1) * nbSamplesPerBar; FloatComplex[] sub = new FloatComplex[nbSamplesPerBar]; for (int j = 0; j < iMax - iMin; j++) { sub[j] = new FloatComplex(signal[j + iMin], 0); } fftFoward.FFTInPlace(sub); for (int j = 0; j < nbSamplesPerBar; j++) { TG[j][i] = sub[j]; } } return(TG); }
public float[][] ES(FloatComplex[][] s, int[] indPartition, float[] valuesT, float[] valuesFS) { float[][] signature = new float[2][]; List <float> freqs = new List <float>(); List <float> values = new List <float>(); int nbBars = s[0].Length; for (int i = 0; i < nbBands; i++) { int iMin = indPartition[i]; int iMax = Math.Min(indPartition[i + 1], s.Length); // Band extraction : FloatComplex[][] band = new FloatComplex[iMax - iMin][]; for (int b1 = 0; b1 < iMax - iMin; b1++) { band[b1] = new FloatComplex[nbBars]; for (int b2 = 0; b2 < nbBars; b2++) { band[b1][b2] = s[b1 + iMin][b2]; } } // Localisation of locales max float[][] localesMax = getLocalesMaximum(band); // threshold : mean + std float threshold = Mean(localesMax[1]) + STD(localesMax[1]); // Get frequencies upper than the threshold for (int j = 0; j < localesMax[0].Length; j++) { if (localesMax[1][j] > threshold) { freqs.Add(valuesT[j]); values.Add(i); //values.Add(valuesFS[(int) (localesMax[0][j]+ iMin)]); } } } signature[0] = freqs.ToArray(); signature[1] = values.ToArray(); return(signature); }
public static void Native(int log2FftSize, int fftRepeat) { int i; int size = 1 << log2FftSize; FloatComplex[] xy = new FloatComplex[size]; FloatComplex[] xy_out = new FloatComplex[xy.Length]; for (i = 0; i < size / 2; i++) { xy[i] = new FloatComplex(1.0f, 0.0f); } for (i = size / 2; i < size; i++) { xy[i] = new FloatComplex(-1.0f, 0.0f); } var stopwatch = Stopwatch.StartNew(); for (i = 0; i < fftRepeat; i++) { fft(log2FftSize, xy_out, xy); } stopwatch.Stop(); Console.WriteLine($"Total ({fftRepeat}): {stopwatch.ElapsedMilliseconds}"); var tpp = stopwatch.ElapsedMilliseconds / (float)fftRepeat; Console.WriteLine($"{fftRepeat} piece(s) of {1 << log2FftSize} pt FFT; {tpp} ms/piece\n"); for (i = 0; i < 6; i++) { Console.WriteLine("{0}\t{1}", i, xy_out[i]); } }
/** Complex abs : sqrt(x^2 + y^2) */ private static float Abs(FloatComplex complex) { return((float)Math.Sqrt(Math.Pow(complex.Real, 2) + Math.Pow(complex.Imag, 2))); }
private int sampleFrequency = 44100; // Hz public float[][] Main(float[] signal) { // Variables int n = signal.Length; float time = n / sampleFrequency; float barTime = 60f / bpm; //float barTime = 0.2f; int nbBars = (int)(time / barTime); int nbSamplesPerBar = n / nbBars; float[] valuesT = new float[nbBars]; for (int i = 0; i < nbBars; i++) { valuesT[i] = ((float)i * time) / ((float)(nbBars - 1)); } // Gabor & audibles freq float stepF = sampleFrequency / (float)(nbSamplesPerBar); int nbValuesFS = (int)(fMax / stepF); float[] valuesFS = new float[nbValuesFS + 1]; for (int i = 0; i < nbValuesFS + 1; i++) { valuesFS[i] = i * stepF; } FloatComplex[][] gabor = TGabor(signal, nbSamplesPerBar); // Sonogram (complex) FloatComplex[][] s = new FloatComplex[nbValuesFS][]; for (int i = 0; i < s.Length; i++) { s[i] = new FloatComplex[nbBars]; for (int j = 0; j < nbBars; j++) { s[i][j] = gabor[i][j]; } } // Partition float iMinPart = (float)Math.Log(fMin); float iMaxPart = (float)Math.Log(fMax); float stepPart = (iMaxPart - iMinPart) / (float)nbBands; float[] partition = new float[nbBands + 1]; for (int i = 0; i < nbBands + 1; i++) { partition[i] = (float)Math.Exp(iMinPart + stepPart * ((float)i)); } int[] indPartition = new int[nbBands + 1]; for (int i = 0; i < nbBands; i++) { indPartition[i] = MinIndice(valuesFS, partition[i]); } indPartition[nbBands] = valuesFS.Length; // Compute sound signature float[][] signature = ES(s, indPartition, valuesT, valuesFS); return(signature); }