feat: implemented track level automation

This commit is contained in:
Xiaohan-Tian
2026-05-08 15:44:07 -07:00
parent 6e5d9466f4
commit 31e02b4149
24 changed files with 1931 additions and 36 deletions
+49
View File
@@ -4,6 +4,8 @@ import { KGMidiRegion } from '../region/KGMidiRegion';
import { KGAudioRegion } from '../region/KGAudioRegion';
import { AUDIO_INTERFACE_CONSTANTS } from '../../constants/coreConstants';
import { WithDefault } from '../../types/projectTypes';
import { KGTrackAutomationPoint, type TrackAutomationType } from './KGTrackAutomationPoint';
import { clampTrackAutomationValue } from '../../util/trackAutomationUtil';
// Track type enum
export enum TrackType {
@@ -49,6 +51,14 @@ export class KGTrack {
})
protected regions: KGRegion[] = [];
@Expose()
@Type(() => KGTrackAutomationPoint)
protected volumeAutomation: KGTrackAutomationPoint[] = [];
@Expose()
@Type(() => KGTrackAutomationPoint)
protected panAutomation: KGTrackAutomationPoint[] = [];
constructor(name: string = 'Untitled Track', id: number = 0, type: TrackType = TrackType.MIDI, volume: number = AUDIO_INTERFACE_CONSTANTS.DEFAULT_TRACK_VOLUME) {
this.name = name;
this.id = id;
@@ -114,6 +124,45 @@ export class KGTrack {
this.regions = regions;
}
public getVolumeAutomation(): KGTrackAutomationPoint[] {
return this.volumeAutomation;
}
public setVolumeAutomation(points: KGTrackAutomationPoint[]): void {
this.volumeAutomation = points
.map(point => {
point.setValue(clampTrackAutomationValue('volume', point.getValue()));
return point;
})
.sort((left, right) => left.getBeat() - right.getBeat());
}
public getPanAutomation(): KGTrackAutomationPoint[] {
return this.panAutomation;
}
public setPanAutomation(points: KGTrackAutomationPoint[]): void {
this.panAutomation = points
.map(point => {
point.setValue(clampTrackAutomationValue('pan', point.getValue()));
return point;
})
.sort((left, right) => left.getBeat() - right.getBeat());
}
public getAutomationPoints(type: TrackAutomationType): KGTrackAutomationPoint[] {
return type === 'volume' ? this.volumeAutomation : this.panAutomation;
}
public setAutomationPoints(type: TrackAutomationType, points: KGTrackAutomationPoint[]): void {
if (type === 'volume') {
this.setVolumeAutomation(points);
return;
}
this.setPanAutomation(points);
}
// Add a single region
public addRegion(region: KGRegion): void {
this.regions.push(region);
+68
View File
@@ -0,0 +1,68 @@
import { Expose } from 'class-transformer';
import type { Selectable } from '../../components/interfaces';
export type TrackAutomationType = 'volume' | 'pan';
export class KGTrackAutomationPoint implements Selectable {
@Expose()
private id: string = '';
@Expose()
private beat: number = 0;
@Expose()
private value: number = 0;
@Expose()
private selected: boolean = false;
constructor(id: string, beat: number = 0, value: number = 0) {
this.id = id;
this.beat = beat;
this.value = value;
}
public getId(): string {
return this.id;
}
public getBeat(): number {
return this.beat;
}
public getValue(): number {
return this.value;
}
public setId(id: string): void {
this.id = id;
}
public setBeat(beat: number): void {
this.beat = beat;
}
public setValue(value: number): void {
this.value = value;
}
public select(): void {
this.selected = true;
}
public deselect(): void {
this.selected = false;
}
public isSelected(): boolean {
return this.selected;
}
public getRootType(): string {
return 'KGTrackAutomationPoint';
}
public getCurrentType(): string {
return 'KGTrackAutomationPoint';
}
}