view 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
line wrap: on
line source
1 // Blip_Buffer 0.4.1. http://www.slack.net/~ant/
3 #include "Blip_Buffer.h"
5 #include <assert.h>
6 #include <limits.h>
7 #include <string.h>
8 #include <stdlib.h>
9 #include <math.h>
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
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
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
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
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 */
22 // TODO: use scoped for variables in treble_eq()
24 #ifdef BLARGG_ENABLE_OPTIMIZER
25 #include BLARGG_ENABLE_OPTIMIZER
26 #endif
28 int const silent_buf_size = 1; // size used for Silent_Blip_Buffer
30 Blip_Buffer::Blip_Buffer()
31 {
32 factor_ = LONG_MAX;
33 buffer_ = 0;
34 buffer_size_ = 0;
35 sample_rate_ = 0;
36 bass_shift_ = 0;
37 clock_rate_ = 0;
38 bass_freq_ = 16;
39 length_ = 0;
41 // assumptions code makes about implementation-defined features
42 #ifndef NDEBUG
43 // right shift of negative value preserves sign
44 buf_t_ i = -0x7FFFFFFE;
45 assert( (i >> 1) == -0x3FFFFFFF );
47 // casting to short truncates to 16 bits and sign-extends
48 i = 0x18000;
49 assert( (short) i == -0x8000 );
50 #endif
52 Clear();
53 }
55 Blip_Buffer::~Blip_Buffer()
56 {
57 if ( buffer_size_ != silent_buf_size )
58 free( buffer_ );
59 }
61 Silent_Blip_Buffer::Silent_Blip_Buffer()
62 {
63 factor_ = 0;
64 buffer_ = buf;
65 buffer_size_ = silent_buf_size;
66 clear();
67 }
69 void Blip_Buffer::clear( int entire_buffer )
70 {
71 offset_ = 0;
72 reader_accum_ = 0;
73 modified_ = 0;
74 if ( buffer_ )
75 {
76 long count = (entire_buffer ? buffer_size_ : samples_avail());
77 memset( buffer_, 0, (count + blip_buffer_extra_) * sizeof (buf_t_) );
78 }
79 }
81 Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int msec )
82 {
83 if ( buffer_size_ == silent_buf_size )
84 {
85 assert( 0 );
86 return "Internal (tried to resize Silent_Blip_Buffer)";
87 }
89 // start with maximum length that resampled time can represent
90 long new_size = (ULONG_MAX >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 64;
91 if ( msec != blip_max_length )
92 {
93 long s = (new_rate * (msec + 1) + 999) / 1000;
94 if ( s < new_size )
95 new_size = s;
96 else
97 assert( 0 ); // fails if requested buffer length exceeds limit
98 }
100 if ( buffer_size_ != new_size )
101 {
102 void* p = realloc( buffer_, (new_size + blip_buffer_extra_) * sizeof *buffer_ );
103 if ( !p )
104 return "Out of memory";
105 buffer_ = (buf_t_*) p;
106 }
108 buffer_size_ = new_size;
109 assert( buffer_size_ != silent_buf_size ); // size should never happen to match this
111 // update things based on the sample rate
112 sample_rate_ = new_rate;
113 length_ = new_size * 1000 / new_rate - 1;
114 if ( msec )
115 assert( length_ == msec ); // ensure length is same as that passed in
117 // update these since they depend on sample rate
118 if ( clock_rate_ )
119 clock_rate( clock_rate_ );
120 bass_freq( bass_freq_ );
122 clear();
124 return 0; // success
125 }
127 blip_resampled_time_t Blip_Buffer::clock_rate_factor( long rate ) const
128 {
129 double ratio = (double) sample_rate_ / rate;
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
132 return (blip_resampled_time_t) factor;
133 }
135 void Blip_Buffer::bass_freq( int freq )
136 {
137 bass_freq_ = freq;
138 int shift = 31;
139 if ( freq > 0 )
140 {
141 shift = 13;
142 long f = (freq << 16) / sample_rate_;
143 while ( (f >>= 1) && --shift ) { }
144 }
145 bass_shift_ = shift;
146 }
148 void Blip_Buffer::end_frame( blip_time_t t )
149 {
150 offset_ += t * factor_;
151 assert( samples_avail() <= (long) buffer_size_ ); // fails if time is past end of buffer
152 }
154 long Blip_Buffer::count_samples( blip_time_t t ) const
155 {
156 blip_resampled_time_t last_sample = resampled_time( t ) >> BLIP_BUFFER_ACCURACY;
157 blip_resampled_time_t first_sample = offset_ >> BLIP_BUFFER_ACCURACY;
158 return long (last_sample - first_sample);
159 }
161 blip_time_t Blip_Buffer::count_clocks( long count ) const
162 {
163 if ( !factor_ )
164 {
165 assert( 0 ); // sample rate and clock rates must be set first
166 return 0;
167 }
169 if ( count > buffer_size_ )
170 count = buffer_size_;
171 blip_resampled_time_t time = (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
172 return (blip_time_t) ((time - offset_ + factor_ - 1) / factor_);
173 }
175 void Blip_Buffer::remove_samples( long count )
176 {
177 if ( count )
178 {
179 remove_silence( count );
181 // copy remaining samples to beginning and clear old samples
182 long remain = samples_avail() + blip_buffer_extra_;
183 memmove( buffer_, buffer_ + count, remain * sizeof *buffer_ );
184 memset( buffer_ + remain, 0, count * sizeof *buffer_ );
185 }
186 }
188 // Blip_Synth_
190 Blip_Synth_Fast_::Blip_Synth_Fast_()
191 {
192 buf = 0;
193 last_amp = 0;
194 delta_factor = 0;
195 }
197 void Blip_Synth_Fast_::volume_unit( double new_unit )
198 {
199 delta_factor = int (new_unit * (1L << blip_sample_bits) + 0.5);
200 }
202 #if !BLIP_BUFFER_FAST
204 Blip_Synth_::Blip_Synth_( short* p, int w ) :
205 impulses( p ),
206 width( w )
207 {
208 volume_unit_ = 0.0;
209 kernel_unit = 0;
210 buf = 0;
211 last_amp = 0;
212 delta_factor = 0;
213 }
215 #undef PI
216 #define PI 3.1415926535897932384626433832795029
218 static void gen_sinc( float* out, int count, double oversample, double treble, double cutoff )
219 {
220 if ( cutoff >= 0.999 )
221 cutoff = 0.999;
223 if ( treble < -300.0 )
224 treble = -300.0;
225 if ( treble > 5.0 )
226 treble = 5.0;
228 double const maxh = 4096.0;
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 );
231 double const to_angle = PI / 2 / maxh / oversample;
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 );
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;
245 out [i] = (float) ((a * d + c * b) / (b * d)); // a / b + c / d
246 }
247 }
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;
259 gen_sinc( out, count, blip_res * oversample, treble, cutoff );
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 }
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 )
276 {
277 error -= impulses [i + p ];
278 error -= impulses [i + p2];
279 }
280 if ( p == p2 )
281 error /= 2; // phase = 0.5 impulse uses same half for both sides
282 impulses [size - blip_res + p] += (short) error;
283 //printf( "error: %ld\n", error );
284 }
286 //for ( int i = blip_res; i--; printf( "\n" ) )
287 // for ( int j = 0; j < width / 2; j++ )
288 // printf( "%5ld,", impulses [j * blip_res + i + 1] );
289 }
291 void Blip_Synth_::treble_eq( blip_eq_t const& eq )
292 {
293 float fimpulse [blip_res / 2 * (blip_widest_impulse_ - 1) + blip_res * 2];
295 int const half_size = blip_res / 2 * (width - 1);
296 eq.generate( &fimpulse [blip_res], half_size );
298 int i;
300 // need mirror slightly past center for calculation
301 for ( i = blip_res; i--; )
302 fimpulse [blip_res + half_size + i] = fimpulse [blip_res + half_size - 1 - i];
304 // starts at 0
305 for ( i = 0; i < blip_res; i++ )
306 fimpulse [i] = 0.0f;
308 // find rescale factor
309 double total = 0.0;
310 for ( i = 0; i < half_size; i++ )
311 total += fimpulse [blip_res + i];
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;
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();
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 }
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 );
348 volume_unit_ = new_unit;
349 double factor = new_unit * (1L << blip_sample_bits) / kernel_unit;
351 if ( factor > 0.0 )
352 {
353 int shift = 0;
355 // if unit is really small, might need to attenuate kernel
356 while ( factor < 2.0 )
357 {
358 shift++;
359 factor *= 2.0;
360 }
362 if ( shift )
363 {
364 kernel_unit >>= shift;
365 assert( kernel_unit > 0 ); // fails if volume unit is too low
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
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;
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;
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 }
419 BLIP_READER_END( reader, *this );
421 remove_samples( count );
422 }
423 return count;
424 }
426 void Blip_Buffer::mix_samples( blip_sample_t const* in, long count )
427 {
428 if ( buffer_size_ == silent_buf_size )
429 {
430 assert( 0 );
431 return;
432 }
434 buf_t_* out = buffer_ + (offset_ >> BLIP_BUFFER_ACCURACY) + blip_widest_impulse_ / 2;
436 int const sample_shift = blip_sample_bits - 16;
437 int prev = 0;
438 while ( count-- )
439 {
440 blip_long s = (blip_long) *in++ << sample_shift;
441 *out += s - prev;
442 prev = s;
443 ++out;
444 }
445 *out -= prev;
446 }
448 blip_ulong const subsample_mask = (1L << BLIP_BUFFER_ACCURACY) - 1;
450 void Blip_Buffer::save_state( blip_buffer_state_t* out )
451 {
452 assert( samples_avail() == 0 );
453 out->offset_ = offset_;
454 out->reader_accum_ = reader_accum_;
455 memcpy( out->buf, &buffer_ [offset_ >> BLIP_BUFFER_ACCURACY], sizeof out->buf );
456 }
458 void Blip_Buffer::load_state( blip_buffer_state_t const& in )
459 {
460 clear( false );
462 offset_ = in.offset_;
463 reader_accum_ = in.reader_accum_;
464 memcpy( buffer_, in.buf, sizeof in.buf );
465 }