Zoom the height of a sound's wave over its level scale (#357)
The Sound tab always drew the wave at the full height of the tab. Quiet stretches were hard to see, and there was no room above a loud wave. - A level scale in dB stands left of the wave, a mark every 6 dB down from 0, as long as a mark lies inside the area and at least 14 px from the middle. - The wheel over the scale zooms the height, from 0.25x to 16x. Over the wave it zooms the time as before. - What is louder than the area stops at its edge. The fade ramps grow with the wave. - Fit puts the height back to 1x. The tab keeps the height with its view when another tab is shown. - The rules live in waveView.ts (zoomLevel, levelMarks), the hooks give the height, the scale and the top of a full-scale wave. Tests: - Unit wave-view: 10 green (2 new), 2 counter-checks each red - e2e 34 (melektaus-atx): ALL PASSED, 87 checks (1 new) - Gate (melektaus-atx): CHECK EXIT 0, 270 files, 4183 tests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
25c1d02b06
commit
c7fa1d15b0
5 files changed
+245
-35
No files matched your search
@@ -49,6 +49,43 @@ export function clampWave(view: WaveView, duration: number, width: number): Wave
|
||||
return { ...view, panX: clamp(view.panX, least, lead) };
|
||||
}
|
||||
|
||||
/** How far the wave's height zooms: out to a quarter, in to a sixteenth of full scale (#357). */
|
||||
export const MIN_LEVEL = 0.25;
|
||||
export const MAX_LEVEL = 16;
|
||||
/** Decibels apart the level scale's marks are. */
|
||||
const LEVEL_STEP_DB = 6;
|
||||
/** The quietest mark the scale goes down to. */
|
||||
const QUIETEST_DB = -96;
|
||||
|
||||
export function zoomLevel(level: number, factor: number): number {
|
||||
return clamp(level * factor, MIN_LEVEL, MAX_LEVEL);
|
||||
}
|
||||
|
||||
/** Pixels from the middle of the wave an amplitude is drawn at, `half` being full scale at level 1. */
|
||||
export function levelOffset(amplitude: number, level: number, half: number): number {
|
||||
return amplitude * level * half;
|
||||
}
|
||||
|
||||
/**
|
||||
* The marks of the level scale: every 6 dB down from 0, as far from the middle as they are drawn.
|
||||
* Only those within `room` of the middle and at least `minPx` from it – 6 dB halve the distance,
|
||||
* so that keeps them as far apart from each other too.
|
||||
*/
|
||||
export function levelMarks(
|
||||
level: number,
|
||||
half: number,
|
||||
room: number,
|
||||
minPx: number,
|
||||
): { db: number; offset: number }[] {
|
||||
const marks: { db: number; offset: number }[] = [];
|
||||
for (let db = 0; db >= QUIETEST_DB; db -= LEVEL_STEP_DB) {
|
||||
const offset = levelOffset(10 ** (db / 20), level, half);
|
||||
if (offset < minPx) break;
|
||||
if (offset <= room) marks.push({ db, offset });
|
||||
}
|
||||
return marks;
|
||||
}
|
||||
|
||||
/** Seconds between the ruler's labels: 1, 2 or 5 times a power of ten, at least `minPx` apart. */
|
||||
export function rulerStep(pxPerSecond: number, minPx: number): number {
|
||||
const rough = minPx / pxPerSecond;
|
||||
|
||||
Reference in new issue
Block a user