Adding new FM synthesis mode
This commit is contained in:
89
src/utils/fmPatches.ts
Normal file
89
src/utils/fmPatches.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import type { TileState } from '../types/tiles'
|
||||
import { getDefaultEngineValues, getDefaultEffectValues } from '../config/effects'
|
||||
import { getDefaultLFOValues } from '../stores/settings'
|
||||
|
||||
export interface FMPatchConfig {
|
||||
algorithm: number
|
||||
feedback: number
|
||||
lfoRates: [number, number, number, number]
|
||||
}
|
||||
|
||||
export function generateRandomFMPatch(complexity: number = 1): FMPatchConfig {
|
||||
let algorithmRange: number[]
|
||||
|
||||
switch (complexity) {
|
||||
case 0:
|
||||
algorithmRange = [0, 2, 6, 8, 9, 10]
|
||||
break
|
||||
case 2:
|
||||
algorithmRange = [1, 4, 5, 7, 11, 12, 13, 14, 15]
|
||||
break
|
||||
default:
|
||||
algorithmRange = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
|
||||
}
|
||||
|
||||
const algorithm = algorithmRange[Math.floor(Math.random() * algorithmRange.length)]
|
||||
const feedback = Math.floor(Math.random() * 100)
|
||||
|
||||
const lfoRates: [number, number, number, number] = [
|
||||
0.2 + Math.random() * 0.8,
|
||||
0.3 + Math.random() * 1.0,
|
||||
0.4 + Math.random() * 1.2,
|
||||
0.25 + Math.random() * 0.9
|
||||
]
|
||||
|
||||
return { algorithm, feedback, lfoRates }
|
||||
}
|
||||
|
||||
export function createFMTileState(patch: FMPatchConfig): TileState {
|
||||
const formula = JSON.stringify(patch)
|
||||
|
||||
const pitchValues = [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 2.0]
|
||||
const randomPitch = pitchValues[Math.floor(Math.random() * pitchValues.length)]
|
||||
|
||||
return {
|
||||
formula,
|
||||
engineParams: {
|
||||
...getDefaultEngineValues(),
|
||||
a: Math.floor(Math.random() * 128) + 64,
|
||||
b: Math.floor(Math.random() * 128) + 64,
|
||||
c: Math.floor(Math.random() * 128) + 64,
|
||||
d: Math.floor(Math.random() * 128) + 64,
|
||||
pitch: randomPitch,
|
||||
fmAlgorithm: patch.algorithm,
|
||||
fmFeedback: patch.feedback
|
||||
},
|
||||
effectParams: getDefaultEffectValues(),
|
||||
lfoConfigs: getDefaultLFOValues()
|
||||
}
|
||||
}
|
||||
|
||||
export function generateFMTileGrid(size: number, columns: number, complexity: number = 1): TileState[][] {
|
||||
const tiles: TileState[][] = []
|
||||
const rows = Math.ceil(size / columns)
|
||||
|
||||
for (let i = 0; i < rows; i++) {
|
||||
const row: TileState[] = []
|
||||
for (let j = 0; j < columns; j++) {
|
||||
if (i * columns + j < size) {
|
||||
const patch = generateRandomFMPatch(complexity)
|
||||
row.push(createFMTileState(patch))
|
||||
}
|
||||
}
|
||||
tiles.push(row)
|
||||
}
|
||||
|
||||
return tiles
|
||||
}
|
||||
|
||||
export function parseFMPatch(formula: string): FMPatchConfig | null {
|
||||
try {
|
||||
const parsed = JSON.parse(formula)
|
||||
if (typeof parsed.algorithm === 'number' && typeof parsed.feedback === 'number') {
|
||||
return parsed
|
||||
}
|
||||
} catch {
|
||||
// Not a valid FM patch
|
||||
}
|
||||
return null
|
||||
}
|
||||
Reference in New Issue
Block a user