Absolutely wonderful!<p>> "We obtain these times from MIDI files, though in the future I’d like to explore more automated ways of extracting them from audio."<p>Same here. In case it helps: I suspect a suitable option is (python libs) Spleeter (<a href="https://github.com/deezer/spleeter">https://github.com/deezer/spleeter</a>) to split stems and Librosa (<a href="https://github.com/librosa/librosa">https://github.com/librosa/librosa</a>) for beat times. I haven't ventured into this yet though so I may be off. My ultimate goal is to be able to do it 'on the fly', i.e. in a live music setting being able to generate visualisations a couple of seconds ahead being played along with the track.<p>Not sure if this is unsavory self promotion (it's not for commercial purposes, just experimenting), but I am in the middle of documenting something similar at the moment.<p>Experiments #1 - A Mutating Maurer Rose | Syncing Scripted Geometric Patterns to Music: <a href="https://www.youtube.com/watch?v=bfU58rBInpw" rel="nofollow">https://www.youtube.com/watch?v=bfU58rBInpw</a><p>It generates a mutating Maurer Rose using react-native-svg on my RN stack, synced to a music track I created in Suno AI *.
Manually scripted to sync up at the moment (not automatic until I investigate the above python libs).<p>Not yet optimised, proof of concept.
The Geometric pattern (left) is the only component intended to be 'user facing' in the live version - But the manual controls (middle) and the svg+path html tags (right) are included in this demo in order to show some of the 'behind the scenes'.<p>Code not yet available, app not yet available to play with. Other geometric patterns in the app that I have implemented:<p>- Modified Maurer<p>- Cosine Rose Curve<p>- Modified Rose Curve<p>- Cochleoid Spiral<p>- Lissajous Curve<p>- Hypotrochoid Spirograph<p>- Epitrochoid Spirograph<p>- Lorenz Attractor<p>- Dragon Curve<p>- Two Pendulum Harmonograph<p>- Three Pendulum Harmonograph<p>- Four Pendulum Harmonograph<p>This is the Typescript Maurer Rose function (that is used with setInterval + an object array of beat times which determine when to advance the 'n' variable):<p><pre><code> export const generateGeometricsSimplemaurer = (n: number, d: number, scale: number = 1) => {
const pathArray: TypeSvgPathArray = [];
for (let i = 0; i <= 360; i += 1) {
const k = i \* d;
const r = Math.sin(n \* k \* (Math.PI / 180));
const x =
r \*
Math.cos(k \* (Math.PI / 180)) \*
40 \* // base scale
scale +
50; // to center the image
const y =
r \*
Math.sin(k \* (Math.PI / 180)) \*
40 \* // base scale
scale +
50; // to center the image
pathArray.push(\${i === 0 ? "M" : "L"} ${x} ${y}`);`
}
const pathString: string = pathArray.join(" ");
return pathString;
};
</code></pre>
setInterval isn't an appropriate solution for the long term.<p>The geometric patterns (with their controls) will have a playground app that you can use to adjust variables... As for the music sync side, it will probably take me a long time.<p>*Edit: I just noticed that the author (Victor Tao) actually works at Suno