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.c237
1 files changed, 93 insertions, 144 deletions
diff --git a/apps/codecs/libgme/blip_buffer.c b/apps/codecs/libgme/blip_buffer.c
index d8ecbb8bb2..ba0a6558d2 100644
--- a/apps/codecs/libgme/blip_buffer.c
+++ b/apps/codecs/libgme/blip_buffer.c
@@ -2,7 +2,6 @@
2 2
3#include "blip_buffer.h" 3#include "blip_buffer.h"
4 4
5#include <assert.h>
6#include <limits.h> 5#include <limits.h>
7#include <string.h> 6#include <string.h>
8#include <stdlib.h> 7#include <stdlib.h>
@@ -19,96 +18,78 @@ details. 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, 18License along with this module; if not, write to the Free Software Foundation,
20Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 19Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
21 20
22#ifdef BLARGG_ENABLE_OPTIMIZER 21#include "blargg_source.h"
23 #include BLARGG_ENABLE_OPTIMIZER
24#endif
25
26int const silent_buf_size = 1; // size used for Silent_Blip_Buffer
27 22
28void Blip_init( struct Blip_Buffer* this ) 23void Blip_init( struct Blip_Buffer* this )
29{ 24{
30 this->factor_ = (blip_ulong)LONG_MAX; 25 this->factor_ = UINT_MAX/2 + 1;;
31 this->offset_ = 0; 26 this->buffer_center_ = NULL;
32 this->buffer_size_ = 0; 27 this->buffer_size_ = 0;
33 this->sample_rate_ = 0; 28 this->sample_rate_ = 0;
34 this->reader_accum_ = 0; 29 this->bass_shift_ = 0;
35 this->bass_shift_ = 0; 30 this->clock_rate_ = 0;
36 this->clock_rate_ = 0; 31 this->bass_freq_ = 16;
37 this->bass_freq_ = 16; 32 this->length_ = 0;
38 this->length_ = 0; 33
39
40 // assumptions code makes about implementation-defined features 34 // assumptions code makes about implementation-defined features
41 #ifndef NDEBUG 35 #ifndef NDEBUG
42 // right shift of negative value preserves sign 36 // right shift of negative value preserves sign
43 buf_t_ i = -0x7FFFFFFE; 37 buf_t_ i = -0x7FFFFFFE;
44 assert( (i >> 1) == -0x3FFFFFFF ); 38 assert( (i >> 1) == -0x3FFFFFFF );
45 39
46 // casting to short truncates to 16 bits and sign-extends 40 // casting to short truncates to 16 bits and sign-extends
47 i = 0x18000; 41 i = 0x18000;
48 assert( (short) i == -0x8000 ); 42 assert( (short) i == -0x8000 );
49 #endif 43 #endif
50}
51 44
52void Blip_stop( struct Blip_Buffer* this ) 45 Blip_clear( this );
53{
54 if ( this->buffer_size_ != silent_buf_size )
55 free( this->buffer_ );
56} 46}
57 47
58void Blip_clear( struct Blip_Buffer* this, int entire_buffer ) 48void Blip_clear( struct Blip_Buffer* this )
59{ 49{
60 this->offset_ = 0; 50 bool const entire_buffer = true;
51
52 this->offset_ = 0;
61 this->reader_accum_ = 0; 53 this->reader_accum_ = 0;
62 this->modified_ = 0; 54 this->modified = false;
55
63 if ( this->buffer_ ) 56 if ( this->buffer_ )
64 { 57 {
65 long count = (entire_buffer ? this->buffer_size_ : Blip_samples_avail( this )); 58 int count = (entire_buffer ? this->buffer_size_ : Blip_samples_avail( this ));
66 memset( this->buffer_, 0, (count + blip_buffer_extra_) * sizeof (buf_t_) ); 59 memset( this->buffer_, 0, (count + blip_buffer_extra_) * sizeof (delta_t) );
67 } 60 }
68} 61}
69 62
70blargg_err_t Blip_set_sample_rate( struct Blip_Buffer* this, long new_rate, int msec ) 63blargg_err_t Blip_set_sample_rate( struct Blip_Buffer* this, int new_rate, int msec )
71{ 64{
72 if ( this->buffer_size_ == silent_buf_size ) 65 // Limit to maximum size that resampled time can represent
73 { 66 int max_size = (((blip_resampled_time_t) -1) >> BLIP_BUFFER_ACCURACY) -
74 assert( 0 ); 67 blip_buffer_extra_ - 64; // TODO: -64 isn't needed
75 return "Internal (tried to resize Silent_Blip_Buffer)"; 68 int new_size = (new_rate * (msec + 1) + 999) / 1000;
76 } 69 if ( new_size > max_size )
77 70 new_size = max_size;
78 // start with maximum length that resampled time can represent 71
79 long new_size = (ULONG_MAX >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 64; 72 // Resize buffer
80 if ( msec != blip_max_length ) 73 if ( this->buffer_size_ != new_size ) {
81 { 74 this->buffer_center_ = this->buffer_ + BLIP_MAX_QUALITY/2;
82 long s = (new_rate * (msec + 1) + 999) / 1000; 75 this->buffer_size_ = new_size;
83 if ( s < new_size ) 76 }
84 new_size = s; 77
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 78 // update things based on the sample rate
96 this->sample_rate_ = new_rate; 79 this->sample_rate_ = new_rate;
97 this->length_ = new_size * 1000 / new_rate - 1; 80 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_ ) 81 if ( this->clock_rate_ )
101 Blip_set_clock_rate( this, this->clock_rate_ ); 82 Blip_set_clock_rate( this, this->clock_rate_ );
102 Blip_bass_freq( this, this->bass_freq_ ); 83 Blip_bass_freq( this, this->bass_freq_ );
103 84
104 Blip_clear( this, 1 ); 85 Blip_clear( this );
105 86
106 return 0; // success 87 return 0; // success
107} 88}
108 89
109blip_resampled_time_t Blip_clock_rate_factor( struct Blip_Buffer* this, long rate ) 90blip_resampled_time_t Blip_clock_rate_factor( struct Blip_Buffer* this, int rate )
110{ 91{
111 blip_long factor = (blip_long) ( this->sample_rate_ * (1LL << BLIP_BUFFER_ACCURACY) / rate); 92 int factor = (int) ( this->sample_rate_ * (1LL << BLIP_BUFFER_ACCURACY) / rate);
112 assert( factor > 0 || !this->sample_rate_ ); // fails if clock/output ratio is too large 93 assert( factor > 0 || !this->sample_rate_ ); // fails if clock/output ratio is too large
113 return (blip_resampled_time_t) factor; 94 return (blip_resampled_time_t) factor;
114} 95}
@@ -117,119 +98,111 @@ void Blip_bass_freq( struct Blip_Buffer* this, int freq )
117{ 98{
118 this->bass_freq_ = freq; 99 this->bass_freq_ = freq;
119 int shift = 31; 100 int shift = 31;
120 if ( freq > 0 ) 101 if ( freq > 0 && this->sample_rate_ )
121 { 102 {
122 shift = 13; 103 shift = 13;
123 long f = (freq << 16) / this->sample_rate_; 104 int f = (freq << 16) / this->sample_rate_;
124 while ( (f >>= 1) && --shift ) { } 105 while ( (f >>= 1) && --shift ) { }
125 } 106 }
126 this->bass_shift_ = shift; 107 this->bass_shift_ = shift;
127} 108}
128 109
129void Blip_end_frame( struct Blip_Buffer* this, blip_time_t t ) 110void Blip_end_frame( struct Blip_Buffer* this, blip_time_t t )
130{ 111{
131 this->offset_ += t * this->factor_; 112 this->offset_ += t * this->factor_;
132 assert( Blip_samples_avail( this ) <= (long) this->buffer_size_ ); // time outside buffer length 113 assert( Blip_samples_avail( this ) <= (int) this->buffer_size_ ); // time outside buffer length
133} 114}
134 115
135void Blip_remove_silence( struct Blip_Buffer* this, long count ) 116int Blip_count_samples( struct Blip_Buffer* this, blip_time_t t )
136{ 117{
137 assert( count <= Blip_samples_avail( this ) ); // tried to remove more samples than available 118 blip_resampled_time_t last_sample = Blip_resampled_time( this, t ) >> BLIP_BUFFER_ACCURACY;
138 this->offset_ -= (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY; 119 blip_resampled_time_t first_sample = this->offset_ >> BLIP_BUFFER_ACCURACY;
120 return (int) (last_sample - first_sample);
139} 121}
140 122
141long Blip_count_samples( struct Blip_Buffer* this, blip_time_t t ) 123blip_time_t Blip_count_clocks( struct Blip_Buffer* this, int count )
142{ 124{
143 unsigned long last_sample = Blip_resampled_time( this, t ) >> BLIP_BUFFER_ACCURACY;
144 unsigned long first_sample = this->offset_ >> BLIP_BUFFER_ACCURACY;
145 return (long) (last_sample - first_sample);
146}
147
148blip_time_t Blip_count_clocks( struct Blip_Buffer* this, long count )
149{
150 if ( !this->factor_ )
151 {
152 assert( 0 ); // sample rate and clock rates must be set first
153 return 0;
154 }
155
156 if ( count > this->buffer_size_ ) 125 if ( count > this->buffer_size_ )
157 count = this->buffer_size_; 126 count = this->buffer_size_;
158 blip_resampled_time_t time = (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY; 127 blip_resampled_time_t time = (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
159 return (blip_time_t) ((time - this->offset_ + this->factor_ - 1) / this->factor_); 128 return (blip_time_t) ((time - this->offset_ + this->factor_ - 1) / this->factor_);
160} 129}
161 130
162void Blip_remove_samples( struct Blip_Buffer* this, long count ) 131void Blip_remove_samples( struct Blip_Buffer* this, int count )
163{ 132{
164 if ( count ) 133 if ( count )
165 { 134 {
166 Blip_remove_silence( this, count ); 135 Blip_remove_silence( this, count );
167 136
168 // copy remaining samples to beginning and clear old samples 137 // copy remaining samples to beginning and clear old samples
169 long remain = Blip_samples_avail( this ) + blip_buffer_extra_; 138 int remain = Blip_samples_avail( this ) + blip_buffer_extra_;
170 memmove( this->buffer_, this->buffer_ + count, remain * sizeof *this->buffer_ ); 139 memmove( this->buffer_, this->buffer_ + count, remain * sizeof *this->buffer_ );
171 memset( this->buffer_ + remain, 0, count * sizeof *this->buffer_ ); 140 memset( this->buffer_ + remain, 0, count * sizeof *this->buffer_ );
172 } 141 }
173} 142}
174 143
175long Blip_read_samples( struct Blip_Buffer* this, blip_sample_t* BLIP_RESTRICT out, long max_samples, int stereo ) 144int Blip_read_samples( struct Blip_Buffer* this, blip_sample_t out_ [], int max_samples, bool stereo )
176{ 145{
177 long count = Blip_samples_avail( this ); 146 int count = Blip_samples_avail( this );
178 if ( count > max_samples ) 147 if ( count > max_samples )
179 count = max_samples; 148 count = max_samples;
180 149
181 if ( count ) 150 if ( count )
182 { 151 {
183 int const bass = BLIP_READER_BASS( *this ); 152 int const bass = this->bass_shift_;
184 BLIP_READER_BEGIN( reader, *this ); 153 delta_t const* reader = this->buffer_ + count;
185 154 int reader_sum = this->reader_accum_;
155
156 blip_sample_t* BLARGG_RESTRICT out = out_ + count;
157 if ( stereo )
158 out += count;
159 int offset = -count;
160
186 if ( !stereo ) 161 if ( !stereo )
187 { 162 {
188 blip_long n; 163 do
189 for ( n = count; n; --n )
190 { 164 {
191 blip_long s = BLIP_READER_READ( reader ); 165 int s = reader_sum >> delta_bits;
192 if ( (blip_sample_t) s != s ) 166
193 s = 0x7FFF - (s >> 24); 167 reader_sum -= reader_sum >> bass;
194 *out++ = (blip_sample_t) s; 168 reader_sum += reader [offset];
195 BLIP_READER_NEXT( reader, bass ); 169
170 BLIP_CLAMP( s, s );
171 out [offset] = (blip_sample_t) s;
196 } 172 }
173 while ( ++offset );
197 } 174 }
198 else 175 else
199 { 176 {
200 blip_long n; 177 do
201 for ( n = count; n; --n )
202 { 178 {
203 blip_long s = BLIP_READER_READ( reader ); 179 int s = reader_sum >> delta_bits;
204 if ( (blip_sample_t) s != s ) 180
205 s = 0x7FFF - (s >> 24); 181 reader_sum -= reader_sum >> bass;
206 *out = (blip_sample_t) s; 182 reader_sum += reader [offset];
207 out += 2; 183
208 BLIP_READER_NEXT( reader, bass ); 184 BLIP_CLAMP( s, s );
185 out [offset * 2] = (blip_sample_t) s;
209 } 186 }
187 while ( ++offset );
210 } 188 }
211 BLIP_READER_END( reader, *this ); 189
212 190 this->reader_accum_ = reader_sum;
191
213 Blip_remove_samples( this, count ); 192 Blip_remove_samples( this, count );
214 } 193 }
215 return count; 194 return count;
216} 195}
217 196
218void Blip_mix_samples( struct Blip_Buffer* this, blip_sample_t const* in, long count ) 197void Blip_mix_samples( struct Blip_Buffer* this, blip_sample_t const in [], int count )
219{ 198{
220 if ( this->buffer_size_ == silent_buf_size ) 199 delta_t* out = this->buffer_center_ + (this->offset_ >> BLIP_BUFFER_ACCURACY);
221 { 200
222 assert( 0 );
223 return;
224 }
225
226 buf_t_* out = this->buffer_ + (this->offset_ >> BLIP_BUFFER_ACCURACY) + blip_widest_impulse_ / 2;
227
228 int const sample_shift = blip_sample_bits - 16; 201 int const sample_shift = blip_sample_bits - 16;
229 int prev = 0; 202 int prev = 0;
230 while ( count-- ) 203 while ( --count >= 0 )
231 { 204 {
232 blip_long s = (blip_long) *in++ << sample_shift; 205 int s = *in++ << sample_shift;
233 *out += s - prev; 206 *out += s - prev;
234 prev = s; 207 prev = s;
235 ++out; 208 ++out;
@@ -237,40 +210,16 @@ void Blip_mix_samples( struct Blip_Buffer* this, blip_sample_t const* in, long
237 *out -= prev; 210 *out -= prev;
238} 211}
239 212
240void Blip_set_modified( struct Blip_Buffer* this ) 213// Blip_Synth
241{
242 this->modified_ = 1;
243}
244
245int Blip_clear_modified( struct Blip_Buffer* this )
246{
247 int b = this->modified_;
248 this->modified_ = 0;
249 return b;
250}
251
252blip_resampled_time_t Blip_resampled_duration( struct Blip_Buffer* this, int t )
253{
254 return t * this->factor_;
255}
256 214
257blip_resampled_time_t Blip_resampled_time( struct Blip_Buffer* this, blip_time_t t ) 215void volume_unit( struct Blip_Synth* this, int new_unit )
258{ 216{
259 return t * this->factor_ + this->offset_; 217 this->delta_factor = (int) (new_unit * (1LL << blip_sample_bits) / FP_ONE_VOLUME);
260} 218}
261 219
262
263// Blip_Synth
264
265void Synth_init( struct Blip_Synth* this ) 220void Synth_init( struct Blip_Synth* this )
266{ 221{
267 this->buf = 0; 222 this->buf = 0;
268 this->last_amp = 0; 223 this->last_amp = 0;
269 this->delta_factor = 0; 224 this->delta_factor = 0;
270} 225}
271
272// Set overall volume of waveform
273void Synth_volume( struct Blip_Synth* this, int v )
274{
275 this->delta_factor = (int) (v * (1LL << blip_sample_bits) / FP_ONE_VOLUME);
276}