when exporting KGProject to ABC Notation Music Sheet, we need to export all the tracks including the track contains user selected region, but we should skip the track with no region or no note.
This commit is contained in:
@@ -4,9 +4,6 @@ import { KGMidiTrack } from '../../core/track/KGMidiTrack';
|
|||||||
import { KGMidiRegion } from '../../core/region/KGMidiRegion';
|
import { KGMidiRegion } from '../../core/region/KGMidiRegion';
|
||||||
import { convertRegionToABCNotation } from '../../util/abcNotationUtil';
|
import { convertRegionToABCNotation } from '../../util/abcNotationUtil';
|
||||||
import { KEY_SIGNATURE_MAP } from '../../constants/coreConstants';
|
import { KEY_SIGNATURE_MAP } from '../../constants/coreConstants';
|
||||||
import { useProjectStore } from '../../stores/projectStore';
|
|
||||||
import { KGRegion } from '../../core/region/KGRegion';
|
|
||||||
import { KGCore } from '../../core/KGCore';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tool for reading music content from the project
|
* Tool for reading music content from the project
|
||||||
@@ -104,65 +101,43 @@ export class ReadMusicTool extends BaseTool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get KGCore instance
|
* Find tracks that should be skipped because they have no musical content
|
||||||
|
* (no regions or regions with no notes)
|
||||||
*/
|
*/
|
||||||
private getKGCore(): KGCore {
|
private findTracksToSkip(tracks: KGMidiTrack[]): KGMidiTrack[] {
|
||||||
return KGCore.instance();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the track that contains the active piano roll region or first selected region
|
|
||||||
*/
|
|
||||||
private findTrackToSkip(tracks: KGMidiTrack[]): KGMidiTrack | null {
|
|
||||||
try {
|
try {
|
||||||
const store = useProjectStore.getState();
|
const tracksToSkip: KGMidiTrack[] = [];
|
||||||
const core = this.getKGCore();
|
|
||||||
|
|
||||||
// First check for active piano roll region
|
for (const track of tracks) {
|
||||||
if (store.activeRegionId) {
|
const regions = track.getRegions();
|
||||||
const activeRegion = this.findRegionById(store.activeRegionId, tracks);
|
|
||||||
if (activeRegion) {
|
// Skip tracks with no regions
|
||||||
const track = this.findTrackByRegion(activeRegion, tracks);
|
if (regions.length === 0) {
|
||||||
return track;
|
tracksToSkip.push(track);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if all regions in this track are empty (have no notes)
|
||||||
|
const hasAnyNotes = regions.some(region => {
|
||||||
|
if (region.getCurrentType() === 'KGMidiRegion') {
|
||||||
|
return (region as KGMidiRegion).getNotes().length > 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Skip tracks where no regions have notes
|
||||||
|
if (!hasAnyNotes) {
|
||||||
|
tracksToSkip.push(track);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then check for selected regions
|
return tracksToSkip;
|
||||||
const selectedItems = core.getSelectedItems();
|
|
||||||
const selectedRegion = selectedItems.find((item: unknown) => item instanceof KGRegion) as KGRegion;
|
|
||||||
|
|
||||||
if (selectedRegion) {
|
|
||||||
const track = this.findTrackByRegion(selectedRegion, tracks);
|
|
||||||
return track;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error finding track to skip:', error);
|
console.error('Error finding tracks to skip:', error);
|
||||||
return null;
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Find a region by ID across all tracks
|
|
||||||
*/
|
|
||||||
private findRegionById(regionId: string, tracks: KGMidiTrack[]): KGRegion | null {
|
|
||||||
for (const track of tracks) {
|
|
||||||
const regions = track.getRegions();
|
|
||||||
const region = regions.find(r => r.getId() === regionId);
|
|
||||||
if (region) {
|
|
||||||
return region;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find track that contains the given region
|
|
||||||
*/
|
|
||||||
private findTrackByRegion(region: KGRegion, tracks: KGMidiTrack[]): KGMidiTrack | null {
|
|
||||||
return tracks.find(track => track.getRegions().includes(region)) || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate ABC notation for all tracks
|
* Generate ABC notation for all tracks
|
||||||
@@ -174,9 +149,8 @@ export class ReadMusicTool extends BaseTool {
|
|||||||
return 'No MIDI tracks found in the project.';
|
return 'No MIDI tracks found in the project.';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the track to skip (unless it's the first track)
|
// Find tracks to skip (tracks with no content)
|
||||||
const trackToSkip = this.findTrackToSkip(midiTracks);
|
const tracksToSkip = this.findTracksToSkip(midiTracks);
|
||||||
const firstTrack = midiTracks[0]; // The melody track
|
|
||||||
|
|
||||||
// Get project settings for proper notation
|
// Get project settings for proper notation
|
||||||
const project = this.getCurrentProject();
|
const project = this.getCurrentProject();
|
||||||
@@ -187,8 +161,8 @@ export class ReadMusicTool extends BaseTool {
|
|||||||
let output = `All Tracks (beats ${startBeat}-${endBeat || 'end'}):\n\n`;
|
let output = `All Tracks (beats ${startBeat}-${endBeat || 'end'}):\n\n`;
|
||||||
|
|
||||||
midiTracks.forEach((track, index) => {
|
midiTracks.forEach((track, index) => {
|
||||||
// Skip this track if it's the track to skip AND it's not the first track (melody)
|
// Skip tracks that have no musical content
|
||||||
if (trackToSkip && track === trackToSkip && track !== firstTrack) {
|
if (tracksToSkip.includes(track)) {
|
||||||
return; // Skip this track
|
return; // Skip this track
|
||||||
}
|
}
|
||||||
const trackNumber = index + 1;
|
const trackNumber = index + 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user