1ardour { 2 ["type"] = "dsp", 3 name = "Simple Synth", 4 category = "Instrument", 5 license = "MIT", 6 author = "Ardour Team", 7 description = [[An Example synth for prototyping: Sine-wave with a basic attack/sustain/release envelope, variable number of output channels.]] 8} 9 10function dsp_ioconfig () 11 return 12 { 13 -- { midi_in = 1, audio_in = 0, audio_out = -1}, -- any number of channels 14 -- { midi_in = 1, audio_in = 0, audio_out = 1}, -- values > 0, precisely N channels 15 { midi_in = 1, audio_in = 0, audio_out = 2}, -- values > 0, precisely N channels 16 { midi_in = 1, audio_in = 0, audio_out = 4}, -- values > 0, precisely N channels 17 { midi_in = 1, audio_in = 0, audio_out = 8}, -- values > 0, precisely N channels 18 -- { midi_in = 1, audio_in = 0, audio_out = -6}, -- values < -2, up to -N channels, here 1,..,6 19 } 20end 21 22local note_table = {} 23local active_notes = {} 24local phases = {} 25local env = .01; 26 27function dsp_init (rate) 28 for n = 1,128 do 29 note_table [n] = (440 / 32) * 2^((n - 10.0) / 12.0) / rate 30 end 31 env = 100 / rate 32end 33 34function dsp_run (ins, outs, n_samples) 35 -- initialize output buffer 36 local a = {} 37 for s = 1, n_samples do a[s] = 0 end 38 39 40 -- very basic synth, simple sine, basic envelope 41 local function synth (s_start, s_end) 42 for n,v in pairs (active_notes) do 43 local vel = v["vel"] or 0 44 local tgt = v["tvel"]; 45 for s = s_start,s_end do 46 local phase = phases[n] or 0 47 vel = vel + env * (tgt - vel) 48 a[s] = a[s] + math.sin(6.283185307 * phase) * vel / 167 49 phase = phase + note_table[n] 50 if (phase > 1.0) then 51 phases[n] = phase - 2.0 52 else 53 phases[n] = phase 54 end 55 end 56 if vel < 1 and tgt == 0 then 57 active_notes[n] = nil 58 else 59 active_notes[n]["vel"] = vel; 60 end 61 end 62 end 63 64 local tme = 1 65 -- parse midi messages 66 assert (type(midiin) == "table") -- global table of midi events (for now) 67 for _,b in pairs (midiin) do 68 local t = b["time"] -- t = [ 1 .. n_samples ] 69 70 -- synth sound until event 71 synth(tme, t) 72 tme = t + 1 73 74 local d = b["data"] -- get midi-event 75 -- we ignore the midi channel 76 if (#d == 3 and (d[1] & 240) == 144) then -- note on 77 local n = 1 + d[2]; 78 active_notes[n] = active_notes[n] or {} 79 active_notes[n]["tvel"] = d[3] 80 end 81 if (#d == 3 and (d[1] & 240) == 128) then -- note off 82 local n = 1 + d[2]; 83 active_notes[n] = active_notes[n] or {} 84 active_notes[n]["tvel"] = 0 85 end 86 if (#d == 3 and (d[1] & 240) == 176) then -- CC 87 if (d[2] == 120 or d[2] == 123) then -- panic 88 active_notes = {} 89 end 90 end 91 end 92 93 -- synth rest of cycle 94 synth(tme, n_samples) 95 96 -- copy 97 for c = 1,#outs do 98 outs[c]:set_table(a, n_samples) 99 end 100end 101