phr00t / AutoStepper

Java tool to automate StepMania SM generation. Complete generation with banner & background art, all difficulty levels, multiple beat detection methods etc.
http://www.phr00t.com/
113 stars 23 forks source link

Support songs which change BPM in the middle #5

Open dhouck opened 6 years ago

dhouck commented 6 years ago

I have no clue if this can be auto-detected or not, but there should at least be an option to supply BPM details on the command line.

phr00t commented 6 years ago

It would be very difficult to auto-detect, since it is using the whole song to try and guess a single BPM. You'd have to detect not only both BPMs, but also when it changes. This tool wasn't really designed to work for complicated tracks or compilations, but someone can feel free to offer code for this feature.

karai17 commented 5 years ago

A quick guess as to how it could work might be to sample the track in chunks and determine the bpm of those chunks, analyze what each beat looks like (amplitude, frequency, etc) and if there is a beat that is outside of some threshold, assume the beat is changing and sample that area for the change.

A stepmania editing tool that was released last decade was too accurate in its beat detection and would create massive sm files where every single beat was adjusted at the millisecond level instead of allowing minor variances to average out.

phr00t commented 5 years ago

The tricky thing is... most songs do not change BPMs, so looking at the whole song provides more data for picking the right BPM, instead of just looking at chunks in the rare chance BPM changes. Picking the right BPM for constant BPM songs is already not an exact science and not completely accurate... trying to set a threshold for different BPMs within the same song will just lower proper detection rates for the majority of music.

Someone is free to try to add an option to attempt detecting multiple BPM rate changes, but it will be very difficult to say the least.

karai17 commented 5 years ago

It's imperfect but generally doable. The question is more about how a beat is defined. Typically in any given song, a beat has some sort of commonality, whether it be the bang of a bass drum or something else, beats are typically visible. so if you can find each beat in a song, you can determine the exact timing between them and convert that to a BPM and average it out over a span of time so that all the 299.985 and all the 301.015 beats come together as a singel span of 300 bpm.

AssortedBits commented 5 years ago

There is a direct analytical way to do this:

1) Extract the volume of the song as a time series. 2) Calculate the FFT, take the norm. 3) Find the spikes. (Omit the large spike at 0-freq.) Their frequency-locations are your BPMs. 4) Go back to the time series. For each BPM detected above, do a correlation integral with a test-sinusoid at that freq (integrate from zero offset to one period of offset). The peak location tells you the offset of that BPM, modulus the cycle-period. 5) Go to the time series again. For each BPM detected above, multiply the time series by a test sinusoid of that BPM and offset. 6) Do an average-filter of the above series, with a width of one period of the test sinusoid. 7) Look for the plateaus. Their time intervals are when those BPMs occur. (Round the start and stop times to the nearest integer number of cycles aligned with the per-cycle offset you calculated earlier.)

And yer done. :+1: