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
|