Mercurial > vba-clojure
comparison 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 |
comparison
equal
deleted
inserted
replaced
0:8ced16adf2e1 | 1:f9f4f1b99eed |
---|---|
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 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 >= 1400 | |
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 |