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