private void UpdateEvent(AudioDetectorType type, double significance) { this.eventBuffer.AddOrUpdate( type, audioDetectorType => { return(new AudioEvent() { type = audioDetectorType, significance = significance, }); }, (audioDetectorType, existingAudioEvent) => { existingAudioEvent.significance = Math.Max( existingAudioEvent.significance, significance ); return(existingAudioEvent); } ); }
private void UpdateEnergyHistory() { var energyLevels = new Dictionary <AudioDetectorType, double>(); foreach (var key in bins.Keys) { energyLevels[key] = 0.0; } for (int i = 1; i < this.AudioData.Length / 2; i++) { foreach (var pair in bins) { AudioDetectorType type = pair.Key; double[] window = pair.Value; if (WindowContains(window, i)) { energyLevels[type] += this.AudioData[i] * this.AudioData[i]; } } } foreach (var type in bins.Keys) { double current = energyLevels[type]; double[] history = this.energyHistory[type]; double previous = history[ (this.currentHistoryOffset + historyLength - 1) % historyLength ]; double change = current - previous; double avg = history.Average(); double max = history.Max(); double ssd = history.Select(val => (val - avg) * (val - avg)).Sum(); double sd = Math.Sqrt(ssd / historyLength); double stdsFromAverage = (current - avg) / sd; if (type == AudioDetectorType.Kick) { if ( current > max && stdsFromAverage > this.config.kickT && avg < this.config.kickQ && current > .001 ) { double significance = Math.Atan( stdsFromAverage / (this.config.kickT + 0.001) ) * 2 / Math.PI; this.UpdateEvent(type, significance); } } else if (type == AudioDetectorType.Snare) { if ( current > max && stdsFromAverage > this.config.snareT && avg < this.config.snareQ && current > .001 ) { double significance = Math.Atan( stdsFromAverage / (this.config.snareT + 0.001) ) * 2 / Math.PI; this.UpdateEvent(type, significance); } } } foreach (var type in bins.Keys) { this.energyHistory[type][this.currentHistoryOffset] = energyLevels[type]; } this.currentHistoryOffset = (this.currentHistoryOffset + 1) % historyLength; }