public static void onsetDetection() { Time timer = new Time(); int starts = 0; int stops = 0; List<int> noteStops; List<double> pitches; noteStarts = new List<int>(100); noteStops = new List<int>(100); lengths = new List<int>(100); pitches = new List<double>(100); HFC = new float[stftRep.timeFreqData[0].Length]; //timer.next("Onset setup"); Thread[] mine = new Thread[MainProgram.Num_threads]; for (int a = 0; a < MainProgram.Num_threads; a++) { mine[a] = new Thread(onsetloop1); mine[a].Start(a); } for (int a = 0; a < MainProgram.Num_threads; a++) { mine[a].Join(); } //timer.next("Onset loop 1"); float maxi = HFC.Max(); for (int jj = 0; jj < stftRep.timeFreqData[0].Length; jj++) { HFC[jj] = (float)Math.Pow((HFC[jj] / maxi), 2); } //timer.next("Onset loop 2"); for (int jj = 0; jj < stftRep.timeFreqData[0].Length; jj++) { if (starts > stops) { if (HFC[jj] < 0.001) { noteStops.Add(jj * ((stftRep.wSamp - 1) / 2)); stops = stops + 1; } } else if (starts - stops == 0) { if (HFC[jj] > 0.001) { noteStarts.Add(jj * ((stftRep.wSamp - 1) / 2)); starts = starts + 1; } } } //timer.next("Onset loop 3"); if (starts > stops) { noteStops.Add(waveIn.data.Length); } // DETERMINES START AND FINISH TIME OF NOTES BASED ON ONSET DETECTION ///* // timer.restart(); for (int ii = 0; ii < noteStops.Count; ii++) { lengths.Add(noteStops[ii] - noteStarts[ii]); } timer.next("Onset loop 4"); allpitches = new List<double>[Num_threads]; for (int a = 0; a < Num_threads; a++) { allpitches[a] = new List<double>(); mine[a] = new Thread(onsetloopmm); mine[a].Start(a); } for (int a = 0; a < Num_threads; a++) { mine[a].Join(); pitches.AddRange(allpitches[a]); } timer.next("onset mm loop"); musicNote[] noteArray; noteArray = new musicNote[noteStarts.Count()]; for (int ii = 0; ii < noteStarts.Count(); ii++) { noteArray[ii] = new musicNote(pitches[ii], lengths[ii]); } //timer.next("onset loop 6"); int[] sheetPitchArray = new int[sheetmusic.Length]; int[] notePitchArray = new int[noteArray.Length]; for (int ii = 0; ii < sheetmusic.Length; ii++) { sheetPitchArray[ii] = sheetmusic[ii].pitch % 12; } //timer.next("onset loop 7"); for (int jj = 0; jj < noteArray.Length; jj++) { notePitchArray[jj] = noteArray[jj].pitch % 12; } //timer.next("onset loop 8"); string[] alignedStrings = new string[2]; alignedStrings = stringMatch(sheetPitchArray, notePitchArray); musicNote[] alignedStaffArray = new musicNote[alignedStrings[0].Length / 2]; musicNote[] alignedNoteArray = new musicNote[alignedStrings[1].Length / 2]; int staffCount = 0; int noteCount = 0; //timer.next("onset stuff"); for (int ii = 0; ii < alignedStrings[0].Length / 2; ii++) { if (alignedStrings[0][2 * ii] == ' ') { alignedStaffArray[ii] = new musicNote(0, 0); } else { alignedStaffArray[ii] = sheetmusic[staffCount]; staffCount++; } if (alignedStrings[1][2 * ii] == ' ') { alignedNoteArray[ii] = new musicNote(0, 0); } else { alignedNoteArray[ii] = noteArray[noteCount]; noteCount++; } } timer.end("onset last"); }
// FFT function for Pitch Detection public static musicNote[] readXML(string filename) { List<string> stepList = new List<string>(100); List<int> octaveList = new List<int>(100); List<int> durationList = new List<int>(100); List<int> alterList = new List<int>(100); int noteCount = 0; bool sharp; musicNote[] scoreArray; FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read); if (file == null) { System.Console.Write("Failed to Open File!"); } XmlTextReader reader = new XmlTextReader(filename); bool finished = false; while (finished == false) { sharp = false; while ((!reader.Name.Equals("note") || reader.NodeType == XmlNodeType.EndElement) && !finished) { reader.Read(); if (reader.ReadState == ReadState.EndOfFile) { finished = true; } } reader.Read(); reader.Read(); if (reader.Name.Equals("rest")) { } else if (reader.Name.Equals("pitch")) { while (!reader.Name.Equals("step")) { reader.Read(); } reader.Read(); stepList.Add(reader.Value); while (!reader.Name.Equals("octave")) { if (reader.Name.Equals("alter") && reader.NodeType == XmlNodeType.Element) { reader.Read(); alterList.Add(int.Parse(reader.Value)); sharp = true; } reader.Read(); } reader.Read(); if (!sharp) { alterList.Add(0); } sharp = false; octaveList.Add(int.Parse(reader.Value)); while (!reader.Name.Equals("duration")) { reader.Read(); } reader.Read(); durationList.Add(int.Parse(reader.Value)); //System.Console.Out.Write("Note ~ Pitch: " + stepList[noteCount] + alterList[noteCount] + " Octave: " + octaveList[noteCount] + " Duration: " + durationList[noteCount] + "\n"); noteCount++; } } scoreArray = new musicNote[noteCount]; double c0 = 16.351625; for (int nn = 0; nn < noteCount; nn++) { int step = (int)Enum.Parse(typeof(pitchConv), stepList[nn]); double freq = c0 * Math.Pow(2, octaveList[nn]) * (Math.Pow(2, ((double)step + (double)alterList[nn]) / 12)); scoreArray[nn] = new musicNote(freq, (double)durationList[nn] * 60 * waveIn.SampleRate / (4 * bpm)); } return scoreArray; }