diff options
Diffstat (limited to 'apps/codecs/libgme/blip_buffer.c')
-rw-r--r-- | apps/codecs/libgme/blip_buffer.c | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/apps/codecs/libgme/blip_buffer.c b/apps/codecs/libgme/blip_buffer.c new file mode 100644 index 0000000000..3061f68573 --- /dev/null +++ b/apps/codecs/libgme/blip_buffer.c | |||
@@ -0,0 +1,285 @@ | |||
1 | // Blip_Buffer 0.4.1. http://www.slack.net/~ant/ | ||
2 | |||
3 | #include "blip_buffer.h" | ||
4 | |||
5 | #include <assert.h> | ||
6 | #include <limits.h> | ||
7 | #include <string.h> | ||
8 | #include <stdlib.h> | ||
9 | #include <math.h> | ||
10 | |||
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 */ | ||
21 | |||
22 | #ifdef BLARGG_ENABLE_OPTIMIZER | ||
23 | #include BLARGG_ENABLE_OPTIMIZER | ||
24 | #endif | ||
25 | |||
26 | int const silent_buf_size = 1; // size used for Silent_Blip_Buffer | ||
27 | |||
28 | void Blip_init( struct Blip_Buffer* this ) | ||
29 | { | ||
30 | this->factor_ = LONG_MAX; | ||
31 | this->offset_ = 0; | ||
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; | ||
38 | this->length_ = 0; | ||
39 | |||
40 | // assumptions code makes about implementation-defined features | ||
41 | #ifndef NDEBUG | ||
42 | // right shift of negative value preserves sign | ||
43 | buf_t_ i = -0x7FFFFFFE; | ||
44 | assert( (i >> 1) == -0x3FFFFFFF ); | ||
45 | |||
46 | // casting to short truncates to 16 bits and sign-extends | ||
47 | i = 0x18000; | ||
48 | assert( (short) i == -0x8000 ); | ||
49 | #endif | ||
50 | } | ||
51 | |||
52 | void Blip_stop( struct Blip_Buffer* this ) | ||
53 | { | ||
54 | if ( this->buffer_size_ != silent_buf_size ) | ||
55 | free( this->buffer_ ); | ||
56 | } | ||
57 | |||
58 | void Blip_clear( struct Blip_Buffer* this, int entire_buffer ) | ||
59 | { | ||
60 | this->offset_ = 0; | ||
61 | this->reader_accum_ = 0; | ||
62 | this->modified_ = 0; | ||
63 | if ( this->buffer_ ) | ||
64 | { | ||
65 | long count = (entire_buffer ? this->buffer_size_ : Blip_samples_avail( this )); | ||
66 | memset( this->buffer_, 0, (count + blip_buffer_extra_) * sizeof (buf_t_) ); | ||
67 | } | ||
68 | } | ||
69 | |||
70 | blargg_err_t Blip_set_sample_rate( struct Blip_Buffer* this, long new_rate, int msec ) | ||
71 | { | ||
72 | if ( this->buffer_size_ == silent_buf_size ) | ||
73 | { | ||
74 | assert( 0 ); | ||
75 | return "Internal (tried to resize Silent_Blip_Buffer)"; | ||
76 | } | ||
77 | |||
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 ) | ||
81 | { | ||
82 | long s = (new_rate * (msec + 1) + 999) / 1000; | ||
83 | if ( s < new_size ) | ||
84 | new_size = s; | ||
85 | else | ||
86 | assert( 0 ); // fails if requested buffer length exceeds limit | ||
87 | } | ||
88 | |||
89 | if ( new_size > blip_buffer_max ) | ||
90 | return "Out of memory"; | ||
91 | |||
92 | this->buffer_size_ = new_size; | ||
93 | assert( this->buffer_size_ != silent_buf_size ); | ||
94 | |||
95 | // update things based on the sample rate | ||
96 | this->sample_rate_ = new_rate; | ||
97 | this->length_ = new_size * 1000 / new_rate - 1; | ||
98 | if ( msec ) | ||
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_ ); | ||
103 | |||
104 | Blip_clear( this, 1 ); | ||
105 | |||
106 | return 0; // success | ||
107 | } | ||
108 | |||
109 | /* Not sure if this affects sound quality */ | ||
110 | #if defined(ROCKBOX) | ||
111 | double floor(double x) { | ||
112 | if ( x > 0 ) return (int)x; | ||
113 | return (int)(x-0.9999999999999999); | ||
114 | } | ||
115 | #endif | ||
116 | |||
117 | blip_resampled_time_t Blip_clock_rate_factor( struct Blip_Buffer* this, long rate ) | ||
118 | { | ||
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; | ||
123 | } | ||
124 | |||
125 | void Blip_bass_freq( struct Blip_Buffer* this, int freq ) | ||
126 | { | ||
127 | this->bass_freq_ = freq; | ||
128 | int shift = 31; | ||
129 | if ( freq > 0 ) | ||
130 | { | ||
131 | shift = 13; | ||
132 | long f = (freq << 16) / this->sample_rate_; | ||
133 | while ( (f >>= 1) && --shift ) { } | ||
134 | } | ||
135 | this->bass_shift_ = shift; | ||
136 | } | ||
137 | |||
138 | void Blip_end_frame( struct Blip_Buffer* this, blip_time_t t ) | ||
139 | { | ||
140 | this->offset_ += t * this->factor_; | ||
141 | assert( Blip_samples_avail( this ) <= (long) this->buffer_size_ ); // time outside buffer length | ||
142 | } | ||
143 | |||
144 | void Blip_remove_silence( struct Blip_Buffer* this, long count ) | ||
145 | { | ||
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; | ||
148 | } | ||
149 | |||
150 | long Blip_count_samples( struct Blip_Buffer* this, blip_time_t t ) | ||
151 | { | ||
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); | ||
155 | } | ||
156 | |||
157 | blip_time_t Blip_count_clocks( struct Blip_Buffer* this, long count ) | ||
158 | { | ||
159 | if ( !this->factor_ ) | ||
160 | { | ||
161 | assert( 0 ); // sample rate and clock rates must be set first | ||
162 | return 0; | ||
163 | } | ||
164 | |||
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_); | ||
169 | } | ||
170 | |||
171 | void Blip_remove_samples( struct Blip_Buffer* this, long count ) | ||
172 | { | ||
173 | if ( count ) | ||
174 | { | ||
175 | Blip_remove_silence( this, count ); | ||
176 | |||
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_ ); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | long Blip_read_samples( struct Blip_Buffer* this, blip_sample_t* BLIP_RESTRICT out, long max_samples, int stereo ) | ||
185 | { | ||
186 | long count = Blip_samples_avail( this ); | ||
187 | if ( count > max_samples ) | ||
188 | count = max_samples; | ||
189 | |||
190 | if ( count ) | ||
191 | { | ||
192 | int const bass = BLIP_READER_BASS( *this ); | ||
193 | BLIP_READER_BEGIN( reader, *this ); | ||
194 | |||
195 | if ( !stereo ) | ||
196 | { | ||
197 | blip_long n; | ||
198 | for ( n = count; n; --n ) | ||
199 | { | ||
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 ); | ||
205 | } | ||
206 | } | ||
207 | else | ||
208 | { | ||
209 | blip_long n; | ||
210 | for ( n = count; n; --n ) | ||
211 | { | ||
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; | ||
216 | out += 2; | ||
217 | BLIP_READER_NEXT( reader, bass ); | ||
218 | } | ||
219 | } | ||
220 | BLIP_READER_END( reader, *this ); | ||
221 | |||
222 | Blip_remove_samples( this, count ); | ||
223 | } | ||
224 | return count; | ||
225 | } | ||
226 | |||
227 | void Blip_mix_samples( struct Blip_Buffer* this, blip_sample_t const* in, long count ) | ||
228 | { | ||
229 | if ( this->buffer_size_ == silent_buf_size ) | ||
230 | { | ||
231 | assert( 0 ); | ||
232 | return; | ||
233 | } | ||
234 | |||
235 | buf_t_* out = this->buffer_ + (this->offset_ >> BLIP_BUFFER_ACCURACY) + blip_widest_impulse_ / 2; | ||
236 | |||
237 | int const sample_shift = blip_sample_bits - 16; | ||
238 | int prev = 0; | ||
239 | while ( count-- ) | ||
240 | { | ||
241 | blip_long s = (blip_long) *in++ << sample_shift; | ||
242 | *out += s - prev; | ||
243 | prev = s; | ||
244 | ++out; | ||
245 | } | ||
246 | *out -= prev; | ||
247 | } | ||
248 | |||
249 | void Blip_set_modified( struct Blip_Buffer* this ) | ||
250 | { | ||
251 | this->modified_ = 1; | ||
252 | } | ||
253 | |||
254 | int Blip_clear_modified( struct Blip_Buffer* this ) | ||
255 | { | ||
256 | int b = this->modified_; | ||
257 | this->modified_ = 0; | ||
258 | return b; | ||
259 | } | ||
260 | |||
261 | blip_resampled_time_t Blip_resampled_duration( struct Blip_Buffer* this, int t ) | ||
262 | { | ||
263 | return t * this->factor_; | ||
264 | } | ||
265 | |||
266 | blip_resampled_time_t Blip_resampled_time( struct Blip_Buffer* this, blip_time_t t ) | ||
267 | { | ||
268 | return t * this->factor_ + this->offset_; | ||
269 | } | ||
270 | |||
271 | |||
272 | // Blip_Synth | ||
273 | |||
274 | void Synth_init( struct Blip_Synth* this ) | ||
275 | { | ||
276 | this->buf = 0; | ||
277 | this->last_amp = 0; | ||
278 | this->delta_factor = 0; | ||
279 | } | ||
280 | |||
281 | // Set overall volume of waveform | ||
282 | void Synth_volume( struct Blip_Synth* this, double v ) | ||
283 | { | ||
284 | this->delta_factor = (int) (v * (1L << blip_sample_bits) + 0.5); | ||
285 | } | ||