Video-Frame (not sample)
[ardour.git] / scripts / noisegen.lua
1 ardour {
2         ["type"]    = "dsp",
3         name        = "NoiseGen",
4         category    = "Instrument",
5         license     = "MIT",
6         author      = "Ardour Team",
7         description = [[Noise Generator (v-1.02)]]
8 }
9
10 function dsp_params ()
11         return
12         {
13                 { ["type"] = "input", name = "White/Pink", min = 0, max = 1, default = 0, toggled = true },
14                 { ["type"] = "input", name = "Gain", min = -60, max = 0, default = -18, unit="dB" },
15         }
16 end
17
18 function dsp_ioconfig ()
19         return { [1] = { audio_in = -1, audio_out = -1}, }
20 end
21
22 local sr = 0
23
24 function dsp_init (rate)
25         sr = rate
26 end
27
28 local ao = 0
29 local draw = 0
30
31 function dsp_run (ins, outs, n_samples)
32
33         local a = {} -- init array
34         local ctrl = CtrlPorts:array ()
35         local noise = ctrl[1] or 0
36         local amplitude =  ARDOUR.DSP.dB_to_coefficient (ctrl[2]) or ARDOUR.DSP.dB_to_coefficient (-18)
37
38         local b0 = 0.0
39         local b1 = 0.0
40         local b2 = 0.0
41         local b3 = 0.0
42         local b4 = 0.0
43         local b5 = 0.0
44         local b6 = 0.0
45
46         --Pink noise generation courtesy of Paul Kellet's refined method
47         --http://www.musicdsp.org/files/pink.txt
48         --If 'white' consists of uniform random numbers,
49         --the pink noise will have an almost gaussian distribution.
50         for s = 1, n_samples do
51                 if noise == 0 then
52                         a[s] = amplitude * 2 * (math.random() - 0.5)
53                 end
54                 if noise == 1 then
55                         white = (amplitude * 0.25) * 2 * (math.random() - 0.5)
56                         b0 = 0.99886 * b0 + white * 0.0555179;
57                         b1 = 0.99332 * b1 + white * 0.0750759;
58                         b2 = 0.96900 * b2 + white * 0.1538520;
59                         b3 = 0.86650 * b3 + white * 0.3104856;
60                         b4 = 0.55000 * b4 + white * 0.5329522;
61                         b5 = -0.7616 * b5 - white * 0.0168980;
62                         b6 = white * 0.115926;
63                         a[s] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362;
64                 end
65         end
66
67         if (draw > (sr/15)) then
68                 self:queue_draw()
69                 draw = 0
70         end
71
72         -- passes array a {} into buffer
73         for c = 1,#outs do
74                 outs[c]:set_table(a, n_samples)
75         end
76         draw = draw + n_samples
77 end
78
79 function render_inline (ctx, w, max_h) --inline display
80         local ctrl = CtrlPorts:array()
81         h = 30
82         p = 0
83         inc = 0
84         ycy = 0.5
85         pink = false
86         local amplitude = ARDOUR.DSP.dB_to_coefficient(ctrl[2])
87         if ctrl[1] == 1 then pink = true end
88         if pink then inc = 0.7/w end
89
90         --draw rectangle
91         ctx:rectangle(0, 0, w, h)
92         ctx:set_source_rgba(0, 0, 0, 1.0)
93         ctx:fill()
94         ctx:set_line_width(1.5)
95         ctx:set_source_rgba(0.8, 0.8, 0.8, 1.0)
96
97         l_x = 0
98         l_y = 0
99         for x = 0,w do
100                 if pink then ycy = 0.3 else ycy = 0.5 end --slant slightly like an actual pink noise spectrum
101                 y = math.log(20^amplitude) * (math.random() - 0.5) - p
102                 yc = ycy * h + ((-0.5 * h) * y)
103                 ctx:move_to (x, yc + 3)
104                 ctx:line_to (l_x, l_y + 3)
105                 l_x = x
106                 l_y = yc
107                 ctx:stroke()
108                 p = p + inc
109         end
110         return {w, h + 6}
111 end