xxxxxxxxxx
182
let soundFile1, soundFile2, soundFile3, soundFile4;
let textBoxes = [];
let mcOut = [];
let audioPlayers = [];
let currentBPM = 120;
let bpmSlider;
let dotDuration, dashDuration;
let bpmText;
function preload() {
soundFile1 = loadSound('audio0.mp3');
soundFile2 = loadSound('audio1.mp3');
soundFile3 = loadSound('audio2.mp3');
soundFile4 = loadSound('audio3.mp3');
font = loadFont('dig.ttf');
}
function setup() {
createCanvas(400, 300);
background(255);
bpmSlider = createSlider(60, 180, currentBPM);
bpmSlider.position(20, 360);
fft = new p5.FFT();
//text and audio init
for (let i = 0; i < 4; i++) {
let textBox = createInput('');
textBox.position(20, 5 + i * 40);
textBox.size(350);
textBox.input(() => updatePlayMC(i));
textBoxes.push(textBox);
}
audioPlayers[0] = new AudioPlayer(soundFile1);
audioPlayers[1] = new AudioPlayer(soundFile2);
audioPlayers[2] = new AudioPlayer(soundFile3);
audioPlayers[3] = new AudioPlayer(soundFile4);
}
function draw() {
background(255);
//fft analysis
let spectrum = fft.analyze();
//freq spec visual
noStroke();
fill(255, 0, 0); //red
for (let i = 0; i < spectrum.length; i++) {
let x = map(i, 0, spectrum.length, 0, width);
let h = -height + map(spectrum[i], 0, 255, height/1.2, 0);
rect(x, height, width / spectrum.length, h);
}
fill(0);
let newBPM = bpmSlider.value(); //bpm from slider
if (newBPM !== currentBPM) {
currentBPM = newBPM;
updateSeqTime(currentBPM); //update bpm changes
restartAllSeq();
}
for (let i = 0; i < textBoxes.length; i++) {
let yPosition = 30 + i * 40;
text(mcOut[i] || '', 20, yPosition + 10);
}
fill(0); //black
textFont(font);
textSize(140);
text(newBPM + " bpm", 20, 250);
textSize(20);
}
function restartAllSeq() {
for (let i = 0; i < audioPlayers.length; i++) {
if (mcOut[i]) {
audioPlayers[i].playSequence(mcOut[i]);
}
}
}
function updateSeqTime(bpm) {
const beatDuration = (60 / bpm) * 1000; //beat duration in ms
dotDuration = beatDuration / 3; //dot duration
dashDuration = dotDuration * 3; //dash duration
}
function updatePlayMC(index) {
mcOut[index] = textToMorse(textBoxes[index].value());
audioPlayers[index].playSequence(mcOut[index]);
}
function textToMorse(text) {
return text.toUpperCase().split('').map(char => mcDict[char] || char).join(' ').trim();
}
class AudioPlayer {
constructor(sound) {
this.sound = sound;
this.sequence = [];
this.isPlaying = false;
this.currentIndex = 0;
this.timeout = null; // Store the timeout ID
}
playSequence(morseCode) {
this.sequence = morseCode.split('').map(char => {
if (char === '.') return dotDuration;
if (char === '-') return dashDuration;
if (char === ' ') return dashDuration; //Space = Silence
return 0; //empty = no sound
});
this.currentIndex = 0;
if (!this.isPlaying) {
this.startPlayback();
}
}
startPlayback() {
this.isPlaying = true;
this.playNext();
}
playNext() {
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = null;
}
if (this.currentIndex >= this.sequence.length) {
this.currentIndex = 0; // Reset to the start of the sequence
}
if (this.sequence[this.currentIndex] > 0) {
if (this.sound.isPlaying()) {
this.sound.stop();
}
this.sound.play();
}
//sched next sound
this.timeout = setTimeout(() => {
this.currentIndex++;
this.playNext();
}, this.sequence[this.currentIndex]);
}
stopPlayback() {
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = null;
}
if (this.sound.isPlaying()) {
this.sound.stop();
}
this.isPlaying = false;
this.currentIndex = 0;
}
}
// Morse code dict
const mcDict = {
'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..',
'E': '.', 'F': '..-.', 'G': '--.', 'H': '....',
'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..',
'M': '--', 'N': '-.', 'O': '---', 'P': '.--.',
'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-',
'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-',
'Y': '-.--', 'Z': '--..',
'1': '.----', '2': '..---', '3': '...--', '4': '....-',
'5': '.....', '6': '-....', '7': '--...', '8': '---..',
'9': '----.', '0': '-----',
'.': '.-.-.-',',': '--..--','?': '..--..','!': '-.-.--',
'@': '.--.-.', '&': '.-...', ':': '---...',';': '-.-.-.',
'=': '-...-', '+': '.-.-.', '-': '-....-','_': '..--.-',
'"': '.-..-.','\'': '.----.','(': '-.--.', ')': '-.--.-',
'/': '-..-.', '$': '...-..-','&': '.-...', '%': '-----',
'#': '......','*': '...-.-'
};