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