summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libgme/blip_buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libgme/blip_buffer.c')
-rw-r--r--lib/rbcodec/codecs/libgme/blip_buffer.c225
1 files changed, 225 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libgme/blip_buffer.c b/lib/rbcodec/codecs/libgme/blip_buffer.c
new file mode 100644
index 0000000000..ba0a6558d2
--- /dev/null
+++ b/lib/rbcodec/codecs/libgme/blip_buffer.c
@@ -0,0 +1,225 @@
1// Blip_Buffer 0.4.1. http://www.slack.net/~ant/
2
3#include "blip_buffer.h"
4
5#include <limits.h>
6#include <string.h>
7#include <stdlib.h>
8#include <math.h>
9
10/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
11can redistribute it and/or modify it under the terms of the GNU Lesser
12General Public License as published by the Free Software Foundation; either
13version 2.1 of the License, or (at your option) any later version. This
14module is distributed in the hope that it will be useful, but WITHOUT ANY
15WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17details. You should have received a copy of the GNU Lesser General Public
18License along with this module; if not, write to the Free Software Foundation,
19Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
20
21#include "blargg_source.h"
22
23void Blip_init( struct Blip_Buffer* this )
24{
25 this->factor_ = UINT_MAX/2 + 1;;
26 this->buffer_center_ = NULL;
27 this->buffer_size_ = 0;
28 this->sample_rate_ = 0;
29 this->bass_shift_ = 0;
30 this->clock_rate_ = 0;
31 this->bass_freq_ = 16;
32 this->length_ = 0;
33
34 // assumptions code makes about implementation-defined features
35 #ifndef NDEBUG
36 // right shift of negative value preserves sign
37 buf_t_ i = -0x7FFFFFFE;
38 assert( (i >> 1) == -0x3FFFFFFF );
39
40 // casting to short truncates to 16 bits and sign-extends
41 i = 0x18000;
42 assert( (short) i == -0x8000 );
43 #endif
44
45 Blip_clear( this );
46}
47
48void Blip_clear( struct Blip_Buffer* this )
49{
50 bool const entire_buffer = true;
51
52 this->offset_ = 0;
53 this->reader_accum_ = 0;
54 this->modified = false;
55
56 if ( this->buffer_ )
57 {
58 int count = (entire_buffer ? this->buffer_size_ : Blip_samples_avail( this ));
59 memset( this->buffer_, 0, (count + blip_buffer_extra_) * sizeof (delta_t) );
60 }
61}
62
63blargg_err_t Blip_set_sample_rate( struct Blip_Buffer* this, int new_rate, int msec )
64{
65 // Limit to maximum size that resampled time can represent
66 int max_size = (((blip_resampled_time_t) -1) >> BLIP_BUFFER_ACCURACY) -
67 blip_buffer_extra_ - 64; // TODO: -64 isn't needed
68 int new_size = (new_rate * (msec + 1) + 999) / 1000;
69 if ( new_size > max_size )
70 new_size = max_size;
71
72 // Resize buffer
73 if ( this->buffer_size_ != new_size ) {
74 this->buffer_center_ = this->buffer_ + BLIP_MAX_QUALITY/2;
75 this->buffer_size_ = new_size;
76 }
77
78 // update things based on the sample rate
79 this->sample_rate_ = new_rate;
80 this->length_ = new_size * 1000 / new_rate - 1;
81 if ( this->clock_rate_ )
82 Blip_set_clock_rate( this, this->clock_rate_ );
83 Blip_bass_freq( this, this->bass_freq_ );
84
85 Blip_clear( this );
86
87 return 0; // success
88}
89
90blip_resampled_time_t Blip_clock_rate_factor( struct Blip_Buffer* this, int rate )
91{
92 int factor = (int) ( this->sample_rate_ * (1LL << BLIP_BUFFER_ACCURACY) / rate);
93 assert( factor > 0 || !this->sample_rate_ ); // fails if clock/output ratio is too large
94 return (blip_resampled_time_t) factor;
95}
96
97void Blip_bass_freq( struct Blip_Buffer* this, int freq )
98{
99 this->bass_freq_ = freq;
100 int shift = 31;
101 if ( freq > 0 && this->sample_rate_ )
102 {
103 shift = 13;
104 int f = (freq << 16) / this->sample_rate_;
105 while ( (f >>= 1) && --shift ) { }
106 }
107 this->bass_shift_ = shift;
108}
109
110void Blip_end_frame( struct Blip_Buffer* this, blip_time_t t )
111{
112 this->offset_ += t * this->factor_;
113 assert( Blip_samples_avail( this ) <= (int) this->buffer_size_ ); // time outside buffer length
114}
115
116int Blip_count_samples( struct Blip_Buffer* this, blip_time_t t )
117{
118 blip_resampled_time_t last_sample = Blip_resampled_time( this, t ) >> BLIP_BUFFER_ACCURACY;
119 blip_resampled_time_t first_sample = this->offset_ >> BLIP_BUFFER_ACCURACY;
120 return (int) (last_sample - first_sample);
121}
122
123blip_time_t Blip_count_clocks( struct Blip_Buffer* this, int count )
124{
125 if ( count > this->buffer_size_ )
126 count = this->buffer_size_;
127 blip_resampled_time_t time = (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
128 return (blip_time_t) ((time - this->offset_ + this->factor_ - 1) / this->factor_);
129}
130
131void Blip_remove_samples( struct Blip_Buffer* this, int count )
132{
133 if ( count )
134 {
135 Blip_remove_silence( this, count );
136
137 // copy remaining samples to beginning and clear old samples
138 int remain = Blip_samples_avail( this ) + blip_buffer_extra_;
139 memmove( this->buffer_, this->buffer_ + count, remain * sizeof *this->buffer_ );
140 memset( this->buffer_ + remain, 0, count * sizeof *this->buffer_ );
141 }
142}
143
144int Blip_read_samples( struct Blip_Buffer* this, blip_sample_t out_ [], int max_samples, bool stereo )
145{
146 int count = Blip_samples_avail( this );
147 if ( count > max_samples )
148 count = max_samples;
149
150 if ( count )
151 {
152 int const bass = this->bass_shift_;
153 delta_t const* reader = this->buffer_ + count;
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
161 if ( !stereo )
162 {
163 do
164 {
165 int s = reader_sum >> delta_bits;
166
167 reader_sum -= reader_sum >> bass;
168 reader_sum += reader [offset];
169
170 BLIP_CLAMP( s, s );
171 out [offset] = (blip_sample_t) s;
172 }
173 while ( ++offset );
174 }
175 else
176 {
177 do
178 {
179 int s = reader_sum >> delta_bits;
180
181 reader_sum -= reader_sum >> bass;
182 reader_sum += reader [offset];
183
184 BLIP_CLAMP( s, s );
185 out [offset * 2] = (blip_sample_t) s;
186 }
187 while ( ++offset );
188 }
189
190 this->reader_accum_ = reader_sum;
191
192 Blip_remove_samples( this, count );
193 }
194 return count;
195}
196
197void Blip_mix_samples( struct Blip_Buffer* this, blip_sample_t const in [], int count )
198{
199 delta_t* out = this->buffer_center_ + (this->offset_ >> BLIP_BUFFER_ACCURACY);
200
201 int const sample_shift = blip_sample_bits - 16;
202 int prev = 0;
203 while ( --count >= 0 )
204 {
205 int s = *in++ << sample_shift;
206 *out += s - prev;
207 prev = s;
208 ++out;
209 }
210 *out -= prev;
211}
212
213// Blip_Synth
214
215void volume_unit( struct Blip_Synth* this, int new_unit )
216{
217 this->delta_factor = (int) (new_unit * (1LL << blip_sample_bits) / FP_ONE_VOLUME);
218}
219
220void Synth_init( struct Blip_Synth* this )
221{
222 this->buf = 0;
223 this->last_amp = 0;
224 this->delta_factor = 0;
225}