Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
6909bcb
copy readme to waves
ArdenButterfield Sep 15, 2025
82d6d03
gitignore .idea
ArdenButterfield Sep 15, 2025
9364c75
add triangluar and gaussian dither options
ArdenButterfield Sep 15, 2025
c2175d7
prefilter waveform
ArdenButterfield Sep 16, 2025
7d716bc
capitalization on classes
ArdenButterfield Sep 16, 2025
8b1ca77
typo
ArdenButterfield Sep 16, 2025
c854e38
dither historgram
ArdenButterfield Sep 18, 2025
f7054c3
reconstructed delay
ArdenButterfield Sep 19, 2025
ecfb304
lots of refactoring
ArdenButterfield Sep 19, 2025
5413515
new slider options for audio inputs
ArdenButterfield Sep 21, 2025
610130c
play preloaded wav files
ArdenButterfield Sep 21, 2025
6ec31a6
vowel formants
ArdenButterfield Sep 25, 2025
12cf409
begin rewrite of widget to use separate canvas for each panel/slider
ArdenButterfield Oct 2, 2025
e5c2731
sliders and panels as separate canvasses
ArdenButterfield Oct 3, 2025
8042234
filter kernel time domain
ArdenButterfield Oct 20, 2025
d25436b
filter graphs
ArdenButterfield Oct 20, 2025
792b5a4
collapse buttons
ArdenButterfield Oct 20, 2025
68d80cd
putting functions in classes
ArdenButterfield Oct 20, 2025
1afe95c
slider arrangement
ArdenButterfield Oct 21, 2025
9ea8119
refactoring buffers
ArdenButterfield Oct 26, 2025
99c4b62
put code into functions
ArdenButterfield Oct 26, 2025
c447fba
working on play function
ArdenButterfield Oct 27, 2025
d62b6da
panel layouts
ArdenButterfield Nov 3, 2025
496e2d6
bug fixes
ArdenButterfield Nov 18, 2025
a62f71a
prevent aliasing on input
ArdenButterfield Nov 18, 2025
f2f4f01
gaussian dither
ArdenButterfield Nov 18, 2025
4796302
reformat
ArdenButterfield Nov 18, 2025
d4d74cf
amplitude slider
ArdenButterfield Nov 18, 2025
85b796c
collapse button symbol
ArdenButterfield Nov 24, 2025
a3de40d
update p5 version
ArdenButterfield Nov 24, 2025
68d2cea
anti-imaging filter order
ArdenButterfield Nov 25, 2025
131f25a
css
ArdenButterfield Nov 25, 2025
9696688
try supporting separate page for delta sigma
ArdenButterfield Nov 26, 2025
615f6a9
start delta sigma page
ArdenButterfield Nov 26, 2025
22cd019
bug fixes on reconstruction filter
ArdenButterfield Nov 27, 2025
6736d00
a couple more fixes
ArdenButterfield Nov 27, 2025
17628a9
time and amp zoom sliders, names
ArdenButterfield Dec 7, 2025
87d3028
bring changes over to dsig as well
ArdenButterfield Dec 7, 2025
a1fcb1a
code efficiency improvements
ArdenButterfield Dec 8, 2025
5c68eb2
refactor repaint function
ArdenButterfield Dec 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
README.md.backup
.idea
177 changes: 141 additions & 36 deletions all-panels/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,44 +14,149 @@
<script src="../fft.js"></script>
<script src="../waves.js"></script>
<script src="../widget.js"></script>
<script src="../interaction.js"></script>
<title>Digital Audio Workbench</title>
</head>
<body>
<body>
<main>
<script>
const widget = new_widget(
[ new inputSigPanel()
, new inputSigFreqPanel()
, new impulsePanel()
, new impulseFreqPanel()
, new sampledInputPanel()
, new sampledInputFreqPanel()
, new quantNoisePanel()
, new quantNoiseFFTPanel()
, new reconstructedSigPanel()
, new reconstructedSigFFTPanel()
, new inputPlusSampledPanel()
, new allSignalsPanel()
],
[ new freqSlider()
, new numHarmSlider()
, new sampleRateSlider()
, new antialiasingSlider()
, new ditherSlider()
, new bitDepthSlider()
, new amplitudeSlider()
, new phaseSlider()
, new ampZoomSlider()
, new freqZoomSlider()
, new timeZoomSlider()
]
);
</script>
<div class="timeline">

<h1>Digital Audio Workbench (Sampling and Quantization)</h1>

