ScriptaGames / zorbio

A 3D multiplayer WebGL game
MIT License
8 stars 1 forks source link

Improve sfx #244

Closed mwcz closed 8 years ago

mwcz commented 8 years ago

Current recordings have poor quality and the scale of the chimes won't sound good with most songs.

This lib should help a lot with synthesizing chimes of a given scale. We should save the scale of each song we use and generate sfx that match the song!

https://github.com/danigb/tonal

mwcz commented 8 years ago

I got some awesome tips from Dave on sfx synthesis. Based on his tips I found a lib called Wad which is awesome. I came up with a chime sound for food capture, and a woosh sound for speed boost, in just a few minutes (mostly because of Dave's tips).

const chime = new Wad({
    source: 'sine',
    env: {
        attack: 0,
        decay: 0.01,
        sustain: .9,
        hold: 0.3,
        release: 0.3
    }
});

chime.play({ pitch: 440 });
// or
chime.play({ pitch: 'A4' });

const woosh = new Wad({
    source: 'noise',
    env: {
        attack: 0.5,
        decay: 0.5,
        sustain: 1,
        hold: 5,
        release: .5
    },
    filter: {
        type: 'lowpass',
        frequency: 300,
        q: 1.0
    },
});

woosh.play();
mwcz commented 8 years ago

Here are his tips, for reference:

Hey Mike!

Are you looking for something that sounds like the kalimba sounds in your links? If so, I think the basic formula is something like:

  • Take a sine wave oscillator
  • Apply an ADSR (attack-decay-sustain-release) envelope:
    • 0 attack (i.e. immediate attack, doesn't fade in)
    • fast decay (i.e. a small, non-zero number) to emulate the "strike" of the chime
    • sustain level around 90% (in other words, a little quieter than when it was "struck")
    • release time is however long you want the chime to last -- maybe 500 ms or something

I haven't done ADSR with the Web Audio API yet, but this looks like an easy way to do it: https://github.com/mmckegg/adsr


If you're looking for a different sort of chime, you could try generating a major third.

To do this:

  • Have 2 oscillators, one to play the root note and one to play the third. You could play around with using different types of oscillators -- sine vs. square vs. sawtooth vs triangle.
  • Set their frequencies to the right ratio. This is just a simple mathematical ratio, based on the overtone series -- see below for more details.
  • Play them at the same time.
  • For best results, also apply an ADSR envelope to each oscillator, as described above.

The overtone series:

1/1 (e.g. 100 Hz) unison 2/1 (e.g. 200 Hz, where 100 Hz is the fundamental) octave 3/1 (e.g. 300 Hz) perfect fifth 4/1 (e.g. 400 Hz) octave (this is 2 octaves higher than the fundamental, 1 octave higher than the 2nd partial (200 Hz)) 5/1 (e.g. 500 Hz) major third 6/1 (e.g. 600 Hz) perfect fifth

It goes up infinitely from there, with the intervals getting smaller and smaller.

A good interval to use for a chime is a major third, so for example, combining 2 oscillators where the frequencies are 400 and 500 Hz would give you a major third. In this case, the fundamental would actually be 100 Hz, and you're just using the 4th and 5th partials of the overtone series starting from 100 Hz as the fundamental. So, the way to calculate the pitch of the upper note, if you know the pitch you want for the lower note, is to divide by 4 and then multiply by 5. You might also try adding a third oscillator that's playing the 6th partial (e.g. 400, 500 and 600 Hz), for a full major chord (root + major third + perfect fifth)

Hope that helps - I'm curious to see what you come up with!

mwcz commented 8 years ago

I just pushed a change that removes the recorded sound effects and uses dynamically synthesized sounds instead. Just for food capture so far, but I'll add more.

mwcz commented 8 years ago

Existing sfx improved. Will make new issues for adding sfx for player capture, etc