Skip to content

Commit

Permalink
cube audio
Browse files Browse the repository at this point in the history
  • Loading branch information
anthonypetersen committed Nov 9, 2023
1 parent 58301fa commit 36ca031
Show file tree
Hide file tree
Showing 4 changed files with 337 additions and 5 deletions.
128 changes: 128 additions & 0 deletions src/pages/cubes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { renderNotation } from './../shared/common.js';
import constants from "../shared/constants.js";
import { snare } from '../shared/audio.js';
import { state } from '../shared/common.js';

const rollDice = (dice) => {
const roll = Math.floor(Math.random() * dice.length);
return dice[roll];
}

const pushBeats = (groove, dice) => {
for(let i = 0; i < dice.length; i++) {
groove.push(dice[i]);
}
}

export const cube_driver = () => {

snare();
console.log("Creating new groove...");

let groove = {
kickSnare: [],
hiHat: [],
fill: []
};

let kickSnare = rollDice(constants.KICK_SNARE_PATTERNS);

for(let i = 0; i < 2; i++) {
pushBeats(groove.kickSnare, kickSnare.pattern);
}

for (let i = 0; i < groove.kickSnare.length; i += 2) {
groove.kickSnare.splice(i + 1, 0, 0);
}

let hiHat = rollDice(constants.HIHAT_PATTERNS_SIMPLE);

for(let i = 0; i < 4; i++) {
pushBeats(groove.hiHat, hiHat.pattern);
}

let fill1 = rollDice(constants.FILL_PATTERNS);
pushBeats(groove.fill, fill1.pattern);

let fill2 = rollDice(constants.FILL_PATTERNS);
pushBeats(groove.fill, fill2.pattern);

let fill3 = rollDice(constants.FILL_PATTERNS);
pushBeats(groove.fill, fill3.pattern);

let fill4 = rollDice(constants.FILL_PATTERNS);
pushBeats(groove.fill, fill4.pattern);

console.log(groove);

renderNotation(groove, 'grooveResults');
}

export const cube_player = () => {

let groove = [
...state.getState().cubeGroove[0].tickables,
...state.getState().cubeFill[0].tickables
];


play(groove);
}

const play = (groove) => {

let audioCtx = state.getState().audioContext;

const bpm = 90;
const secondsPerBeat = 60 / bpm;
const ticksPerQuarterNote = Vex.Flow.RESOLUTION / 4; // Default is 4096 ticks per quarter note
console.log(Vex.Flow.RESOLUTION);
const secondsPerTick = secondsPerBeat / ticksPerQuarterNote;

function playBufferAtTime(buffer, time) {
const source = audioCtx.createBufferSource();
source.buffer = buffer;
source.connect(audioCtx.destination);
source.start(time);
}
function getBufferForNoteName(noteName) {
// Add your logic to return the correct buffer based on the note name
// For example:
switch (noteName) {
case constants.KICK:
return state.getState().kickBuffer;
case constants.SNARE:
return state.getState().snareBuffer;
case constants.HIHAT:
return state.getState().hiHatBuffer;
case constants.RACK:
return state.getState().midTomBuffer;
default:
return null; // Return null or undefined if there's no buffer for the note
}
}

let currentTime = audioCtx.currentTime;
console.log(currentTime);


groove.forEach((note) => {
// Determine the note's duration in seconds
const noteDurationSeconds = note.ticks.value() * secondsPerTick;

// If it's a chord, note.keys will have multiple notes
note.keys.forEach((key) => {
// Retrieve the buffer for this particular note
const bufferToPlay = getBufferForNoteName(key);

// If we have a buffer to play, schedule it
if (bufferToPlay) {
playBufferAtTime(bufferToPlay, currentTime);
}
});

// Increment the current time by the note's duration
currentTime += noteDurationSeconds;
});

}
177 changes: 177 additions & 0 deletions src/pages/letters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import constants from "../shared/constants.js";
import { state, drawCircle, drawVerticalLines } from '../shared/common.js';
import { kick, snare, ghost } from '../shared/audio.js';

let kickCircles;
let snareCircles;
let ghostCircles;

let groove;

export const letter_driver = () => {
let groove = generate_combo();
state.updateState({groove: groove});
visualize_groove(groove);
}

