Rev 2266 | Rev 2302 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
964 | jag | 1 | /* |
2 | * play.cc |
||
2097 | jag | 3 | * DIN Is Noise is copyright (c) 2006-2024 Jagannathan Sampath |
1713 | jag | 4 | * DIN Is Noise is released under GNU Public License 2.0 |
1479 | jag | 5 | * For more information, please visit https://dinisnoise.org/ |
964 | jag | 6 | */ |
7 | |||
8 | #include "audio.h" |
||
9 | #include "play.h" |
||
10 | #include "multi_curve.h" |
||
11 | #include <string.h> |
||
12 | |||
13 | void play::init () { |
||
14 | sol = 0; |
||
15 | x = 0.0f; |
||
16 | dx = 0.0f; |
||
17 | vol = 0.0f; |
||
18 | pdx = pvol = 0; |
||
19 | alloc (); |
||
20 | pdx [0] = 0.0f; pdx [n_1] = 1.0f; |
||
21 | pvol [0] = 0.0f; pvol [n_1] = 1.0f; |
||
22 | } |
||
23 | |||
24 | void play::alloc () { |
||
25 | n = aout.samples_per_channel; |
||
26 | n_1 = n - 1; |
||
27 | da = 1.0f / n_1; |
||
28 | if (pdx) delete [] pdx; |
||
29 | if (pvol) delete [] pvol; |
||
30 | pdx = new float [n]; |
||
31 | pvol = new float [n]; |
||
32 | int sz = n * sizeof (float); |
||
33 | memset (pdx, 0, sz); |
||
34 | memset (pvol, 0, sz); |
||
35 | } |
||
36 | |||
37 | void play::realloc () { |
||
38 | alloc (); |
||
39 | fill_pitch (dx); |
||
40 | fill_volume (vol); |
||
41 | } |
||
42 | |||
43 | play::play (solver *w) { |
||
44 | init (); |
||
45 | set_wave (w); |
||
46 | } |
||
47 | |||
48 | play::play () { |
||
49 | init (); |
||
50 | } |
||
51 | |||
52 | play::play (const play& p) { |
||
53 | sol = p.sol; |
||
54 | x = p.x; |
||
55 | dx = p.dx; |
||
56 | vol = p.vol; |
||
57 | n = p.n; |
||
58 | n_1 = p.n_1; |
||
59 | da = p.da; |
||
60 | pdx = new float [n]; |
||
61 | pvol = new float [n]; |
||
62 | for (int i = 0; i < n; ++i) { |
||
63 | pdx [i] = p.pdx [i]; |
||
64 | pvol [i] = p.pvol [i]; |
||
65 | } |
||
66 | } |
||
67 | |||
68 | play::~play () { |
||
69 | if (pdx) delete[] pdx; |
||
70 | if (pvol) delete[] pvol; |
||
71 | } |
||
72 | |||
73 | void play::fill_pitch (float xd) { |
||
74 | for (int i = 0; i < n; ++i) pdx[i] = xd; |
||
75 | dx = xd; |
||
76 | } |
||
77 | |||
78 | void play::fill_volume (float v) { |
||
79 | for (int i = 0; i < n; ++i) pvol[i] = v; |
||
80 | vol = v; |
||
81 | } |
||
82 | |||
83 | void play::interpolate_buffer (float* buf, float s, float e) { |
||
84 | float a = 0; |
||
85 | float es = e - s; |
||
86 | for (int i = 0; i < n; ++i) { |
||
87 | buf[i] = s + a * es; |
||
88 | a += da; |
||
89 | } |
||
90 | } |
||
91 | |||
92 | void play::set_interpolated_volume (float v) { |
||
93 | interpolate_buffer (pvol, vol, v); |
||
94 | vol = v; |
||
95 | } |
||
96 | |||
97 | void play::set_interpolated_pitch (float xd) { |
||
98 | interpolate_buffer (pdx, dx, xd); |
||
99 | dx = xd; |
||
100 | } |
||
101 | |||
102 | void play::set_interpolated_pitch (float xd, int check) { |
||
103 | if ((pdx[0] == pdx[n_1]) && (pdx[0] == xd)) return; // pitch is same |
||
104 | else |
||
105 | if (xd == dx) |
||
106 | for (int i = 0; i < n; ++i) pdx[i] = dx; // same as last pitch so just fill ie no interpolation needed |
||
107 | else |
||
108 | set_interpolated_pitch (xd); |
||
109 | } |
||
110 | |||
111 | void play::set_interpolated_volume (float v, int check) { |
||
112 | if ((pvol[0]==pvol[n_1]) && (pvol[0]==v)) return; // volume is same |
||
113 | else |
||
114 | if (v == vol) |
||
115 | for (int i = 0; i < n; ++i) pvol[i] = v; // same as last volume so just fill ie no interpolation needed |
||
116 | else |
||
117 | set_interpolated_volume (v); |
||
118 | } |
||
119 | |||
120 | void play::gen_wav_and_mix (float* wav, int n) { |
||
121 | (*sol) (x, pdx, n, wav); |
||
122 | if (mixer.active) { |
||
123 | mixer.gen_mix (aout.mix, n); |
||
124 | mixer.do_mix (wav, aout.mix, aout.mixa, n); |
||
125 | } |
||
126 | } |
||
127 | |||
128 | void play::master (float* L, float* R, float* wav, int n, float* vola) { // master with volume array |
||
129 | gen_wav_and_mix (wav, n); // mix waveforms |
||
130 | operator() (L, n, wav, vola); // multiply volumes |
||
131 | memcpy (R, L, aout.samples_channel_size); // copy to R |
||
132 | } |
||
133 | |||
134 | void play::master (float* L, float* R, float* wav, int n, float vol) { // master with volume |
||
135 | gen_wav_and_mix (wav, n); // mix waveforms |
||
136 | operator() (L, n, wav, vol); // apply volume |
||
137 | memcpy (R, L, aout.samples_channel_size); // copy to R |
||
138 | } |
||
139 | |||
2266 | jag | 140 | |
141 | void play::master (float* L, float* wav, int n, float vol) { // master with volume |
||
142 | gen_wav_and_mix (wav, n); // mix waveforms |
||
143 | operator() (L, n, wav, vol); // apply volume |
||
144 | } |
||
145 | |||
2267 | jag | 146 | |
147 | void play::master (float* L, float* wav, int n, float* vola) { // master with volume array |
||
148 | gen_wav_and_mix (wav, n); // mix waveforms |
||
149 | operator() (L, n, wav, vola); // apply volume |
||
150 | } |
||
151 | |||
964 | jag | 152 | void play::gen_wav_fm (solver& _sol, float& _x, float* wav, float* fm, int n) { // generate waveform samples with FM |
153 | _sol (_x, pdx, n, fm, wav); |
||
154 | } |
||
155 | |||
156 | void play::gen_wav_am (float* out, float* wav, float* am, int n) { // apply AM to waveform samples |
||
157 | for (int i = 0; i < n; ++i) out[i] = ((pvol[i] + am[i]) * wav[i]); |
||
158 | } |
||
159 | |||
160 | void play::gen_wav_fm_am_mix (float* out, int n) { // generate waveform samples, apply AM and FM and mix (if present) |
||
161 | gen_wav_fm (*sol, x, aout.result, aout.fms, n); |
||
162 | gen_wav_am (out, aout.result, aout.ams, n); |
||
163 | if (mixer.active) { |
||
164 | mixer.gen_fm (aout.result, n, aout.fms); |
||
165 | gen_wav_am (aout.mix, aout.result, aout.ams, n); |
||
166 | mixer.do_mix (out, aout.mix, aout.mixa, n); |
||
167 | } |
||
168 | } |
||
169 | |||
170 | void play::gen_wav_mix (float* out, float* vola, int n) { |
||
171 | gen_wav_and_mix (aout.result, n); |
||
172 | operator() (out, n, aout.result, vola); |
||
173 | } |
||
174 | |||
175 | void play::gen_wav_mix (float* out, float vol, int n) { |
||
176 | gen_wav_and_mix (aout.result, n); |
||
177 | operator() (out, n, aout.result, vol); |
||
178 | } |
||
179 | |||
1799 | jag | 180 | void play::set_mix (multi_curve& crv, const std::string& nam) { |
964 | jag | 181 | mixer.setup (crv, x, dx); |
1799 | jag | 182 | mixer.name = nam; |
964 | jag | 183 | } |