User:Thijshijsijsjss/Pen Plotting Panache/Volume Plotting
A modification of the code written at Zinecamp 2023 that captures audio and makes HPGL code for a volume plot. This version is more user friendly, with buttons for starting, restarting and copying, and with input length and title. Like this:
Volume plotting is part of the SI23 webquilt! Find it here, or get your own with the code below:
<!DOCTYPE html>
<html>
<head>
<title>Noiseplotting!</title>
</head>
<body>
<h1></h1>
<p>This is a small script to capture a snippet of sound and convert it to a volume HPGL code for your penplotting pleasure. </p>
<p>Usage:
<ol>
<li>Press the button saying 'Start recording'.</li>
<li>Wait until recording is done, indicated by HPGL code appearing below.</li>
<li>Copy the HPGL output if you want to use it.</li>
<li>Press the button saying 'Rerecord' to repeat the process!!</li>
</ol>
</p>
<p>(Don't forget to allow the use of the microphone!)</p>
<p>Optionally, change the length of the recording: <input type="text" value="1000" id="nr_points_input"> points</p>
<p>Optionally, change the title of the recording: <input type="text" value="ZINECAMP RECORDING" id="title_input"></p>
<button onclick="start_recording()">Start recording</button>
<button onclick="copy_HPGL()">Copy HPGL output</button>
<button onclick="clear_HPGL()">Rerecord</button>
<p id="output-p">(HPGL code will appear here)</p>
</body>
<script>
var noise_values = [];
var nr_points = 1000;
console.log(nr_points);
var start = 0.0;
var end = 0.0;
function start_recording() {
nr_points = document.getElementById("nr_points_input").value;
if (start == 0.0) start = Date.now();
// capturing template taken from https://stackoverflow.com/questions/52097840/how-to-overwrite-text-in-p-tag-using-javascript
navigator.mediaDevices.getUserMedia({
audio: true,
video: true
})
.then(function(stream) {
const audioContext = new AudioContext();
const analyser = audioContext.createAnalyser();
const microphone = audioContext.createMediaStreamSource(stream);
const scriptProcessor = audioContext.createScriptProcessor(2048, 1, 1);
analyser.smoothingTimeConstant = 0.8;
analyser.fftSize = 1024;
microphone.connect(analyser);
analyser.connect(scriptProcessor);
scriptProcessor.connect(audioContext.destination);
scriptProcessor.onaudioprocess = function() {
const array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(array);
const arraySum = array.reduce((a, value) => a + value, 0);
const average = arraySum / array.length;
noise_values.push(Math.round(average));
if(noise_values.length >= nr_points) {create_output(); return;}
console.log(Math.round(average));
// colorPids(average);
};
})
.catch(function(err) {
console.error(err);
});
}
function create_output() {
console.log(noise_values[0]);
var output = "IN;SC0,100,0,100;PU;DT$;SI0.2,1;";
if (end == 0.0) end = Date.now();
output += "PA2,90;LB" + document.getElementById("title_input").value + ":$;";
output += "PA2,80;LBstart recording at: " + start + "$;";
output += "PA2,70;LBend recording at: " + end + "$;";
output += "PA2,60;LB(seconds after Unix Epoch)$;";
for (var x = 0; x < nr_points; x += 1) {
output += "PA"+ (x/10) + "," + noise_values[x] + ";PD;\n";
}
output += "PU;";
// console.log(output);
document.getElementById("output-p").innerText = output;
}
// inspired by https://www.w3schools.com/howto/howto_js_copy_clipboard.asp
function copy_HPGL () {
// Get the text field
var copyText = document.getElementById("output-p");
// Copy the text inside the text field
navigator.clipboard.writeText(copyText.innerText);
// Alert the copied text
alert("Copied the text: " + copyText.innerText);
}
function clear_HPGL() {
noise_values = [];
start = 0.0;
end = 0.0;
nr_points = document.getElementById("nr_points_input").value;
document.getElementById("output-p").innerText = "";
}
</script>
</html>