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