feat: added an option to let user choose the vertical resolution of the spectrogram, also fixed a bug that peak of pitch in the spectrogram has been mapped to the start of the note bin instead of the center

This commit is contained in:
Xiaohan-Tian
2026-05-04 20:14:04 -07:00
parent d089456676
commit 8a6e904ab4
12 changed files with 302 additions and 41 deletions
+42
View File
@@ -18,6 +18,10 @@ import { beatsToBar } from '../../util/midiUtil';
import { UpdateRegionCommand } from '../../core/commands';
import { getSuitableChords, noteNameToPitchClass } from '../../util/scaleUtil';
import { showAlert, showPrompt } from '../../util/dialogUtil';
import {
normalizeSpectrogramHeightResolution,
type SpectrogramHeightResolution,
} from '../../util/spectrogramUtil';
interface PianoRollProps {
onClose: () => void;
@@ -50,6 +54,8 @@ const PianoRoll: React.FC<PianoRollProps> = ({
// Spectrogram controls (only used in spectrogram mode)
const [spectrogramThresholdDb, setSpectrogramThresholdDb] = useState<number>(-25);
const [spectrogramPower, setSpectrogramPower] = useState<number>(0.5);
const [spectrogramHeightResolution, setSpectrogramHeightResolution] =
useState<SpectrogramHeightResolution>(3);
// Piano roll zoom (1x8x); updates --region-grid-beat-width CSS variable
const [pianoRollZoom, setPianoRollZoom] = useState<number>(1);
@@ -201,6 +207,41 @@ const PianoRoll: React.FC<PianoRollProps> = ({
}
}, []); // Empty dependency array means this runs once on mount
useEffect(() => {
let unsubscribe: (() => void) | undefined;
const initializeSpectrogramHeightResolution = async () => {
const configManager = ConfigManager.instance();
if (!configManager.getIsInitialized()) {
await configManager.initialize();
}
const applyResolutionFromConfig = () => {
setSpectrogramHeightResolution(
normalizeSpectrogramHeightResolution(
configManager.get('editor.spectrogram_height_resolution')
)
);
};
applyResolutionFromConfig();
unsubscribe = configManager.addChangeListener((changedKeys) => {
if (
changedKeys.includes('__all__') ||
changedKeys.includes('editor.spectrogram_height_resolution')
) {
applyResolutionFromConfig();
}
});
};
void initializeSpectrogramHeightResolution();
return () => {
unsubscribe?.();
};
}, []);
// Add keyboard event listener for Escape
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
@@ -1048,6 +1089,7 @@ const PianoRoll: React.FC<PianoRollProps> = ({
bpm={bpm}
spectrogramThresholdDb={spectrogramThresholdDb}
spectrogramPower={spectrogramPower}
spectrogramHeightResolution={spectrogramHeightResolution}
pianoRollZoom={pianoRollZoom}
/>