basic abc frontend support

This commit is contained in:
josc146 2024-01-05 13:47:00 +08:00
parent 62350d975d
commit e3b3452a73
3 changed files with 45 additions and 9 deletions

View File

@ -13,6 +13,7 @@
"@magenta/music": "^1.23.1", "@magenta/music": "^1.23.1",
"@microsoft/fetch-event-source": "^2.0.1", "@microsoft/fetch-event-source": "^2.0.1",
"@primer/octicons-react": "^19.1.0", "@primer/octicons-react": "^19.1.0",
"abcjs": "^6.2.3",
"chart.js": "^4.3.0", "chart.js": "^4.3.0",
"classnames": "^2.3.2", "classnames": "^2.3.2",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
@ -2690,6 +2691,15 @@
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"optional": true "optional": true
}, },
"node_modules/abcjs": {
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/abcjs/-/abcjs-6.2.3.tgz",
"integrity": "sha512-epu8C1yRkxV7Ss9hS0Bu72rairl1p2sR3hviVowjtdDJvb5GRE0SrB4TtN4HBbaoYhvxGnSZQxGULfQlW3o3RQ==",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/paulrosen"
}
},
"node_modules/acorn": { "node_modules/acorn": {
"version": "7.4.1", "version": "7.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",

View File

@ -14,6 +14,7 @@
"@magenta/music": "^1.23.1", "@magenta/music": "^1.23.1",
"@microsoft/fetch-event-source": "^2.0.1", "@microsoft/fetch-event-source": "^2.0.1",
"@primer/octicons-react": "^19.1.0", "@primer/octicons-react": "^19.1.0",
"abcjs": "^6.2.3",
"chart.js": "^4.3.0", "chart.js": "^4.3.0",
"classnames": "^2.3.2", "classnames": "^2.3.2",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",

View File

@ -21,6 +21,7 @@ import {
FileExists, FileExists,
OpenFileFolder, OpenFileFolder,
OpenMidiPort, OpenMidiPort,
OpenSaveFileDialog,
OpenSaveFileDialogBytes, OpenSaveFileDialogBytes,
SaveFile, SaveFile,
StartFile StartFile
@ -36,7 +37,9 @@ const CompositionPanel: FC = observer(() => {
const { t } = useTranslation(); const { t } = useTranslation();
const mq = useMediaQuery('(min-width: 640px)'); const mq = useMediaQuery('(min-width: 640px)');
const inputRef = useRef<HTMLTextAreaElement>(null); const inputRef = useRef<HTMLTextAreaElement>(null);
const port = commonStore.getCurrentModelConfig().apiParameters.apiPort; const modelConfig = commonStore.getCurrentModelConfig();
const port = modelConfig.apiParameters.apiPort;
const isABC = modelConfig.modelParameters.modelName.toLowerCase().includes('abc');
const visualizerRef = useRef<VisualizerElement>(null); const visualizerRef = useRef<VisualizerElement>(null);
const playerRef = useRef<PlayerElement>(null); const playerRef = useRef<PlayerElement>(null);
@ -133,6 +136,13 @@ const CompositionPanel: FC = observer(() => {
}, [commonStore.midiPorts]); }, [commonStore.midiPorts]);
const generateNs = (autoPlay: boolean) => { const generateNs = (autoPlay: boolean) => {
if (commonStore.getCurrentModelConfig().modelParameters.modelName.toLowerCase().includes('abc')) {
import('abcjs').then(ABCJS => {
ABCJS.renderAbc('abc-paper', commonStore.compositionParams.prompt, { responsive: 'resize' });
});
return;
}
fetch(getServerRoot(port) + '/text-to-midi', { fetch(getServerRoot(port) + '/text-to-midi', {
method: 'POST', method: 'POST',
headers: { headers: {
@ -396,18 +406,33 @@ const CompositionPanel: FC = observer(() => {
</div> </div>
<div className="flex flex-col"> <div className="flex flex-col">
<div className="ml-auto mr-auto"> <div className="ml-auto mr-auto">
<midi-visualizer {isABC ? <div /> :
ref={visualizerRef} <midi-visualizer
type="waterfall" ref={visualizerRef}
/> type="waterfall"
/>}
</div> </div>
<div className="flex"> <div className="flex">
<midi-player {isABC ? <div className="flex flex-col overflow-y-auto grow m-1" style={{ maxHeight: '260px' }}>
ref={playerRef} <div id="abc-paper" />
style={{ width: '100%' }} </div> :
/> <midi-player
ref={playerRef}
style={{ width: '100%' }}
/>}
<Button icon={<Save28Regular />} size={mq ? 'large' : 'medium'} appearance={mq ? 'secondary' : 'subtle'} <Button icon={<Save28Regular />} size={mq ? 'large' : 'medium'} appearance={mq ? 'secondary' : 'subtle'}
onClick={() => { onClick={() => {
if (isABC) {
OpenSaveFileDialog('*.txt', 'abc-music.txt', commonStore.compositionParams.prompt).then((path) => {
if (path)
toastWithButton(t('File Saved'), t('Open'), () => {
OpenFileFolder(path, false);
});
}).catch((e) => {
toast(t('Error') + ' - ' + (e.message || e), { type: 'error', autoClose: 2500 });
});
return;
}
if (params.midi) { if (params.midi) {
OpenSaveFileDialogBytes('*.mid', 'music.mid', Array.from(new Uint8Array(params.midi))).then((path) => { OpenSaveFileDialogBytes('*.mid', 'music.mid', Array.from(new Uint8Array(params.midi))).then((path) => {
if (path) if (path)