Skip to content

Commit ccf6e40

Browse files
committed
Finalized Delta modulation page, with adaptive delta modulation. Fixed visual bugs with the slider, changed the alignment a bit.
1 parent 7460ab6 commit ccf6e40

7 files changed

Lines changed: 64 additions & 25 deletions

File tree

delta-modulation/index.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
</center>
3232
<div id = "content-wrap" class="title qs">
3333
<H1>
34-
Delta Modulation
34+
Adaptive Delta Modulation
3535
</H1>
3636
<hr>
3737
</div>
@@ -41,15 +41,17 @@ <H1>
4141
<script>
4242
const widgetset = new_widget(
4343
[ new deltaModPanel()
44+
, new inputSigFreqPanel()
4445
, new reconstructedSigPanel()
46+
, new reconstructedSigFFTPanel()
4547
],
4648
[ new freqSlider()
4749
, new numHarmSlider()
4850
, new sampleRateDeltaSlider()
4951
, new deltaStepSlider()
5052
, new timeZoomSlider()
5153
]
52-
, ["original","recon","quant"]
54+
, ["original","recon","quant","adaptive"]
5355
,"Question"
5456
,"qs"
5557
, 120

delta-modulation/panel_delta.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,25 @@ function drawDeltaModulation(panel, signal) {
134134
panel.buffer.curveTightness(1.0);
135135
let visibleSamples = Math.floor(panel.plotWidth / panel.settings.downsamplingFactor/panel.settings.timeZoom+1);
136136
let ypos = panel.halfh;
137+
let counter = 0; //Consecutive similar bits counter for adaptive modulation
138+
let lastBit = 0;
137139
for (let x = 0; x < visibleSamples; x++) {
138140
let xpos = Math.round(panel.plotLeft + x * panel.settings.downsamplingFactor*panel.settings.timeZoom);
139141
panel.buffer.curveVertex(xpos, ypos);
140142
if (pixel_max * signal[Math.floor((x/visibleSamples)*panel.plotWidth/panel.settings.timeZoom)]*panel.settings.ampZoom < panel.halfh - ypos) {
141-
ypos += panel.settings.deltaStep*panel.plotHeight;
142-
//if (ypos >= panel.plotBottom) ypos -= 2*panel.settings.deltaStep*panel.plotHeight; //Prevent signal from going below bounds
143+
if (panel.settings.deltaType == "adaptive") {
144+
if (lastBit == 1) { //If the last bit is similar to this one, increment counter, otherwise reset
145+
counter++;
146+
} else {counter = 0; lastBit = 1;}
147+
}
148+
ypos += panel.settings.deltaStep*panel.plotHeight*(1+Math.floor(counter/panel.settings.adaptiveNumSteps)); //For adaptive modulation, increase the multiplier every numSteps consecutive steps
143149
} else {
144-
ypos -= panel.settings.deltaStep*panel.plotHeight;
145-
//if (ypos <= panel.plotTop) ypos += 2*panel.settings.deltaStep*panel.plotHeight; //Same for the top bound
150+
if (panel.settings.deltaType == "adaptive") {
151+
if (lastBit == 0) {
152+
counter++;
153+
} else {counter = 0; lastBit = 0;}
154+
}
155+
ypos -= panel.settings.deltaStep*panel.plotHeight*(1+Math.floor(counter/panel.settings.adaptiveNumSteps));
146156
}
147157
ypos = (ypos<panel.plotTop)? ypos=panel.plotTop : (ypos>panel.plotBottom)? ypos= panel.plotBottom: ypos=ypos;
148158
panel.buffer.curveVertex(xpos, ypos);

delta-modulation/slider_delta.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ class slider{
5151

5252
this.slider.style('width', Math.round(sliderWidth).toString() + "px");
5353
this.slider.position(x, y);
54-
this.textLabel.position(x + this.slider.width + 10, y - 15);
54+
this.textLabel.position(x + this.slider.width+5, y-18);
5555
this.textBox.position(x+this.slider.width + labelWidth,y);
5656
this.textBox.style('width', Math.round(textboxWidth).toString() + "px");
57-
this.button.position(this.textBox.x+this.textBox.width+5,y);
57+
this.button.position(this.textBox.x+this.textBox.width,y);
5858
this.button.style('width', Math.round(buttonWidth).toString() + "px");
5959
}
6060
buttonPressed(){
@@ -76,7 +76,7 @@ class slider{
7676
this.settings = settings;
7777
this.name ="Frequency (Hz)";
7878
this.propName = "fundFreq";
79-
this.min = 0;
79+
this.min = 100;
8080
this.max = this.settings.sampleRate / 4 ;
8181
this.initial = 440;
8282
this.step = 1.0;
@@ -133,7 +133,7 @@ class slider{
133133
this.oddEvenSel.position(x+this.slider.width+10,y);
134134
this.slopeSel.style('width', Math.round(dropDownWidth).toString() + "px");
135135
this.slopeSel.position(x+this.slider.width+dropDownWidth+10,y);
136-
this.textLabel.position(x + 2*dropDownWidth + this.slider.width + 20, y - 15);
136+
this.textLabel.position(x + 2*dropDownWidth + this.slider.width + 18, y - 18);
137137
this.textBox.position(x + this.slider.width + 2*dropDownWidth+ labelWidth+10,y);
138138
this.textBox.style('width', Math.round(textboxWidth).toString() + "px");
139139
this.button.position(this.textBox.x + this.textBox.width,y);
@@ -195,7 +195,7 @@ class slider{
195195
class deltaStepSlider extends slider {
196196
setup(p,settings){
197197
this.settings = settings;
198-
this.name ="Delta Step (%):";
198+
this.name ="Delta Step (%)";
199199
this.propName="deltaStep";
200200
this.min = 0.001;
201201
this.max = 0.1;

delta-modulation/styles_delta.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ body {
7575

7676
}
7777
.input {
78-
margin-bottom: 0px;
78+
margin-bottom: 100px;
7979
}
8080
.button:hover{
8181
background-color: #ddd;
@@ -141,7 +141,7 @@ body {
141141
}
142142
#footer {
143143
position: relative;
144-
bottom: 0;
144+
bottom: 10;
145145
width: 100%;
146146
height: 2.5rem; /* Footer height */
147147

delta-modulation/waves_delta.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,11 +242,23 @@ function renderWavesImpl(settings, fft, p) { return (playback = false) => {
242242
let stepSize = (settings.quantType == "midTread") ? 2/(maxInt-1) : 2/(maxInt);
243243

244244
let currentAmp = 0;
245+
let counter = 0; //Consecutive similar bits counter for adaptive modulation
246+
let lastBit = 0;
245247
for (let x = 0; x < downsampled.length; x++) {
246-
if (original[Math.floor(x/downsampled.length*original.length)] > currentAmp) {
247-
currentAmp += settings.deltaStep;
248+
if (original[Math.floor(x/downsampled.length*original.length)] >= currentAmp) {
249+
if (settings.deltaType == "adaptive") {
250+
if (lastBit == 0) { //If the last bit is similar to this one, increment counter, otherwise reset
251+
counter++;
252+
} else {counter = 0; lastBit = 0;}
253+
}
254+
currentAmp += 2*settings.deltaStep*(1+Math.floor(counter/settings.adaptiveNumSteps)); //For adaptive modulation, increase the multiplier every numSteps consecutive steps
248255
} else {
249-
currentAmp -= settings.deltaStep;
256+
if (settings.deltaType == "adaptive") {
257+
if (lastBit == 1) {
258+
counter++;
259+
} else {counter = 0; lastBit = 1;}
260+
}
261+
currentAmp -= 2*settings.deltaStep*(1+Math.floor(counter/settings.adaptiveNumSteps));
250262
}
251263
currentAmp = (currentAmp>1.0)? currentAmp = 1.0 : (currentAmp<-1.0)? currentAmp = -1.0 : currentAmp = currentAmp;
252264
downsampled[x] = currentAmp;

delta-modulation/widget_delta.js

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ var settings =
8484
, timeZoom: 1.0 // X axis zoom for signal panels
8585
, deltaFrequency: 96000
8686
, deltaStep: 0.05
87+
, deltaType: "non-adaptive"
88+
, adaptiveNumSteps: 1 //Number of consecutive steps needed to trigger adaptive delta modulation
8789
, element : element
8890
, margine_size : margin_size+20
8991
, p5: undefined
@@ -142,15 +144,16 @@ p.windowResized = function() {
142144

143145
console.log("slider position", sliderPos);
144146
sliders.forEach( (slider, index) => {
145-
let y = yoffset + p.floor(index / numColumns) * sliderHeight;
147+
let y = yoffset + p.floor(index / numColumns) * sliderHeight+20;
146148
//let x = p.floor(index % numColumns) * panelWidth;
147149
slider.resize(sliderPos[index % numColumns], y, sliderWidth,p);
148150
});
149-
let y = yoffset + p.floor((numSliders)/ numColumns) * sliderHeight;
151+
let y = yoffset + p.floor((numSliders+1)/ numColumns) * sliderHeight+5;
150152
let x = margin_size;
151153
originalButton.position(x + 20, y);
152154
reconstructedButton.position(originalButton.x + originalButton.width * 1.1, originalButton.y);
153155
quantNoiseButton.position(reconstructedButton.x + reconstructedButton.width * 1.1, reconstructedButton.y);
156+
adaptiveSwitchButton.position(quantNoiseButton.x + quantNoiseButton.width * 1.1, quantNoiseButton.y);
154157
intro_height = 0;
155158
};
156159

@@ -162,7 +165,7 @@ function resize(w, h) {
162165
panelWidth = w / numColumns;
163166
sliderWidth = w / numColumns - 200;
164167
panelHeight = h / panelRows;
165-
sliderHeight = 200 / sliderRows;
168+
sliderHeight = panelHeight / sliderRows*2/3;
166169
if (sliderHeight < 30) { // keep sliders from getting squished
167170
sliderHeight = 30;
168171
let sliderPanelHeight = sliderHeight * sliderRows;
@@ -171,8 +174,7 @@ function resize(w, h) {
171174
}
172175

173176
function buttonSetup() {
174-
originalButton = p.createButton("play original");
175-
originalButton.position(p.width/2 + 10, p.height - p.height /numPanels, 'absolute');
177+
originalButton = p.createButton("Play original");
176178
originalButton.mousePressed( () => {
177179
renderWaves(true);
178180
if (!settings.snd) settings.snd = new (window.AudioContext || window.webkitAudioContext)();
@@ -182,9 +184,9 @@ function buttonSetup() {
182184
if(!buttons.includes("original")){
183185
originalButton.hide();
184186
}
187+
console.log("button",originalButton.width,originalButton.x, originalButton.y)
185188

186-
reconstructedButton = p.createButton("play reconstructed");
187-
reconstructedButton.position(originalButton.x + originalButton.width * 1.1, originalButton.y);
189+
reconstructedButton = p.createButton("Play reconstructed");
188190
reconstructedButton.mousePressed( () => {
189191
renderWaves(true);
190192
if (!settings.snd) settings.snd = new (window.AudioContext || window.webkitAudioContext)();
@@ -194,8 +196,8 @@ function buttonSetup() {
194196
if(!buttons.includes("recon")){
195197
reconstructedButton.hide();
196198
}
197-
quantNoiseButton = p.createButton("play quantization noise");
198-
quantNoiseButton.position(reconstructedButton.x + reconstructedButton.width * 1.1, reconstructedButton.y);
199+
200+
quantNoiseButton = p.createButton("Play quantization noise");
199201
quantNoiseButton.mousePressed( () => {
200202
renderWaves(true);
201203
if (!settings.snd) settings.snd = new (window.AudioContext || window.webkitAudioContext)();
@@ -205,6 +207,18 @@ function buttonSetup() {
205207
if(!buttons.includes("quant")){
206208
quantNoiseButton.hide();
207209
}
210+
211+
adaptiveSwitchButton = p.createButton("Switch to adaptive modulation");
212+
adaptiveSwitchButton.mousePressed( () => {
213+
if (settings.deltaType == "adaptive") {settings.deltaType = "non-adaptive";adaptiveSwitchButton.html("Switch to adaptive modulation");}
214+
else {settings.deltaType = "adaptive";adaptiveSwitchButton.html("Switch to non-adaptive modulation");}
215+
settings.render();
216+
settings.p5.draw();
217+
});
218+
adaptiveSwitchButton.parent(element.id);
219+
if(!buttons.includes("adaptive")){
220+
adaptiveSwitchButton.hide();
221+
}
208222

209223
}
210224

widget.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ p.windowResized = function() {
102102
originalButton.position(x + 20, y);
103103
reconstructedButton.position(originalButton.x + originalButton.width * 1.1, originalButton.y);
104104
quantNoiseButton.position(reconstructedButton.x + reconstructedButton.width * 1.1, reconstructedButton.y);
105+
105106
};
106107

107108
function resize(w, h) {

0 commit comments

Comments
 (0)