//This function should be called every tick/frame. This used the previous functions to //Update time, get the current spectrum and the adaptive threshold and then does a check //to see if a beat has occured. It also allows for some post-detection ignore clause. //This function also does functions such as update the smoothing median list, create a //timestamp object, update the lastBeatRegistered and checks to see if the song //is still playing public void update() { // Console.WriteLine(specFlux); if (started) { float[] specStereo; updateTime(); specStereo = getCurrentSpectrum(); //Console.WriteLine(specStereo); beatThreshold = calculateFluxAndSmoothing(specStereo); //Beat detected if (specFlux > beatThreshold && ((uint) stopW.ElapsedMilliseconds - timeBetween) > 350) { if (smootherValues.Count > 1) smootherValues.Insert(smootherValues.Count - 1, specFlux); else smootherValues.Insert(smootherValues.Count, specFlux); if (smootherValues.Count >= 5) { smootherValues.Remove(0); } timeBetween = (uint)stopW.ElapsedMilliseconds; TimeStamp t = new TimeStamp(currentMinutes, currentSeconds, currentMillis, specFlux); Console.WriteLine("BEAT AT: " + t.getMinutes() + ":" + t.getSeconds() + ":" + t.getMilliseconds() + " -- BEAT FREQ: " + t.getFrequency() + " -- THRESHOLD: " + beatThreshold); lastBeatRegistered = t; } else if (((uint) stopW.ElapsedMilliseconds - timeBetween) > 5000) { if (thresholdSmoother>0.4f) thresholdSmoother -= 0.4f; timeBetween = (uint)stopW.ElapsedMilliseconds; } if(!delayedSong) songChannel1.isPlaying(ref areWePlaying); else songChannel2.isPlaying(ref areWePlaying); //delete[] specStereo; } else { Console.ReadLine(); if (test == 1) setStarted(true); } }
//Updates the timer and creates a "TimeStamp" object. This is used to detect where in the song //we are, so timekeeping is a necessity. private void updateTime() { time = stopW.Elapsed; timeString = time.ToString(); currentTime = (int)stopW.ElapsedMilliseconds; currentTime = currentTime - initialTime; // if (currentTime > 1000) //currentTime = 0; //Console.WriteLine(time.ToString("mm\\:ss\\.ff")); currentMillis = Int32.Parse(timeString.Substring(9, 2)); currentSeconds = Int32.Parse(timeString.Substring(6, 2)); currentMinutes = Int32.Parse(timeString.Substring(3, 2)); if(timeToDelay!=0) { if(currentTime>timeToDelay) { //songChannel2.setChannelGroup(channelMusic); songChannel2.setPaused(false); timeToDelay = 0; } } //if (currentMinutes > 0) // currentSeconds = ((currentTime / 1000) - (60 * currentMinutes)); //else // currentSeconds = (currentTime / 1000); //if (currentSeconds != lastSeconds) //{ // currentMillis = 0; // lastSeconds = currentSeconds; //} //else //{ // currentMillis++; // if (currentMillis > 1000) // currentMillis = 0; //} //currentMinutes = ((currentTime / 1000) / 60); currentTimeStamp = new TimeStamp(currentMinutes, currentSeconds, currentMillis); }
//Loads a song into memory given a sample size and file-path to an audio file. //The most commonly used and accurate Sample Size is 1024. public void LoadSong(int sSize, string audioString) { //Take in Aruguments sampleSize = sSize; songString = audioString; stopW.Start(); areWePlaying = true; specFlux = 0.0f; timeBetween = 0; initialTime = (int)stopW.ElapsedMilliseconds; currentTime = 0; currentSeconds = 0; lastSeconds = 0; currentMillis = 0; currentMinutes = 0; median = 0.0f; smoothMedian = 0.0f; beatThreshold = 0.6f; thresholdSmoother = 0.6f; started = false; lastBeatRegistered = new TimeStamp(); audio = new FMOD.Sound(); songChannel1 = new FMOD.Channel(); channelMusic = new FMOD.ChannelGroup(); previousFFT = new float[sampleSize / 2 + 1]; for (int i = 0; i < sampleSize / 2; i++) { previousFFT[i] = 0; } //Brute force for testing //songString = "Music/drums.wav"; //Create channel and audio FMODErrorCheck(system.createChannelGroup(null, ref channelMusic)); // CREATESOUNDEXINFO ex = new CREATESOUNDEXINFO(); FMODErrorCheck(system.createStream(songString, FMOD.MODE.SOFTWARE, ref audio)); audio.getLength(ref seconds, FMOD.TIMEUNIT.MS); audio.getDefaults(ref sampleRate, ref zeroF, ref zeroF, ref zero); seconds = ((seconds + 500) / 1000); minutes = seconds / 60; fullSeconds = (int)seconds; seconds = seconds - (minutes * 60); FMODErrorCheck(system.playSound(FMOD.CHANNELINDEX.FREE, audio, true, ref songChannel1)); //hzRange = (sampleRate / 2) / static_cast<float>(sampleSize); songChannel1.setChannelGroup(channelMusic); songChannel1.setPaused(true); Console.WriteLine("Song Length: " + minutes + ":" + seconds); Console.WriteLine("Sample Rate: " + sampleRate); //std::cout << "Freq Range: " << hzRange << std::endl; //songChannel1.setVolume(0); }