public static IdolWaveNote ProcessData(short[] data, int sampleRate) { double[] x = new double[data.Length]; for (int i = 0; i < x.Length; i++) { x[i] = data[i]; } double[] spectr = IdolFFTAlgorithm.Calculate(x); int minSpectr = (int)(MinFreq * spectr.Length / sampleRate / magicNumber) + 1; int index = 1; double max = spectr[index]; int usefullMaxSpectr = Math.Min(spectr.Length, (int)(MaxFreq * spectr.Length / sampleRate / magicNumber) + 1); //Console.WriteLine(usefullMaxSpectr + " " + spectr.Length + " " + usefullMaxSpectr * sampleRate / spectr.Length); //Console.WriteLine("= " + max); for (int i = index; i < usefullMaxSpectr; i++) { if (max < spectr[i]) { max = spectr[i]; index = i; } } //Console.WriteLine("- " + max + " " + index); double freq = (double) magicNumber * sampleRate * index / spectr.Length; if (freq < MinFreq) freq = 0; IdolWaveNote waveNote = new IdolWaveNote(); waveNote.freq = freq; waveNote.max = max; return waveNote; //return freq; }
private static void GetNotes(int startIdx, int endIdx, IdolWave _wave, List<IdolWaveNote> result) { IdolWaveNote waveNote; //short[] waveShortBuffer = new short[bufferSize]; //float timeLength = 0.4f; //short[] waveShortBuffer = new short[(int)(_wave.ByteRate / 2 * timeLength)]; //byte[] waveByteBuffer = new byte[(int)(_wave.ByteRate / 2 * timeLength)]; byte[] waveByteBuffer = new byte[bufferSize]; int waveIdx = startIdx; int bufferIdx = 0; AudioFrame audioFrame = new AudioFrame(false); double MinFreq = 80; double MaxFreq = 800; int defaultIdx = -99; int batchNo = 0; while (waveIdx < endIdx) { batchNo++; bufferIdx = 0; /************************************************/ //while (waveIdx < endIdx && // bufferIdx < waveShortBuffer.Length) //{ // waveShortBuffer[bufferIdx] = (Int16)swapByteOrder(BitConverter.ToUInt16(_wave.Data, waveIdx)); // waveIdx += _wave.NumChannels; // bufferIdx++; //} //waveNote = IdolSoundAnalyzer.ProcessData(waveShortBuffer, _wave.SampleRate); //IdolSoundAnalyzer.FindClosestNote((int)Math.Round(waveNote.freq), out closestFreq, out waveNote.NoteIdx, out waveNote.NoteName); /************************************************/ while (waveIdx < endIdx && bufferIdx < waveByteBuffer.Length) { waveByteBuffer[bufferIdx] = _wave.Data[waveIdx]; waveIdx ++; bufferIdx++; } audioFrame.ProcessMono(ref waveByteBuffer); int fftBufferLength = audioFrame._fftLeft.Length; int minSpectr = (int)(MinFreq * (fftBufferLength * 2) / _wave.SampleRate) + 1; int index = minSpectr; double max = audioFrame._fftLeft[index]; int usefullMaxSpectr = Math.Min((fftBufferLength * 2), (int)(MaxFreq * (fftBufferLength * 2) / _wave.SampleRate) + 1); List<Peak> peakList = new List<Peak>(); double current = max; double last = max; double last2 = max; for (int i = index; i < usefullMaxSpectr; i++) { last2 = last; last = current; current = audioFrame._fftLeft[i]; if (last > 51) { if (last > last2 && last > current) { Peak peak = new Peak(); peak.Index = i - 1; peak.Freq = _wave.SampleRate * (i - 1) / (audioFrame._fftLeft.Length * 2); peak.Amp = audioFrame._fftLeft[i - 1]; peakList.Add(peak); } } if (max < audioFrame._fftLeft[i]) { max = audioFrame._fftLeft[i]; index = i; } } double freq = 0; if (peakList.Count > 0) { int i = 0; bool found = false; while (i < peakList.Count && !found) { if (peakList[i].Amp >= 58) { index = peakList[i].Index; found = true; } else i++; } if (!found) { index = peakList[0].Index; } else { for (int j = 0; j < i; j++) { double ratio = peakList[i].Freq / peakList[j].Freq; if (ratio >= 1 && (ratio % 1.0f < 0.1f || ratio % 1.0f > 0.9f)) { index = peakList[j].Index; if (peakList[j].Freq == 93) { peakList[j].Freq *= 1; } break; } } } } freq = _wave.SampleRate * index / (audioFrame._fftLeft.Length * 2); if (freq < MinFreq) freq = 0; waveNote = new IdolWaveNote(); waveNote.freq = freq; waveNote.max = audioFrame._fftLeft[index]; IdolSoundAnalyzer.FindClosestNote((int)Math.Round(waveNote.freq), out closestFreq, out waveNote.NoteIdx, out waveNote.NoteName); /************************************************/ result.Add(waveNote); } }