function waveformSelect({
audioBuffer,
width = 250,
height = 50,
selectionStart = 0,
selectionEnd = audioBuffer.length
} = {}) {
const data = audioBuffer.getChannelData(0);
const density = seriesDensity(width, height)
.yDomain([-1, 1])
.arcLengthNormalize(false)
.xDomain([0, data.length]);
let plot = densityPlot(density)
.drawAxes(false)
.background("white")
.color(() => () => ({r:0, g:0, b:0, opacity:1}));
const waveform = plot([data]);
let start = null;
function mousedown(evt) {
const rect = ui.getBoundingClientRect()
const x = evt.clientX - rect.left
start = x;
setSelectionStart(x * px2x)
return false;
}
function mousemove(evt) {
if (!evt.buttons) start = null;
if (start) {
const rect = ui.getBoundingClientRect()
const x = evt.clientX - rect.left
setSelectionEnd(x * px2x)
}
}
let selectionStartRect, selectionEndRect;
const px2x = data.length * 1.0 / width;
const x2px = width * 1.0 / data.length;
function setSelectionStart(start) {
selectionStart = start;
selectionStartRect.setAttribute("width", start*x2px)
notifyInput()
}
function setSelectionEnd(end) {
selectionEnd = end;
selectionEndRect.setAttribute("x", end*x2px)
notifyInput()
}
const value = {
selectionStart, selectionEnd,
setSelectionStart, setSelectionEnd
};
function notifyInput() {
value.selectionStart = selectionStart;
value.selectionEnd = selectionEnd;
ui.dispatchEvent(new CustomEvent("input"));
}
const overlay = svg`<svg
viewBox="0 0 ${width} ${height}"
width="${width}px"
height="${height}px"
preserveAspectRatio="none"
fill="rgba(0, 0, 0, 0.3)"
stroke="none"
style="position: absolute"
>
<rect class="wselect-start"
x="0"
width=${selectionStart*x2px}
height=${height} />
<rect class="wselect-end"
x=${selectionEnd * x2px}
width=${width}
height=${height} />
</svg>`
const ui = html`<span>
${overlay}
${waveform}
</span>`
selectionStartRect = ui.querySelector(".wselect-start");
selectionEndRect = ui.querySelector(".wselect-end");
ui.addEventListener('mousedown', mousedown);
document.addEventListener('mousemove', mousemove);
invalidation.then(() => {
ui.removeEventListener('mousedown', mousedown);
document.removeEventListener('mousemove', mousemove);
})
ui.value = value;
return ui;
}