diff options
author | Sean Bartell <wingedtachikoma@gmail.com> | 2011-06-25 21:32:25 -0400 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2012-04-25 22:13:20 +0200 |
commit | f40bfc9267b13b54e6379dfe7539447662879d24 (patch) | |
tree | 9b20069d5e62809ff434061ad730096836f916f2 /lib/rbcodec/codecs/libgme/blip_buffer.c | |
parent | a0009907de7a0107d49040d8a180f140e2eff299 (diff) | |
download | rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.tar.gz rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.zip |
Add codecs to librbcodec.
Change-Id: Id7f4717d51ed02d67cb9f9cb3c0ada4a81843f97
Reviewed-on: http://gerrit.rockbox.org/137
Reviewed-by: Nils Wallménius <nils@rockbox.org>
Tested-by: Nils Wallménius <nils@rockbox.org>
Diffstat (limited to 'lib/rbcodec/codecs/libgme/blip_buffer.c')
-rw-r--r-- | lib/rbcodec/codecs/libgme/blip_buffer.c | 225 |
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 | ||
11 | can redistribute it and/or modify it under the terms of the GNU Lesser | ||
12 | General Public License as published by the Free Software Foundation; either | ||
13 | version 2.1 of the License, or (at your option) any later version. This | ||
14 | module is distributed in the hope that it will be useful, but WITHOUT ANY | ||
15 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | ||
16 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more | ||
17 | details. You should have received a copy of the GNU Lesser General Public | ||
18 | License along with this module; if not, write to the Free Software Foundation, | ||
19 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ | ||
20 | |||
21 | #include "blargg_source.h" | ||
22 | |||
23 | void 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 | |||
48 | void 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 | |||
63 | blargg_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 | |||
90 | blip_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 | |||
97 | void 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 | |||
110 | void 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 | |||
116 | int 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 | |||
123 | blip_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 | |||
131 | void 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 | |||
144 | int 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 | |||
197 | void 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 | |||
215 | void 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 | |||
220 | void Synth_init( struct Blip_Synth* this ) | ||
221 | { | ||
222 | this->buf = 0; | ||
223 | this->last_amp = 0; | ||
224 | this->delta_factor = 0; | ||
225 | } | ||