import { debug } from "debug"; import { html, LitElement, PropertyValues } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import { NamedNode } from "n3"; import { getTopGraph } from "./RdfdbSyncedGraph"; import { SyncedGraph } from "./SyncedGraph"; const log = debug("audio"); export interface Zoom { duration: number | null; t1: number; t2: number; } function nodeHasChanged(newVal?: NamedNode, oldVal?: NamedNode): boolean { if (newVal === undefined && oldVal === undefined) { return false; } if (newVal === undefined || oldVal === undefined) { return true; } return !newVal.equals(oldVal); } // (potentially-zoomed) spectrogram view @customElement("light9-timeline-audio") export class Light9TimelineAudio extends LitElement { graph!: SyncedGraph; graphReady: Promise; render() { return html`
`; } @property({ hasChanged: nodeHasChanged }) show!: NamedNode; @property({ hasChanged: nodeHasChanged }) song!: NamedNode; @property() zoom: Zoom = { duration: null, t1: 0, t2: 1 }; @state() imgSrc: string = "#"; @state() imgWidth: string = "0"; // css @state() imgLeft: string = "0"; // css constructor() { super(); this.graphReady = getTopGraph().then((g) => { this.graph = g; }); } async updated(changedProperties: PropertyValues) { super.updated(changedProperties); if (changedProperties.has("song") || changedProperties.has("show")) { await this.graphReady; if (this.song && this.show) { this.graph.runHandler(this.setImgSrc.bind(this), "timeline-audio " + this.song.value); } } if (changedProperties.has("zoom")) { this.imgWidth = this._imgWidth(this.zoom); this.imgLeft = this._imgLeft(this.zoom); } } setImgSrc() { try { var root = this.graph.stringValue(this.show, this.graph.Uri(":spectrogramUrlRoot")); } catch (e) { return; } try { var filename = this.graph.stringValue(this.song, this.graph.Uri(":songFilename")); } catch (e) { return; } this.imgSrc = root + "/" + filename.replace(".wav", ".png").replace(".ogg", ".png"); log(`imgSrc ${this.imgSrc}`); } _imgWidth(zoom: Zoom): string { if (!zoom.duration) { return "100%"; } return 100 / ((zoom.t2 - zoom.t1) / zoom.duration) + "%"; } _imgLeft(zoom: Zoom): string { if (!zoom.duration) { return "0"; } var percentPerSec = 100 / (zoom.t2 - zoom.t1); return -percentPerSec * zoom.t1 + "%"; } }