<h2>By Arden Butterfield, Josh Rohs, Travis J. West & Marcelo M. Wanderley
with contributions by Eduardo Meneses, Christian Frisson, Erivan Duarte, Laurent Tarabout, and Maxwell Gentili-Morin</h2>
<h3>Copyright IDMIL/McGill University, 2025</h3>

<div class="section" id="input-section">
<div class="titlebar">
<div class="section-title">
<h2>Input</h2>
</div>
<button class="collapse-button" id="coll-input" onclick="collapseClick(this.id)"></button>
</div>
<div class="collapse">
<div class="row panels">
<div class="panel" id="input-time-domain"></div>
<div class="panel" id="input-freq-domain"></div>
</div>
<div class="row sliders">
<div class="slider" id="audio-input-type-slider"></div>
<div class="slider" id="frequency-slider"></div>
<div class="slider" id="num-harmonics-slider"></div>
<div class="slider" id="amplitude-slider"></div>
</div>
<button class="play-button" id="play-input">Play</button>
</div>
</div>
<div class="section" id="filter-section">
<div class="titlebar">
<div class="section-title">
<h2>Filter</h2>
</div>
<button class="collapse-button" id="coll-filter" onclick="collapseClick(this.id)"></button>
</div>
<div class="collapse">
<div class="row panels">
<div class="panel" id="filter-kernel"></div>
<div class="panel" id="filter-kernel-fft"></div>
</div>
<div class="row panels">
<div class="panel" id="input-filtered-time-domain"></div>
<div class="panel" id="input-filtered-freq-domain"></div>
</div>
<div class="row sliders">
<div class="slider" id="antialiasing-filter-order-slider"></div>
</div>
<button class="play-button" id="play-filter-kernel">Play kernel</button>
<button class="play-button" id="play-filtered-input">Play filtered input</button>
</div>
</div>
<div class="section" id="samplerate-section">
<div class="titlebar">
<div class="section-title">
<h2>Sample Rate</h2>
</div>
<button class="collapse-button" id="coll-fs" onclick="collapseClick(this.id)"></button>
</div>
<div class="collapse">
<div class="row panels">
<div class="panel" id="input-plus-sampled"></div>
<div class="panel" id="sampling-freq-domain"></div>
</div>
<div class="row sliders">
<div class="slider" id="sample-rate-slider"></div>
</div>
<button class="play-button" id="play-sample-rate">Play</button>
</div>
</div>
<div class="section" id="dither-section">
<div class="titlebar">
<div class="section-title">
<h2>Dither</h2>
</div>
<button class="collapse-button" id="coll-dither" onclick="collapseClick(this.id)"></button>

</div>
<div class="collapse">
<div class="row panels">
<div class="panel" id="dither-histogram"></div>
</div>
<div class="row sliders">
<div class="slider" id="dither-slider"></div>
</div>
</div>
</div>
<div class="section" id="quantization-section">
<div class="titlebar">
<div class="section-title">
<h2>Quantization</h2>
</div>
<button class="collapse-button" id="coll-quantization" onclick="collapseClick(this.id)"></button>
</div>
<div class="collapse">
<div class="row panels">
<div class="panel" id="quantization-noise"></div>
<div class="panel" id="quantization-noise-fft"></div>
</div>
<div class="row sliders">
<div class="slider" id="quantization-slider"></div>
</div>
<button class="play-button" id="play-quantized-noise">Play</button>
</div>
</div>
<div class="section" id="reconstructed-section">
<div class="titlebar">
<div class="section-title">
<h2>Reconstructed</h2>
</div>
<button class="collapse-button" id="coll-recon" onclick="collapseClick(this.id)"></button>

