feat: add audio track support with WAV/MP3 playback and looping
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
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { Expose, Type } from 'class-transformer';
|
||||
import { KGTrack } from './track/KGTrack';
|
||||
import { KGMidiTrack } from './track/KGMidiTrack';
|
||||
import { KGAudioTrack } from './track/KGAudioTrack';
|
||||
import { type TimeSignature, WithDefault } from '../types/projectTypes';
|
||||
import { TIME_CONSTANTS, KEY_SIGNATURE_MAP } from '../constants/coreConstants';
|
||||
|
||||
@@ -47,7 +48,7 @@ export class KGProject {
|
||||
@WithDefault(0)
|
||||
private projectStructureVersion: number = 0;
|
||||
|
||||
public static readonly CURRENT_PROJECT_STRUCTURE_VERSION: number = 3;
|
||||
public static readonly CURRENT_PROJECT_STRUCTURE_VERSION: number = 4;
|
||||
|
||||
@Expose()
|
||||
@Type(() => KGTrack, {
|
||||
@@ -56,6 +57,7 @@ export class KGProject {
|
||||
subTypes: [
|
||||
{ value: KGTrack, name: 'KGTrack' },
|
||||
{ value: KGMidiTrack, name: 'KGMidiTrack' },
|
||||
{ value: KGAudioTrack, name: 'KGAudioTrack' },
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user