comparison src/apu/Blip_Buffer.cpp @ 3:b05d00f19d80

fix some formatting
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:33:11 -0600
parents f9f4f1b99eed
children
comparison
equal deleted inserted replaced
2:3549bbe597ed 3:b05d00f19d80
7 #include <string.h> 7 #include <string.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 #include <math.h> 9 #include <math.h>
10 10
11 /* Copyright (C) 2003-2007 Shay Green. This module is free software; you 11 /* Copyright (C) 2003-2007 Shay Green. This module is free software; you
12 can redistribute it and/or modify it under the terms of the GNU Lesser 12 can redistribute it and/or modify it under the terms of the GNU Lesser
13 General Public License as published by the Free Software Foundation; either 13 General Public License as published by the Free Software Foundation; either
14 version 2.1 of the License, or (at your option) any later version. This 14 version 2.1 of the License, or (at your option) any later version. This
15 module is distributed in the hope that it will be useful, but WITHOUT ANY 15 module is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 17 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
18 details. You should have received a copy of the GNU Lesser General Public 18 details. You should have received a copy of the GNU Lesser General Public
19 License along with this module; if not, write to the Free Software Foundation, 19 License along with this module; if not, write to the Free Software Foundation,
20 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 20 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
21 21
22 // TODO: use scoped for variables in treble_eq() 22 // TODO: use scoped for variables in treble_eq()
23 23
24 #ifdef BLARGG_ENABLE_OPTIMIZER 24 #ifdef BLARGG_ENABLE_OPTIMIZER
25 #include BLARGG_ENABLE_OPTIMIZER 25 #include BLARGG_ENABLE_OPTIMIZER
26 #endif 26 #endif
27 27
28 int const silent_buf_size = 1; // size used for Silent_Blip_Buffer 28 int const silent_buf_size = 1; // size used for Silent_Blip_Buffer
29 29
30 Blip_Buffer::Blip_Buffer() 30 Blip_Buffer::Blip_Buffer()
31 { 31 {
32 factor_ = LONG_MAX; 32 factor_ = LONG_MAX;
33 buffer_ = 0; 33 buffer_ = 0;
34 buffer_size_ = 0; 34 buffer_size_ = 0;
35 sample_rate_ = 0; 35 sample_rate_ = 0;
36 bass_shift_ = 0; 36 bass_shift_ = 0;
37 clock_rate_ = 0; 37 clock_rate_ = 0;
38 bass_freq_ = 16; 38 bass_freq_ = 16;
39 length_ = 0; 39 length_ = 0;
40 40
41 // assumptions code makes about implementation-defined features 41 // assumptions code makes about implementation-defined features
42 #ifndef NDEBUG 42 #ifndef NDEBUG
43 // right shift of negative value preserves sign 43 // right shift of negative value preserves sign
44 buf_t_ i = -0x7FFFFFFE; 44 buf_t_ i = -0x7FFFFFFE;
45 assert( (i >> 1) == -0x3FFFFFFF ); 45 assert( (i >> 1) == -0x3FFFFFFF );
46 46
47 // casting to short truncates to 16 bits and sign-extends 47 // casting to short truncates to 16 bits and sign-extends
48 i = 0x18000; 48 i = 0x18000;
49 assert( (short) i == -0x8000 ); 49 assert( (short) i == -0x8000 );
50 #endif 50 #endif
51 51
52 clear(); 52 Clear();
53 } 53 }
54 54
55 Blip_Buffer::~Blip_Buffer() 55 Blip_Buffer::~Blip_Buffer()
56 { 56 {
57 if ( buffer_size_ != silent_buf_size ) 57 if ( buffer_size_ != silent_buf_size )
58 free( buffer_ ); 58 free( buffer_ );
59 } 59 }
60 60
61 Silent_Blip_Buffer::Silent_Blip_Buffer() 61 Silent_Blip_Buffer::Silent_Blip_Buffer()
62 { 62 {
63 factor_ = 0; 63 factor_ = 0;
64 buffer_ = buf; 64 buffer_ = buf;
65 buffer_size_ = silent_buf_size; 65 buffer_size_ = silent_buf_size;
66 clear(); 66 clear();
67 } 67 }
68 68
69 void Blip_Buffer::clear( int entire_buffer ) 69 void Blip_Buffer::clear( int entire_buffer )
70 { 70 {
71 offset_ = 0; 71 offset_ = 0;
72 reader_accum_ = 0; 72 reader_accum_ = 0;
73 modified_ = 0; 73 modified_ = 0;
74 if ( buffer_ ) 74 if ( buffer_ )
75 { 75 {
76 long count = (entire_buffer ? buffer_size_ : samples_avail()); 76 long count = (entire_buffer ? buffer_size_ : samples_avail());
77 memset( buffer_, 0, (count + blip_buffer_extra_) * sizeof (buf_t_) ); 77 memset( buffer_, 0, (count + blip_buffer_extra_) * sizeof (buf_t_) );
78 } 78 }
79 } 79 }
80 80
81 Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int msec ) 81 Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int msec )
82 { 82 {
83 if ( buffer_size_ == silent_buf_size ) 83 if ( buffer_size_ == silent_buf_size )
84 { 84 {
85 assert( 0 ); 85 assert( 0 );
86 return "Internal (tried to resize Silent_Blip_Buffer)"; 86 return "Internal (tried to resize Silent_Blip_Buffer)";
87 } 87 }
88 88
89 // start with maximum length that resampled time can represent 89 // start with maximum length that resampled time can represent
90 long new_size = (ULONG_MAX >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 64; 90 long new_size = (ULONG_MAX >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 64;
91 if ( msec != blip_max_length ) 91 if ( msec != blip_max_length )
92 { 92 {
93 long s = (new_rate * (msec + 1) + 999) / 1000; 93 long s = (new_rate * (msec + 1) + 999) / 1000;
94 if ( s < new_size ) 94 if ( s < new_size )
95 new_size = s; 95 new_size = s;
96 else 96 else
97 assert( 0 ); // fails if requested buffer length exceeds limit 97 assert( 0 ); // fails if requested buffer length exceeds limit
98 } 98 }
99 99
100 if ( buffer_size_ != new_size ) 100 if ( buffer_size_ != new_size )
101 { 101 {
102 void* p = realloc( buffer_, (new_size + blip_buffer_extra_) * sizeof *buffer_ ); 102 void* p = realloc( buffer_, (new_size + blip_buffer_extra_) * sizeof *buffer_ );
103 if ( !p ) 103 if ( !p )
104 return "Out of memory"; 104 return "Out of memory";
105 buffer_ = (buf_t_*) p; 105 buffer_ = (buf_t_*) p;
106 } 106 }
107 107
108 buffer_size_ = new_size; 108 buffer_size_ = new_size;
109 assert( buffer_size_ != silent_buf_size ); // size should never happen to match this 109 assert( buffer_size_ != silent_buf_size ); // size should never happen to match this
110 110
111 // update things based on the sample rate 111 // update things based on the sample rate
112 sample_rate_ = new_rate; 112 sample_rate_ = new_rate;
113 length_ = new_size * 1000 / new_rate - 1; 113 length_ = new_size * 1000 / new_rate - 1;
114 if ( msec ) 114 if ( msec )
115 assert( length_ == msec ); // ensure length is same as that passed in 115 assert( length_ == msec ); // ensure length is same as that passed in
116 116
117 // update these since they depend on sample rate 117 // update these since they depend on sample rate
118 if ( clock_rate_ ) 118 if ( clock_rate_ )
119 clock_rate( clock_rate_ ); 119 clock_rate( clock_rate_ );
120 bass_freq( bass_freq_ ); 120 bass_freq( bass_freq_ );
121 121
122 clear(); 122 clear();
123 123
124 return 0; // success 124 return 0; // success
125 } 125 }
126 126
127 blip_resampled_time_t Blip_Buffer::clock_rate_factor( long rate ) const 127 blip_resampled_time_t Blip_Buffer::clock_rate_factor( long rate ) const
128 { 128 {
129 double ratio = (double) sample_rate_ / rate; 129 double ratio = (double) sample_rate_ / rate;
130 blip_long factor = (blip_long) floor( ratio * (1L << BLIP_BUFFER_ACCURACY) + 0.5 ); 130 blip_long factor = (blip_long) floor( ratio * (1L << BLIP_BUFFER_ACCURACY) + 0.5 );
131 assert( factor > 0 || !sample_rate_ ); // fails if clock/output ratio is too large 131 assert( factor > 0 || !sample_rate_ ); // fails if clock/output ratio is too large
132 return (blip_resampled_time_t) factor; 132 return (blip_resampled_time_t) factor;
133 } 133 }
134 134
135 void Blip_Buffer::bass_freq( int freq ) 135 void Blip_Buffer::bass_freq( int freq )
136 { 136 {
137 bass_freq_ = freq; 137 bass_freq_ = freq;
138 int shift = 31; 138 int shift = 31;
139 if ( freq > 0 ) 139 if ( freq > 0 )
140 { 140 {
141 shift = 13; 141 shift = 13;
142 long f = (freq << 16) / sample_rate_; 142 long f = (freq << 16) / sample_rate_;
143 while ( (f >>= 1) && --shift ) { } 143 while ( (f >>= 1) && --shift ) { }
144 } 144 }
145 bass_shift_ = shift; 145 bass_shift_ = shift;
146 } 146 }
147 147
148 void Blip_Buffer::end_frame( blip_time_t t ) 148 void Blip_Buffer::end_frame( blip_time_t t )
149 { 149 {
150 offset_ += t * factor_; 150 offset_ += t * factor_;
151 assert( samples_avail() <= (long) buffer_size_ ); // fails if time is past end of buffer 151 assert( samples_avail() <= (long) buffer_size_ ); // fails if time is past end of buffer
152 } 152 }
153 153
154 long Blip_Buffer::count_samples( blip_time_t t ) const 154 long Blip_Buffer::count_samples( blip_time_t t ) const
155 { 155 {
156 blip_resampled_time_t last_sample = resampled_time( t ) >> BLIP_BUFFER_ACCURACY; 156 blip_resampled_time_t last_sample = resampled_time( t ) >> BLIP_BUFFER_ACCURACY;
157 blip_resampled_time_t first_sample = offset_ >> BLIP_BUFFER_ACCURACY; 157 blip_resampled_time_t first_sample = offset_ >> BLIP_BUFFER_ACCURACY;
158 return long (last_sample - first_sample); 158 return long (last_sample - first_sample);
159 } 159 }
160 160
161 blip_time_t Blip_Buffer::count_clocks( long count ) const 161 blip_time_t Blip_Buffer::count_clocks( long count ) const
162 { 162 {
163 if ( !factor_ ) 163 if ( !factor_ )
164 { 164 {
165 assert( 0 ); // sample rate and clock rates must be set first 165 assert( 0 ); // sample rate and clock rates must be set first
166 return 0; 166 return 0;
167 } 167 }
168 168
169 if ( count > buffer_size_ ) 169 if ( count > buffer_size_ )
170 count = buffer_size_; 170 count = buffer_size_;
171 blip_resampled_time_t time = (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY; 171 blip_resampled_time_t time = (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
172 return (blip_time_t) ((time - offset_ + factor_ - 1) / factor_); 172 return (blip_time_t) ((time - offset_ + factor_ - 1) / factor_);
173 } 173 }
174 174
175 void Blip_Buffer::remove_samples( long count ) 175 void Blip_Buffer::remove_samples( long count )
176 { 176 {
177 if ( count ) 177 if ( count )
178 { 178 {
179 remove_silence( count ); 179 remove_silence( count );
180 180
181 // copy remaining samples to beginning and clear old samples 181 // copy remaining samples to beginning and clear old samples
182 long remain = samples_avail() + blip_buffer_extra_; 182 long remain = samples_avail() + blip_buffer_extra_;
183 memmove( buffer_, buffer_ + count, remain * sizeof *buffer_ ); 183 memmove( buffer_, buffer_ + count, remain * sizeof *buffer_ );
184 memset( buffer_ + remain, 0, count * sizeof *buffer_ ); 184 memset( buffer_ + remain, 0, count * sizeof *buffer_ );
185 } 185 }
186 } 186 }
187 187
188 // Blip_Synth_ 188 // Blip_Synth_
189 189
190 Blip_Synth_Fast_::Blip_Synth_Fast_() 190 Blip_Synth_Fast_::Blip_Synth_Fast_()
191 { 191 {
192 buf = 0; 192 buf = 0;
193 last_amp = 0; 193 last_amp = 0;
194 delta_factor = 0; 194 delta_factor = 0;
195 } 195 }
196 196
197 void Blip_Synth_Fast_::volume_unit( double new_unit ) 197 void Blip_Synth_Fast_::volume_unit( double new_unit )
198 { 198 {
199 delta_factor = int (new_unit * (1L << blip_sample_bits) + 0.5); 199 delta_factor = int (new_unit * (1L << blip_sample_bits) + 0.5);
200 } 200 }
201 201
202 #if !BLIP_BUFFER_FAST 202 #if !BLIP_BUFFER_FAST
203 203
204 Blip_Synth_::Blip_Synth_( short* p, int w ) : 204 Blip_Synth_::Blip_Synth_( short* p, int w ) :
205 impulses( p ), 205 impulses( p ),
206 width( w ) 206 width( w )
207 { 207 {
208 volume_unit_ = 0.0; 208 volume_unit_ = 0.0;
209 kernel_unit = 0; 209 kernel_unit = 0;
210 buf = 0; 210 buf = 0;
211 last_amp = 0; 211 last_amp = 0;
212 delta_factor = 0; 212 delta_factor = 0;
213 } 213 }
214 214
215 #undef PI 215 #undef PI
216 #define PI 3.1415926535897932384626433832795029 216 #define PI 3.1415926535897932384626433832795029
217 217
218 static void gen_sinc( float* out, int count, double oversample, double treble, double cutoff ) 218 static void gen_sinc( float* out, int count, double oversample, double treble, double cutoff )
219 { 219 {
220 if ( cutoff >= 0.999 ) 220 if ( cutoff >= 0.999 )
221 cutoff = 0.999; 221 cutoff = 0.999;
222 222
223 if ( treble < -300.0 ) 223 if ( treble < -300.0 )
224 treble = -300.0; 224 treble = -300.0;
225 if ( treble > 5.0 ) 225 if ( treble > 5.0 )
226 treble = 5.0; 226 treble = 5.0;
227 227
228 double const maxh = 4096.0; 228 double const maxh = 4096.0;
229 double const rolloff = pow( 10.0, 1.0 / (maxh * 20.0) * treble / (1.0 - cutoff) ); 229 double const rolloff = pow( 10.0, 1.0 / (maxh * 20.0) * treble / (1.0 - cutoff) );
230 double const pow_a_n = pow( rolloff, maxh - maxh * cutoff ); 230 double const pow_a_n = pow( rolloff, maxh - maxh * cutoff );
231 double const to_angle = PI / 2 / maxh / oversample; 231 double const to_angle = PI / 2 / maxh / oversample;
232 for ( int i = 0; i < count; i++ ) 232 for ( int i = 0; i < count; i++ )
233 {
234 double angle = ((i - count) * 2 + 1) * to_angle;
235 double c = rolloff * cos( (maxh - 1.0) * angle ) - cos( maxh * angle );
236 double cos_nc_angle = cos( maxh * cutoff * angle );
237 double cos_nc1_angle = cos( (maxh * cutoff - 1.0) * angle );
238 double cos_angle = cos( angle );
239
240 c = c * pow_a_n - rolloff * cos_nc1_angle + cos_nc_angle;
241 double d = 1.0 + rolloff * (rolloff - cos_angle - cos_angle);
242 double b = 2.0 - cos_angle - cos_angle;
243 double a = 1.0 - cos_angle - cos_nc_angle + cos_nc1_angle;
244
245 out [i] = (float) ((a * d + c * b) / (b * d)); // a / b + c / d
246 }
247 }
248
249 void blip_eq_t::generate( float* out, int count ) const
250 {
251 // lower cutoff freq for narrow kernels with their wider transition band
252 // (8 points->1.49, 16 points->1.15)
253 double oversample = blip_res * 2.25 / count + 0.85;
254 double half_rate = sample_rate * 0.5;
255 if ( cutoff_freq )
256 oversample = half_rate / cutoff_freq;
257 double cutoff = rolloff_freq * oversample / half_rate;
258
259 gen_sinc( out, count, blip_res * oversample, treble, cutoff );
260
261 // apply (half of) hamming window
262 double to_fraction = PI / (count - 1);
263 for ( int i = count; i--; )
264 out [i] *= 0.54f - 0.46f * (float) cos( i * to_fraction );
265 }
266
267 void Blip_Synth_::adjust_impulse()
268 {
269 // sum pairs for each phase and add error correction to end of first half
270 int const size = impulses_size();
271 for ( int p = blip_res; p-- >= blip_res / 2; )
272 {
273 int p2 = blip_res - 2 - p;
274 long error = kernel_unit;
275 for ( int i = 1; i < size; i += blip_res )
233 { 276 {
234 double angle = ((i - count) * 2 + 1) * to_angle; 277 error -= impulses [i + p ];
235 double c = rolloff * cos( (maxh - 1.0) * angle ) - cos( maxh * angle ); 278 error -= impulses [i + p2];
236 double cos_nc_angle = cos( maxh * cutoff * angle );
237 double cos_nc1_angle = cos( (maxh * cutoff - 1.0) * angle );
238 double cos_angle = cos( angle );
239
240 c = c * pow_a_n - rolloff * cos_nc1_angle + cos_nc_angle;
241 double d = 1.0 + rolloff * (rolloff - cos_angle - cos_angle);
242 double b = 2.0 - cos_angle - cos_angle;
243 double a = 1.0 - cos_angle - cos_nc_angle + cos_nc1_angle;
244
245 out [i] = (float) ((a * d + c * b) / (b * d)); // a / b + c / d
246 } 279 }
247 } 280 if ( p == p2 )
248 281 error /= 2; // phase = 0.5 impulse uses same half for both sides
249 void blip_eq_t::generate( float* out, int count ) const 282 impulses [size - blip_res + p] += (short) error;
250 { 283 //printf( "error: %ld\n", error );
251 // lower cutoff freq for narrow kernels with their wider transition band 284 }
252 // (8 points->1.49, 16 points->1.15) 285
253 double oversample = blip_res * 2.25 / count + 0.85; 286 //for ( int i = blip_res; i--; printf( "\n" ) )
254 double half_rate = sample_rate * 0.5; 287 // for ( int j = 0; j < width / 2; j++ )
255 if ( cutoff_freq ) 288 // printf( "%5ld,", impulses [j * blip_res + i + 1] );
256 oversample = half_rate / cutoff_freq; 289 }
257 double cutoff = rolloff_freq * oversample / half_rate; 290
258 291 void Blip_Synth_::treble_eq( blip_eq_t const& eq )
259 gen_sinc( out, count, blip_res * oversample, treble, cutoff ); 292 {
260 293 float fimpulse [blip_res / 2 * (blip_widest_impulse_ - 1) + blip_res * 2];
261 // apply (half of) hamming window 294
262 double to_fraction = PI / (count - 1); 295 int const half_size = blip_res / 2 * (width - 1);
263 for ( int i = count; i--; ) 296 eq.generate( &fimpulse [blip_res], half_size );
264 out [i] *= 0.54f - 0.46f * (float) cos( i * to_fraction ); 297
265 } 298 int i;
266 299
267 void Blip_Synth_::adjust_impulse() 300 // need mirror slightly past center for calculation
268 { 301 for ( i = blip_res; i--; )
269 // sum pairs for each phase and add error correction to end of first half 302 fimpulse [blip_res + half_size + i] = fimpulse [blip_res + half_size - 1 - i];
270 int const size = impulses_size(); 303
271 for ( int p = blip_res; p-- >= blip_res / 2; ) 304 // starts at 0
305 for ( i = 0; i < blip_res; i++ )
306 fimpulse [i] = 0.0f;
307
308 // find rescale factor
309 double total = 0.0;
310 for ( i = 0; i < half_size; i++ )
311 total += fimpulse [blip_res + i];
312
313 //double const base_unit = 44800.0 - 128 * 18; // allows treble up to +0 dB
314 //double const base_unit = 37888.0; // allows treble to +5 dB
315 double const base_unit = 32768.0; // necessary for blip_unscaled to work
316 double rescale = base_unit / 2 / total;
317 kernel_unit = (long) base_unit;
318
319 // integrate, first difference, rescale, convert to int
320 double sum = 0.0;
321 double next = 0.0;
322 int const size = this->impulses_size();
323 for ( i = 0; i < size; i++ )
324 {
325 impulses [i] = (short) (int) floor( (next - sum) * rescale + 0.5 );
326 sum += fimpulse [i];
327 next += fimpulse [i + blip_res];
328 }
329 adjust_impulse();
330
331 // volume might require rescaling
332 double vol = volume_unit_;
333 if ( vol )
334 {
335 volume_unit_ = 0.0;
336 volume_unit( vol );
337 }
338 }
339
340 void Blip_Synth_::volume_unit( double new_unit )
341 {
342 if ( new_unit != volume_unit_ )
343 {
344 // use default eq if it hasn't been set yet
345 if ( !kernel_unit )
346 treble_eq( -8.0 );
347
348 volume_unit_ = new_unit;
349 double factor = new_unit * (1L << blip_sample_bits) / kernel_unit;
350
351 if ( factor > 0.0 )
272 { 352 {
273 int p2 = blip_res - 2 - p; 353 int shift = 0;
274 long error = kernel_unit; 354
275 for ( int i = 1; i < size; i += blip_res ) 355 // if unit is really small, might need to attenuate kernel
276 { 356 while ( factor < 2.0 )
277 error -= impulses [i + p ]; 357 {
278 error -= impulses [i + p2]; 358 shift++;
279 } 359 factor *= 2.0;
280 if ( p == p2 ) 360 }
281 error /= 2; // phase = 0.5 impulse uses same half for both sides 361
282 impulses [size - blip_res + p] += (short) error; 362 if ( shift )
283 //printf( "error: %ld\n", error ); 363 {
364 kernel_unit >>= shift;
365 assert( kernel_unit > 0 ); // fails if volume unit is too low
366
367 // keep values positive to avoid round-towards-zero of sign-preserving
368 // right shift for negative values
369 long offset = 0x8000 + (1 << (shift - 1));
370 long offset2 = 0x8000 >> shift;
371 for ( int i = impulses_size(); i--; )
372 impulses [i] = (short) (int) (((impulses [i] + offset) >> shift) - offset2);
373 adjust_impulse();
374 }
284 } 375 }
285 376 delta_factor = (int) floor( factor + 0.5 );
286 //for ( int i = blip_res; i--; printf( "\n" ) ) 377 //printf( "delta_factor: %d, kernel_unit: %d\n", delta_factor, kernel_unit );
287 // for ( int j = 0; j < width / 2; j++ ) 378 }
288 // printf( "%5ld,", impulses [j * blip_res + i + 1] ); 379 }
289 } 380 #endif
290 381
291 void Blip_Synth_::treble_eq( blip_eq_t const& eq ) 382 long Blip_Buffer::read_samples( blip_sample_t* out_, long max_samples, int stereo )
292 { 383 {
293 float fimpulse [blip_res / 2 * (blip_widest_impulse_ - 1) + blip_res * 2]; 384 long count = samples_avail();
294 385 if ( count > max_samples )
295 int const half_size = blip_res / 2 * (width - 1); 386 count = max_samples;
296 eq.generate( &fimpulse [blip_res], half_size ); 387
297 388 if ( count )
298 int i; 389 {
299 390 int const bass = BLIP_READER_BASS( *this );
300 // need mirror slightly past center for calculation 391 BLIP_READER_BEGIN( reader, *this );
301 for ( i = blip_res; i--; ) 392 BLIP_READER_ADJ_( reader, count );
302 fimpulse [blip_res + half_size + i] = fimpulse [blip_res + half_size - 1 - i]; 393 blip_sample_t* BLIP_RESTRICT out = out_ + count;
303 394 blip_long offset = (blip_long) -count;
304 // starts at 0 395
305 for ( i = 0; i < blip_res; i++ ) 396 if ( !stereo )
306 fimpulse [i] = 0.0f;
307
308 // find rescale factor
309 double total = 0.0;
310 for ( i = 0; i < half_size; i++ )
311 total += fimpulse [blip_res + i];
312
313 //double const base_unit = 44800.0 - 128 * 18; // allows treble up to +0 dB
314 //double const base_unit = 37888.0; // allows treble to +5 dB
315 double const base_unit = 32768.0; // necessary for blip_unscaled to work
316 double rescale = base_unit / 2 / total;
317 kernel_unit = (long) base_unit;
318
319 // integrate, first difference, rescale, convert to int
320 double sum = 0.0;
321 double next = 0.0;
322 int const size = this->impulses_size();
323 for ( i = 0; i < size; i++ )
324 { 397 {
325 impulses [i] = (short) (int) floor( (next - sum) * rescale + 0.5 ); 398 do
326 sum += fimpulse [i]; 399 {
327 next += fimpulse [i + blip_res]; 400 blip_long s = BLIP_READER_READ( reader );
401 BLIP_READER_NEXT_IDX_( reader, bass, offset );
402 BLIP_CLAMP( s, s );
403 out [offset] = (blip_sample_t) s;
404 }
405 while ( ++offset );
328 } 406 }
329 adjust_impulse(); 407 else
330
331 // volume might require rescaling
332 double vol = volume_unit_;
333 if ( vol )
334 { 408 {
335 volume_unit_ = 0.0; 409 do
336 volume_unit( vol ); 410 {
411 blip_long s = BLIP_READER_READ( reader );
412 BLIP_READER_NEXT_IDX_( reader, bass, offset );
413 BLIP_CLAMP( s, s );
414 out [offset * 2] = (blip_sample_t) s;
415 }
416 while ( ++offset );
337 } 417 }
338 } 418
339 419 BLIP_READER_END( reader, *this );
340 void Blip_Synth_::volume_unit( double new_unit ) 420
341 { 421 remove_samples( count );
342 if ( new_unit != volume_unit_ ) 422 }
343 { 423 return count;
344 // use default eq if it hasn't been set yet
345 if ( !kernel_unit )
346 treble_eq( -8.0 );
347
348 volume_unit_ = new_unit;
349 double factor = new_unit * (1L << blip_sample_bits) / kernel_unit;
350
351 if ( factor > 0.0 )
352 {
353 int shift = 0;
354
355 // if unit is really small, might need to attenuate kernel
356 while ( factor < 2.0 )
357 {
358 shift++;
359 factor *= 2.0;
360 }
361
362 if ( shift )
363 {
364 kernel_unit >>= shift;
365 assert( kernel_unit > 0 ); // fails if volume unit is too low
366
367 // keep values positive to avoid round-towards-zero of sign-preserving
368 // right shift for negative values
369 long offset = 0x8000 + (1 << (shift - 1));
370 long offset2 = 0x8000 >> shift;
371 for ( int i = impulses_size(); i--; )
372 impulses [i] = (short) (int) (((impulses [i] + offset) >> shift) - offset2);
373 adjust_impulse();
374 }
375 }
376 delta_factor = (int) floor( factor + 0.5 );
377 //printf( "delta_factor: %d, kernel_unit: %d\n", delta_factor, kernel_unit );
378 }
379 }
380 #endif
381
382 long Blip_Buffer::read_samples( blip_sample_t* out_, long max_samples, int stereo )
383 {
384 long count = samples_avail();
385 if ( count > max_samples )
386 count = max_samples;
387
388 if ( count )
389 {
390 int const bass = BLIP_READER_BASS( *this );
391 BLIP_READER_BEGIN( reader, *this );
392 BLIP_READER_ADJ_( reader, count );
393 blip_sample_t* BLIP_RESTRICT out = out_ + count;
394 blip_long offset = (blip_long) -count;
395
396 if ( !stereo )
397 {
398 do
399 {
400 blip_long s = BLIP_READER_READ( reader );
401 BLIP_READER_NEXT_IDX_( reader, bass, offset );
402 BLIP_CLAMP( s, s );
403 out [offset] = (blip_sample_t) s;
404 }
405 while ( ++offset );
406 }
407 else
408 {
409 do
410 {
411 blip_long s = BLIP_READER_READ( reader );
412 BLIP_READER_NEXT_IDX_( reader, bass, offset );
413 BLIP_CLAMP( s, s );
414 out [offset * 2] = (blip_sample_t) s;
415 }
416 while ( ++offset );
417 }
418
419 BLIP_READER_END( reader, *this );
420
421 remove_samples( count );
422 }
423 return count;
424 } 424 }
425 425
426 void Blip_Buffer::mix_samples( blip_sample_t const* in, long count ) 426 void Blip_Buffer::mix_samples( blip_sample_t const* in, long count )
427 { 427 {
428 if ( buffer_size_ == silent_buf_size ) 428 if ( buffer_size_ == silent_buf_size )
429 { 429 {
430 assert( 0 ); 430 assert( 0 );
431 return; 431 return;
432 } 432 }
433 433
434 buf_t_* out = buffer_ + (offset_ >> BLIP_BUFFER_ACCURACY) + blip_widest_impulse_ / 2; 434 buf_t_* out = buffer_ + (offset_ >> BLIP_BUFFER_ACCURACY) + blip_widest_impulse_ / 2;
435 435
436 int const sample_shift = blip_sample_bits - 16; 436 int const sample_shift = blip_sample_bits - 16;
437 int prev = 0; 437 int prev = 0;
438 while ( count-- ) 438 while ( count-- )
439 { 439 {
440 blip_long s = (blip_long) *in++ << sample_shift; 440 blip_long s = (blip_long) *in++ << sample_shift;
441 *out += s - prev; 441 *out += s - prev;
442 prev = s; 442 prev = s;
443 ++out; 443 ++out;
444 } 444 }
445 *out -= prev; 445 *out -= prev;
446 } 446 }
447 447
448 blip_ulong const subsample_mask = (1L << BLIP_BUFFER_ACCURACY) - 1; 448 blip_ulong const subsample_mask = (1L << BLIP_BUFFER_ACCURACY) - 1;
449 449
450 void Blip_Buffer::save_state( blip_buffer_state_t* out ) 450 void Blip_Buffer::save_state( blip_buffer_state_t* out )
451 { 451 {
452 assert( samples_avail() == 0 ); 452 assert( samples_avail() == 0 );
453 out->offset_ = offset_; 453 out->offset_ = offset_;
454 out->reader_accum_ = reader_accum_; 454 out->reader_accum_ = reader_accum_;
455 memcpy( out->buf, &buffer_ [offset_ >> BLIP_BUFFER_ACCURACY], sizeof out->buf ); 455 memcpy( out->buf, &buffer_ [offset_ >> BLIP_BUFFER_ACCURACY], sizeof out->buf );
456 } 456 }
457 457
458 void Blip_Buffer::load_state( blip_buffer_state_t const& in ) 458 void Blip_Buffer::load_state( blip_buffer_state_t const& in )
459 { 459 {
460 clear( false ); 460 clear( false );
461 461
462 offset_ = in.offset_; 462 offset_ = in.offset_;
463 reader_accum_ = in.reader_accum_; 463 reader_accum_ = in.reader_accum_;
464 memcpy( buffer_, in.buf, sizeof in.buf ); 464 memcpy( buffer_, in.buf, sizeof in.buf );
465 } 465 }