Blip_Buffer.h (18126B)
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 18typedef blip_long blip_time_t; 19 20// Output samples are 16-bit signed, with a range of -32768 to 32767 21typedef short blip_sample_t; 22enum { blip_sample_max = 32767 }; 23 24struct blip_buffer_state_t; 25 26class Blip_Buffer { 27public: 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; 112public: 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 ); } 120private: 121 // noncopyable 122 Blip_Buffer( const Blip_Buffer& ); 123 Blip_Buffer& operator = ( const Blip_Buffer& ); 124public: 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_; 132private: 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. 199const int blip_med_quality = 8; 200const int blip_good_quality = 12; 201const 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). 206template<int quality,int range> 207class Blip_Synth { 208public: 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 242private: 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]; 249public: 250 Blip_Synth() : impl( impulses, quality ) { } 251#endif 252}; 253 254// Low-pass equalization parameters 255class blip_eq_t { 256public: 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 264private: 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 273int 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. 277class Silent_Blip_Buffer : public Blip_Buffer { 278 buf_t_ buf [blip_buffer_extra_ + 1]; 279public: 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 306int 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 327blip_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 341const long blip_unscaled = 65535; 342const int blip_low_quality = blip_med_quality; 343const 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 ) 353class Blip_Reader { 354public: 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; } 360private: 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 376struct 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 389template<int quality,int range> 390inline 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 502template<int quality,int range> 503#if BLIP_BUFFER_FAST 504 inline 505#endif 506void 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 511template<int quality,int range> 512#if BLIP_BUFFER_FAST 513 inline 514#endif 515void 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 522inline blip_eq_t::blip_eq_t( double t ) : 523 treble( t ), rolloff_freq( 0 ), sample_rate( 44100 ), cutoff_freq( 0 ) { } 524inline 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 527inline int Blip_Buffer::length() const { return length_; } 528inline long Blip_Buffer::samples_avail() const { return (long) (offset_ >> BLIP_BUFFER_ACCURACY); } 529inline long Blip_Buffer::sample_rate() const { return sample_rate_; } 530inline int Blip_Buffer::output_latency() const { return blip_widest_impulse_ / 2; } 531inline long Blip_Buffer::clock_rate() const { return clock_rate_; } 532inline void Blip_Buffer::clock_rate( long cps ) { factor_ = clock_rate_factor( clock_rate_ = cps ); } 533 534inline 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 541inline 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 548inline blip_ulong Blip_Buffer::unsettled() const 549{ 550 return reader_accum_ >> (blip_sample_bits - 16); 551} 552 553int const blip_max_length = 0; 554int const blip_default_length = 250; // 1/4 second 555 556#endif