summaryrefslogtreecommitdiff
path: root/sample_editor/sample_editor2.html
diff options
context:
space:
mode:
Diffstat (limited to 'sample_editor/sample_editor2.html')
-rw-r--r--sample_editor/sample_editor2.html290
1 files changed, 290 insertions, 0 deletions
diff --git a/sample_editor/sample_editor2.html b/sample_editor/sample_editor2.html
new file mode 100644
index 0000000..5671603
--- /dev/null
+++ b/sample_editor/sample_editor2.html
@@ -0,0 +1,290 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Tabbed Interface App</title>
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
+ <link rel="stylesheet" href="topbar.css">
+ <link rel="stylesheet" href="sample_editor.css">
+ <style>
+ </style>
+</head>
+<body>
+ <div class="top-menu-bar">
+ <div class="tab burger-menu" id="burger-menu" onclick="toggleDropdown()">
+ <i class="fas fa-bars burger-menu-icon"></i>
+ </div>
+ <div class="dropdown-menu" id="dropdown-menu">
+ <div class="dropdown-item" onclick="menuAction('load')">Load From Device</div>
+ <div class="dropdown-item" onclick="menuAction('save')">Save to Device</div>
+ <div class="dropdown-item" onclick="menuAction('save_uf2')">Save to UF2</div>
+ <div class="dropdown-item" onclick="menuAction('clear')">Clear</div>
+ </div>
+ <div class="tab" onclick="selectTab(0)">
+ <div class="circle">1</div>
+ <canvas class="minicanvas-container"></canvas>
+ </div>
+ <div class="tab" onclick="selectTab(1)">
+ <div class="circle">2</div>
+ <canvas class="minicanvas-container"></canvas>
+ </div>
+ <div class="tab" onclick="selectTab(2)">
+ <div class="circle">3</div>
+ <canvas class="minicanvas-container"></canvas>
+ </div>
+ <div class="tab" onclick="selectTab(3)">
+ <div class="circle">4</div>
+ <canvas class="minicanvas-container"></canvas>
+ </div>
+ <div class="tab" onclick="selectTab(4)">
+ <div class="circle">5</div>
+ <canvas class="minicanvas-container"></canvas>
+ </div>
+ <div class="tab" onclick="selectTab(5)">
+ <div class="circle">6</div>
+ <canvas class="minicanvas-container"></canvas>
+ </div>
+ <div class="tab" onclick="selectTab(6)">
+ <div class="circle">7</div>
+ <canvas class="minicanvas-container"></canvas>
+ </div>
+ <div class="tab" onclick="selectTab(7)">
+ <div class="circle">8</div>
+ <canvas class="minicanvas-container"></canvas>
+ </div>
+ <div class="tab" onclick="selectTab(8)">
+ <div class="circle">W</div>
+ <canvas class="minicanvas-container"></canvas>
+ </div>
+ </div>
+ <!----------------------------------------->
+ <div class="canvas-container">
+ <span id="help">Drop one or more audio files here to begin.</span>
+ <canvas id="audioCanvas"></canvas>
+ </div>
+ <div class="main-container">
+ <div class="slice-list">
+ <ul id="sliceList"></ul>
+ </div>
+ <div class="editor-container">
+ <div class="name-track-container">
+ <div>
+ <label for="sliceName">Name:</label>
+ <input type="text" id="sliceName" style="width: 100%;">
+ </div>
+ </div>
+ <div class="spacer"></div>
+ <label for="gainSlider">Pre-Gain: <span id="gainValue">0</span> dB</label>
+ <input type="range" id="gainSlider" class="slider" min="-60" max="60" value="0">
+
+ <div class="radio-group">
+ <!-- <button id ="normalize">Normalize</button> -->
+ <label><input type="checkbox" id="pitchedCheckbox"> Pitched</label>
+ <label><input type="checkbox" id="reversedCheckbox"> Reversed</label>
+ </div>
+ <div class="spacer"></div>
+
+ <label for="basePitchSlider" id="basePitchLabel" style="display: none;">Base Pitch: <span
+ id="basePitchValue">C4</span></label>
+ <input type="range" id="basePitchSlider" class="slider" min="0" max="127" value="48" style="display: none;">
+
+ </div>
+ <div class="eq-container">
+ <canvas id="eqCanvas"></canvas>
+ <canvas id="fftCanvas"></canvas>
+ </div>
+ </div>
+ <script src="slicer.js" defer> </script>
+
+ <script>
+
+
+ function toggleDropdown() {
+ const dropdown = document.getElementById('dropdown-menu');
+ dropdown.classList.toggle('open');
+ }
+
+ function menuAction(action) {
+ console.log('Menu action:', action);
+ toggleDropdown();
+ }
+
+ function renderMiniCanvas(index, minimap) {
+ const canvas = document.querySelectorAll('.minicanvas-container')[index];
+ canvas.width=256;
+ canvas.height=32;
+ const ctx = canvas.getContext('2d');
+ ctx.fillStyle = 'black';
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ for (let i = 0; i < canvas.width; i++) {
+ const y = minimap[i*8];
+ ctx.fillRect(i, 16 - y, 1, y * 2);
+ }
+ }
+
+ // Close dropdown when clicking outside of it
+ document.addEventListener('click', (event) => {
+ const dropdown = document.getElementById('dropdown-menu');
+ const burgerMenu = document.getElementById('burger-menu');
+ if (!dropdown.contains(event.target) && !burgerMenu.contains(event.target)) {
+ dropdown.classList.remove('open');
+ }
+ });
+
+ function init_topbar() {
+ selectTab(0);
+
+ }
+
+ document.addEventListener("DOMContentLoaded", (event) => {
+ console.log("DOM fully loaded and parsed");
+ function resizeCanvas() {
+ const eqcanvas = document.getElementById('eqCanvas');
+ eqcanvas.width = eqcanvas.clientWidth * dpr;
+ eqcanvas.height = eqcanvas.clientHeight * dpr;
+
+ const fftcanvas = document.getElementById('fftCanvas');
+ fftcanvas.width = fftcanvas.clientWidth * dpr;
+ fftcanvas.height = fftcanvas.clientHeight * dpr;
+
+ const wfcanvas = document.getElementById('audioCanvas');
+ wfcanvas.width = wfcanvas.clientWidth * dpr;
+ wfcanvas.height = wfcanvas.clientHeight * dpr;
+ updateAudioDisplay();
+ }
+
+
+ window.addEventListener('resize', resizeCanvas);
+
+ function onDragStart(event, index) {
+ event.dataTransfer.setData('text/plain', index);
+ }
+ function onDrop(event, dropIndex) {
+ const draggedIndex = parseInt(event.dataTransfer.getData('text/plain'), 10);
+ if (draggedIndex !== dropIndex) {
+ const draggedItem = G.slices[draggedIndex];
+ G.slices.splice(draggedIndex, 1);
+ G.slices.splice(dropIndex, 0, draggedItem);
+ updateSliceList();
+ selectSlice(dropIndex);
+ }
+ }
+
+ document.getElementById('sliceName').addEventListener('input', function () {
+ if (G.currentSlice >= G.slices.length) return;
+ G.slices[G.currentSlice].name = this.value;
+ document.querySelector(`#sliceList li:nth-child(${G.currentSlice + 1})`).innerHTML = `<span class="color-chip" style="background-color: hsl(${G.slices[G.currentSlice].hue}, 100%, 50%)"></span>${this.value}`;
+ });
+
+ document.getElementById('gainSlider').addEventListener('input', function () {
+ if (G.currentSlice >= G.slices.length) return;
+ G.slices[G.currentSlice].gain = this.value;
+ document.getElementById('gainValue').innerText = this.value;
+ if (customNode) {
+ const gainValue = db2lin(G.slices[G.currentSlice].gain);
+ customNode.parameters.get('gain').setValueAtTime(gainValue, 0);
+ }
+ updateAudioDisplay();
+ });
+
+
+ document.getElementById('basePitchSlider').addEventListener('input', function () {
+ if (G.currentSlice >= G.slices.length) return;
+ document.getElementById('basePitchValue').innerText = midiToNoteName(this.value);
+ G.slices[G.currentSlice].base_pitch = parseInt(this.value);
+ updateAudioDisplay();
+ });
+
+ document.getElementById('reversedCheckbox').addEventListener('change', function () {
+ if (G.currentSlice >= G.slices.length) return;
+ G.slices[G.currentSlice].reversed = this.checked;
+ updateAudioDisplay();
+ });
+
+ document.getElementById('pitchedCheckbox').addEventListener('change', function () {
+ G.pitched = this.checked;
+ updateAudioDisplay();
+ updateExtraSlider();
+ });
+
+ function update_value(event) {
+ if (event.key === 'Enter') {
+ event.preventDefault();
+ this.blur();
+ const value = parseFloat(this.innerText);
+ if (!isNaN(value)) {
+ updateAudioDisplay();
+ }
+ }
+ }
+ document.addEventListener('keyup', function (event) {
+ if (event.key == 'Shift') {
+ console.log("end megazoom");
+ if (prev_zoom) {
+ G.zoom = prev_zoom;
+ G.first_sample = prev_first_sample;
+ prev_zoom = null;
+ updateAudioDisplay();
+ }
+ }
+ });
+
+ let prev_first_sample = null;
+ let prev_zoom = null;
+
+ document.addEventListener('keydown', function (event) {
+ makeAudioContext();
+ // if an input control is focused, then don't process keyboard shortcuts
+ if (document.activeElement.id == 'sampleRateValue' || document.activeElement.id == 'bpmValue' || document.activeElement.id == 'sliceName') return;
+ console.log(event.key);
+ if (event.key == 'Escape') {
+ selectSlice(G.slices.length);
+ return;
+ }
+ else if (event.key == 'Shift') {
+ if (!prev_zoom) {
+ console.log("megazoom");
+ prev_zoom = G.zoom;
+ prev_first_sample = G.first_sample;
+ if (G.zoom > 8)
+ G.zoom = 4;
+ else
+ G.zoom = 1;
+ G.first_sample = mouseSample - mouseX * G.zoom;
+ G.first_sample = Math.max(0, Math.min(G.first_sample, G.the_audio.length - wfcanvas.width * G.zoom));
+ updateAudioDisplay();
+ }
+ }
+ if (event.key === 'Backspace') {
+ deleteSlice(G.currentSlice, event.ctrlKey || event.metaKey || event.shiftKey);
+ }
+ else if (event.key === 'ArrowUp' || event.key === 'ArrowDown' || event.key == 'ArrowLeft' || event.key == 'ArrowRight') {
+ event.preventDefault();
+ if (event.key == 'ArrowUp' || event.key == 'ArrowLeft')
+ if (G.currentSlice > 0) G.currentSlice--;
+ else G.currentSlice = G.slices.length - 1;
+ else
+ if (G.currentSlice < G.slices.length - 1) G.currentSlice++;
+ else G.currentSlice = 0;
+ selectSlice(G.currentSlice);
+ }
+ else if (event.key.toLowerCase() == 'r') {
+ G.slices[G.currentSlice].reversed = !G.slices[G.currentSlice].reversed;
+ document.getElementById('reversedCheckbox').checked = G.slices[G.currentSlice].reversed;
+ updateAudioDisplay();
+ } else if (event.key == ' ') {
+ playAudio();
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ });
+ resizeCanvas();
+ updateSliceList();
+ setupBiquads();
+ drawEQCurve();
+ init_topbar();
+ });
+ </script>
+</body>
+</html>