Files
topos/src/classes/ZPlayer.ts

97 lines
2.9 KiB
TypeScript

import { Chord, Pitch, Rest as ZRest, Ziffers } from "zifferjs";
import { Editor } from "../main";
import { Event, Skip } from "./Event";
import { Sound } from "./Sound";
import { Note } from "./Note";
import { Rest } from "./Rest";
export class Player extends Event {
input: string;
ziffers: Ziffers;
callTime: number = 0;
played: boolean = false;
current!: Pitch|Chord|ZRest;
retro: boolean = false;
tick: number = 0;
constructor(input: string, options: object, public app: Editor) {
super(app);
this.input = input;
this.ziffers = new Ziffers(input, options);
}
next = (): Pitch|Chord|ZRest => {
this.current = this.ziffers.next() as Pitch|Chord|ZRest;
this.played = true;
return this.current;
}
areWeThereYet = (): boolean => {
const howAboutNow = (this.ziffers.notStarted() || this.app.api.epulse() > this.callTime+(this.current.duration*this.app.api.ppqn()));
if(howAboutNow) {
this.tick = 0;
} else {
this.tick++;
}
return howAboutNow;
}
sound(name: string) {
if(this.areWeThereYet()) {
const event = this.next() as Pitch|Chord|ZRest;
if(event instanceof Pitch) {
// TODO: Quick hack. Select which attributes to use, but some ziffers stuff is needed for chaining key change etc.
const obj = event.getExisting("freq","pitch","key","scale","octave");
return new Sound(obj, this.app).sound(name);
} else if(event instanceof ZRest) {
return Rest.createRestProxy(event.duration, this.app);
}
} else {
return Skip.createRestProxy();
}
}
note(value: number|undefined = undefined) {
if(this.areWeThereYet()) {
const event = this.next() as Pitch|Chord|ZRest;
if(event instanceof Pitch) {
// TODO: Quick hack. Select which attributes to use, but some ziffers stuff is needed for chaining key change etc.
const obj = event.getExisting("note","pitch","bend","key","scale","octave");
const note = new Note(obj, this.app);
return value ? note.note(value) : note;
} else if(event instanceof ZRest) {
return Rest.createRestProxy(event.duration, this.app);
}
} else {
return Skip.createRestProxy();
}
}
scale(name: string) {
this.ziffers.scale(name);
return this;
}
key(name: string) {
this.ziffers.key(name);
return this;
}
octave(value: number) {
this.ziffers.octave(value);
return this;
}
retrograde() {
if(this.tick === 0 && this.ziffers.index === 0) {
this.ziffers.retrograde();
}
return this;
}
out = (): void => {
// TODO?
}
}