/src/vlc/contrib/contrib-build/game-music-emu/gme/Effects_Buffer.cpp
Line | Count | Source |
1 | | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/ |
2 | | |
3 | | #include "Effects_Buffer.h" |
4 | | |
5 | | #include <string.h> |
6 | | #include <algorithm> |
7 | | |
8 | | /* Copyright (C) 2003-2006 Shay Green. This module is free software; you |
9 | | can redistribute it and/or modify it under the terms of the GNU Lesser |
10 | | General Public License as published by the Free Software Foundation; either |
11 | | version 2.1 of the License, or (at your option) any later version. This |
12 | | module is distributed in the hope that it will be useful, but WITHOUT ANY |
13 | | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
14 | | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
15 | | details. You should have received a copy of the GNU Lesser General Public |
16 | | License along with this module; if not, write to the Free Software Foundation, |
17 | | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ |
18 | | |
19 | | #include "blargg_source.h" |
20 | | |
21 | | #ifdef BLARGG_ENABLE_OPTIMIZER |
22 | | #include BLARGG_ENABLE_OPTIMIZER |
23 | | #endif |
24 | | |
25 | | typedef int32_t fixed_t; |
26 | | |
27 | | using std::min; |
28 | | using std::max; |
29 | | |
30 | 0 | #define TO_FIXED( f ) fixed_t ((f) * (1L << 15) + 0.5) |
31 | 0 | #define FMUL( x, y ) (((x) * (y)) >> 15) |
32 | | |
33 | | static const unsigned echo_size = 4096; |
34 | | static const unsigned echo_mask = echo_size - 1; |
35 | | static_assert( (echo_size & echo_mask) == 0, "echo_size must be a power of 2" ); |
36 | | |
37 | | static const unsigned reverb_size = 8192 * 2; |
38 | | static const unsigned reverb_mask = reverb_size - 1; |
39 | | static_assert( (reverb_size & reverb_mask) == 0, "reverb_size must be a power of 2" ); |
40 | | |
41 | | Effects_Buffer::config_t::config_t() |
42 | 5.24k | { |
43 | 5.24k | pan_1 = -0.15f; |
44 | 5.24k | pan_2 = 0.15f; |
45 | 5.24k | reverb_delay = 88.0f; |
46 | 5.24k | reverb_level = 0.12f; |
47 | 5.24k | echo_delay = 61.0f; |
48 | 5.24k | echo_level = 0.10f; |
49 | 5.24k | delay_variance = 18.0f; |
50 | 5.24k | effects_enabled = false; |
51 | 5.24k | } |
52 | | |
53 | | void Effects_Buffer::set_depth( double d ) |
54 | 2.62k | { |
55 | 2.62k | float f = (float) d; |
56 | 2.62k | config_t c; |
57 | 2.62k | c.pan_1 = -0.6f * f; |
58 | 2.62k | c.pan_2 = 0.6f * f; |
59 | 2.62k | c.reverb_delay = 880 * 0.1f; |
60 | 2.62k | c.echo_delay = 610 * 0.1f; |
61 | 2.62k | if ( f > 0.5 ) |
62 | 0 | f = 0.5; // TODO: more linear reduction of extreme reverb/echo |
63 | 2.62k | c.reverb_level = 0.5f * f; |
64 | 2.62k | c.echo_level = 0.30f * f; |
65 | 2.62k | c.delay_variance = 180 * 0.1f; |
66 | 2.62k | c.effects_enabled = (d > 0.0f); |
67 | 2.62k | config( c ); |
68 | 2.62k | } |
69 | | |
70 | | Effects_Buffer::Effects_Buffer( int num_voices, bool center_only ) |
71 | 2.62k | : Multi_Buffer( 2*num_voices ) |
72 | 2.62k | , max_voices(num_voices) |
73 | 2.62k | , bufs(max_voices * (center_only ? (max_buf_count - 4) : max_buf_count)) |
74 | 2.62k | , chan_types(max_voices * chan_types_count) |
75 | 2.62k | , stereo_remain(0) |
76 | 2.62k | , effect_remain(0) |
77 | | // TODO: Reorder buf_count to be initialized before bufs to factor out channel sizing |
78 | 2.62k | , buf_count(max_voices * (center_only ? (max_buf_count - 4) : max_buf_count)) |
79 | 2.62k | , effects_enabled(false) |
80 | 2.62k | , reverb_buf(max_voices, std::vector<blip_sample_t>(reverb_size)) |
81 | 2.62k | , echo_buf(max_voices, std::vector<blip_sample_t>(echo_size)) |
82 | 2.62k | , reverb_pos(max_voices) |
83 | 2.62k | , echo_pos(max_voices) |
84 | 2.62k | { |
85 | 2.62k | set_depth( 0 ); |
86 | 2.62k | } |
87 | | |
88 | | Effects_Buffer::~Effects_Buffer() |
89 | 2.62k | {} |
90 | | |
91 | | blargg_err_t Effects_Buffer::set_sample_rate( long rate, int msec ) noexcept |
92 | 2.62k | { |
93 | 5.24k | for(int i=0; i<max_voices; i++) |
94 | 2.62k | { |
95 | 2.62k | if ( !echo_buf[i].size() ) |
96 | 0 | { |
97 | 0 | echo_buf[i].resize( echo_size ); |
98 | 0 | } |
99 | | |
100 | 2.62k | if ( !reverb_buf[i].size() ) |
101 | 0 | { |
102 | 0 | reverb_buf[i].resize( reverb_size ); |
103 | 0 | } |
104 | | |
105 | 2.62k | if ( !echo_buf[i].size() || !reverb_buf[i].size() ) |
106 | 0 | { |
107 | 0 | return "Out of memory"; |
108 | 0 | } |
109 | 2.62k | } |
110 | | |
111 | 20.9k | for ( int i = 0; i < buf_count; i++ ) |
112 | 18.3k | RETURN_ERR( bufs [i].set_sample_rate( rate, msec ) ); |
113 | | |
114 | 2.62k | config( config_ ); |
115 | 2.62k | clear(); |
116 | | |
117 | 2.62k | return Multi_Buffer::set_sample_rate( bufs [0].sample_rate(), bufs [0].length() ); |
118 | 2.62k | } |
119 | | |
120 | | void Effects_Buffer::clock_rate( uint32_t rate ) |
121 | 2.64k | { |
122 | 21.1k | for ( int i = 0; i < buf_count; i++ ) |
123 | 18.4k | bufs [i].clock_rate( rate ); |
124 | 2.64k | } |
125 | | |
126 | | void Effects_Buffer::bass_freq( int freq ) |
127 | 2.64k | { |
128 | 21.1k | for ( int i = 0; i < buf_count; i++ ) |
129 | 18.4k | bufs [i].bass_freq( freq ); |
130 | 2.64k | } |
131 | | |
132 | | void Effects_Buffer::clear() |
133 | 14.1k | { |
134 | 14.1k | stereo_remain = 0; |
135 | 14.1k | effect_remain = 0; |
136 | | |
137 | 28.3k | for(int i=0; i<max_voices; i++) |
138 | 14.1k | { |
139 | 14.1k | if ( echo_buf[i].size() ) |
140 | 14.1k | memset( &echo_buf[i][0], 0, echo_size * sizeof echo_buf[i][0] ); |
141 | | |
142 | 14.1k | if ( reverb_buf[i].size() ) |
143 | 14.1k | memset( &reverb_buf[i][0], 0, reverb_size * sizeof reverb_buf[i][0] ); |
144 | 14.1k | } |
145 | | |
146 | 113k | for ( int i = 0; i < buf_count; i++ ) |
147 | 99.0k | bufs [i].clear(); |
148 | 14.1k | } |
149 | | |
150 | | inline int pin_range( int n, int max, int min = 0 ) |
151 | 0 | { |
152 | 0 | if ( n < min ) |
153 | 0 | return min; |
154 | 0 | if ( n > max ) |
155 | 0 | return max; |
156 | 0 | return n; |
157 | 0 | } |
158 | | |
159 | | void Effects_Buffer::config( const config_t& cfg ) |
160 | 5.24k | { |
161 | 5.24k | channels_changed(); |
162 | | |
163 | | // clear echo and reverb buffers |
164 | | // ensure the echo/reverb buffers have already been allocated, so this method can be |
165 | | // called before set_sample_rate is called |
166 | 5.24k | if ( !config_.effects_enabled && cfg.effects_enabled && echo_buf[0].size() ) |
167 | 0 | { |
168 | 0 | for(int i=0; i<max_voices; i++) |
169 | 0 | { |
170 | 0 | memset( &echo_buf[i][0], 0, echo_size * sizeof echo_buf[i][0] ); |
171 | 0 | memset( &reverb_buf[i][0], 0, reverb_size * sizeof reverb_buf[i][0] ); |
172 | 0 | } |
173 | 0 | } |
174 | | |
175 | 5.24k | config_ = cfg; |
176 | | |
177 | 5.24k | if ( config_.effects_enabled ) |
178 | 0 | { |
179 | | // convert to internal format |
180 | |
|
181 | 0 | chans.pan_1_levels [0] = TO_FIXED( 1 ) - TO_FIXED( config_.pan_1 ); |
182 | 0 | chans.pan_1_levels [1] = TO_FIXED( 2 ) - chans.pan_1_levels [0]; |
183 | |
|
184 | 0 | chans.pan_2_levels [0] = TO_FIXED( 1 ) - TO_FIXED( config_.pan_2 ); |
185 | 0 | chans.pan_2_levels [1] = TO_FIXED( 2 ) - chans.pan_2_levels [0]; |
186 | |
|
187 | 0 | chans.reverb_level = TO_FIXED( config_.reverb_level ); |
188 | 0 | chans.echo_level = TO_FIXED( config_.echo_level ); |
189 | |
|
190 | 0 | int delay_offset = int (1.0 / 2000 * config_.delay_variance * sample_rate()); |
191 | |
|
192 | 0 | int reverb_sample_delay = int (1.0 / 1000 * config_.reverb_delay * sample_rate()); |
193 | 0 | chans.reverb_delay_l = pin_range( reverb_size - |
194 | 0 | (reverb_sample_delay - delay_offset) * 2, reverb_size - 2, 0 ); |
195 | 0 | chans.reverb_delay_r = pin_range( reverb_size + 1 - |
196 | 0 | (reverb_sample_delay + delay_offset) * 2, reverb_size - 1, 1 ); |
197 | |
|
198 | 0 | int echo_sample_delay = int (1.0 / 1000 * config_.echo_delay * sample_rate()); |
199 | 0 | chans.echo_delay_l = pin_range( echo_size - 1 - (echo_sample_delay - delay_offset), |
200 | 0 | echo_size - 1 ); |
201 | 0 | chans.echo_delay_r = pin_range( echo_size - 1 - (echo_sample_delay + delay_offset), |
202 | 0 | echo_size - 1 ); |
203 | |
|
204 | 0 | for(int i=0; i<max_voices; i++) |
205 | 0 | { |
206 | 0 | chan_types [i*chan_types_count+0].center = &bufs [i*max_buf_count+0]; |
207 | 0 | chan_types [i*chan_types_count+0].left = &bufs [i*max_buf_count+3]; |
208 | 0 | chan_types [i*chan_types_count+0].right = &bufs [i*max_buf_count+4]; |
209 | |
|
210 | 0 | chan_types [i*chan_types_count+1].center = &bufs [i*max_buf_count+1]; |
211 | 0 | chan_types [i*chan_types_count+1].left = &bufs [i*max_buf_count+3]; |
212 | 0 | chan_types [i*chan_types_count+1].right = &bufs [i*max_buf_count+4]; |
213 | |
|
214 | 0 | chan_types [i*chan_types_count+2].center = &bufs [i*max_buf_count+2]; |
215 | 0 | chan_types [i*chan_types_count+2].left = &bufs [i*max_buf_count+5]; |
216 | 0 | chan_types [i*chan_types_count+2].right = &bufs [i*max_buf_count+6]; |
217 | 0 | } |
218 | 0 | blaarg_static_assert( chan_types_count >= 3, "Need at least three audio channels for effects processing" ); |
219 | 0 | } |
220 | 5.24k | else |
221 | 5.24k | { |
222 | 10.4k | for(int i=0; i<max_voices; i++) |
223 | 5.24k | { |
224 | | // set up outputs |
225 | 20.9k | for ( int j = 0; j < chan_types_count; j++ ) |
226 | 15.7k | { |
227 | 15.7k | channel_t& c = chan_types [i*chan_types_count+j]; |
228 | 15.7k | c.center = &bufs [i*max_buf_count+0]; |
229 | 15.7k | c.left = &bufs [i*max_buf_count+1]; |
230 | 15.7k | c.right = &bufs [i*max_buf_count+2]; |
231 | 15.7k | } |
232 | 5.24k | } |
233 | 5.24k | } |
234 | | |
235 | 5.24k | if ( buf_count < max_buf_count ) // if center_only |
236 | 0 | { |
237 | 0 | for(int i=0; i<max_voices; i++) |
238 | 0 | { |
239 | 0 | for ( int j = 0; j < chan_types_count; j++ ) |
240 | 0 | { |
241 | 0 | channel_t& c = chan_types [i*chan_types_count+j]; |
242 | 0 | c.left = c.center; |
243 | 0 | c.right = c.center; |
244 | 0 | } |
245 | 0 | } |
246 | 0 | } |
247 | 5.24k | } |
248 | | |
249 | | Effects_Buffer::channel_t Effects_Buffer::channel( int i, int type ) |
250 | 17.1k | { |
251 | 17.1k | int out = chan_types_count-1; |
252 | 17.1k | if ( !type ) |
253 | 264 | { |
254 | 264 | out = i % 5; |
255 | 264 | if ( out > chan_types_count-1 ) |
256 | 66 | out = chan_types_count-1; |
257 | 264 | } |
258 | 16.9k | else if ( !(type & noise_type) && (type & type_index_mask) % 3 != 0 ) |
259 | 8.41k | { |
260 | 8.41k | out = type & 1; |
261 | 8.41k | } |
262 | 17.1k | return chan_types [(i%max_voices)*chan_types_count+out]; |
263 | 17.1k | } |
264 | | |
265 | | void Effects_Buffer::end_frame( blip_time_t clock_count ) |
266 | 1.92M | { |
267 | 1.92M | int bufs_used = 0; |
268 | 1.92M | int stereo_mask = (config_.effects_enabled ? 0x78 : 0x06); |
269 | | |
270 | 1.92M | const int buf_count_per_voice = buf_count/max_voices; |
271 | 3.85M | for ( int v = 0; v < max_voices; v++ ) // foreach voice |
272 | 1.92M | { |
273 | 15.4M | for ( int i = 0; i < buf_count_per_voice; i++) // foreach buffer of that voice |
274 | 13.5M | { |
275 | 13.5M | bufs_used |= bufs [v*buf_count_per_voice + i].clear_modified() << i; |
276 | 13.5M | bufs [v*buf_count_per_voice + i].end_frame( clock_count ); |
277 | | |
278 | 13.5M | if ( (bufs_used & stereo_mask) && buf_count == max_voices*max_buf_count ) |
279 | 1.97M | stereo_remain = max(stereo_remain, bufs [v*buf_count_per_voice + i].samples_avail() + bufs [v*buf_count_per_voice + i].output_latency()); |
280 | 13.5M | if ( effects_enabled || config_.effects_enabled ) |
281 | 0 | effect_remain = max(effect_remain, bufs [v*buf_count_per_voice + i].samples_avail() + bufs [v*buf_count_per_voice + i].output_latency()); |
282 | 13.5M | } |
283 | 1.92M | bufs_used = 0; |
284 | 1.92M | } |
285 | | |
286 | 1.92M | effects_enabled = config_.effects_enabled; |
287 | 1.92M | } |
288 | | |
289 | | long Effects_Buffer::samples_avail() const |
290 | 0 | { |
291 | 0 | return bufs [0].samples_avail() * 2; |
292 | 0 | } |
293 | | |
294 | | long Effects_Buffer::read_samples( blip_sample_t* out, long total_samples ) |
295 | 6.38M | { |
296 | 6.38M | const int n_channels = max_voices * 2; |
297 | 6.38M | const int buf_count_per_voice = buf_count/max_voices; |
298 | | |
299 | 6.38M | require( total_samples % n_channels == 0 ); // as many items needed to fill at least one frame |
300 | | |
301 | 6.38M | long remain = bufs [0].samples_avail(); |
302 | 6.38M | total_samples = remain = min( remain, total_samples/n_channels ); |
303 | | |
304 | 12.7M | while ( remain ) |
305 | 6.37M | { |
306 | 6.37M | int active_bufs = buf_count_per_voice; |
307 | 6.37M | long count = remain; |
308 | | |
309 | | // optimizing mixing to skip any channels which had nothing added |
310 | 6.37M | if ( effect_remain ) |
311 | 0 | { |
312 | 0 | if ( count > effect_remain ) |
313 | 0 | count = effect_remain; |
314 | |
|
315 | 0 | if ( stereo_remain ) |
316 | 0 | { |
317 | 0 | mix_enhanced( out, count ); |
318 | 0 | } |
319 | 0 | else |
320 | 0 | { |
321 | 0 | mix_mono_enhanced( out, count ); |
322 | 0 | active_bufs = 3; |
323 | 0 | } |
324 | 0 | } |
325 | 6.37M | else if ( stereo_remain ) |
326 | 1.11M | { |
327 | 1.11M | mix_stereo( out, count ); |
328 | 1.11M | active_bufs = 3; |
329 | 1.11M | } |
330 | 5.26M | else |
331 | 5.26M | { |
332 | 5.26M | mix_mono( out, count ); |
333 | 5.26M | active_bufs = 1; |
334 | 5.26M | } |
335 | | |
336 | 6.37M | out += count * n_channels; |
337 | 6.37M | remain -= count; |
338 | | |
339 | 6.37M | stereo_remain -= count; |
340 | 6.37M | if ( stereo_remain < 0 ) |
341 | 5.26M | stereo_remain = 0; |
342 | | |
343 | 6.37M | effect_remain -= count; |
344 | 6.37M | if ( effect_remain < 0 ) |
345 | 6.37M | effect_remain = 0; |
346 | | |
347 | | // skip the output from any buffers that didn't contribute to the sound output |
348 | | // during this frame (e.g. if we only render mono then only the very first buf |
349 | | // is 'active') |
350 | 12.7M | for ( int v = 0; v < max_voices; v++ ) // foreach voice |
351 | 6.37M | { |
352 | 51.0M | for ( int i = 0; i < buf_count_per_voice; i++) // foreach buffer of that voice |
353 | 44.6M | { |
354 | 44.6M | if ( i < active_bufs ) |
355 | 8.60M | bufs [v*buf_count_per_voice + i].remove_samples( count ); |
356 | 36.0M | else // keep time synchronized |
357 | 36.0M | bufs [v*buf_count_per_voice + i].remove_silence( count ); |
358 | 44.6M | } |
359 | 6.37M | } |
360 | 6.37M | } |
361 | | |
362 | 6.38M | return total_samples * n_channels; |
363 | 6.38M | } |
364 | | |
365 | | void Effects_Buffer::mix_mono( blip_sample_t* out_, int32_t count ) |
366 | 5.26M | { |
367 | 10.5M | for(int i=0; i<max_voices; i++) |
368 | 5.26M | { |
369 | 5.26M | blip_sample_t* BLIP_RESTRICT out = out_; |
370 | 5.26M | int const bass = BLIP_READER_BASS( bufs [i*max_buf_count+0] ); |
371 | 5.26M | BLIP_READER_BEGIN( c, bufs [i*max_buf_count+0] ); |
372 | | |
373 | | // unrolled loop |
374 | 1.90G | for ( int32_t n = count >> 1; n; --n ) |
375 | 1.90G | { |
376 | 1.90G | int32_t cs0 = BLIP_READER_READ( c ); |
377 | 1.90G | BLIP_READER_NEXT( c, bass ); |
378 | | |
379 | 1.90G | int32_t cs1 = BLIP_READER_READ( c ); |
380 | 1.90G | BLIP_READER_NEXT( c, bass ); |
381 | | |
382 | 1.90G | if ( (int16_t) cs0 != cs0 ) |
383 | 0 | cs0 = 0x7FFF - (cs0 >> 24); |
384 | 1.90G | ((uint32_t*) out) [i] = ((uint16_t) cs0) | (uint16_t(cs0) << 16); |
385 | | |
386 | 1.90G | if ( (int16_t) cs1 != cs1 ) |
387 | 0 | cs1 = 0x7FFF - (cs1 >> 24); |
388 | 1.90G | ((uint32_t*) out) [i+max_voices] = ((uint16_t) cs1) | (uint16_t(cs1) << 16); |
389 | 1.90G | out += max_voices*4; |
390 | 1.90G | } |
391 | | |
392 | 5.26M | if ( count & 1 ) |
393 | 1.77M | { |
394 | 1.77M | int s = BLIP_READER_READ( c ); |
395 | 1.77M | BLIP_READER_NEXT( c, bass ); |
396 | 1.77M | if ( (int16_t) s != s ) |
397 | 0 | s = 0x7FFF - (s >> 24); |
398 | 1.77M | out [i*2+0] = s; |
399 | 1.77M | out [i*2+1] = s; |
400 | 1.77M | } |
401 | | |
402 | 5.26M | BLIP_READER_END( c, bufs [i*max_buf_count+0] ); |
403 | 5.26M | } |
404 | 5.26M | } |
405 | | |
406 | | void Effects_Buffer::mix_stereo( blip_sample_t* out_, int32_t frames ) |
407 | 1.11M | { |
408 | 2.22M | for(int i=0; i<max_voices; i++) |
409 | 1.11M | { |
410 | 1.11M | blip_sample_t* BLIP_RESTRICT out = out_; |
411 | 1.11M | int const bass = BLIP_READER_BASS( bufs [i*max_buf_count+0] ); |
412 | 1.11M | BLIP_READER_BEGIN( c, bufs [i*max_buf_count+0] ); |
413 | 1.11M | BLIP_READER_BEGIN( l, bufs [i*max_buf_count+1] ); |
414 | 1.11M | BLIP_READER_BEGIN( r, bufs [i*max_buf_count+2] ); |
415 | | |
416 | 1.11M | int count = frames; |
417 | 809M | while ( count-- ) |
418 | 808M | { |
419 | 808M | int cs = BLIP_READER_READ( c ); |
420 | 808M | BLIP_READER_NEXT( c, bass ); |
421 | 808M | int left = cs + BLIP_READER_READ( l ); |
422 | 808M | int right = cs + BLIP_READER_READ( r ); |
423 | 808M | BLIP_READER_NEXT( l, bass ); |
424 | 808M | BLIP_READER_NEXT( r, bass ); |
425 | | |
426 | 808M | if ( (int16_t) left != left ) |
427 | 0 | left = 0x7FFF - (left >> 24); |
428 | | |
429 | 808M | if ( (int16_t) right != right ) |
430 | 0 | right = 0x7FFF - (right >> 24); |
431 | | |
432 | 808M | out [i*2+0] = left; |
433 | 808M | out [i*2+1] = right; |
434 | | |
435 | 808M | out += max_voices*2; |
436 | | |
437 | 808M | } |
438 | | |
439 | 1.11M | BLIP_READER_END( r, bufs [i*max_buf_count+2] ); |
440 | 1.11M | BLIP_READER_END( l, bufs [i*max_buf_count+1] ); |
441 | 1.11M | BLIP_READER_END( c, bufs [i*max_buf_count+0] ); |
442 | 1.11M | } |
443 | 1.11M | } |
444 | | |
445 | | void Effects_Buffer::mix_mono_enhanced( blip_sample_t* out_, int32_t frames ) |
446 | 0 | { |
447 | 0 | for(int i=0; i<max_voices; i++) |
448 | 0 | { |
449 | 0 | blip_sample_t* BLIP_RESTRICT out = out_; |
450 | 0 | int const bass = BLIP_READER_BASS( bufs [i*max_buf_count+2] ); |
451 | 0 | BLIP_READER_BEGIN( center, bufs [i*max_buf_count+2] ); |
452 | 0 | BLIP_READER_BEGIN( sq1, bufs [i*max_buf_count+0] ); |
453 | 0 | BLIP_READER_BEGIN( sq2, bufs [i*max_buf_count+1] ); |
454 | |
|
455 | 0 | blip_sample_t* const reverb_buf = &this->reverb_buf[i][0]; |
456 | 0 | blip_sample_t* const echo_buf = &this->echo_buf[i][0]; |
457 | 0 | int echo_pos = this->echo_pos[i]; |
458 | 0 | int reverb_pos = this->reverb_pos[i]; |
459 | |
|
460 | 0 | int count = frames; |
461 | 0 | while ( count-- ) |
462 | 0 | { |
463 | 0 | int sum1_s = BLIP_READER_READ( sq1 ); |
464 | 0 | int sum2_s = BLIP_READER_READ( sq2 ); |
465 | |
|
466 | 0 | BLIP_READER_NEXT( sq1, bass ); |
467 | 0 | BLIP_READER_NEXT( sq2, bass ); |
468 | |
|
469 | 0 | int new_reverb_l = FMUL( sum1_s, chans.pan_1_levels [0] ) + |
470 | 0 | FMUL( sum2_s, chans.pan_2_levels [0] ) + |
471 | 0 | reverb_buf [(reverb_pos + chans.reverb_delay_l) & reverb_mask]; |
472 | |
|
473 | 0 | int new_reverb_r = FMUL( sum1_s, chans.pan_1_levels [1] ) + |
474 | 0 | FMUL( sum2_s, chans.pan_2_levels [1] ) + |
475 | 0 | reverb_buf [(reverb_pos + chans.reverb_delay_r) & reverb_mask]; |
476 | |
|
477 | 0 | fixed_t reverb_level = chans.reverb_level; |
478 | 0 | reverb_buf [reverb_pos] = (blip_sample_t) FMUL( new_reverb_l, reverb_level ); |
479 | 0 | reverb_buf [reverb_pos + 1] = (blip_sample_t) FMUL( new_reverb_r, reverb_level ); |
480 | 0 | reverb_pos = (reverb_pos + 2) & reverb_mask; |
481 | |
|
482 | 0 | int sum3_s = BLIP_READER_READ( center ); |
483 | 0 | BLIP_READER_NEXT( center, bass ); |
484 | |
|
485 | 0 | int left = new_reverb_l + sum3_s + FMUL( chans.echo_level, |
486 | 0 | echo_buf [(echo_pos + chans.echo_delay_l) & echo_mask] ); |
487 | 0 | int right = new_reverb_r + sum3_s + FMUL( chans.echo_level, |
488 | 0 | echo_buf [(echo_pos + chans.echo_delay_r) & echo_mask] ); |
489 | |
|
490 | 0 | echo_buf [echo_pos] = sum3_s; |
491 | 0 | echo_pos = (echo_pos + 1) & echo_mask; |
492 | |
|
493 | 0 | if ( (int16_t) left != left ) |
494 | 0 | left = 0x7FFF - (left >> 24); |
495 | |
|
496 | 0 | if ( (int16_t) right != right ) |
497 | 0 | right = 0x7FFF - (right >> 24); |
498 | |
|
499 | 0 | out [i*2+0] = left; |
500 | 0 | out [i*2+1] = right; |
501 | 0 | out += max_voices*2; |
502 | 0 | } |
503 | 0 | this->reverb_pos[i] = reverb_pos; |
504 | 0 | this->echo_pos[i] = echo_pos; |
505 | |
|
506 | 0 | BLIP_READER_END( sq1, bufs [i*max_buf_count+0] ); |
507 | 0 | BLIP_READER_END( sq2, bufs [i*max_buf_count+1] ); |
508 | 0 | BLIP_READER_END( center, bufs [i*max_buf_count+2] ); |
509 | 0 | } |
510 | 0 | } |
511 | | |
512 | | void Effects_Buffer::mix_enhanced( blip_sample_t* out_, int32_t frames ) |
513 | 0 | { |
514 | 0 | for(int i=0; i<max_voices; i++) |
515 | 0 | { |
516 | 0 | blip_sample_t* BLIP_RESTRICT out = out_; |
517 | 0 | int const bass = BLIP_READER_BASS( bufs [i*max_buf_count+2] ); |
518 | 0 | BLIP_READER_BEGIN( center, bufs [i*max_buf_count+2] ); |
519 | 0 | BLIP_READER_BEGIN( l1, bufs [i*max_buf_count+3] ); |
520 | 0 | BLIP_READER_BEGIN( r1, bufs [i*max_buf_count+4] ); |
521 | 0 | BLIP_READER_BEGIN( l2, bufs [i*max_buf_count+5] ); |
522 | 0 | BLIP_READER_BEGIN( r2, bufs [i*max_buf_count+6] ); |
523 | 0 | BLIP_READER_BEGIN( sq1, bufs [i*max_buf_count+0] ); |
524 | 0 | BLIP_READER_BEGIN( sq2, bufs [i*max_buf_count+1] ); |
525 | |
|
526 | 0 | blip_sample_t* const reverb_buf = &this->reverb_buf[i][0]; |
527 | 0 | blip_sample_t* const echo_buf = &this->echo_buf[i][0]; |
528 | 0 | int echo_pos = this->echo_pos[i]; |
529 | 0 | int reverb_pos = this->reverb_pos[i]; |
530 | |
|
531 | 0 | int count = frames; |
532 | 0 | while ( count-- ) |
533 | 0 | { |
534 | 0 | int sum1_s = BLIP_READER_READ( sq1 ); |
535 | 0 | int sum2_s = BLIP_READER_READ( sq2 ); |
536 | |
|
537 | 0 | BLIP_READER_NEXT( sq1, bass ); |
538 | 0 | BLIP_READER_NEXT( sq2, bass ); |
539 | |
|
540 | 0 | int new_reverb_l = FMUL( sum1_s, chans.pan_1_levels [0] ) + |
541 | 0 | FMUL( sum2_s, chans.pan_2_levels [0] ) + BLIP_READER_READ( l1 ) + |
542 | 0 | reverb_buf [(reverb_pos + chans.reverb_delay_l) & reverb_mask]; |
543 | |
|
544 | 0 | int new_reverb_r = FMUL( sum1_s, chans.pan_1_levels [1] ) + |
545 | 0 | FMUL( sum2_s, chans.pan_2_levels [1] ) + BLIP_READER_READ( r1 ) + |
546 | 0 | reverb_buf [(reverb_pos + chans.reverb_delay_r) & reverb_mask]; |
547 | |
|
548 | 0 | BLIP_READER_NEXT( l1, bass ); |
549 | 0 | BLIP_READER_NEXT( r1, bass ); |
550 | |
|
551 | 0 | fixed_t reverb_level = chans.reverb_level; |
552 | 0 | reverb_buf [reverb_pos] = (blip_sample_t) FMUL( new_reverb_l, reverb_level ); |
553 | 0 | reverb_buf [reverb_pos + 1] = (blip_sample_t) FMUL( new_reverb_r, reverb_level ); |
554 | 0 | reverb_pos = (reverb_pos + 2) & reverb_mask; |
555 | |
|
556 | 0 | int sum3_s = BLIP_READER_READ( center ); |
557 | 0 | BLIP_READER_NEXT( center, bass ); |
558 | |
|
559 | 0 | int left = new_reverb_l + sum3_s + BLIP_READER_READ( l2 ) + FMUL( chans.echo_level, |
560 | 0 | echo_buf [(echo_pos + chans.echo_delay_l) & echo_mask] ); |
561 | 0 | int right = new_reverb_r + sum3_s + BLIP_READER_READ( r2 ) + FMUL( chans.echo_level, |
562 | 0 | echo_buf [(echo_pos + chans.echo_delay_r) & echo_mask] ); |
563 | |
|
564 | 0 | BLIP_READER_NEXT( l2, bass ); |
565 | 0 | BLIP_READER_NEXT( r2, bass ); |
566 | |
|
567 | 0 | echo_buf [echo_pos] = sum3_s; |
568 | 0 | echo_pos = (echo_pos + 1) & echo_mask; |
569 | |
|
570 | 0 | if ( (int16_t) left != left ) |
571 | 0 | left = 0x7FFF - (left >> 24); |
572 | |
|
573 | 0 | if ( (int16_t) right != right ) |
574 | 0 | right = 0x7FFF - (right >> 24); |
575 | |
|
576 | 0 | out [i*2+0] = left; |
577 | 0 | out [i*2+1] = right; |
578 | |
|
579 | 0 | out += max_voices*2; |
580 | 0 | } |
581 | 0 | this->reverb_pos[i] = reverb_pos; |
582 | 0 | this->echo_pos[i] = echo_pos; |
583 | |
|
584 | 0 | BLIP_READER_END( l1, bufs [i*max_buf_count+3] ); |
585 | 0 | BLIP_READER_END( r1, bufs [i*max_buf_count+4] ); |
586 | 0 | BLIP_READER_END( l2, bufs [i*max_buf_count+5] ); |
587 | 0 | BLIP_READER_END( r2, bufs [i*max_buf_count+6] ); |
588 | 0 | BLIP_READER_END( sq1, bufs [i*max_buf_count+0] ); |
589 | 0 | BLIP_READER_END( sq2, bufs [i*max_buf_count+1] ); |
590 | 0 | BLIP_READER_END( center, bufs [i*max_buf_count+2] ); |
591 | 0 | } |
592 | 0 | } |
593 | | |