1 // Blip_Buffer 0.4.1. http://www.slack.net/~ant/
3 #include "blip_buffer.h"
11 /* Copyright (C) 2003-2006 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 #ifdef BLARGG_ENABLE_OPTIMIZER
23 #include BLARGG_ENABLE_OPTIMIZER
26 int const silent_buf_size
= 1; // size used for Silent_Blip_Buffer
28 void Blip_init( struct Blip_Buffer
* this )
30 this->factor_
= LONG_MAX
;
32 this->buffer_size_
= 0;
33 this->sample_rate_
= 0;
34 this->reader_accum_
= 0;
35 this->bass_shift_
= 0;
36 this->clock_rate_
= 0;
37 this->bass_freq_
= 16;
40 // assumptions code makes about implementation-defined features
42 // right shift of negative value preserves sign
43 buf_t_ i
= -0x7FFFFFFE;
44 assert( (i
>> 1) == -0x3FFFFFFF );
46 // casting to short truncates to 16 bits and sign-extends
48 assert( (short) i
== -0x8000 );
52 void Blip_stop( struct Blip_Buffer
* this )
54 if ( this->buffer_size_
!= silent_buf_size
)
55 free( this->buffer_
);
58 void Blip_clear( struct Blip_Buffer
* this, int entire_buffer
)
61 this->reader_accum_
= 0;
65 long count
= (entire_buffer
? this->buffer_size_
: Blip_samples_avail( this ));
66 memset( this->buffer_
, 0, (count
+ blip_buffer_extra_
) * sizeof (buf_t_
) );
70 blargg_err_t
Blip_set_sample_rate( struct Blip_Buffer
* this, long new_rate
, int msec
)
72 if ( this->buffer_size_
== silent_buf_size
)
75 return "Internal (tried to resize Silent_Blip_Buffer)";
78 // start with maximum length that resampled time can represent
79 long new_size
= (ULONG_MAX
>> BLIP_BUFFER_ACCURACY
) - blip_buffer_extra_
- 64;
80 if ( msec
!= blip_max_length
)
82 long s
= (new_rate
* (msec
+ 1) + 999) / 1000;
86 assert( 0 ); // fails if requested buffer length exceeds limit
89 if ( new_size
> blip_buffer_max
)
90 return "Out of memory";
92 this->buffer_size_
= new_size
;
93 assert( this->buffer_size_
!= silent_buf_size
);
95 // update things based on the sample rate
96 this->sample_rate_
= new_rate
;
97 this->length_
= new_size
* 1000 / new_rate
- 1;
99 assert( this->length_
== msec
); // ensure length is same as that passed in
100 if ( this->clock_rate_
)
101 Blip_set_clock_rate( this, this->clock_rate_
);
102 Blip_bass_freq( this, this->bass_freq_
);
104 Blip_clear( this, 1 );
109 /* Not sure if this affects sound quality */
111 double floor(double x
) {
112 if ( x
> 0 ) return (int)x
;
113 return (int)(x
-0.9999999999999999);
117 blip_resampled_time_t
Blip_clock_rate_factor( struct Blip_Buffer
* this, long rate
)
119 double ratio
= (double) this->sample_rate_
/ rate
;
120 blip_long factor
= (blip_long
) floor( ratio
* (1L << BLIP_BUFFER_ACCURACY
) + 0.5 );
121 assert( factor
> 0 || !this->sample_rate_
); // fails if clock/output ratio is too large
122 return (blip_resampled_time_t
) factor
;
125 void Blip_bass_freq( struct Blip_Buffer
* this, int freq
)
127 this->bass_freq_
= freq
;
132 long f
= (freq
<< 16) / this->sample_rate_
;
133 while ( (f
>>= 1) && --shift
) { }
135 this->bass_shift_
= shift
;
138 void Blip_end_frame( struct Blip_Buffer
* this, blip_time_t t
)
140 this->offset_
+= t
* this->factor_
;
141 assert( Blip_samples_avail( this ) <= (long) this->buffer_size_
); // time outside buffer length
144 void Blip_remove_silence( struct Blip_Buffer
* this, long count
)
146 assert( count
<= Blip_samples_avail( this ) ); // tried to remove more samples than available
147 this->offset_
-= (blip_resampled_time_t
) count
<< BLIP_BUFFER_ACCURACY
;
150 long Blip_count_samples( struct Blip_Buffer
* this, blip_time_t t
)
152 unsigned long last_sample
= Blip_resampled_time( this, t
) >> BLIP_BUFFER_ACCURACY
;
153 unsigned long first_sample
= this->offset_
>> BLIP_BUFFER_ACCURACY
;
154 return (long) (last_sample
- first_sample
);
157 blip_time_t
Blip_count_clocks( struct Blip_Buffer
* this, long count
)
159 if ( !this->factor_
)
161 assert( 0 ); // sample rate and clock rates must be set first
165 if ( count
> this->buffer_size_
)
166 count
= this->buffer_size_
;
167 blip_resampled_time_t time
= (blip_resampled_time_t
) count
<< BLIP_BUFFER_ACCURACY
;
168 return (blip_time_t
) ((time
- this->offset_
+ this->factor_
- 1) / this->factor_
);
171 void Blip_remove_samples( struct Blip_Buffer
* this, long count
)
175 Blip_remove_silence( this, count
);
177 // copy remaining samples to beginning and clear old samples
178 long remain
= Blip_samples_avail( this ) + blip_buffer_extra_
;
179 memmove( this->buffer_
, this->buffer_
+ count
, remain
* sizeof *this->buffer_
);
180 memset( this->buffer_
+ remain
, 0, count
* sizeof *this->buffer_
);
184 long Blip_read_samples( struct Blip_Buffer
* this, blip_sample_t
* BLIP_RESTRICT out
, long max_samples
, int stereo
)
186 long count
= Blip_samples_avail( this );
187 if ( count
> max_samples
)
192 int const bass
= BLIP_READER_BASS( *this );
193 BLIP_READER_BEGIN( reader
, *this );
198 for ( n
= count
; n
; --n
)
200 blip_long s
= BLIP_READER_READ( reader
);
201 if ( (blip_sample_t
) s
!= s
)
202 s
= 0x7FFF - (s
>> 24);
203 *out
++ = (blip_sample_t
) s
;
204 BLIP_READER_NEXT( reader
, bass
);
210 for ( n
= count
; n
; --n
)
212 blip_long s
= BLIP_READER_READ( reader
);
213 if ( (blip_sample_t
) s
!= s
)
214 s
= 0x7FFF - (s
>> 24);
215 *out
= (blip_sample_t
) s
;
217 BLIP_READER_NEXT( reader
, bass
);
220 BLIP_READER_END( reader
, *this );
222 Blip_remove_samples( this, count
);
227 void Blip_mix_samples( struct Blip_Buffer
* this, blip_sample_t
const* in
, long count
)
229 if ( this->buffer_size_
== silent_buf_size
)
235 buf_t_
* out
= this->buffer_
+ (this->offset_
>> BLIP_BUFFER_ACCURACY
) + blip_widest_impulse_
/ 2;
237 int const sample_shift
= blip_sample_bits
- 16;
241 blip_long s
= (blip_long
) *in
++ << sample_shift
;
249 void Blip_set_modified( struct Blip_Buffer
* this )
254 int Blip_clear_modified( struct Blip_Buffer
* this )
256 int b
= this->modified_
;
261 blip_resampled_time_t
Blip_resampled_duration( struct Blip_Buffer
* this, int t
)
263 return t
* this->factor_
;
266 blip_resampled_time_t
Blip_resampled_time( struct Blip_Buffer
* this, blip_time_t t
)
268 return t
* this->factor_
+ this->offset_
;
274 void Synth_init( struct Blip_Synth
* this )
278 this->delta_factor
= 0;
281 // Set overall volume of waveform
282 void Synth_volume( struct Blip_Synth
* this, double v
)
284 this->delta_factor
= (int) (v
* (1L << blip_sample_bits
) + 0.5);