summaryrefslogtreecommitdiff
path: root/apps/codecs/libgme/blip_buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libgme/blip_buffer.c')
-rw-r--r--apps/codecs/libgme/blip_buffer.c285
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
12can redistribute it and/or modify it under the terms of the GNU Lesser
13General Public License as published by the Free Software Foundation; either
14version 2.1 of the License, or (at your option) any later version. This
15module is distributed in the hope that it will be useful, but WITHOUT ANY
16WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
18details. You should have received a copy of the GNU Lesser General Public
19License along with this module; if not, write to the Free Software Foundation,
20Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
21
22#ifdef BLARGG_ENABLE_OPTIMIZER
23 #include BLARGG_ENABLE_OPTIMIZER
24#endif
25
26int const silent_buf_size = 1; // size used for Silent_Blip_Buffer
27
28void 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
52void Blip_stop( struct Blip_Buffer* this )
53{
54 if ( this->buffer_size_ != silent_buf_size )
55 free( this->buffer_ );
56}
57
58void 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
70blargg_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)
111double floor(double x) {
112 if ( x > 0 ) return (int)x;
113 return (int)(x-0.9999999999999999);
114}
115#endif
116
117blip_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
125void 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
138void 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
144void 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
150long 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
157blip_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
171void 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
184long 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
227void 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
249void Blip_set_modified( struct Blip_Buffer* this )
250{
251 this->modified_ = 1;
252}
253
254int Blip_clear_modified( struct Blip_Buffer* this )
255{
256 int b = this->modified_;
257 this->modified_ = 0;
258 return b;
259}
260
261blip_resampled_time_t Blip_resampled_duration( struct Blip_Buffer* this, int t )
262{
263 return t * this->factor_;
264}
265
266blip_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
274void 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
282void Synth_volume( struct Blip_Synth* this, double v )
283{
284 this->delta_factor = (int) (v * (1L << blip_sample_bits) + 0.5);
285}