import type { Chapter } from '../../ui/types.ts'
import type { Params } from '../../engine/types.ts'
import driver from '../membrane/driver.m?raw'
import script from './drum.m?raw'
import text from './text.md?raw'
import {
CentsPanels,
STRIKE_CONTROL,
StrikePanels,
strikeParams,
strikeSummary,
type CentsOut,
type StrikeOut,
} from '../membrane/panels.tsx'
import { fmtCents } from '../common/panels.tsx'
export const ch04: Chapter = {
id: 'square',
nav: 'A square drum',
part: 'Drums',
title: 'A square drum',
blurb:
'The same scheme in two dimensions: an inharmonic set of partials, a stability limit of 1/√2, and a pitch error that depends on the direction a wave travels.',
text,
labs: [
{
id: 'strike',
title: 'Striking the drum',
caption:
'The fundamental is 150 Hz. Listen to the exact drum first, then to the grid; move the strike to the centre and hear three quarters of the modes disappear.',
driver,
script,
controls: [
{ kind: 'slider', key: 'N', label: 'grid intervals N', min: 0, max: 0, values: [24, 32, 48, 64] },
{ kind: 'slider', key: 'lam', label: 'Courant number λ', min: 0, max: 0, values: [0.3, 0.5, 0.7] },
STRIKE_CONTROL,
],
defaults: { N: 48, lam: 0.7, at: 'off' },
derive: (p: Params) => strikeParams(p, 'fd2'),
editorOpen: true,
render: (d: StrikeOut) => ,
summary: strikeSummary,
},
{
id: 'cents',
title: 'Pitch error in every direction',
caption:
'Modes at three wavelengths, at directions from nearly along an edge to nearly along the other. Markers are measured; lines are the dispersion relation at the same modes.',
driver,
script,
controls: [{ kind: 'slider', key: 'N', label: 'grid intervals N', min: 0, max: 0, values: [32, 64] }],
defaults: { N: 64 },
derive: (p: Params) => {
const N = Number(p.N)
return { mode: 'cents', N, lams: [0.3, 0.5, Math.SQRT1_2], rs: [N / 8, N / 4, N / 2], nang: 9 }
},
render: (d: CentsOut) => ,
summary: (d: CentsOut) => [{ label: 'measured minus predicted, largest', value: fmtCents(d.agree) }],
},
],
}