@hackage pl-synth0.1.0.0

Bindings and wrappers for PL_SYNTH - no-deps sound effects synthesizer and tracker.

  • Installation

  • Dependencies (1)

  • Dependents (0)

pl-synth

Bindings and wrappers for PL_SYNTH - no-deps sound effects synthesizer and tracker.

Original C (and JS) implementation: https://github.com/phoboslab/pl_synth

Generating sounds

A sound is defined by wrapping a synthesizer definition with a duration and a note:

sound :: PlSynthSoundT
sound = PlSynthSoundT
  { synth = emptyPlSynthT
      { osc0_oct = 7
      , osc0_vol = 192
      , osc1_oct = 7
      , osc1_vol = 192
      , osc1_waveform = SAW
      , env_attack = 200
      , env_sustain = 2000
      , env_release = 20000
      , env_master = 192
      }
  , row_len = 5168
  , note = 135
  }

Or, as its author uses it:

coin :: PlSynthSoundT
coin = PlSynthSoundT
  { synth = PlSynthT 10 0 0 1 189 1 12 0 9 1 172 2 0 2750 689 95 129 0 1086 219 1 117 0 0 0 0 0 0 0
  , row_len = 5168
  , note = 135
  }

Generating music

A song is a bunch of tracks running in parrallel. Each track is a sequence of patterns and each pattern is a series of notes (32 of them).

Here's the "blips" track from the example song:

t1 =
  ( [1,2,1,2,1,2,0,0,1,2,1,2] -- pattern sequences of the track
  , [ [ 138,145,138,150 -- pattern 1
      , 138,145,138,150
      , 138,145,138,150
      , 138,145,138,150
      , 136,145,138,148
      , 136,145,138,148
      , 136,145,138,148
      , 136,145,138,148
      ]
    , [ 135,145,138,147 -- pattern 2
      , 135,145,138,147
      , 135,145,138,147
      , 135,145,138,147
      , 135,143,138,146
      , 135,143,138,146
      , 135,143,138,146
      , 135,143,138,146
      ]
    ]
  , emptyPlSynthT -- the instument that plays the notes
      { osc0_oct = 7, osc0_vol = 121, osc0_waveform = 1
      , osc1_oct = 7, osc1_vol = 91, osc1_waveform = 3
      , env_attack = 100, env_sustain = 1212, env_release = 5513, env_master = 100
      , fx_freq = 6, fx_resonance = 19, fx_delay_time = 3, fx_delay_amt = 121, fx_pan_freq = 6, fx_pan_amt = 21
      , lfo_fx_freq = 1, lfo_freq = 1, lfo_amt = 29
      }
  )

Using the generated data

The main intent of PL_SYNTH is to replace pre-rendered files with some code that can generate buffers at run time.

genBuffers =
  withPlSynth do -- may wrap `main`
    withSound coin \ptr lenBytes -> -- generate samples
      alBufferData coinBuf AL_FORMAT_STEREO_16 ptr len 44100 -- copy rendered buffer to a sound-playing API