fc84edfc59
Introduce KGAudioTrack and KGAudioRegion as new track/region types alongside existing MIDI tracks. Users can import WAV, MP3, OGG, FLAC, and AAC files into audio tracks with full playback, looping, and solo/mute/volume support. New core models: - KGAudioTrack (extends KGTrack with TrackType.Wave) - KGAudioRegion (extends KGRegion with audio file reference) - KGAudioPlayerBus (Tone.Gain + ToneBufferSource-based playback) - KGAudioFileStorage (OPFS media/ directory for binary audio files) New commands: - AddAudioTrackCommand (create audio track with player bus) - ImportAudioCommand (import audio file, create region at playhead, auto-expand maxBars) Playback features: - Audio regions scheduled via Tone.Transport alongside MIDI events - Loop support with duration capping at loop boundaries - Resume safety offset to prevent ToneBufferSource timing misses - Cross-track buffer copy when moving audio regions between tracks - Proper buffer cleanup on track deletion and project switch UI changes: - Separate "+ MIDI" and "+ Audio" buttons in top-left spacer - Audio track shows upload button instead of instrument selector - FileImportModal reused for audio file drag-and-drop upload - Real waveform rendering on audio region canvas - Green color scheme for audio regions (vs blue for MIDI) - Pencil icon and resize handles hidden for audio regions - Cross-type region moves blocked (MIDI ↔ Audio) - Piano roll blocked for audio regions - Audio region deletion support Infrastructure: - Project structure version bumped to 4 (no-op migration) - class-transformer discriminators updated for new subtypes - RemoveTrackCommand updated to clean up audio player buses
39 lines
1.2 KiB
TypeScript
39 lines
1.2 KiB
TypeScript
import { Expose, Type } from 'class-transformer';
|
|
import { KGTrack, TrackType } from './KGTrack';
|
|
import { KGRegion } from '../region/KGRegion';
|
|
import { KGAudioRegion } from '../region/KGAudioRegion';
|
|
import { AUDIO_INTERFACE_CONSTANTS } from '../../constants/coreConstants';
|
|
|
|
export class KGAudioTrack extends KGTrack {
|
|
@Expose()
|
|
protected override __type: string = 'KGAudioTrack';
|
|
|
|
@Expose()
|
|
@Type(() => KGRegion, {
|
|
discriminator: {
|
|
property: '__type',
|
|
subTypes: [
|
|
{ value: KGRegion, name: 'KGRegion' },
|
|
{ value: KGAudioRegion, name: 'KGAudioRegion' },
|
|
],
|
|
},
|
|
})
|
|
protected override regions: KGAudioRegion[] = [];
|
|
|
|
constructor(name: string = 'Untitled Audio Track', id: number = 0, volume: number = AUDIO_INTERFACE_CONSTANTS.DEFAULT_TRACK_VOLUME) {
|
|
super(name, id, TrackType.Wave);
|
|
this.__type = 'KGAudioTrack';
|
|
this.volume = volume;
|
|
}
|
|
|
|
// Override parent setRegions to enforce KGAudioRegion type
|
|
public override setRegions(regions: KGAudioRegion[]): void {
|
|
this.regions = regions;
|
|
}
|
|
|
|
// Override getCurrentType to return specific subclass type
|
|
public override getCurrentType(): string {
|
|
return 'KGAudioTrack';
|
|
}
|
|
}
|