<CsoundSynthesizer>
<CsOptions>
</CsOptions>
<CsInstruments>
sr = 44100
ksmps = 128
nchnls = 2
0dbfs = 1
instr Init
i_Threshold = 1.7
i_MovingAverageSize = 64
i_FFTSize = 1024
i_HopSize = i_FFTSize / 4
gi_AudioFileTable ftgen 0, 0, 0, -1, "major.wav", 0, 0, 1
gi_PreviousMagnitudesTable ftgen 0, 0, i_FFTSize / 2, 2, 0
gi_MovingAverageTable ftgen 0, 0, i_MovingAverageSize, 2, 0
k_Trigger init 0
gi_FFTFrameAmp ftgen 0, 0, i_FFTSize / 2, 2, 0
f_AudioFile pvstanal 1, 1, 1, gi_AudioFileTable, 0, 0, 0, i_FFTSize, i_HopSize, 0
k_Flag pvsftw f_AudioFile, gi_FFTFrameAmp
if k_Flag == 1 then
k_Index = 0
k_Sum = 0
k_Flux = 0
AmpLoop:
k_Amp table k_Index, gi_FFTFrameAmp
k_PreviousAmp table k_Index, gi_PreviousMagnitudesTable
k_Flux = k_Flux + abs(k_Amp - k_PreviousAmp)
tablew k_Amp, k_Index, gi_PreviousMagnitudesTable
loop_le k_Index, 1, i_FFTSize / 2, AmpLoop
k_ShiftIndex = i_MovingAverageSize
ShiftLoop:
k_Shift table k_ShiftIndex - 1, gi_MovingAverageTable
tablew k_Shift, k_ShiftIndex, gi_MovingAverageTable
loop_ge k_ShiftIndex, 1, 0, ShiftLoop
k_AverageSum = 0
k_AverageIndex = 0
k_Index = 0
AverageLoop:
k_AverageVal table k_Index, gi_MovingAverageTable
k_AverageSum = k_AverageSum + k_AverageVal
loop_le k_Index, 1, i_MovingAverageSize, AverageLoop
k_MovingAverage = k_AverageSum / i_MovingAverageSize
tablew k_Flux, 0,gi_MovingAverageTable
endif
a_Out pvsynth f_AudioFile
; printk2 k_Flux
; printk2 k_MovingAverage,5
if k_Flux > k_MovingAverage * i_Threshold then
if k_Trigger == 0 then
k_Trigger = 1
schedkwhen k_Trigger, 0, 1, "Beep", 0, 0.05
endif
endif
if k_Flux >= k_MovingAverage * i_Threshold then
k_Trigger = 0
endif
outs a_Out, a_Out
endin
instr Beep
ares vco2 .2, 440
outs ares, ares
endin
</CsInstruments>
<CsScore>
i "Init" 0 10
</CsScore>
</CsoundSynthesizer>
The amplitudes of each bin are read and are subtracted from the previous bins amplitude, the absolute value of this figure for every bin is added together and this gives the flux value, this value is then written to a table which is used to take a running average of the flux. An onset is detected when the current flux value is larger than the current running average value multiplied by a threshold value, which is 1.7 in this example. It works ok but there are still plenty of false positives, you really need to tune the running average size and threshold values for the best results.
Ed