Skip to content

Commit

Permalink
feat(synths): add daft synth instead of duplicated 'other drums'
Browse files Browse the repository at this point in the history
  • Loading branch information
domi7777 committed Nov 10, 2024
1 parent 4e77ed9 commit 85867fb
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 5 deletions.
88 changes: 88 additions & 0 deletions src/scenes/DaftSynthScene.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import {allFrequencies} from '../samples/synth-frequencies.ts';
import {createAudioContext} from '../samples/sample-utils.ts';
import {logger} from '../utils/logger.ts';
import {SimpleSynthScene} from './SimpleSynthScene.ts';
import Phaser from 'phaser';

export class DaftSynthScene extends SimpleSynthScene {

create() {
super.create();
}

getPadColor(numberOfPads: number, index: number): Phaser.Display.Color {
const padColor = super.getPadColor(numberOfPads, index);
return padColor.saturate(50)
}

playSound(index: number): void {
const note = allFrequencies[index].freq;
logger.log('Playing note', note);
return playDaftPunkSynth(note, this.settings.volume);
}
}

function playDaftPunkSynth(frequency: number, volume: number) {
// Create Audio Context
const audioContext =createAudioContext();

// Main oscillator for the core sound
const oscillator = audioContext.createOscillator();
oscillator.type = 'sawtooth';
oscillator.frequency.setValueAtTime(frequency, audioContext.currentTime);

// Gain node for volume control
const gainNode = audioContext.createGain();
gainNode.gain.value = volume / 100;

// Low-pass filter to shape the sound (for a more "vintage" vibe)
const filter = audioContext.createBiquadFilter();
filter.type = 'lowpass';
filter.frequency.setValueAtTime(800, audioContext.currentTime); // Cutoff frequency
filter.Q.value = 1; // Resonance

// Add some distortion for grit
const distortion = audioContext.createWaveShaper();
distortion.curve = makeDistortionCurve(400); // Amount of distortion
distortion.oversample = '4x';

// LFO for filter modulation (gives it a funky, wah-like sound)
const lfo = audioContext.createOscillator();
lfo.type = 'sine';
lfo.frequency.setValueAtTime(3, audioContext.currentTime); // Frequency of modulation (in Hz)

// LFO gain control to adjust the modulation intensity
const lfoGain = audioContext.createGain();
lfoGain.gain.value = 200; // Adjust this for how much the filter moves

// Connect the LFO to modulate the filter cutoff
lfo.connect(lfoGain);
lfoGain.connect(filter.frequency);

// Connect nodes in the audio graph
oscillator.connect(gainNode);
gainNode.connect(filter);
filter.connect(distortion);
distortion.connect(audioContext.destination);

// Start oscillators
oscillator.start();
lfo.start();

// Stop the sound after 1 second for this demo
oscillator.stop(audioContext.currentTime + 1);
lfo.stop(audioContext.currentTime + 1);

// Helper function to create distortion curve
function makeDistortionCurve(amount: number) {
const k = typeof amount === 'number' ? amount : 50;
const n_samples = 44100;
const curve = new Float32Array(n_samples);
const deg = Math.PI / 180;
for (let i = 0; i < n_samples; ++i) {
const x = (i * 2) / n_samples - 1;
curve[i] = ((3 + k) * x * 20 * deg) / (Math.PI + k * Math.abs(x));
}
return curve;
}
}
11 changes: 6 additions & 5 deletions src/scenes/EmptyScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {DrumsScene} from './DrumsScene.ts';
import {GibberishScene} from './GiberishScene.ts';
import {SimpleSynthScene} from './SimpleSynthScene.ts';
import {EVENTS} from '../events.ts';
import {DaftSynthScene} from './DaftSynthScene.ts';

export class EmptyScene extends Phaser.Scene {
static key = 'EmptyScene';
Expand Down Expand Up @@ -34,15 +35,15 @@ export class EmptyScene extends Phaser.Scene {
const drumsButton = this.instrumentButtons[1][2];
drumsButton.setData('text', this.addText(drumsButton, 'Drums'));

const otherDrumsButton = this.instrumentButtons[3][2];
otherDrumsButton.setData('text', this.addText(otherDrumsButton, 'Other Drums'));
const daftSynthButton = this.instrumentButtons[3][2];
daftSynthButton.setData('text', this.addText(daftSynthButton, 'Daft synth'));

const gibberishButton = this.instrumentButtons[2][3];
gibberishButton.setData('text', this.addText(gibberishButton, 'Gibberish'));

const activeButtons = [
drumsButton,
otherDrumsButton,
daftSynthButton,
gibberishButton,
simpleSynthButton
];
Expand All @@ -58,8 +59,8 @@ export class EmptyScene extends Phaser.Scene {
drumsButton.on(Phaser.Input.Events.POINTER_UP, () => {
this.scene.add(trackSceneKey, DrumsScene, true, {type: 'drums'});
});
otherDrumsButton.on(Phaser.Input.Events.POINTER_UP, () => {
this.scene.add(trackSceneKey, DrumsScene, true, {type: 'other'});
daftSynthButton.on(Phaser.Input.Events.POINTER_UP, () => {
this.scene.add(trackSceneKey, DaftSynthScene, true);
});
gibberishButton.on(Phaser.Input.Events.POINTER_UP, () => {
this.scene.add(trackSceneKey, GibberishScene, true, {numberOfPads: 8});
Expand Down

0 comments on commit 85867fb

Please sign in to comment.