Mercurial > vba-clojure
diff src/apu/Blip_Buffer.h @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/apu/Blip_Buffer.h Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,556 @@ 1.4 +// Band-limited sound synthesis buffer 1.5 + 1.6 +// Blip_Buffer 0.4.1 1.7 +#ifndef BLIP_BUFFER_H 1.8 +#define BLIP_BUFFER_H 1.9 + 1.10 + // internal 1.11 + #include <limits.h> 1.12 + #if INT_MAX < 0x7FFFFFFF || LONG_MAX == 0x7FFFFFFF 1.13 + typedef long blip_long; 1.14 + typedef unsigned long blip_ulong; 1.15 + #else 1.16 + typedef int blip_long; 1.17 + typedef unsigned blip_ulong; 1.18 + #endif 1.19 + 1.20 +// Time unit at source clock rate 1.21 +typedef blip_long blip_time_t; 1.22 + 1.23 +// Output samples are 16-bit signed, with a range of -32768 to 32767 1.24 +typedef short blip_sample_t; 1.25 +enum { blip_sample_max = 32767 }; 1.26 + 1.27 +struct blip_buffer_state_t; 1.28 + 1.29 +class Blip_Buffer { 1.30 +public: 1.31 + typedef const char* blargg_err_t; 1.32 + 1.33 + // Sets output sample rate and buffer length in milliseconds (1/1000 sec, defaults 1.34 + // to 1/4 second) and clears buffer. If there isn't enough memory, leaves buffer 1.35 + // untouched and returns "Out of memory", otherwise returns NULL. 1.36 + blargg_err_t set_sample_rate( long samples_per_sec, int msec_length = 1000 / 4 ); 1.37 + 1.38 + // Sets number of source time units per second 1.39 + void clock_rate( long clocks_per_sec ); 1.40 + 1.41 + // Ends current time frame of specified duration and makes its samples available 1.42 + // (along with any still-unread samples) for reading with read_samples(). Begins 1.43 + // a new time frame at the end of the current frame. 1.44 + void end_frame( blip_time_t time ); 1.45 + 1.46 + // Reads at most 'max_samples' out of buffer into 'dest', removing them from from 1.47 + // the buffer. Returns number of samples actually read and removed. If stereo is 1.48 + // true, increments 'dest' one extra time after writing each sample, to allow 1.49 + // easy interleving of two channels into a stereo output buffer. 1.50 + long read_samples( blip_sample_t* dest, long max_samples, int stereo = 0 ); 1.51 + 1.52 +// Additional features 1.53 + 1.54 + // Removes all available samples and clear buffer to silence. If 'entire_buffer' is 1.55 + // false, just clears out any samples waiting rather than the entire buffer. 1.56 + void clear( int entire_buffer = 1 ); 1.57 + 1.58 + // Number of samples available for reading with read_samples() 1.59 + long samples_avail() const; 1.60 + 1.61 + // Removes 'count' samples from those waiting to be read 1.62 + void remove_samples( long count ); 1.63 + 1.64 + // Sets frequency high-pass filter frequency, where higher values reduce bass more 1.65 + void bass_freq( int frequency ); 1.66 + 1.67 + // Current output sample rate 1.68 + long sample_rate() const; 1.69 + 1.70 + // Length of buffer in milliseconds 1.71 + int length() const; 1.72 + 1.73 + // Number of source time units per second 1.74 + long clock_rate() const; 1.75 + 1.76 +// Experimental features 1.77 + 1.78 + // Saves state, including high-pass filter and tails of last deltas. 1.79 + // All samples must have been read from buffer before calling this. 1.80 + void save_state( blip_buffer_state_t* out ); 1.81 + 1.82 + // Loads state. State must have been saved from Blip_Buffer with same 1.83 + // settings during same run of program. States can NOT be stored on disk. 1.84 + // Clears buffer before loading state. 1.85 + void load_state( blip_buffer_state_t const& in ); 1.86 + 1.87 + // Number of samples delay from synthesis to samples read out 1.88 + int output_latency() const; 1.89 + 1.90 + // Counts number of clocks needed until 'count' samples will be available. 1.91 + // If buffer can't even hold 'count' samples, returns number of clocks until 1.92 + // buffer becomes full. 1.93 + blip_time_t count_clocks( long count ) const; 1.94 + 1.95 + // Number of raw samples that can be mixed within frame of specified duration. 1.96 + long count_samples( blip_time_t duration ) const; 1.97 + 1.98 + // Mixes in 'count' samples from 'buf_in' 1.99 + void mix_samples( blip_sample_t const* buf_in, long count ); 1.100 + 1.101 + 1.102 + // Signals that sound has been added to buffer. Could be done automatically in 1.103 + // Blip_Synth, but that would affect performance more, as you can arrange that 1.104 + // this is called only once per time frame rather than for every delta. 1.105 + void set_modified() { modified_ = this; } 1.106 + 1.107 + // not documented yet 1.108 + blip_ulong unsettled() const; 1.109 + Blip_Buffer* clear_modified() { Blip_Buffer* b = modified_; modified_ = 0; return b; } 1.110 + void remove_silence( long count ); 1.111 + typedef blip_ulong blip_resampled_time_t; 1.112 + blip_resampled_time_t resampled_duration( int t ) const { return t * factor_; } 1.113 + blip_resampled_time_t resampled_time( blip_time_t t ) const { return t * factor_ + offset_; } 1.114 + blip_resampled_time_t clock_rate_factor( long clock_rate ) const; 1.115 +public: 1.116 + Blip_Buffer(); 1.117 + ~Blip_Buffer(); 1.118 + 1.119 + // Deprecated 1.120 + typedef blip_resampled_time_t resampled_time_t; 1.121 + blargg_err_t sample_rate( long r ) { return set_sample_rate( r ); } 1.122 + blargg_err_t sample_rate( long r, int msec ) { return set_sample_rate( r, msec ); } 1.123 +private: 1.124 + // noncopyable 1.125 + Blip_Buffer( const Blip_Buffer& ); 1.126 + Blip_Buffer& operator = ( const Blip_Buffer& ); 1.127 +public: 1.128 + typedef blip_long buf_t_; 1.129 + blip_ulong factor_; 1.130 + blip_resampled_time_t offset_; 1.131 + buf_t_* buffer_; 1.132 + blip_long buffer_size_; 1.133 + blip_long reader_accum_; 1.134 + int bass_shift_; 1.135 +private: 1.136 + long sample_rate_; 1.137 + long clock_rate_; 1.138 + int bass_freq_; 1.139 + int length_; 1.140 + Blip_Buffer* modified_; // non-zero = true (more optimal than using bool, heh) 1.141 + friend class Blip_Reader; 1.142 +}; 1.143 + 1.144 +#ifdef HAVE_CONFIG_H 1.145 + #include "config.h" 1.146 +#endif 1.147 + 1.148 +// Number of bits in resample ratio fraction. Higher values give a more accurate ratio 1.149 +// but reduce maximum buffer size. 1.150 +#ifndef BLIP_BUFFER_ACCURACY 1.151 + #define BLIP_BUFFER_ACCURACY 16 1.152 +#endif 1.153 + 1.154 +// Number bits in phase offset. Fewer than 6 bits (64 phase offsets) results in 1.155 +// noticeable broadband noise when synthesizing high frequency square waves. 1.156 +// Affects size of Blip_Synth objects since they store the waveform directly. 1.157 +#ifndef BLIP_PHASE_BITS 1.158 + #if BLIP_BUFFER_FAST 1.159 + #define BLIP_PHASE_BITS 8 1.160 + #else 1.161 + #define BLIP_PHASE_BITS 6 1.162 + #endif 1.163 +#endif 1.164 + 1.165 + // Internal 1.166 + typedef blip_ulong blip_resampled_time_t; 1.167 + int const blip_widest_impulse_ = 16; 1.168 + int const blip_buffer_extra_ = blip_widest_impulse_ + 2; 1.169 + int const blip_res = 1 << BLIP_PHASE_BITS; 1.170 + class blip_eq_t; 1.171 + 1.172 + class Blip_Synth_Fast_ { 1.173 + public: 1.174 + Blip_Buffer* buf; 1.175 + int last_amp; 1.176 + int delta_factor; 1.177 + 1.178 + void volume_unit( double ); 1.179 + Blip_Synth_Fast_(); 1.180 + void treble_eq( blip_eq_t const& ) { } 1.181 + }; 1.182 + 1.183 + class Blip_Synth_ { 1.184 + public: 1.185 + Blip_Buffer* buf; 1.186 + int last_amp; 1.187 + int delta_factor; 1.188 + 1.189 + void volume_unit( double ); 1.190 + Blip_Synth_( short* impulses, int width ); 1.191 + void treble_eq( blip_eq_t const& ); 1.192 + private: 1.193 + double volume_unit_; 1.194 + short* const impulses; 1.195 + int const width; 1.196 + blip_long kernel_unit; 1.197 + int impulses_size() const { return blip_res / 2 * width + 1; } 1.198 + void adjust_impulse(); 1.199 + }; 1.200 + 1.201 +// Quality level, better = slower. In general, use blip_good_quality. 1.202 +const int blip_med_quality = 8; 1.203 +const int blip_good_quality = 12; 1.204 +const int blip_high_quality = 16; 1.205 + 1.206 +// Range specifies the greatest expected change in amplitude. Calculate it 1.207 +// by finding the difference between the maximum and minimum expected 1.208 +// amplitudes (max - min). 1.209 +template<int quality,int range> 1.210 +class Blip_Synth { 1.211 +public: 1.212 + // Sets overall volume of waveform 1.213 + void volume( double v ) { impl.volume_unit( v * (1.0 / (range < 0 ? -range : range)) ); } 1.214 + 1.215 + // Configures low-pass filter (see blip_buffer.txt) 1.216 + void treble_eq( blip_eq_t const& eq ) { impl.treble_eq( eq ); } 1.217 + 1.218 + // Gets/sets Blip_Buffer used for output 1.219 + Blip_Buffer* output() const { return impl.buf; } 1.220 + void output( Blip_Buffer* b ) { impl.buf = b; impl.last_amp = 0; } 1.221 + 1.222 + // Updates amplitude of waveform at given time. Using this requires a separate 1.223 + // Blip_Synth for each waveform. 1.224 + void update( blip_time_t time, int amplitude ); 1.225 + 1.226 +// Low-level interface 1.227 + 1.228 + // Adds an amplitude transition of specified delta, optionally into specified buffer 1.229 + // rather than the one set with output(). Delta can be positive or negative. 1.230 + // The actual change in amplitude is delta * (volume / range) 1.231 + void offset( blip_time_t, int delta, Blip_Buffer* ) const; 1.232 + void offset( blip_time_t t, int delta ) const { offset( t, delta, impl.buf ); } 1.233 + 1.234 + // Works directly in terms of fractional output samples. Contact author for more info. 1.235 + void offset_resampled( blip_resampled_time_t, int delta, Blip_Buffer* ) const; 1.236 + 1.237 + // Same as offset(), except code is inlined for higher performance 1.238 + void offset_inline( blip_time_t t, int delta, Blip_Buffer* buf ) const { 1.239 + offset_resampled( t * buf->factor_ + buf->offset_, delta, buf ); 1.240 + } 1.241 + void offset_inline( blip_time_t t, int delta ) const { 1.242 + offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf ); 1.243 + } 1.244 + 1.245 +private: 1.246 +#if BLIP_BUFFER_FAST 1.247 + Blip_Synth_Fast_ impl; 1.248 +#else 1.249 + Blip_Synth_ impl; 1.250 + typedef short imp_t; 1.251 + imp_t impulses [blip_res * (quality / 2) + 1]; 1.252 +public: 1.253 + Blip_Synth() : impl( impulses, quality ) { } 1.254 +#endif 1.255 +}; 1.256 + 1.257 +// Low-pass equalization parameters 1.258 +class blip_eq_t { 1.259 +public: 1.260 + // Logarithmic rolloff to treble dB at half sampling rate. Negative values reduce 1.261 + // treble, small positive values (0 to 5.0) increase treble. 1.262 + blip_eq_t( double treble_db = 0 ); 1.263 + 1.264 + // See blip_buffer.txt 1.265 + blip_eq_t( double treble, long rolloff_freq, long sample_rate, long cutoff_freq = 0 ); 1.266 + 1.267 +private: 1.268 + double treble; 1.269 + long rolloff_freq; 1.270 + long sample_rate; 1.271 + long cutoff_freq; 1.272 + void generate( float* out, int count ) const; 1.273 + friend class Blip_Synth_; 1.274 +}; 1.275 + 1.276 +int const blip_sample_bits = 30; 1.277 + 1.278 +// Dummy Blip_Buffer to direct sound output to, for easy muting without 1.279 +// having to stop sound code. 1.280 +class Silent_Blip_Buffer : public Blip_Buffer { 1.281 + buf_t_ buf [blip_buffer_extra_ + 1]; 1.282 +public: 1.283 + // The following cannot be used (an assertion will fail if attempted): 1.284 + blargg_err_t set_sample_rate( long samples_per_sec, int msec_length ); 1.285 + blip_time_t count_clocks( long count ) const; 1.286 + void mix_samples( blip_sample_t const* buf, long count ); 1.287 + 1.288 + Silent_Blip_Buffer(); 1.289 +}; 1.290 + 1.291 + #if __GNUC__ >= 3 || _MSC_VER >= 1400 1.292 + #define BLIP_RESTRICT __restrict 1.293 + #else 1.294 + #define BLIP_RESTRICT 1.295 + #endif 1.296 + 1.297 +// Optimized reading from Blip_Buffer, for use in custom sample output 1.298 + 1.299 +// Begins reading from buffer. Name should be unique to the current block. 1.300 +#define BLIP_READER_BEGIN( name, blip_buffer ) \ 1.301 + const Blip_Buffer::buf_t_* BLIP_RESTRICT name##_reader_buf = (blip_buffer).buffer_;\ 1.302 + blip_long name##_reader_accum = (blip_buffer).reader_accum_ 1.303 + 1.304 +// Gets value to pass to BLIP_READER_NEXT() 1.305 +#define BLIP_READER_BASS( blip_buffer ) ((blip_buffer).bass_shift_) 1.306 + 1.307 +// Constant value to use instead of BLIP_READER_BASS(), for slightly more optimal 1.308 +// code at the cost of having no bass control 1.309 +int const blip_reader_default_bass = 9; 1.310 + 1.311 +// Current sample 1.312 +#define BLIP_READER_READ( name ) (name##_reader_accum >> (blip_sample_bits - 16)) 1.313 + 1.314 +// Current raw sample in full internal resolution 1.315 +#define BLIP_READER_READ_RAW( name ) (name##_reader_accum) 1.316 + 1.317 +// Advances to next sample 1.318 +#define BLIP_READER_NEXT( name, bass ) \ 1.319 + (void) (name##_reader_accum += *name##_reader_buf++ - (name##_reader_accum >> (bass))) 1.320 + 1.321 +// Ends reading samples from buffer. The number of samples read must now be removed 1.322 +// using Blip_Buffer::remove_samples(). 1.323 +#define BLIP_READER_END( name, blip_buffer ) \ 1.324 + (void) ((blip_buffer).reader_accum_ = name##_reader_accum) 1.325 + 1.326 + 1.327 +// experimental 1.328 +#define BLIP_READER_ADJ_( name, offset ) (name##_reader_buf += offset) 1.329 + 1.330 +blip_long const blip_reader_idx_factor = sizeof (Blip_Buffer::buf_t_); 1.331 + 1.332 +#define BLIP_READER_NEXT_IDX_( name, bass, idx ) {\ 1.333 + name##_reader_accum -= name##_reader_accum >> (bass);\ 1.334 + name##_reader_accum += name##_reader_buf [(idx)];\ 1.335 +} 1.336 + 1.337 +#define BLIP_READER_NEXT_RAW_IDX_( name, bass, idx ) {\ 1.338 + name##_reader_accum -= name##_reader_accum >> (bass);\ 1.339 + name##_reader_accum +=\ 1.340 + *(Blip_Buffer::buf_t_ const*) ((char const*) name##_reader_buf + (idx));\ 1.341 +} 1.342 + 1.343 +// Compatibility with older version 1.344 +const long blip_unscaled = 65535; 1.345 +const int blip_low_quality = blip_med_quality; 1.346 +const int blip_best_quality = blip_high_quality; 1.347 + 1.348 +// Deprecated; use BLIP_READER macros as follows: 1.349 +// Blip_Reader r; r.begin( buf ); -> BLIP_READER_BEGIN( r, buf ); 1.350 +// int bass = r.begin( buf ) -> BLIP_READER_BEGIN( r, buf ); int bass = BLIP_READER_BASS( buf ); 1.351 +// r.read() -> BLIP_READER_READ( r ) 1.352 +// r.read_raw() -> BLIP_READER_READ_RAW( r ) 1.353 +// r.next( bass ) -> BLIP_READER_NEXT( r, bass ) 1.354 +// r.next() -> BLIP_READER_NEXT( r, blip_reader_default_bass ) 1.355 +// r.end( buf ) -> BLIP_READER_END( r, buf ) 1.356 +class Blip_Reader { 1.357 +public: 1.358 + int begin( Blip_Buffer& ); 1.359 + blip_long read() const { return accum >> (blip_sample_bits - 16); } 1.360 + blip_long read_raw() const { return accum; } 1.361 + void next( int bass_shift = 9 ) { accum += *buf++ - (accum >> bass_shift); } 1.362 + void end( Blip_Buffer& b ) { b.reader_accum_ = accum; } 1.363 +private: 1.364 + const Blip_Buffer::buf_t_* buf; 1.365 + blip_long accum; 1.366 +}; 1.367 + 1.368 +#if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \ 1.369 + defined (__x86_64__) || defined (__ia64__) || defined (__i386__) 1.370 + #define BLIP_CLAMP_( in ) in < -0x8000 || 0x7FFF < in 1.371 +#else 1.372 + #define BLIP_CLAMP_( in ) (blip_sample_t) in != in 1.373 +#endif 1.374 + 1.375 +// Clamp sample to blip_sample_t range 1.376 +#define BLIP_CLAMP( sample, out )\ 1.377 + { if ( BLIP_CLAMP_( (sample) ) ) (out) = ((sample) >> 24) ^ 0x7FFF; } 1.378 + 1.379 +struct blip_buffer_state_t 1.380 +{ 1.381 + blip_resampled_time_t offset_; 1.382 + blip_long reader_accum_; 1.383 + blip_long buf [blip_buffer_extra_]; 1.384 +}; 1.385 + 1.386 +// End of public interface 1.387 + 1.388 +#ifndef assert 1.389 + #include <assert.h> 1.390 +#endif 1.391 + 1.392 +template<int quality,int range> 1.393 +inline void Blip_Synth<quality,range>::offset_resampled( blip_resampled_time_t time, 1.394 + int delta, Blip_Buffer* blip_buf ) const 1.395 +{ 1.396 + // If this assertion fails, it means that an attempt was made to add a delta 1.397 + // at a negative time or past the end of the buffer. 1.398 + assert( (blip_long) (time >> BLIP_BUFFER_ACCURACY) < blip_buf->buffer_size_ ); 1.399 + 1.400 + delta *= impl.delta_factor; 1.401 + blip_long* BLIP_RESTRICT buf = blip_buf->buffer_ + (time >> BLIP_BUFFER_ACCURACY); 1.402 + int phase = (int) (time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS) & (blip_res - 1)); 1.403 + 1.404 +#if BLIP_BUFFER_FAST 1.405 + blip_long left = buf [0] + delta; 1.406 + 1.407 + // Kind of crappy, but doing shift after multiply results in overflow. 1.408 + // Alternate way of delaying multiply by delta_factor results in worse 1.409 + // sub-sample resolution. 1.410 + blip_long right = (delta >> BLIP_PHASE_BITS) * phase; 1.411 + left -= right; 1.412 + right += buf [1]; 1.413 + 1.414 + buf [0] = left; 1.415 + buf [1] = right; 1.416 +#else 1.417 + 1.418 + int const fwd = (blip_widest_impulse_ - quality) / 2; 1.419 + int const rev = fwd + quality - 2; 1.420 + int const mid = quality / 2 - 1; 1.421 + 1.422 + imp_t const* BLIP_RESTRICT imp = impulses + blip_res - phase; 1.423 + 1.424 + #if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \ 1.425 + defined (__x86_64__) || defined (__ia64__) || defined (__i386__) 1.426 + 1.427 + // this straight forward version gave in better code on GCC for x86 1.428 + 1.429 + #define ADD_IMP( out, in ) \ 1.430 + buf [out] += (blip_long) imp [blip_res * (in)] * delta 1.431 + 1.432 + #define BLIP_FWD( i ) {\ 1.433 + ADD_IMP( fwd + i, i );\ 1.434 + ADD_IMP( fwd + 1 + i, i + 1 );\ 1.435 + } 1.436 + #define BLIP_REV( r ) {\ 1.437 + ADD_IMP( rev - r, r + 1 );\ 1.438 + ADD_IMP( rev + 1 - r, r );\ 1.439 + } 1.440 + 1.441 + BLIP_FWD( 0 ) 1.442 + if ( quality > 8 ) BLIP_FWD( 2 ) 1.443 + if ( quality > 12 ) BLIP_FWD( 4 ) 1.444 + { 1.445 + ADD_IMP( fwd + mid - 1, mid - 1 ); 1.446 + ADD_IMP( fwd + mid , mid ); 1.447 + imp = impulses + phase; 1.448 + } 1.449 + if ( quality > 12 ) BLIP_REV( 6 ) 1.450 + if ( quality > 8 ) BLIP_REV( 4 ) 1.451 + BLIP_REV( 2 ) 1.452 + 1.453 + ADD_IMP( rev , 1 ); 1.454 + ADD_IMP( rev + 1, 0 ); 1.455 + 1.456 + #undef ADD_IMP 1.457 + 1.458 + #else 1.459 + 1.460 + // for RISC processors, help compiler by reading ahead of writes 1.461 + 1.462 + #define BLIP_FWD( i ) {\ 1.463 + blip_long t0 = i0 * delta + buf [fwd + i];\ 1.464 + blip_long t1 = imp [blip_res * (i + 1)] * delta + buf [fwd + 1 + i];\ 1.465 + i0 = imp [blip_res * (i + 2)];\ 1.466 + buf [fwd + i] = t0;\ 1.467 + buf [fwd + 1 + i] = t1;\ 1.468 + } 1.469 + #define BLIP_REV( r ) {\ 1.470 + blip_long t0 = i0 * delta + buf [rev - r];\ 1.471 + blip_long t1 = imp [blip_res * r] * delta + buf [rev + 1 - r];\ 1.472 + i0 = imp [blip_res * (r - 1)];\ 1.473 + buf [rev - r] = t0;\ 1.474 + buf [rev + 1 - r] = t1;\ 1.475 + } 1.476 + 1.477 + blip_long i0 = *imp; 1.478 + BLIP_FWD( 0 ) 1.479 + if ( quality > 8 ) BLIP_FWD( 2 ) 1.480 + if ( quality > 12 ) BLIP_FWD( 4 ) 1.481 + { 1.482 + blip_long t0 = i0 * delta + buf [fwd + mid - 1]; 1.483 + blip_long t1 = imp [blip_res * mid] * delta + buf [fwd + mid ]; 1.484 + imp = impulses + phase; 1.485 + i0 = imp [blip_res * mid]; 1.486 + buf [fwd + mid - 1] = t0; 1.487 + buf [fwd + mid ] = t1; 1.488 + } 1.489 + if ( quality > 12 ) BLIP_REV( 6 ) 1.490 + if ( quality > 8 ) BLIP_REV( 4 ) 1.491 + BLIP_REV( 2 ) 1.492 + 1.493 + blip_long t0 = i0 * delta + buf [rev ]; 1.494 + blip_long t1 = *imp * delta + buf [rev + 1]; 1.495 + buf [rev ] = t0; 1.496 + buf [rev + 1] = t1; 1.497 + #endif 1.498 + 1.499 +#endif 1.500 +} 1.501 + 1.502 +#undef BLIP_FWD 1.503 +#undef BLIP_REV 1.504 + 1.505 +template<int quality,int range> 1.506 +#if BLIP_BUFFER_FAST 1.507 + inline 1.508 +#endif 1.509 +void Blip_Synth<quality,range>::offset( blip_time_t t, int delta, Blip_Buffer* buf ) const 1.510 +{ 1.511 + offset_resampled( t * buf->factor_ + buf->offset_, delta, buf ); 1.512 +} 1.513 + 1.514 +template<int quality,int range> 1.515 +#if BLIP_BUFFER_FAST 1.516 + inline 1.517 +#endif 1.518 +void Blip_Synth<quality,range>::update( blip_time_t t, int amp ) 1.519 +{ 1.520 + int delta = amp - impl.last_amp; 1.521 + impl.last_amp = amp; 1.522 + offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf ); 1.523 +} 1.524 + 1.525 +inline blip_eq_t::blip_eq_t( double t ) : 1.526 + treble( t ), rolloff_freq( 0 ), sample_rate( 44100 ), cutoff_freq( 0 ) { } 1.527 +inline blip_eq_t::blip_eq_t( double t, long rf, long sr, long cf ) : 1.528 + treble( t ), rolloff_freq( rf ), sample_rate( sr ), cutoff_freq( cf ) { } 1.529 + 1.530 +inline int Blip_Buffer::length() const { return length_; } 1.531 +inline long Blip_Buffer::samples_avail() const { return (long) (offset_ >> BLIP_BUFFER_ACCURACY); } 1.532 +inline long Blip_Buffer::sample_rate() const { return sample_rate_; } 1.533 +inline int Blip_Buffer::output_latency() const { return blip_widest_impulse_ / 2; } 1.534 +inline long Blip_Buffer::clock_rate() const { return clock_rate_; } 1.535 +inline void Blip_Buffer::clock_rate( long cps ) { factor_ = clock_rate_factor( clock_rate_ = cps ); } 1.536 + 1.537 +inline int Blip_Reader::begin( Blip_Buffer& blip_buf ) 1.538 +{ 1.539 + buf = blip_buf.buffer_; 1.540 + accum = blip_buf.reader_accum_; 1.541 + return blip_buf.bass_shift_; 1.542 +} 1.543 + 1.544 +inline void Blip_Buffer::remove_silence( long count ) 1.545 +{ 1.546 + // fails if you try to remove more samples than available 1.547 + assert( count <= samples_avail() ); 1.548 + offset_ -= (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY; 1.549 +} 1.550 + 1.551 +inline blip_ulong Blip_Buffer::unsettled() const 1.552 +{ 1.553 + return reader_accum_ >> (blip_sample_bits - 16); 1.554 +} 1.555 + 1.556 +int const blip_max_length = 0; 1.557 +int const blip_default_length = 250; // 1/4 second 1.558 + 1.559 +#endif