Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
folium-app
GitHub Repository: folium-app/Folium
Path: blob/a-new-beginning/Cherry/Core/include/audio/Blip_Buffer.h
2 views
1
// Band-limited sound synthesis buffer
2
3
// Blip_Buffer 0.4.1
4
#ifndef BLIP_BUFFER_H
5
#define BLIP_BUFFER_H
6
7
// internal
8
#include <limits.h>
9
#if INT_MAX < 0x7FFFFFFF || LONG_MAX == 0x7FFFFFFF
10
typedef long blip_long;
11
typedef unsigned long blip_ulong;
12
#else
13
typedef int blip_long;
14
typedef unsigned blip_ulong;
15
#endif
16
17
// Time unit at source clock rate
18
typedef blip_long blip_time_t;
19
20
// Output samples are 16-bit signed, with a range of -32768 to 32767
21
typedef short blip_sample_t;
22
enum { blip_sample_max = 32767 };
23
24
struct blip_buffer_state_t;
25
26
class Blip_Buffer {
27
public:
28
typedef const char* blargg_err_t;
29
30
// Sets output sample rate and buffer length in milliseconds (1/1000 sec, defaults
31
// to 1/4 second) and clears buffer. If there isn't enough memory, leaves buffer
32
// untouched and returns "Out of memory", otherwise returns NULL.
33
blargg_err_t set_sample_rate( long samples_per_sec, int msec_length = 1000 / 4 );
34
35
// Sets number of source time units per second
36
void clock_rate( long clocks_per_sec );
37
38
// Ends current time frame of specified duration and makes its samples available
39
// (along with any still-unread samples) for reading with read_samples(). Begins
40
// a new time frame at the end of the current frame.
41
void end_frame( blip_time_t time );
42
43
// Reads at most 'max_samples' out of buffer into 'dest', removing them from
44
// the buffer. Returns number of samples actually read and removed. If stereo is
45
// true, increments 'dest' one extra time after writing each sample, to allow
46
// easy interleving of two channels into a stereo output buffer.
47
long read_samples( blip_sample_t* dest, long max_samples, int stereo = 0 );
48
49
// Additional features
50
51
// Removes all available samples and clear buffer to silence. If 'entire_buffer' is
52
// false, just clears out any samples waiting rather than the entire buffer.
53
void clear( int entire_buffer = 1 );
54
55
// Number of samples available for reading with read_samples()
56
long samples_avail() const;
57
58
// Removes 'count' samples from those waiting to be read
59
void remove_samples( long count );
60
61
// Sets frequency high-pass filter frequency, where higher values reduce bass more
62
void bass_freq( int frequency );
63
64
// Current output sample rate
65
long sample_rate() const;
66
67
// Length of buffer in milliseconds
68
int length() const;
69
70
// Number of source time units per second
71
long clock_rate() const;
72
73
// Experimental features
74
75
// Saves state, including high-pass filter and tails of last deltas.
76
// All samples must have been read from buffer before calling this.
77
void save_state( blip_buffer_state_t* out );
78
79
// Loads state. State must have been saved from Blip_Buffer with same
80
// settings during same run of program. States can NOT be stored on disk.
81
// Clears buffer before loading state.
82
void load_state( blip_buffer_state_t const& in );
83
84
// Number of samples delay from synthesis to samples read out
85
int output_latency() const;
86
87
// Counts number of clocks needed until 'count' samples will be available.
88
// If buffer can't even hold 'count' samples, returns number of clocks until
89
// buffer becomes full.
90
blip_time_t count_clocks( long count ) const;
91
92
// Number of raw samples that can be mixed within frame of specified duration.
93
long count_samples( blip_time_t duration ) const;
94
95
// Mixes in 'count' samples from 'buf_in'
96
void mix_samples( blip_sample_t const* buf_in, long count );
97
98
99
// Signals that sound has been added to buffer. Could be done automatically in
100
// Blip_Synth, but that would affect performance more, as you can arrange that
101
// this is called only once per time frame rather than for every delta.
102
void set_modified() { modified_ = this; }
103
104
// not documented yet
105
blip_ulong unsettled() const;
106
Blip_Buffer* clear_modified() { Blip_Buffer* b = modified_; modified_ = 0; return b; }
107
void remove_silence( long count );
108
typedef blip_ulong blip_resampled_time_t;
109
blip_resampled_time_t resampled_duration( int t ) const { return t * factor_; }
110
blip_resampled_time_t resampled_time( blip_time_t t ) const { return t * factor_ + offset_; }
111
blip_resampled_time_t clock_rate_factor( long clock_rate ) const;
112
public:
113
Blip_Buffer();
114
~Blip_Buffer();
115
116
// Deprecated
117
typedef blip_resampled_time_t resampled_time_t;
118
blargg_err_t sample_rate( long r ) { return set_sample_rate( r ); }
119
blargg_err_t sample_rate( long r, int msec ) { return set_sample_rate( r, msec ); }
120
private:
121
// noncopyable
122
Blip_Buffer( const Blip_Buffer& );
123
Blip_Buffer& operator = ( const Blip_Buffer& );
124
public:
125
typedef blip_long buf_t_;
126
blip_ulong factor_;
127
blip_resampled_time_t offset_;
128
buf_t_* buffer_;
129
blip_long buffer_size_;
130
blip_long reader_accum_;
131
int bass_shift_;
132
private:
133
long sample_rate_;
134
long clock_rate_;
135
int bass_freq_;
136
int length_;
137
Blip_Buffer* modified_; // non-zero = true (more optimal than using bool, heh)
138
friend class Blip_Reader;
139
};
140
141
#ifdef HAVE_CONFIG_H
142
#include "config.h"
143
#endif
144
145
// Number of bits in resample ratio fraction. Higher values give a more accurate ratio
146
// but reduce maximum buffer size.
147
#ifndef BLIP_BUFFER_ACCURACY
148
#define BLIP_BUFFER_ACCURACY 16
149
#endif
150
151
// Number bits in phase offset. Fewer than 6 bits (64 phase offsets) results in
152
// noticeable broadband noise when synthesizing high frequency square waves.
153
// Affects size of Blip_Synth objects since they store the waveform directly.
154
#ifndef BLIP_PHASE_BITS
155
#if BLIP_BUFFER_FAST
156
#define BLIP_PHASE_BITS 8
157
#else
158
#define BLIP_PHASE_BITS 6
159
#endif
160
#endif
161
162
// Internal
163
typedef blip_ulong blip_resampled_time_t;
164
int const blip_widest_impulse_ = 16;
165
int const blip_buffer_extra_ = blip_widest_impulse_ + 2;
166
int const blip_res = 1 << BLIP_PHASE_BITS;
167
class blip_eq_t;
168
169
class Blip_Synth_Fast_ {
170
public:
171
Blip_Buffer* buf;
172
int last_amp;
173
int delta_factor;
174
175
void volume_unit( double );
176
Blip_Synth_Fast_();
177
void treble_eq( blip_eq_t const& ) { }
178
};
179
180
class Blip_Synth_ {
181
public:
182
Blip_Buffer* buf;
183
int last_amp;
184
int delta_factor;
185
186
void volume_unit( double );
187
Blip_Synth_( short* impulses, int width );
188
void treble_eq( blip_eq_t const& );
189
private:
190
double volume_unit_;
191
short* const impulses;
192
int const width;
193
blip_long kernel_unit;
194
int impulses_size() const { return blip_res / 2 * width + 1; }
195
void adjust_impulse();
196
};
197
198
// Quality level, better = slower. In general, use blip_good_quality.
199
const int blip_med_quality = 8;
200
const int blip_good_quality = 12;
201
const int blip_high_quality = 16;
202
203
// Range specifies the greatest expected change in amplitude. Calculate it
204
// by finding the difference between the maximum and minimum expected
205
// amplitudes (max - min).
206
template<int quality,int range>
207
class Blip_Synth {
208
public:
209
// Sets overall volume of waveform
210
void volume( double v ) { impl.volume_unit( v * (1.0 / (range < 0 ? -range : range)) ); }
211
212
// Configures low-pass filter (see blip_buffer.txt)
213
void treble_eq( blip_eq_t const& eq ) { impl.treble_eq( eq ); }
214
215
// Gets/sets Blip_Buffer used for output
216
Blip_Buffer* output() const { return impl.buf; }
217
void output( Blip_Buffer* b ) { impl.buf = b; impl.last_amp = 0; }
218
219
// Updates amplitude of waveform at given time. Using this requires a separate
220
// Blip_Synth for each waveform.
221
void update( blip_time_t time, int amplitude );
222
223
// Low-level interface
224
225
// Adds an amplitude transition of specified delta, optionally into specified buffer
226
// rather than the one set with output(). Delta can be positive or negative.
227
// The actual change in amplitude is delta * (volume / range)
228
void offset( blip_time_t, int delta, Blip_Buffer* ) const;
229
void offset( blip_time_t t, int delta ) const { offset( t, delta, impl.buf ); }
230
231
// Works directly in terms of fractional output samples. Contact author for more info.
232
void offset_resampled( blip_resampled_time_t, int delta, Blip_Buffer* ) const;
233
234
// Same as offset(), except code is inlined for higher performance
235
void offset_inline( blip_time_t t, int delta, Blip_Buffer* buf ) const {
236
offset_resampled( t * buf->factor_ + buf->offset_, delta, buf );
237
}
238
void offset_inline( blip_time_t t, int delta ) const {
239
offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf );
240
}
241
242
private:
243
#if BLIP_BUFFER_FAST
244
Blip_Synth_Fast_ impl;
245
#else
246
Blip_Synth_ impl;
247
typedef short imp_t;
248
imp_t impulses [blip_res * (quality / 2) + 1];
249
public:
250
Blip_Synth() : impl( impulses, quality ) { }
251
#endif
252
};
253
254
// Low-pass equalization parameters
255
class blip_eq_t {
256
public:
257
// Logarithmic rolloff to treble dB at half sampling rate. Negative values reduce
258
// treble, small positive values (0 to 5.0) increase treble.
259
blip_eq_t( double treble_db = 0 );
260
261
// See blip_buffer.txt
262
blip_eq_t( double treble, long rolloff_freq, long sample_rate, long cutoff_freq = 0 );
263
264
private:
265
double treble;
266
long rolloff_freq;
267
long sample_rate;
268
long cutoff_freq;
269
void generate( float* out, int count ) const;
270
friend class Blip_Synth_;
271
};
272
273
int const blip_sample_bits = 30;
274
275
// Dummy Blip_Buffer to direct sound output to, for easy muting without
276
// having to stop sound code.
277
class Silent_Blip_Buffer : public Blip_Buffer {
278
buf_t_ buf [blip_buffer_extra_ + 1];
279
public:
280
// The following cannot be used (an assertion will fail if attempted):
281
blargg_err_t set_sample_rate( long samples_per_sec, int msec_length );
282
blip_time_t count_clocks( long count ) const;
283
void mix_samples( blip_sample_t const* buf, long count );
284
285
Silent_Blip_Buffer();
286
};
287
288
#if __GNUC__ >= 3 || _MSC_VER >= 1100
289
#define BLIP_RESTRICT __restrict
290
#else
291
#define BLIP_RESTRICT
292
#endif
293
294
// Optimized reading from Blip_Buffer, for use in custom sample output
295
296
// Begins reading from buffer. Name should be unique to the current block.
297
#define BLIP_READER_BEGIN( name, blip_buffer ) \
298
const Blip_Buffer::buf_t_* BLIP_RESTRICT name##_reader_buf = (blip_buffer).buffer_;\
299
blip_long name##_reader_accum = (blip_buffer).reader_accum_
300
301
// Gets value to pass to BLIP_READER_NEXT()
302
#define BLIP_READER_BASS( blip_buffer ) ((blip_buffer).bass_shift_)
303
304
// Constant value to use instead of BLIP_READER_BASS(), for slightly more optimal
305
// code at the cost of having no bass control
306
int const blip_reader_default_bass = 9;
307
308
// Current sample
309
#define BLIP_READER_READ( name ) (name##_reader_accum >> (blip_sample_bits - 16))
310
311
// Current raw sample in full internal resolution
312
#define BLIP_READER_READ_RAW( name ) (name##_reader_accum)
313
314
// Advances to next sample
315
#define BLIP_READER_NEXT( name, bass ) \
316
(void) (name##_reader_accum += *name##_reader_buf++ - (name##_reader_accum >> (bass)))
317
318
// Ends reading samples from buffer. The number of samples read must now be removed
319
// using Blip_Buffer::remove_samples().
320
#define BLIP_READER_END( name, blip_buffer ) \
321
(void) ((blip_buffer).reader_accum_ = name##_reader_accum)
322
323
324
// experimental
325
#define BLIP_READER_ADJ_( name, offset ) (name##_reader_buf += offset)
326
327
blip_long const blip_reader_idx_factor = sizeof (Blip_Buffer::buf_t_);
328
329
#define BLIP_READER_NEXT_IDX_( name, bass, idx ) {\
330
name##_reader_accum -= name##_reader_accum >> (bass);\
331
name##_reader_accum += name##_reader_buf [(idx)];\
332
}
333
334
#define BLIP_READER_NEXT_RAW_IDX_( name, bass, idx ) {\
335
name##_reader_accum -= name##_reader_accum >> (bass);\
336
name##_reader_accum +=\
337
*(Blip_Buffer::buf_t_ const*) ((char const*) name##_reader_buf + (idx));\
338
}
339
340
// Compatibility with older version
341
const long blip_unscaled = 65535;
342
const int blip_low_quality = blip_med_quality;
343
const int blip_best_quality = blip_high_quality;
344
345
// Deprecated; use BLIP_READER macros as follows:
346
// Blip_Reader r; r.begin( buf ); -> BLIP_READER_BEGIN( r, buf );
347
// int bass = r.begin( buf ) -> BLIP_READER_BEGIN( r, buf ); int bass = BLIP_READER_BASS( buf );
348
// r.read() -> BLIP_READER_READ( r )
349
// r.read_raw() -> BLIP_READER_READ_RAW( r )
350
// r.next( bass ) -> BLIP_READER_NEXT( r, bass )
351
// r.next() -> BLIP_READER_NEXT( r, blip_reader_default_bass )
352
// r.end( buf ) -> BLIP_READER_END( r, buf )
353
class Blip_Reader {
354
public:
355
int begin( Blip_Buffer& );
356
blip_long read() const { return accum >> (blip_sample_bits - 16); }
357
blip_long read_raw() const { return accum; }
358
void next( int bass_shift = 9 ) { accum += *buf++ - (accum >> bass_shift); }
359
void end( Blip_Buffer& b ) { b.reader_accum_ = accum; }
360
private:
361
const Blip_Buffer::buf_t_* buf;
362
blip_long accum;
363
};
364
365
#if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \
366
defined (__x86_64__) || defined (__ia64__) || defined (__i386__)
367
#define BLIP_CLAMP_( in ) in < -0x8000 || 0x7FFF < in
368
#else
369
#define BLIP_CLAMP_( in ) (blip_sample_t) in != in
370
#endif
371
372
// Clamp sample to blip_sample_t range
373
#define BLIP_CLAMP( sample, out )\
374
{ if ( BLIP_CLAMP_( (sample) ) ) (out) = ((sample) >> 24) ^ 0x7FFF; }
375
376
struct blip_buffer_state_t
377
{
378
blip_resampled_time_t offset_;
379
blip_long reader_accum_;
380
blip_long buf [blip_buffer_extra_];
381
};
382
383
// End of public interface
384
385
#ifndef assert
386
#include <assert.h>
387
#endif
388
389
template<int quality,int range>
390
inline void Blip_Synth<quality,range>::offset_resampled( blip_resampled_time_t time,
391
int delta, Blip_Buffer* blip_buf ) const
392
{
393
// If this assertion fails, it means that an attempt was made to add a delta
394
// at a negative time or past the end of the buffer.
395
assert( (blip_long) (time >> BLIP_BUFFER_ACCURACY) < blip_buf->buffer_size_ );
396
397
delta *= impl.delta_factor;
398
blip_long* BLIP_RESTRICT buf = blip_buf->buffer_ + (time >> BLIP_BUFFER_ACCURACY);
399
int phase = (int) (time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS) & (blip_res - 1));
400
401
#if BLIP_BUFFER_FAST
402
blip_long left = buf [0] + delta;
403
404
// Kind of crappy, but doing shift after multiply results in overflow.
405
// Alternate way of delaying multiply by delta_factor results in worse
406
// sub-sample resolution.
407
blip_long right = (delta >> BLIP_PHASE_BITS) * phase;
408
left -= right;
409
right += buf [1];
410
411
buf [0] = left;
412
buf [1] = right;
413
#else
414
415
int const fwd = (blip_widest_impulse_ - quality) / 2;
416
int const rev = fwd + quality - 2;
417
int const mid = quality / 2 - 1;
418
419
imp_t const* BLIP_RESTRICT imp = impulses + blip_res - phase;
420
421
#if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \
422
defined (__x86_64__) || defined (__ia64__) || defined (__i386__)
423
424
// this straight forward version gave in better code on GCC for x86
425
426
#define ADD_IMP( out, in ) \
427
buf [out] += (blip_long) imp [blip_res * (in)] * delta
428
429
#define BLIP_FWD( i ) {\
430
ADD_IMP( fwd + i, i );\
431
ADD_IMP( fwd + 1 + i, i + 1 );\
432
}
433
#define BLIP_REV( r ) {\
434
ADD_IMP( rev - r, r + 1 );\
435
ADD_IMP( rev + 1 - r, r );\
436
}
437
438
BLIP_FWD( 0 )
439
if ( quality > 8 ) BLIP_FWD( 2 )
440
if ( quality > 12 ) BLIP_FWD( 4 )
441
{
442
ADD_IMP( fwd + mid - 1, mid - 1 );
443
ADD_IMP( fwd + mid , mid );
444
imp = impulses + phase;
445
}
446
if ( quality > 12 ) BLIP_REV( 6 )
447
if ( quality > 8 ) BLIP_REV( 4 )
448
BLIP_REV( 2 )
449
450
ADD_IMP( rev , 1 );
451
ADD_IMP( rev + 1, 0 );
452
453
#undef ADD_IMP
454
455
#else
456
457
// for RISC processors, help compiler by reading ahead of writes
458
459
#define BLIP_FWD( i ) {\
460
blip_long t0 = i0 * delta + buf [fwd + i];\
461
blip_long t1 = imp [blip_res * (i + 1)] * delta + buf [fwd + 1 + i];\
462
i0 = imp [blip_res * (i + 2)];\
463
buf [fwd + i] = t0;\
464
buf [fwd + 1 + i] = t1;\
465
}
466
#define BLIP_REV( r ) {\
467
blip_long t0 = i0 * delta + buf [rev - r];\
468
blip_long t1 = imp [blip_res * r] * delta + buf [rev + 1 - r];\
469
i0 = imp [blip_res * (r - 1)];\
470
buf [rev - r] = t0;\
471
buf [rev + 1 - r] = t1;\
472
}
473
474
blip_long i0 = *imp;
475
BLIP_FWD( 0 )
476
if ( quality > 8 ) BLIP_FWD( 2 )
477
if ( quality > 12 ) BLIP_FWD( 4 )
478
{
479
blip_long t0 = i0 * delta + buf [fwd + mid - 1];
480
blip_long t1 = imp [blip_res * mid] * delta + buf [fwd + mid ];
481
imp = impulses + phase;
482
i0 = imp [blip_res * mid];
483
buf [fwd + mid - 1] = t0;
484
buf [fwd + mid ] = t1;
485
}
486
if ( quality > 12 ) BLIP_REV( 6 )
487
if ( quality > 8 ) BLIP_REV( 4 )
488
BLIP_REV( 2 )
489
490
blip_long t0 = i0 * delta + buf [rev ];
491
blip_long t1 = *imp * delta + buf [rev + 1];
492
buf [rev ] = t0;
493
buf [rev + 1] = t1;
494
#endif
495
496
#endif
497
}
498
499
#undef BLIP_FWD
500
#undef BLIP_REV
501
502
template<int quality,int range>
503
#if BLIP_BUFFER_FAST
504
inline
505
#endif
506
void Blip_Synth<quality,range>::offset( blip_time_t t, int delta, Blip_Buffer* buf ) const
507
{
508
offset_resampled( t * buf->factor_ + buf->offset_, delta, buf );
509
}
510
511
template<int quality,int range>
512
#if BLIP_BUFFER_FAST
513
inline
514
#endif
515
void Blip_Synth<quality,range>::update( blip_time_t t, int amp )
516
{
517
int delta = amp - impl.last_amp;
518
impl.last_amp = amp;
519
offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf );
520
}
521
522
inline blip_eq_t::blip_eq_t( double t ) :
523
treble( t ), rolloff_freq( 0 ), sample_rate( 44100 ), cutoff_freq( 0 ) { }
524
inline blip_eq_t::blip_eq_t( double t, long rf, long sr, long cf ) :
525
treble( t ), rolloff_freq( rf ), sample_rate( sr ), cutoff_freq( cf ) { }
526
527
inline int Blip_Buffer::length() const { return length_; }
528
inline long Blip_Buffer::samples_avail() const { return (long) (offset_ >> BLIP_BUFFER_ACCURACY); }
529
inline long Blip_Buffer::sample_rate() const { return sample_rate_; }
530
inline int Blip_Buffer::output_latency() const { return blip_widest_impulse_ / 2; }
531
inline long Blip_Buffer::clock_rate() const { return clock_rate_; }
532
inline void Blip_Buffer::clock_rate( long cps ) { factor_ = clock_rate_factor( clock_rate_ = cps ); }
533
534
inline int Blip_Reader::begin( Blip_Buffer& blip_buf )
535
{
536
buf = blip_buf.buffer_;
537
accum = blip_buf.reader_accum_;
538
return blip_buf.bass_shift_;
539
}
540
541
inline void Blip_Buffer::remove_silence( long count )
542
{
543
// fails if you try to remove more samples than available
544
assert( count <= samples_avail() );
545
offset_ -= (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
546
}
547
548
inline blip_ulong Blip_Buffer::unsettled() const
549
{
550
return reader_accum_ >> (blip_sample_bits - 16);
551
}
552
553
int const blip_max_length = 0;
554
int const blip_default_length = 250; // 1/4 second
555
556
#endif
557
558