export const groove_driver = () => {

const beats_element = document.getElementById('bpm');
const canvas = document.getElementById("alphabetCanvas");
const ctx = canvas.getContext("2d");


const bpm = beats_element && beats_element.value;
const beatDuration = 60000 / bpm;
const quarterBeatDuration = beatDuration / 4;

const delay = 500;

setTimeout(() => {

state.getState().groove.forEach((value, index) => {
setTimeout(() => {

const { ghostCircles, kickCircles, snareCircles } = state.getState();
// Play the bass drum on every 4th beat
if (index % 4 === 0) {
kickCircles[index / 4].setColor("red");
kickCircles[index / 4].draw(ctx);
kick();
}

if (value === 1) {
snare();
snareCircles[index].setColor("red");
snareCircles[index].draw(ctx);
} else if (value === 0) {
ghostCircles[index].setColor("red");
ghostCircles[index].draw(ctx);
ghost();
}
}, index * quarterBeatDuration);
});
}, delay);
}

const visualize_groove = (groove) => {

snareCircles = [];
ghostCircles = [];
kickCircles = [];

const canvas = document.getElementById("alphabetCanvas");
const ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear previous drawings

const circleRadius = 15; // Adjust as needed
const spacing = canvas.width / (groove.length + 1);
const rowHeight = canvas.height / 4; // Divided by 4 to center 3 rows within the canvas height

groove.forEach((value, index) => {
let yPos;

// Top row for groove = 1
if (value === 1) {
yPos = rowHeight;
let circle = drawCircle(ctx, index * spacing + spacing, yPos, circleRadius);
snareCircles.push(circle);
}
else {
snareCircles.push(null);
}

// Middle row for groove = 0
if (value === 0) {
yPos = 2 * rowHeight;
let circle = drawCircle(ctx, index * spacing + spacing, yPos, circleRadius);
ghostCircles.push(circle);
}
else {
ghostCircles.push(null);
}

if(index % 4 === 0) {
yPos = 3 * rowHeight;
let circle = drawCircle(ctx, index * spacing + spacing, yPos, circleRadius);
kickCircles.push(circle);
}
});

drawVerticalLines(ctx, canvas);

state.updateState({
ghostCircles: ghostCircles,
kickCircles: kickCircles,
snareCircles: snareCircles
});
}

const generate_combo = () => {

let flag = true;
let results;
let combo;

while(flag) {
flag = false;

results = "";
combo = new Array();
groove = new Array();

for(let i = 0; i < 4; i++) {
combo.push(constants.LETTERS[Math.floor(Math.random() * constants.LETTERS.length)]);
results += combo[i].letter;
}

for(let index of combo) {
console.log(index);

for(let num of index.beats) {
groove.push(num);
}
}

if(groove[0] == 1) {
console.log(groove);
}
else {
flag = true;
}

let streak = 0;
let longest = 0;

for(let i = 0; i < groove.length; i++) {
if(groove[i] === 1) streak++;
else streak = 0;

if(streak > longest) longest = streak;
}

const combo_element = document.getElementById('maxCombo');
const maximumCombo = combo_element && !combo_element.disabled && combo_element.value;


if(maximumCombo && longest > maximumCombo) {
flag = true;
}

const hit_element = document.getElementById('minHits');
const minimumHits = hit_element && !hit_element.disabled && hit_element.value;

const actualHits = groove.reduce((accumulator, currentValue) => accumulator + currentValue, 0);

if(minimumHits && actualHits < minimumHits) {
flag = true;
}


}

console.log("FINAL GROOVE");
console.log(groove);

return groove;
}
15 changes: 13 additions & 2 deletions src/shared/audio.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { state } from './common.js';
let kickBuffer, snareBuffer, ghostBuffer;
let kickBuffer, snareBuffer, ghostBuffer, hiHatBuffer, midTomBuffer;

export const audio_driver = () => {
Promise.all([
loadAudioFile('audio/kick.wav').then(buffer => { kickBuffer = buffer; }),
loadAudioFile('audio/snare.wav').then(buffer => { snareBuffer = buffer; }),
loadAudioFile('audio/ghost.wav').then(buffer => { ghostBuffer = buffer; })
loadAudioFile('audio/ghost.wav').then(buffer => { ghostBuffer = buffer; }),
loadAudioFile('audio/hihat.wav').then(buffer => { hiHatBuffer = buffer; }),
loadAudioFile('audio/midtom.wav').then(buffer => { midTomBuffer = buffer; })
]).then(() => {
state.updateState({ kickBuffer, snareBuffer, ghostBuffer, hiHatBuffer, midTomBuffer });
console.log('All audio files preloaded');
});
}
Expand Down Expand Up @@ -39,4 +42,12 @@ export const snare = () => {

export const ghost = () => {
playBuffer(ghostBuffer);
}

export const hiHat = () => {
playBuffer(hiHatBuffer);
}

export const midTom = () => {
playBuffer(midTomBuffer);
}
Loading

0 comments on commit 36ca031

Please sign in to comment.