UNPKG

@williamzujkowski/strudel-mcp-server

Version:

Advanced MCP server for AI-powered music generation with Strudel.cc

88 lines (87 loc) 4.41 kB
export class AudioAnalyzer { async inject(page) { await page.evaluate(() => { window.strudelAudioAnalyzer = { analyser: null, dataArray: null, isConnected: false, connect() { const originalGainConnect = GainNode.prototype.connect; let intercepted = false; GainNode.prototype.connect = function (...args) { if (!intercepted && args[0] && args[0].context) { intercepted = true; const ctx = args[0].context; window.strudelAudioAnalyzer.analyser = ctx.createAnalyser(); window.strudelAudioAnalyzer.analyser.fftSize = 2048; window.strudelAudioAnalyzer.dataArray = new Uint8Array(window.strudelAudioAnalyzer.analyser.frequencyBinCount); const result = originalGainConnect.apply(this, args); originalGainConnect.call(this, window.strudelAudioAnalyzer.analyser); window.strudelAudioAnalyzer.isConnected = true; console.log('Audio analyzer connected to Strudel'); return result; } return originalGainConnect.apply(this, args); }; }, analyze() { if (!this.analyser || !this.isConnected) { return { connected: false, error: 'Analyzer not connected' }; } this.analyser.getByteFrequencyData(this.dataArray); const data = Array.from(this.dataArray); const sum = data.reduce((a, b) => a + b, 0); const average = sum / data.length; const bass = data.slice(0, 8).reduce((a, b) => a + b, 0) / 8; const lowMid = data.slice(8, 32).reduce((a, b) => a + b, 0) / 24; const mid = data.slice(32, 128).reduce((a, b) => a + b, 0) / 96; const highMid = data.slice(128, 256).reduce((a, b) => a + b, 0) / 128; const treble = data.slice(256, 512).reduce((a, b) => a + b, 0) / 256; const peak = Math.max(...data); const peakIndex = data.indexOf(peak); const peakFreq = (peakIndex / data.length) * 22050; let weightedSum = 0; let magnitudeSum = 0; data.forEach((mag, i) => { weightedSum += i * mag; magnitudeSum += mag; }); const centroid = magnitudeSum > 0 ? weightedSum / magnitudeSum : 0; const isPlaying = average > 5; const isSilent = average < 1; return { connected: true, timestamp: Date.now(), features: { average: Math.round(average * 10) / 10, peak, peakFrequency: Math.round(peakFreq), centroid: Math.round(centroid * 10) / 10, bass: Math.round(bass), lowMid: Math.round(lowMid), mid: Math.round(mid), highMid: Math.round(highMid), treble: Math.round(treble), isPlaying, isSilent, bassToTrebleRatio: treble > 0 ? (bass / treble).toFixed(2) : 'N/A', brightness: centroid > 500 ? 'bright' : centroid > 200 ? 'balanced' : 'dark' } }; } }; window.strudelAudioAnalyzer.connect(); }); } async getAnalysis(page) { return await page.evaluate(() => { if (window.strudelAudioAnalyzer) { return window.strudelAudioAnalyzer.analyze(); } return { error: 'Analyzer not initialized' }; }); } }