comparison Plugins/Input/console/Blip_Buffer.h @ 493:c04dff121e1d trunk

[svn] hostile merge, phase 2: reimport based on new plugin code
author nenolod
date Tue, 24 Jan 2006 20:19:01 -0800
parents
children
comparison
equal deleted inserted replaced
492:ccb68bad47b2 493:c04dff121e1d
1
2 // Band-limited sound synthesis and buffering
3
4 // Blip_Buffer 0.4.0
5
6 #ifndef BLIP_BUFFER_H
7 #define BLIP_BUFFER_H
8
9 // Time unit at source clock rate
10 typedef long blip_time_t;
11
12 // Output samples are 16-bit signed, with a range of -32768 to 32767
13 typedef short blip_sample_t;
14 enum { blip_sample_max = 32767 };
15
16 class Blip_Buffer {
17 public:
18 typedef const char* blargg_err_t;
19
20 // Set output sample rate and buffer length in milliseconds (1/1000 sec, defaults
21 // to 1/4 second), then clear buffer. Returns NULL on success, otherwise if there
22 // isn't enough memory, returns error without affecting current buffer setup.
23 blargg_err_t set_sample_rate( long samples_per_sec, int msec_length = 1000 / 4 );
24
25 // Set number of source time units per second
26 void clock_rate( long );
27
28 // End current time frame of specified duration and make its samples available
29 // (along with any still-unread samples) for reading with read_samples(). Begins
30 // a new time frame at the end of the current frame.
31 void end_frame( blip_time_t time );
32
33 // Read at most 'max_samples' out of buffer into 'dest', removing them from from
34 // the buffer. Returns number of samples actually read and removed. If stereo is
35 // true, increments 'dest' one extra time after writing each sample, to allow
36 // easy interleving of two channels into a stereo output buffer.
37 long read_samples( blip_sample_t* dest, long max_samples, int stereo = 0 );
38
39 // Additional optional features
40
41 // Current output sample rate
42 long sample_rate() const;
43
44 // Length of buffer, in milliseconds
45 int length() const;
46
47 // Number of source time units per second
48 long clock_rate() const;
49
50 // Set frequency high-pass filter frequency, where higher values reduce bass more
51 void bass_freq( int frequency );
52
53 // Number of samples delay from synthesis to samples read out
54 int output_latency() const;
55
56 // Remove all available samples and clear buffer to silence. If 'entire_buffer' is
57 // false, just clears out any samples waiting rather than the entire buffer.
58 void clear( int entire_buffer = 1 );
59
60 // Number of samples available for reading with read_samples()
61 long samples_avail() const;
62
63 // Remove 'count' samples from those waiting to be read
64 void remove_samples( long count );
65
66 // Experimental features
67
68 // Number of raw samples that can be mixed within frame of specified duration.
69 long count_samples( blip_time_t duration ) const;
70
71 // Mix 'count' samples from 'buf' into buffer.
72 void mix_samples( blip_sample_t const* buf, long count );
73
74 // Count number of clocks needed until 'count' samples will be available.
75 // If buffer can't even hold 'count' samples, returns number of clocks until
76 // buffer becomes full.
77 blip_time_t count_clocks( long count ) const;
78
79 // not documented yet
80 typedef unsigned long blip_resampled_time_t;
81 void remove_silence( long count );
82 blip_resampled_time_t resampled_duration( int t ) const { return t * factor_; }
83 blip_resampled_time_t resampled_time( blip_time_t t ) const { return t * factor_ + offset_; }
84 blip_resampled_time_t clock_rate_factor( long clock_rate ) const;
85 public:
86 Blip_Buffer();
87 ~Blip_Buffer();
88
89 // Deprecated
90 typedef blip_resampled_time_t resampled_time_t;
91 blargg_err_t sample_rate( long r ) { return set_sample_rate( r ); }
92 blargg_err_t sample_rate( long r, int msec ) { return set_sample_rate( r, msec ); }
93 private:
94 // noncopyable
95 Blip_Buffer( const Blip_Buffer& );
96 Blip_Buffer& operator = ( const Blip_Buffer& );
97 public:
98 typedef long buf_t_;
99 unsigned long factor_;
100 blip_resampled_time_t offset_;
101 buf_t_* buffer_;
102 long buffer_size_;
103 private:
104 long reader_accum;
105 int bass_shift;
106 long sample_rate_;
107 long clock_rate_;
108 int bass_freq_;
109 int length_;
110 friend class Blip_Reader;
111 };
112
113 #ifdef HAVE_CONFIG_H
114 #include "config.h"
115 #endif
116
117 // Number of bits in resample ratio fraction. Higher values give a more accurate ratio
118 // but reduce maximum buffer size.
119 #ifndef BLIP_BUFFER_ACCURACY
120 #define BLIP_BUFFER_ACCURACY 16
121 #endif
122
123 // Number bits in phase offset. Fewer than 6 bits (64 phase offsets) results in
124 // noticeable broadband noise when synthesizing high frequency square waves.
125 // Affects size of Blip_Synth objects since they store the waveform directly.
126 #ifndef BLIP_PHASE_BITS
127 #define BLIP_PHASE_BITS 6
128 #endif
129
130 // Internal
131 typedef unsigned long blip_resampled_time_t;
132 int const blip_widest_impulse_ = 16;
133 int const blip_res = 1 << BLIP_PHASE_BITS;
134 class blip_eq_t;
135
136 class Blip_Synth_ {
137 double volume_unit_;
138 short* const impulses;
139 int const width;
140 long kernel_unit;
141 int impulses_size() const { return blip_res / 2 * width + 1; }
142 void adjust_impulse();
143 public:
144 Blip_Buffer* buf;
145 int last_amp;
146 int delta_factor;
147
148 Blip_Synth_( short* impulses, int width );
149 void treble_eq( blip_eq_t const& );
150 void volume_unit( double );
151 };
152
153 // Quality level. Start with blip_good_quality.
154 const int blip_med_quality = 8;
155 const int blip_good_quality = 12;
156 const int blip_high_quality = 16;
157
158 // Range specifies the greatest expected change in amplitude. Calculate it
159 // by finding the difference between the maximum and minimum expected
160 // amplitudes (max - min).
161 template<int quality,int range>
162 class Blip_Synth {
163 public:
164 // Set overall volume of waveform
165 void volume( double v ) { impl.volume_unit( v * (1.0 / (range < 0 ? -range : range)) ); }
166
167 // Configure low-pass filter (see notes.txt)
168 void treble_eq( blip_eq_t const& eq ) { impl.treble_eq( eq ); }
169
170 // Get/set Blip_Buffer used for output
171 Blip_Buffer* output() const { return impl.buf; }
172 void output( Blip_Buffer* b ) { impl.buf = b; impl.last_amp = 0; }
173
174 // Update amplitude of waveform at given time. Using this requires a separate
175 // Blip_Synth for each waveform.
176 void update( blip_time_t time, int amplitude );
177
178 // Low-level interface
179
180 // Add an amplitude transition of specified delta, optionally into specified buffer
181 // rather than the one set with output(). Delta can be positive or negative.
182 // The actual change in amplitude is delta * (volume / range)
183 void offset( blip_time_t, int delta, Blip_Buffer* ) const;
184 void offset( blip_time_t t, int delta ) const { offset( t, delta, impl.buf ); }
185
186 // Works directly in terms of fractional output samples. Contact author for more.
187 void offset_resampled( blip_resampled_time_t, int delta, Blip_Buffer* ) const;
188
189 // Same as offset(), except code is inlined for higher performance
190 void offset_inline( blip_time_t t, int delta, Blip_Buffer* buf ) const {
191 offset_resampled( t * buf->factor_ + buf->offset_, delta, buf );
192 }
193 void offset_inline( blip_time_t t, int delta ) const {
194 offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf );
195 }
196
197 public:
198 Blip_Synth() : impl( impulses, quality ) { }
199 private:
200 typedef short imp_t;
201 imp_t impulses [blip_res * (quality / 2) + 1];
202 Blip_Synth_ impl;
203 };
204
205 // Low-pass equalization parameters
206 class blip_eq_t {
207 public:
208 // Logarithmic rolloff to treble dB at half sampling rate. Negative values reduce
209 // treble, small positive values (0 to 5.0) increase treble.
210 blip_eq_t( double treble_db = 0 );
211
212 // See notes.txt
213 blip_eq_t( double treble, long rolloff_freq, long sample_rate, long cutoff_freq = 0 );
214
215 private:
216 double treble;
217 long rolloff_freq;
218 long sample_rate;
219 long cutoff_freq;
220 void generate( float* out, int count ) const;
221 friend class Blip_Synth_;
222 };
223
224 int const blip_sample_bits = 30;
225
226 // Optimized inline sample reader for custom sample formats and mixing of Blip_Buffer samples
227 class Blip_Reader {
228 public:
229 // Begin reading samples from buffer. Returns value to pass to next() (can
230 // be ignored if default bass_freq is acceptable).
231 int begin( Blip_Buffer& );
232
233 // Current sample
234 long read() const { return accum >> (blip_sample_bits - 16); }
235
236 // Current raw sample in full internal resolution
237 long read_raw() const { return accum; }
238
239 // Advance to next sample
240 void next( int bass_shift = 9 ) { accum += *buf++ - (accum >> bass_shift); }
241
242 // End reading samples from buffer. The number of samples read must now be removed
243 // using Blip_Buffer::remove_samples().
244 void end( Blip_Buffer& b ) { b.reader_accum = accum; }
245
246 private:
247 const Blip_Buffer::buf_t_* buf;
248 long accum;
249 };
250
251
252 // End of public interface
253
254
255 #include <assert.h>
256
257 // Compatibility with older version
258 const long blip_unscaled = 65535;
259 const int blip_low_quality = blip_med_quality;
260 const int blip_best_quality = blip_high_quality;
261
262 #define BLIP_FWD( i ) { \
263 long t0 = i0 * delta + buf [fwd + i]; \
264 long t1 = imp [blip_res * (i + 1)] * delta + buf [fwd + 1 + i]; \
265 i0 = imp [blip_res * (i + 2)]; \
266 buf [fwd + i] = t0; \
267 buf [fwd + 1 + i] = t1; }
268
269 #define BLIP_REV( r ) { \
270 long t0 = i0 * delta + buf [rev - r]; \
271 long t1 = imp [blip_res * r] * delta + buf [rev + 1 - r]; \
272 i0 = imp [blip_res * (r - 1)]; \
273 buf [rev - r] = t0; \
274 buf [rev + 1 - r] = t1; }
275
276 template<int quality,int range>
277 inline void Blip_Synth<quality,range>::offset_resampled( blip_resampled_time_t time,
278 int delta, Blip_Buffer* blip_buf ) const
279 {
280 // Fails if time is beyond end of Blip_Buffer, due to a bug in caller code or the
281 // need for a longer buffer as set by set_sample_rate().
282 assert( (long) (time >> BLIP_BUFFER_ACCURACY) < blip_buf->buffer_size_ );
283 delta *= impl.delta_factor;
284 int phase = (int) (time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS) & (blip_res - 1));
285 imp_t const* imp = impulses + blip_res - phase;
286 long* buf = blip_buf->buffer_ + (time >> BLIP_BUFFER_ACCURACY);
287 long i0 = *imp;
288
289 int const fwd = (blip_widest_impulse_ - quality) / 2;
290 int const rev = fwd + quality - 2;
291
292 BLIP_FWD( 0 )
293 if ( quality > 8 ) BLIP_FWD( 2 )
294 if ( quality > 12 ) BLIP_FWD( 4 )
295 {
296 int const mid = quality / 2 - 1;
297 long t0 = i0 * delta + buf [fwd + mid - 1];
298 long t1 = imp [blip_res * mid] * delta + buf [fwd + mid];
299 imp = impulses + phase;
300 i0 = imp [blip_res * mid];
301 buf [fwd + mid - 1] = t0;
302 buf [fwd + mid] = t1;
303 }
304 if ( quality > 12 ) BLIP_REV( 6 )
305 if ( quality > 8 ) BLIP_REV( 4 )
306 BLIP_REV( 2 )
307
308 long t0 = i0 * delta + buf [rev];
309 long t1 = *imp * delta + buf [rev + 1];
310 buf [rev] = t0;
311 buf [rev + 1] = t1;
312 }
313
314 #undef BLIP_FWD
315 #undef BLIP_REV
316
317 template<int quality,int range>
318 void Blip_Synth<quality,range>::offset( blip_time_t t, int delta, Blip_Buffer* buf ) const
319 {
320 offset_resampled( t * buf->factor_ + buf->offset_, delta, buf );
321 }
322
323 template<int quality,int range>
324 void Blip_Synth<quality,range>::update( blip_time_t t, int amp )
325 {
326 int delta = amp - impl.last_amp;
327 impl.last_amp = amp;
328 offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf );
329 }
330
331 inline blip_eq_t::blip_eq_t( double t ) :
332 treble( t ), rolloff_freq( 0 ), sample_rate( 44100 ), cutoff_freq( 0 ) { }
333 inline blip_eq_t::blip_eq_t( double t, long rf, long sr, long cf ) :
334 treble( t ), rolloff_freq( rf ), sample_rate( sr ), cutoff_freq( cf ) { }
335
336 inline int Blip_Buffer::length() const { return length_; }
337 inline long Blip_Buffer::samples_avail() const { return (long) (offset_ >> BLIP_BUFFER_ACCURACY); }
338 inline long Blip_Buffer::sample_rate() const { return sample_rate_; }
339 inline int Blip_Buffer::output_latency() const { return blip_widest_impulse_ / 2; }
340 inline long Blip_Buffer::clock_rate() const { return clock_rate_; }
341 inline void Blip_Buffer::clock_rate( long cps ) { factor_ = clock_rate_factor( clock_rate_ = cps ); }
342
343 inline int Blip_Reader::begin( Blip_Buffer& blip_buf )
344 {
345 buf = blip_buf.buffer_;
346 accum = blip_buf.reader_accum;
347 return blip_buf.bass_shift;
348 }
349
350 int const blip_max_length = 0;
351 int const blip_default_length = 250;
352
353 #endif
354