</div>
<div class="collapse">
<div class="row panels">
<div class="panel" id="reconstructed"></div>
<div class="panel" id="reconstructed-fft"></div>
</div>
<div class="row panels">
<div class="panel" id="all-signals"></div>
</div>
<div class="row sliders">
<div class="slider" id="reconstruction-filter-order-slider"></div>
</div>
<button class="play-button" id="play-reconstructed">Play Reconstructed</button>
</div>
</div>
</div>
</main>
<footer>
<div>Digital Audio Workbench </div>
<div>By Josh Rohs, Travis J. West & Marcelo M. Wanderley </div>
<div>with contributions by Eduardo Meneses, Christian Frisson, and Erivan Duarte</div>
<div>Copyright <a href="//www-new.idmil.org/">IDMIL</a>/McGill University, 2020 </div>
</footer>
<div class="global-panel">
<div id="global-panel-collapse-button" onclick="collapseGlobalPanel()"></div>
<div class="contents">
<div class="slider" id="time-zoom-slider"></div>
<div class="slider" id="amp-zoom-slider"></div>
</div>
</div>
<script>
createWidgets();
</script>
</body>
</html>
36 changes: 18 additions & 18 deletions delta-modulation/widget_delta.js
Original file line number Diff line number Diff line change
Expand Up @@ -797,21 +797,21 @@ function updatePanel(panels, name, checkBoxState) {
if (!panelPresent) {
//Replace/add lines for more options
if (name == "Input Signal Time Domain with Delta Modulation") {panels.push(new deltaModPanel());}
if (name == "Input Signal Frequency Domain") {panels.push(new inputSigFreqPanel());}
if (name == "Reconstructed Signal Time Domain") {panels.push(new reconstructedSigPanel());}
if (name == "Reconstructed Signal FFT") {panels.push(new reconstructedSigFFTPanel());}
if (name == "Input Signal Frequency Domain") {panels.push(new InputSigFreqPanel());}
if (name == "Reconstructed Signal Time Domain") {panels.push(new ReconstructedSigPanel());}
if (name == "Reconstructed Signal FFT") {panels.push(new ReconstructedSigFFTPanel());}
if (name == "Reconstructed Signal Time Domain using Delta Modulation") {panels.push(new reconstructedDeltaModSigPanel());}
if (name == "Reconstructed Signal using Delta Modulation FFT") {panels.push(new reconstructedDeltaModSigFFTPanel());}
if (name == "Input Signal Time Domain") {panels.push(new inputSigPanel());}
if (name == "Sampled Signal FFT") {panels.push(new sampledInputFFTPanel());}
if (name == "Sampling Signal Time Domain") {panels.push(new impulsePanel());}
if (name == "Sampling Signal Frequency Domain") {panels.push(new impulseFreqPanel());}
if (name == "Sampled Signal Time Domain") {panels.push(new sampledInputPanel());}
if (name == "Sampled Signal Frequency Domain") {panels.push(new sampledInputFreqPanel());}
if (name == "Quantization Noise Time Domain") {panels.push(new quantNoisePanel());}
if (name == "Quantization Noise FFT") {panels.push(new quantNoiseFFTPanel());}
if (name == "Input with Sampled Signal Time Domain") {panels.push(new inputPlusSampledPanel());}
if (name == "Input (solid), Sampled (lollipop), Reconstructed (dotted), Time Domain") {panels.push(new allSignalsPanel());}
if (name == "Input Signal Time Domain") {panels.push(new InputSigPanel());}
if (name == "Sampled Signal FFT") {panels.push(new SampledInputFFTPanel());}
if (name == "Sampling Signal Time Domain") {panels.push(new ImpulsePanel());}
if (name == "Sampling Signal Frequency Domain") {panels.push(new ImpulseFreqPanel());}
if (name == "Sampled Signal Time Domain") {panels.push(new SampledInputPanel());}
if (name == "Sampled Signal Frequency Domain") {panels.push(new SampledInputFreqPanel());}
if (name == "Quantization Noise Time Domain") {panels.push(new QuantNoisePanel());}
if (name == "Quantization Noise FFT") {panels.push(new QuantNoiseFFTPanel());}
if (name == "Input with Sampled Signal Time Domain") {panels.push(new InputPlusSampledPanel());}
if (name == "Input (solid), Sampled (lollipop), Reconstructed (dotted), Time Domain") {panels.push(new AllSignalsPanel());}


//reorderPanels();
Expand Down Expand Up @@ -858,13 +858,13 @@ function updateSlider(sliders, propName, checkBoxState) {
}
if (!sliderPresent) {
//Replace/add lines for more options
if (propName == "timeZoom") {sliders.push(new timeZoomSlider());}
if (propName == "fundFreq") {sliders.push(new freqSlider());}
if (propName == "downsamplingFactor") {sliders.push(new sampleRateSlider());}
if (propName == "timeZoom") {sliders.push(new TimeZoomSlider());}
if (propName == "fundFreq") {sliders.push(new FreqSlider());}
if (propName == "downsamplingFactor") {sliders.push(new SampleRateSlider());}
if (propName == "downsamplingFactorDelta") {sliders.push(new sampleRateDeltaSlider());}
if (propName == "deltaStep") {sliders.push(new deltaStepSlider());}
if (propName == "numHarm") {sliders.push(new numHarmSlider());}
if (propName == "phase") {sliders.push(new phaseSlider());}
if (propName == "numHarm") {sliders.push(new NumHarmSlider());}
if (propName == "phase") {sliders.push(new PhaseSlider());}
/*if (propName == "") {sliders.push(new ());}
if (propName == "") {sliders.push(new ());}
if (propName == "") {sliders.push(new ());}
Expand Down
104 changes: 104 additions & 0 deletions delta-sigma-panels/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="../styles.css" media="screen" />
<!-- p5.js begin -->
<!-- 1) use p5.min.js for optimizing size/transfer -->
<script src="../p5.min.js"></script>
<!-- 2) use p5.js for debugging -->
<!-- <script src="../p5.js"></script> -->
<!-- p5.js end-->
<script src="../fili.min.js"></script>
<script src="../panel.js"></script>
<script src="../slider.js"></script>
<script src="../fft.js"></script>
<script src="../waves.js"></script>
<script src="../widget.js"></script>
<script src="../interaction.js"></script>
</head>
<body>
<main>
<div class="timeline">
<h1>Digital Audio Workbench (Delta-Sigma Encoding)</h1>

<h2>By Arden Butterfield, Josh Rohs, Travis J. West & Marcelo M. Wanderley
with contributions by Eduardo Meneses, Christian Frisson, Erivan Duarte, Laurent Tarabout, and Maxwell Gentili-Morin</h2>
<h3>Copyright IDMIL/McGill University, 2025</h3>

<div class="section" id="input-section">
<div class="titlebar">
<div class="section-title">
<h2>Input</h2>
</div>
<button class="collapse-button" id="coll-input" onclick="collapseClick(this.id)"></button>
</div>
<div class="collapse">
<div class="row panels">
<div class="panel" id="input-time-domain"></div>
<div class="panel" id="input-freq-domain"></div>
</div>
<div class="row sliders">
<div class="slider" id="audio-input-type-slider"></div>
<div class="slider" id="frequency-slider"></div>
<div class="slider" id="num-harmonics-slider"></div>
<div class="slider" id="amplitude-slider"></div>
</div>
<button class="play-button" id="play-input">Play</button>
</div>
</div>
<div class="section" id="delta-sigma-section">
<div class="titlebar">
<div class="section-title">
<h2>Delta-Sigma</h2>
</div>
<button class="collapse-button" id="coll-delta-sigma" onclick="collapseClick(this.id)"></button>
</div>
<div class="collapse">
<div class="row panels">
<div class="panel" id="delta-mod-panel"></div>
</div>
<div class="row sliders">
<div class="slider" id="sample-rate-slider"></div>
<div class="slider" id="delta-sigma-step-slider"></div>
</div>
<button class="play-button" id="play-delta-sigma">Play</button>
</div>
</div>
<div class="section" id="reconstructed-section">
<div class="titlebar">
<div class="section-title">
<h2>Reconstructed</h2>
</div>
<button class="collapse-button" id="coll-recon" onclick="collapseClick(this.id)"></button>

</div>
<div class="collapse">
<div class="row panels">
<div class="panel" id="reconstructed"></div>
<div class="panel" id="reconstructed-fft"></div>
</div>
<div class="row panels">
<div class="panel" id="all-signals"></div>
</div>
<div class="row sliders">
<div class="slider" id="reconstruction-filter-order-slider"></div>
<div class="slider" id="reconstruction-filter-freq-slider"></div>
</div>
<button class="play-button" id="play-reconstructed">Play Reconstructed</button>
</div>
</div>
</div>
</main>
<div class="global-panel">
<div id="global-panel-collapse-button" onclick="collapseGlobalPanel()"></div>
<div class="contents">
<div class="slider" id="time-zoom-slider"></div>
<div class="slider" id="amp-zoom-slider"></div>
</div>
</div>

<script>
createWidgets();
</script>
</body>
</html>
20 changes: 20 additions & 0 deletions interaction.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
function collapseClick(id) {
let collapse = document.getElementById(id).parentNode.parentNode .querySelector('.collapse');
if (collapse.style.display === 'none') {
collapse.style.display = 'block';
document.getElementById(id).textContent = "_";
} else {
collapse.style.display = 'none';
document.getElementById(id).textContent = "\u26F6";
}
}

function collapseGlobalPanel() {
let collapse = document.getElementById("global-panel-collapse-button").parentNode.querySelector('.contents');
if (collapse.style.display === 'none') {
collapse.style.display = 'block';
} else {
collapse.style.display = 'none';
}

}
Loading
Loading