void TryAddClickEvent(QNT_Timestamp current, QNT_Timestamp beat, ClipData clip) { if (current == beat) { bool addedSound = false; foreach (ClickTrackEvent ev in clickTrackEvents) { if (ev.time == current) { addedSound = true; break; } } if (!addedSound) { ClickTrackEvent ev; ev.clip = clip; ev.currentSample = 0; ev.time = current; clickTrackEvents.Add(ev); } } }
IEnumerator LoadHitsounds() { while (KickClip.loadState != AudioDataLoadState.Loaded) { yield return(null); } while (SnareClip.loadState != AudioDataLoadState.Loaded) { yield return(null); } while (PercussionClip.loadState != AudioDataLoadState.Loaded) { yield return(null); } while (ChainStartClip.loadState != AudioDataLoadState.Loaded) { yield return(null); } while (ChainNoteClip.loadState != AudioDataLoadState.Loaded) { yield return(null); } while (MeleeClip.loadState != AudioDataLoadState.Loaded) { yield return(null); } while (MineClip.loadState != AudioDataLoadState.Loaded) { yield return(null); } while (HiHat_Hit.loadState != AudioDataLoadState.Loaded) { yield return(null); } while (HiHat_Hit2.loadState != AudioDataLoadState.Loaded) { yield return(null); } while (HiHat_Open.loadState != AudioDataLoadState.Loaded) { yield return(null); } while (HiHat_Hit3.loadState != AudioDataLoadState.Loaded) { yield return(null); } kick = FromAudioClip(KickClip); snare = FromAudioClip(SnareClip); percussion = FromAudioClip(PercussionClip); chainStart = FromAudioClip(ChainStartClip); chainNote = FromAudioClip(ChainNoteClip); melee = FromAudioClip(MeleeClip); mine = FromAudioClip(MineClip); hihat_hit = FromAudioClip(HiHat_Hit); hihat_hit2 = FromAudioClip(HiHat_Hit2); hihat_hit3 = FromAudioClip(HiHat_Hit3); hihat_open = FromAudioClip(HiHat_Open); }
public static List <float> Detect(ClipData src, Timeline timeline, QNT_Timestamp start, QNT_Timestamp end) { for (int i = 0; i < bpmMatchDatas.Length; i++) { bpmMatchDatas[i].match = 0f; } if (start == end) { return(new List <float>()); } if (end < start) { QNT_Timestamp temp = start; start = end; end = temp; } float startTime = timeline.TimestampToSeconds(start); float endTime = timeline.TimestampToSeconds(end); int channels = src.channels; int frequency = src.frequency; uint numSamples = (uint)(frequency * (endTime - startTime) * channels); int splitFrameSize = BASE_SPLIT_SAMPLE_SIZE; var volumeArr = new float[Mathf.CeilToInt((float)src.samples.Length / (float)splitFrameSize)]; int powerIndex = 0; // Sample data analysis start for (int sampleIndex = 0; sampleIndex < src.samples.Length; sampleIndex += splitFrameSize) { float sum = 0f; for (int frameIndex = sampleIndex; frameIndex < sampleIndex + splitFrameSize; frameIndex++) { if (src.samples.Length <= frameIndex) { break; } // Use the absolute value, because left and right value is -1 to 1 float absValue = Mathf.Abs(src.samples[frameIndex]); if (absValue > 1f) { continue; } // Calculate the amplitude square sum sum += (absValue * absValue); } // Set volume value volumeArr[powerIndex] = Mathf.Sqrt(sum / splitFrameSize); powerIndex++; } // Representing a volume value from 0 to 1 float maxVolume = volumeArr.Max(); for (int i = 0; i < volumeArr.Length; i++) { volumeArr[i] = volumeArr[i] / maxVolume; } // Create volume diff list var diffList = new List <float>(); for (int i = 1; i < volumeArr.Length; i++) { diffList.Add(Mathf.Max(volumeArr[i] - volumeArr[i - 1], 0f)); } // Calculate the degree of coincidence in each BPM int index = 0; float splitFrequency = (float)frequency / (float)splitFrameSize; for (int bpm = MIN_BPM; bpm <= MAX_BPM; bpm++) { float sinMatch = 0f; float cosMatch = 0f; float bps = (float)bpm / 60f; if (diffList.Count > 0) { for (int i = 0; i < diffList.Count; i++) { sinMatch += (diffList[i] * Mathf.Cos(i * 2f * Mathf.PI * bps / splitFrequency)); cosMatch += (diffList[i] * Mathf.Sin(i * 2f * Mathf.PI * bps / splitFrequency)); } sinMatch *= (1f / (float)diffList.Count); cosMatch *= (1f / (float)diffList.Count); } float match = Mathf.Sqrt((sinMatch * sinMatch) + (cosMatch * cosMatch)); bpmMatchDatas[index].bpm = bpm; bpmMatchDatas[index].match = match; index++; } // Returns a high degree of coincidence BPM int matchIndex = Array.FindIndex(bpmMatchDatas, x => x.match == bpmMatchDatas.Max(y => y.match)); var sort = bpmMatchDatas.OrderBy(x => x.match).Reverse().ToList(); List <float> results = new List <float>(); for (int i = 0; i < 10; ++i) { results.Add(sort[i].bpm); } return(results); }