Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
folium-app
GitHub Repository: folium-app/Folium
Path: blob/a-new-beginning/Cherry/Core/audio/Blip_Buffer.cpp
2 views
1
// Blip_Buffer 0.4.1. http://www.slack.net/~ant/
2
3
#include "Blip_Buffer.h"
4
5
#include <assert.h>
6
#include <limits.h>
7
#include <string.h>
8
#include <stdlib.h>
9
#include <math.h>
10
11
/* Copyright (C) 2003-2007 Shay Green. This module is free software; you
12
can redistribute it and/or modify it under the terms of the GNU Lesser
13
General Public License as published by the Free Software Foundation; either
14
version 2.1 of the License, or (at your option) any later version. This
15
module is distributed in the hope that it will be useful, but WITHOUT ANY
16
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
18
details. You should have received a copy of the GNU Lesser General Public
19
License along with this module; if not, write to the Free Software Foundation,
20
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
21
22
// TODO: use scoped for variables in treble_eq()
23
24
#ifdef BLARGG_ENABLE_OPTIMIZER
25
#include BLARGG_ENABLE_OPTIMIZER
26
#endif
27
28
int const silent_buf_size = 1; // size used for Silent_Blip_Buffer
29
30
Blip_Buffer::Blip_Buffer()
31
{
32
factor_ = (blip_ulong)LONG_MAX;
33
buffer_ = 0;
34
buffer_size_ = 0;
35
sample_rate_ = 0;
36
bass_shift_ = 0;
37
clock_rate_ = 0;
38
bass_freq_ = 16;
39
length_ = 0;
40
41
// assumptions code makes about implementation-defined features
42
#ifndef NDEBUG
43
// right shift of negative value preserves sign
44
buf_t_ i = -0x7FFFFFFE;
45
assert( (i >> 1) == -0x3FFFFFFF );
46
47
// casting to short truncates to 16 bits and sign-extends
48
i = 0x18000;
49
assert( (short) i == -0x8000 );
50
#endif
51
52
clear();
53
}
54
55
Blip_Buffer::~Blip_Buffer()
56
{
57
if ( buffer_size_ != silent_buf_size )
58
free( buffer_ );
59
}
60
61
Silent_Blip_Buffer::Silent_Blip_Buffer()
62
{
63
factor_ = 0;
64
buffer_ = buf;
65
buffer_size_ = silent_buf_size;
66
clear();
67
}
68
69
void Blip_Buffer::clear( int entire_buffer )
70
{
71
offset_ = 0;
72
reader_accum_ = 0;
73
modified_ = 0;
74
if ( buffer_ )
75
{
76
long count = (entire_buffer ? buffer_size_ : samples_avail());
77
memset( buffer_, 0, (count + blip_buffer_extra_) * sizeof (buf_t_) );
78
}
79
}
80
81
Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int msec )
82
{
83
if ( buffer_size_ == silent_buf_size )
84
{
85
assert( 0 );
86
return "Internal (tried to resize Silent_Blip_Buffer)";
87
}
88
89
// start with maximum length that resampled time can represent
90
long new_size = (ULONG_MAX >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 64;
91
if ( msec != blip_max_length )
92
{
93
long s = (new_rate * (msec + 1) + 999) / 1000;
94
if ( s < new_size )
95
new_size = s;
96
else
97
assert( 0 ); // fails if requested buffer length exceeds limit
98
}
99
100
if ( buffer_size_ != new_size )
101
{
102
void* p = realloc( buffer_, (new_size + blip_buffer_extra_) * sizeof *buffer_ );
103
if ( !p )
104
return "Out of memory";
105
buffer_ = (buf_t_*) p;
106
}
107
108
buffer_size_ = (int)new_size;
109
assert( buffer_size_ != silent_buf_size ); // size should never happen to match this
110
111
// update things based on the sample rate
112
sample_rate_ = new_rate;
113
length_ = (int)(new_size * 1000 / new_rate - 1);
114
if ( msec )
115
assert( length_ == msec ); // ensure length is same as that passed in
116
117
// update these since they depend on sample rate
118
if ( clock_rate_ )
119
clock_rate( clock_rate_ );
120
bass_freq( bass_freq_ );
121
122
clear();
123
124
return 0; // success
125
}
126
127
blip_resampled_time_t Blip_Buffer::clock_rate_factor( long rate ) const
128
{
129
double ratio = (double) sample_rate_ / rate;
130
blip_long factor = (blip_long) floor( ratio * (1L << BLIP_BUFFER_ACCURACY) + 0.5 );
131
assert( factor > 0 || !sample_rate_ ); // fails if clock/output ratio is too large
132
return (blip_resampled_time_t) factor;
133
}
134
135
void Blip_Buffer::bass_freq( int freq )
136
{
137
bass_freq_ = freq;
138
int shift = 31;
139
if ( freq > 0 )
140
{
141
shift = 13;
142
long f = (freq << 16) / sample_rate_;
143
while ( (f >>= 1) && --shift ) { }
144
}
145
bass_shift_ = shift;
146
}
147
148
void Blip_Buffer::end_frame( blip_time_t t )
149
{
150
offset_ += t * factor_;
151
assert( samples_avail() <= (long) buffer_size_ ); // fails if time is past end of buffer
152
}
153
154
long Blip_Buffer::count_samples( blip_time_t t ) const
155
{
156
blip_resampled_time_t last_sample = resampled_time( t ) >> BLIP_BUFFER_ACCURACY;
157
blip_resampled_time_t first_sample = offset_ >> BLIP_BUFFER_ACCURACY;
158
return long (last_sample - first_sample);
159
}
160
161
blip_time_t Blip_Buffer::count_clocks( long count ) const
162
{
163
if ( !factor_ )
164
{
165
assert( 0 ); // sample rate and clock rates must be set first
166
return 0;
167
}
168
169
if ( count > buffer_size_ )
170
count = buffer_size_;
171
blip_resampled_time_t time = (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
172
return (blip_time_t) ((time - offset_ + factor_ - 1) / factor_);
173
}
174
175
void Blip_Buffer::remove_samples( long count )
176
{
177
if ( count )
178
{
179
remove_silence( count );
180
181
// copy remaining samples to beginning and clear old samples
182
long remain = samples_avail() + blip_buffer_extra_;
183
memmove( buffer_, buffer_ + count, remain * sizeof *buffer_ );
184
memset( buffer_ + remain, 0, count * sizeof *buffer_ );
185
}
186
}
187
188
// Blip_Synth_
189
190
Blip_Synth_Fast_::Blip_Synth_Fast_()
191
{
192
buf = 0;
193
last_amp = 0;
194
delta_factor = 0;
195
}
196
197
void Blip_Synth_Fast_::volume_unit( double new_unit )
198
{
199
delta_factor = int (new_unit * (1L << blip_sample_bits) + 0.5);
200
}
201
202
#if !BLIP_BUFFER_FAST
203
204
Blip_Synth_::Blip_Synth_( short* p, int w ) :
205
impulses( p ),
206
width( w )
207
{
208
volume_unit_ = 0.0;
209
kernel_unit = 0;
210
buf = 0;
211
last_amp = 0;
212
delta_factor = 0;
213
}
214
215
#undef PI
216
#define PI 3.1415926535897932384626433832795029
217
218
static void gen_sinc( float* out, int count, double oversample, double treble, double cutoff )
219
{
220
if ( cutoff >= 0.999 )
221
cutoff = 0.999;
222
223
if ( treble < -300.0 )
224
treble = -300.0;
225
if ( treble > 5.0 )
226
treble = 5.0;
227
228
double const maxh = 4096.0;
229
double const rolloff = pow( 10.0, 1.0 / (maxh * 20.0) * treble / (1.0 - cutoff) );
230
double const pow_a_n = pow( rolloff, maxh - maxh * cutoff );
231
double const to_angle = PI / 2 / maxh / oversample;
232
for ( int i = 0; i < count; i++ )
233
{
234
double angle = ((i - count) * 2 + 1) * to_angle;
235
double c = rolloff * cos( (maxh - 1.0) * angle ) - cos( maxh * angle );
236
double cos_nc_angle = cos( maxh * cutoff * angle );
237
double cos_nc1_angle = cos( (maxh * cutoff - 1.0) * angle );
238
double cos_angle = cos( angle );
239
240
c = c * pow_a_n - rolloff * cos_nc1_angle + cos_nc_angle;
241
double d = 1.0 + rolloff * (rolloff - cos_angle - cos_angle);
242
double b = 2.0 - cos_angle - cos_angle;
243
double a = 1.0 - cos_angle - cos_nc_angle + cos_nc1_angle;
244
245
out [i] = (float) ((a * d + c * b) / (b * d)); // a / b + c / d
246
}
247
}
248
249
void blip_eq_t::generate( float* out, int count ) const
250
{
251
// lower cutoff freq for narrow kernels with their wider transition band
252
// (8 points->1.49, 16 points->1.15)
253
double oversample = blip_res * 2.25 / count + 0.85;
254
double half_rate = sample_rate * 0.5;
255
if ( cutoff_freq )
256
oversample = half_rate / cutoff_freq;
257
double cutoff = rolloff_freq * oversample / half_rate;
258
259
gen_sinc( out, count, blip_res * oversample, treble, cutoff );
260
261
// apply (half of) hamming window
262
double to_fraction = PI / (count - 1);
263
for ( int i = count; i--; )
264
out [i] *= 0.54f - 0.46f * (float) cos( i * to_fraction );
265
}
266
267
void Blip_Synth_::adjust_impulse()
268
{
269
// sum pairs for each phase and add error correction to end of first half
270
int const size = impulses_size();
271
for ( int p = blip_res; p-- >= blip_res / 2; )
272
{
273
int p2 = blip_res - 2 - p;
274
long error = kernel_unit;
275
for ( int i = 1; i < size; i += blip_res )
276
{
277
error -= impulses [i + p ];
278
error -= impulses [i + p2];
279
}
280
if ( p == p2 )
281
error /= 2; // phase = 0.5 impulse uses same half for both sides
282
impulses [size - blip_res + p] += (short) error;
283
//printf( "error: %ld\n", error );
284
}
285
286
//for ( int i = blip_res; i--; printf( "\n" ) )
287
// for ( int j = 0; j < width / 2; j++ )
288
// printf( "%5ld,", impulses [j * blip_res + i + 1] );
289
}
290
291
void Blip_Synth_::treble_eq( blip_eq_t const& eq )
292
{
293
float fimpulse [blip_res / 2 * (blip_widest_impulse_ - 1) + blip_res * 2];
294
295
int const half_size = blip_res / 2 * (width - 1);
296
eq.generate( &fimpulse [blip_res], half_size );
297
298
int i;
299
300
// need mirror slightly past center for calculation
301
for ( i = blip_res; i--; )
302
fimpulse [blip_res + half_size + i] = fimpulse [blip_res + half_size - 1 - i];
303
304
// starts at 0
305
for ( i = 0; i < blip_res; i++ )
306
fimpulse [i] = 0.0f;
307
308
// find rescale factor
309
double total = 0.0;
310
for ( i = 0; i < half_size; i++ )
311
total += fimpulse [blip_res + i];
312
313
//double const base_unit = 44800.0 - 128 * 18; // allows treble up to +0 dB
314
//double const base_unit = 37888.0; // allows treble to +5 dB
315
double const base_unit = 32768.0; // necessary for blip_unscaled to work
316
double rescale = base_unit / 2 / total;
317
kernel_unit = (long) base_unit;
318
319
// integrate, first difference, rescale, convert to int
320
double sum = 0.0;
321
double next = 0.0;
322
int const size = this->impulses_size();
323
for ( i = 0; i < size; i++ )
324
{
325
impulses [i] = (short) (int) floor( (next - sum) * rescale + 0.5 );
326
sum += fimpulse [i];
327
next += fimpulse [i + blip_res];
328
}
329
adjust_impulse();
330
331
// volume might require rescaling
332
double vol = volume_unit_;
333
if ( vol )
334
{
335
volume_unit_ = 0.0;
336
volume_unit( vol );
337
}
338
}
339
340
void Blip_Synth_::volume_unit( double new_unit )
341
{
342
if ( new_unit != volume_unit_ )
343
{
344
// use default eq if it hasn't been set yet
345
if ( !kernel_unit )
346
treble_eq( -8.0 );
347
348
volume_unit_ = new_unit;
349
double factor = new_unit * (1L << blip_sample_bits) / kernel_unit;
350
351
if ( factor > 0.0 )
352
{
353
int shift = 0;
354
355
// if unit is really small, might need to attenuate kernel
356
while ( factor < 2.0 )
357
{
358
shift++;
359
factor *= 2.0;
360
}
361
362
if ( shift )
363
{
364
kernel_unit >>= shift;
365
assert( kernel_unit > 0 ); // fails if volume unit is too low
366
367
// keep values positive to avoid round-towards-zero of sign-preserving
368
// right shift for negative values
369
long offset = 0x8000 + (1 << (shift - 1));
370
long offset2 = 0x8000 >> shift;
371
for ( int i = impulses_size(); i--; )
372
impulses [i] = (short) (int) (((impulses [i] + offset) >> shift) - offset2);
373
adjust_impulse();
374
}
375
}
376
delta_factor = (int) floor( factor + 0.5 );
377
//printf( "delta_factor: %d, kernel_unit: %d\n", delta_factor, kernel_unit );
378
}
379
}
380
#endif
381
382
long Blip_Buffer::read_samples( blip_sample_t* out_, long max_samples, int stereo )
383
{
384
long count = samples_avail();
385
if ( count > max_samples )
386
count = max_samples;
387
388
if ( count )
389
{
390
int const bass = BLIP_READER_BASS( *this );
391
BLIP_READER_BEGIN( reader, *this );
392
BLIP_READER_ADJ_( reader, count );
393
blip_sample_t* BLIP_RESTRICT out = out_ + count;
394
blip_long offset = (blip_long) -count;
395
396
if ( !stereo )
397
{
398
do
399
{
400
blip_long s = BLIP_READER_READ( reader );
401
BLIP_READER_NEXT_IDX_( reader, bass, offset );
402
BLIP_CLAMP( s, s );
403
out [offset] = (blip_sample_t) s;
404
}
405
while ( ++offset );
406
}
407
else
408
{
409
do
410
{
411
blip_long s = BLIP_READER_READ( reader );
412
BLIP_READER_NEXT_IDX_( reader, bass, offset );
413
BLIP_CLAMP( s, s );
414
out [offset * 2] = (blip_sample_t) s;
415
}
416
while ( ++offset );
417
}
418
419
BLIP_READER_END( reader, *this );
420
421
remove_samples( count );
422
}
423
return count;
424
}
425
426
void Blip_Buffer::mix_samples( blip_sample_t const* in, long count )
427
{
428
if ( buffer_size_ == silent_buf_size )
429
{
430
assert( 0 );
431
return;
432
}
433
434
buf_t_* out = buffer_ + (offset_ >> BLIP_BUFFER_ACCURACY) + blip_widest_impulse_ / 2;
435
436
int const sample_shift = blip_sample_bits - 16;
437
int prev = 0;
438
while ( count-- )
439
{
440
blip_long s = (blip_long) *in++ << sample_shift;
441
*out += s - prev;
442
prev = s;
443
++out;
444
}
445
*out -= prev;
446
}
447
448
void Blip_Buffer::save_state( blip_buffer_state_t* out )
449
{
450
assert( samples_avail() == 0 );
451
out->offset_ = offset_;
452
out->reader_accum_ = reader_accum_;
453
memcpy( out->buf, &buffer_ [offset_ >> BLIP_BUFFER_ACCURACY], sizeof out->buf );
454
}
455
456
void Blip_Buffer::load_state( blip_buffer_state_t const& in )
457
{
458
clear( false );
459
460
offset_ = in.offset_;
461
reader_accum_ = in.reader_accum_;
462
memcpy( buffer_, in.buf, sizeof in.buf );
463
}
464
465