Coverage Report

Created: 2026-09-28 07:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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