diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/codecs/SOURCES | 2 | ||||
-rw-r--r-- | apps/codecs/libgme/resampler.c | 426 | ||||
-rw-r--r-- | apps/codecs/libgme/resampler.h | 74 | ||||
-rw-r--r-- | apps/codecs/libgme/vgm_emu.c | 59 | ||||
-rw-r--r-- | apps/codecs/libgme/vgm_emu.h | 6 |
5 files changed, 225 insertions, 342 deletions
diff --git a/apps/codecs/SOURCES b/apps/codecs/SOURCES index 6862eeda8e..db6e82c75f 100644 --- a/apps/codecs/SOURCES +++ b/apps/codecs/SOURCES | |||
@@ -37,8 +37,8 @@ gbs.c | |||
37 | hes.c | 37 | hes.c |
38 | nsf.c | 38 | nsf.c |
39 | sgc.c | 39 | sgc.c |
40 | #if MEMORYSIZE > 2 | ||
41 | vgm.c | 40 | vgm.c |
41 | #if MEMORYSIZE > 2 | ||
42 | kss.c | 42 | kss.c |
43 | #endif | 43 | #endif |
44 | 44 | ||
diff --git a/apps/codecs/libgme/resampler.c b/apps/codecs/libgme/resampler.c index a69a92cc53..e2e0734fc9 100644 --- a/apps/codecs/libgme/resampler.c +++ b/apps/codecs/libgme/resampler.c | |||
@@ -25,294 +25,194 @@ enum { shift = 14 }; | |||
25 | int const unit = 1 << shift; | 25 | int const unit = 1 << shift; |
26 | 26 | ||
27 | blargg_err_t Resampler_setup( struct Resampler* this, int fm_rate, int fm_gain, int rate, int gain ) | 27 | blargg_err_t Resampler_setup( struct Resampler* this, int fm_rate, int fm_gain, int rate, int gain ) |
28 | { | 28 | { |
29 | this->gain_ = (int)( ((1LL << gain_bits) * fm_gain * gain) / FP_ONE_GAIN ); | 29 | this->gain_ = (int)( ((1LL << gain_bits) * fm_gain * gain) / FP_ONE_GAIN ); |
30 | this->step = (int)( ((1LL << shift) * fm_rate) / rate + 1); | 30 | this->step = (int)( ((1LL << shift) * fm_rate) / rate + 1); |
31 | this->rate_ = this->step; | 31 | this->rate_ = this->step; |
32 | return 0; | 32 | return 0; |
33 | } | 33 | } |
34 | 34 | ||
35 | blargg_err_t Resampler_reset( struct Resampler* this, int pairs ) | 35 | blargg_err_t Resampler_reset( struct Resampler* this, int pairs ) |
36 | { | 36 | { |
37 | // expand allocations a bit | 37 | // expand allocations a bit |
38 | Resampler_resize( this, pairs ); | 38 | this->sample_buffer_size = (pairs + (pairs >> 2)) * 2; |
39 | this->resampler_size = this->oversamples_per_frame + (this->oversamples_per_frame >> 2); | 39 | Resampler_resize( this, pairs ); |
40 | 40 | this->resampler_size = this->oversamples_per_frame + (this->oversamples_per_frame >> 2); | |
41 | this->buffer_size = this->resampler_size; | 41 | |
42 | this->pos = 0; | 42 | this->buffer_size = this->resampler_size; |
43 | this->write_pos = 0; | 43 | this->pos = 0; |
44 | return 0; | 44 | this->write_pos = 0; |
45 | |||
46 | Resampler_clear( this ); | ||
47 | return 0; | ||
45 | } | 48 | } |
46 | 49 | ||
47 | void Resampler_resize( struct Resampler* this, int pairs ) | 50 | void Resampler_resize( struct Resampler* this, int pairs ) |
48 | { | 51 | { |
49 | int new_sample_buf_size = pairs * 2; | 52 | int new_sample_buf_size = pairs * 2; |
50 | if ( this->sample_buf_size != new_sample_buf_size ) | 53 | if ( this->sample_buf_size != new_sample_buf_size ) |
51 | { | 54 | { |
52 | this->sample_buf_size = new_sample_buf_size; | 55 | if ( new_sample_buf_size > this->sample_buffer_size ) |
53 | this->oversamples_per_frame = (int) ((pairs * this->rate_ * 2LL) / unit) + 2; | 56 | { |
54 | Resampler_clear( this ); | 57 | check(false); |
55 | } | 58 | return; |
59 | } | ||
60 | |||
61 | this->sample_buf_size = new_sample_buf_size; | ||
62 | this->oversamples_per_frame = (int) ((pairs * this->rate_ * 2LL) / unit) + 2; | ||
63 | Resampler_clear( this ); | ||
64 | } | ||
56 | } | 65 | } |
57 | 66 | ||
58 | static void mix_mono( struct Resampler* this, struct Stereo_Buffer* stereo_buf, dsample_t* out_ ) | 67 | void mix_samples( struct Resampler* this, struct Blip_Buffer* blip_buf, sample_t out_ [] ) |
59 | { | 68 | { |
60 | int const bass = BLIP_READER_BASS( stereo_buf->bufs [0] ); | 69 | int const bass = BLIP_READER_BASS( *blip_buf ); |
61 | BLIP_READER_BEGIN( sn, stereo_buf->bufs [0] ); | 70 | BLIP_READER_BEGIN( sn, *blip_buf ); |
62 | 71 | ||
63 | int count = this->sample_buf_size >> 1; | 72 | int count = this->sample_buf_size >> 1; |
64 | BLIP_READER_ADJ_( sn, count ); | 73 | BLIP_READER_ADJ_( sn, count ); |
65 | 74 | ||
66 | typedef dsample_t stereo_dsample_t [2]; | 75 | typedef sample_t stereo_dsample_t [2]; |
67 | stereo_dsample_t* BLARGG_RESTRICT out = (stereo_dsample_t*) out_ + count; | 76 | stereo_dsample_t* BLARGG_RESTRICT out = (stereo_dsample_t*) out_ + count; |
68 | stereo_dsample_t const* BLARGG_RESTRICT in = | 77 | stereo_dsample_t const* BLARGG_RESTRICT in = |
69 | (stereo_dsample_t const*) this->sample_buf + count; | 78 | (stereo_dsample_t const*) this->sample_buf + count; |
70 | int offset = -count; | 79 | int offset = -count; |
71 | int const gain = this->gain_; | 80 | int const gain = this->gain_; |
72 | do | 81 | do |
73 | { | 82 | { |
74 | int s = BLIP_READER_READ_RAW( sn ) >> (blip_sample_bits - 16); | 83 | int s = BLIP_READER_READ_RAW( sn ) >> (blip_sample_bits - 16); |
75 | BLIP_READER_NEXT_IDX_( sn, bass, offset ); | 84 | BLIP_READER_NEXT_IDX_( sn, bass, offset ); |
76 | 85 | ||
77 | int l = (in [offset] [0] * gain >> gain_bits) + s; | 86 | int l = (in [offset] [0] * gain >> gain_bits) + s; |
78 | int r = (in [offset] [1] * gain >> gain_bits) + s; | 87 | int r = (in [offset] [1] * gain >> gain_bits) + s; |
79 | 88 | ||
80 | BLIP_CLAMP( l, l ); | 89 | BLIP_CLAMP( l, l ); |
81 | out [offset] [0] = (blip_sample_t) l; | 90 | out [offset] [0] = (blip_sample_t) l; |
82 | 91 | ||
83 | BLIP_CLAMP( r, r ); | 92 | BLIP_CLAMP( r, r ); |
84 | out [offset] [1] = (blip_sample_t) r; | 93 | out [offset] [1] = (blip_sample_t) r; |
85 | } | 94 | } |
86 | while ( ++offset ); | 95 | while ( ++offset ); |
87 | 96 | ||
88 | BLIP_READER_END( sn, stereo_buf->bufs [0] ); | 97 | BLIP_READER_END( sn, *blip_buf ); |
89 | } | 98 | } |
90 | 99 | ||
91 | static void mix_stereo( struct Resampler* this, struct Stereo_Buffer* stereo_buf, dsample_t* out_ ) | 100 | sample_t const* resample_( struct Resampler* this, sample_t** out_, |
101 | sample_t const* out_end, sample_t const in [], int in_size ) | ||
92 | { | 102 | { |
93 | int const bass = BLIP_READER_BASS( stereo_buf->bufs [0] ); | 103 | in_size -= write_offset; |
94 | BLIP_READER_BEGIN( snc, stereo_buf->bufs [0] ); | 104 | if ( in_size > 0 ) |
95 | BLIP_READER_BEGIN( snl, stereo_buf->bufs [1] ); | 105 | { |
96 | BLIP_READER_BEGIN( snr, stereo_buf->bufs [2] ); | 106 | sample_t* BLARGG_RESTRICT out = *out_; |
97 | 107 | sample_t const* const in_end = in + in_size; | |
98 | int count = this->sample_buf_size >> 1; | 108 | |
99 | BLIP_READER_ADJ_( snc, count ); | 109 | int const step = this->step; |
100 | BLIP_READER_ADJ_( snl, count ); | 110 | int pos = this->pos; |
101 | BLIP_READER_ADJ_( snr, count ); | 111 | |
102 | 112 | // TODO: IIR filter, then linear resample | |
103 | typedef dsample_t stereo_dsample_t [2]; | 113 | // TODO: detect skipped sample, allowing merging of IIR and resample? |
104 | stereo_dsample_t* BLARGG_RESTRICT out = (stereo_dsample_t*) out_ + count; | 114 | |
105 | stereo_dsample_t const* BLARGG_RESTRICT in = | 115 | do |
106 | (stereo_dsample_t const*) this->sample_buf + count; | 116 | { |
107 | int offset = -count; | 117 | #define INTERP( i, out )\ |
108 | int const gain = this->gain_; | 118 | out = (in [0 + i] * (unit - pos) + ((in [2 + i] + in [4 + i] + in [6 + i]) << shift) +\ |
109 | do | 119 | in [8 + i] * pos) >> (shift + 2); |
110 | { | 120 | |
111 | int sc = BLIP_READER_READ_RAW( snc ) >> (blip_sample_bits - 16); | 121 | int out_0; |
112 | int sl = BLIP_READER_READ_RAW( snl ) >> (blip_sample_bits - 16); | 122 | INTERP( 0, out_0 ) |
113 | int sr = BLIP_READER_READ_RAW( snr ) >> (blip_sample_bits - 16); | 123 | INTERP( 1, out [0] = out_0; out [1] ) |
114 | BLIP_READER_NEXT_IDX_( snc, bass, offset ); | 124 | out += stereo; |
115 | BLIP_READER_NEXT_IDX_( snl, bass, offset ); | 125 | |
116 | BLIP_READER_NEXT_IDX_( snr, bass, offset ); | 126 | pos += step; |
117 | 127 | in += ((unsigned) pos >> shift) * stereo; | |
118 | int l = (in [offset] [0] * gain >> gain_bits) + sl + sc; | 128 | pos &= unit - 1; |
119 | int r = (in [offset] [1] * gain >> gain_bits) + sr + sc; | 129 | } |
120 | 130 | while ( in < in_end && out < out_end ); | |
121 | BLIP_CLAMP( l, l ); | 131 | |
122 | out [offset] [0] = (blip_sample_t) l; | 132 | this->pos = pos; |
123 | 133 | *out_ = out; | |
124 | BLIP_CLAMP( r, r ); | 134 | } |
125 | out [offset] [1] = (blip_sample_t) r; | 135 | return in; |
126 | } | ||
127 | while ( ++offset ); | ||
128 | |||
129 | BLIP_READER_END( snc, stereo_buf->bufs [0] ); | ||
130 | BLIP_READER_END( snl, stereo_buf->bufs [1] ); | ||
131 | BLIP_READER_END( snr, stereo_buf->bufs [2] ); | ||
132 | } | 136 | } |
133 | 137 | ||
134 | static void mix_stereo_no_center( struct Resampler* this, struct Stereo_Buffer* stereo_buf, dsample_t* out_ ) | 138 | inline int resample_wrapper( struct Resampler* this, sample_t out [], int* out_size, |
139 | sample_t const in [], int in_size ) | ||
135 | { | 140 | { |
136 | int const bass = BLIP_READER_BASS( stereo_buf->bufs [0] ); | 141 | assert( Resampler_rate( this ) ); |
137 | BLIP_READER_BEGIN( snl, stereo_buf->bufs [1] ); | ||
138 | BLIP_READER_BEGIN( snr, stereo_buf->bufs [2] ); | ||
139 | |||
140 | int count = this->sample_buf_size >> 1; | ||
141 | BLIP_READER_ADJ_( snl, count ); | ||
142 | BLIP_READER_ADJ_( snr, count ); | ||
143 | |||
144 | typedef dsample_t stereo_dsample_t [2]; | ||
145 | stereo_dsample_t* BLARGG_RESTRICT out = (stereo_dsample_t*) out_ + count; | ||
146 | stereo_dsample_t const* BLARGG_RESTRICT in = | ||
147 | (stereo_dsample_t const*) this->sample_buf + count; | ||
148 | int offset = -count; | ||
149 | int const gain = this->gain_; | ||
150 | do | ||
151 | { | ||
152 | int sl = BLIP_READER_READ_RAW( snl ) >> (blip_sample_bits - 16); | ||
153 | int sr = BLIP_READER_READ_RAW( snr ) >> (blip_sample_bits - 16); | ||
154 | BLIP_READER_NEXT_IDX_( snl, bass, offset ); | ||
155 | BLIP_READER_NEXT_IDX_( snr, bass, offset ); | ||
156 | |||
157 | int l = (in [offset] [0] * gain >> gain_bits) + sl; | ||
158 | int r = (in [offset] [1] * gain >> gain_bits) + sr; | ||
159 | |||
160 | BLIP_CLAMP( l, l ); | ||
161 | out [offset] [0] = (blip_sample_t) l; | ||
162 | |||
163 | BLIP_CLAMP( r, r ); | ||
164 | out [offset] [1] = (blip_sample_t) r; | ||
165 | } | ||
166 | while ( ++offset ); | ||
167 | |||
168 | BLIP_READER_END( snl, stereo_buf->bufs [1] ); | ||
169 | BLIP_READER_END( snr, stereo_buf->bufs [2] ); | ||
170 | } | ||
171 | 142 | ||
172 | static dsample_t const* resample_( struct Resampler* this, dsample_t** out_, | 143 | sample_t* out_ = out; |
173 | dsample_t const* out_end, dsample_t const in [], int in_size ) | 144 | int result = resample_( this, &out_, out + *out_size, in, in_size ) - in; |
174 | { | 145 | assert( out_ <= out + *out_size ); |
175 | in_size -= write_offset; | 146 | assert( result <= in_size ); |
176 | if ( in_size > 0 ) | ||
177 | { | ||
178 | dsample_t* BLIP_RESTRICT out = *out_; | ||
179 | dsample_t const* const in_end = in + in_size; | ||
180 | |||
181 | int const step = this->step; | ||
182 | int pos = this->pos; | ||
183 | |||
184 | // TODO: IIR filter, then linear resample | ||
185 | // TODO: detect skipped sample, allowing merging of IIR and resample? | ||
186 | |||
187 | do | ||
188 | { | ||
189 | #define INTERP( i, out )\ | ||
190 | out = (in [0 + i] * (unit - pos) + ((in [2 + i] + in [4 + i] + in [6 + i]) << shift) +\ | ||
191 | in [8 + i] * pos) >> (shift + 2); | ||
192 | |||
193 | int out_0; | ||
194 | INTERP( 0, out_0 ) | ||
195 | INTERP( 1, out [0] = out_0; out [1] ) | ||
196 | out += stereo; | ||
197 | |||
198 | pos += step; | ||
199 | in += ((unsigned) pos >> shift) * stereo; | ||
200 | pos &= unit - 1; | ||
201 | } | ||
202 | while ( in < in_end && out < out_end ); | ||
203 | |||
204 | this->pos = pos; | ||
205 | *out_ = out; | ||
206 | } | ||
207 | return in; | ||
208 | } | ||
209 | 147 | ||
210 | static inline int resample_wrapper( struct Resampler* this, dsample_t out [], int* out_size, | 148 | *out_size = out_ - out; |
211 | dsample_t const in [], int in_size ) | 149 | return result; |
212 | { | ||
213 | assert( Resampler_rate( this ) ); | ||
214 | |||
215 | dsample_t* out_ = out; | ||
216 | int result = resample_( this, &out_, out + *out_size, in, in_size ) - in; | ||
217 | assert( out_ <= out + *out_size ); | ||
218 | assert( result <= in_size ); | ||
219 | |||
220 | *out_size = out_ - out; | ||
221 | return result; | ||
222 | } | 150 | } |
223 | 151 | ||
224 | static int skip_input( struct Resampler* this, int count ) | 152 | int skip_input( struct Resampler* this, int count ) |
225 | { | 153 | { |
226 | this->write_pos -= count; | 154 | this->write_pos -= count; |
227 | if ( this->write_pos < 0 ) // occurs when downsampling | 155 | if ( this->write_pos < 0 ) // occurs when downsampling |
228 | { | 156 | { |
229 | count += this->write_pos; | 157 | count += this->write_pos; |
230 | this->write_pos = 0; | 158 | this->write_pos = 0; |
231 | } | 159 | } |
232 | memmove( this->buf, &this->buf [count], this->write_pos * sizeof this->buf [0] ); | 160 | memmove( this->buf, &this->buf [count], this->write_pos * sizeof this->buf [0] ); |
233 | return count; | 161 | return count; |
234 | } | 162 | } |
235 | 163 | ||
236 | static void play_frame_( struct Resampler* this, struct Stereo_Buffer* stereo_buf, dsample_t* out ) | 164 | void play_frame_( struct Resampler* this, struct Blip_Buffer* blip_buf, sample_t* out ) |
237 | { | 165 | { |
238 | long pair_count = this->sample_buf_size >> 1; | 166 | int pair_count = this->sample_buf_size >> 1; |
239 | blip_time_t blip_time = Blip_count_clocks( &stereo_buf->bufs [0], pair_count ); | 167 | blip_time_t blip_time = Blip_count_clocks( blip_buf, pair_count ); |
240 | int sample_count = this->oversamples_per_frame - this->write_pos + resampler_extra; | 168 | int sample_count = this->oversamples_per_frame - this->write_pos + resampler_extra; |
241 | 169 | ||
242 | int new_count = this->callback( this->callback_data, blip_time, sample_count, &this->buf [this->write_pos] ); | 170 | int new_count = this->callback( this->callback_data, blip_time, sample_count, &this->buf [this->write_pos] ); |
243 | assert( new_count < resampler_size ); | 171 | assert( new_count < this->resampler_size ); |
244 | 172 | ||
245 | Buffer_end_frame( stereo_buf, blip_time ); | 173 | Blip_end_frame( blip_buf, blip_time ); |
246 | /* Blip_end_frame( &stereo_buf->bufs [0], blip_time ); */ | 174 | assert( Blip_samples_avail( blip_buf ) == pair_count ); |
247 | assert( Blip_samples_avail( &stereo_buf->bufs [0] ) == pair_count * 2 ); | 175 | |
248 | 176 | this->write_pos += new_count; | |
249 | this->write_pos += new_count; | 177 | assert( (unsigned) this->write_pos <= this->buffer_size ); |
250 | assert( (unsigned) this->write_pos <= this->buffer_size ); | 178 | |
251 | 179 | int count = this->sample_buf_size; | |
252 | new_count = this->sample_buf_size; | 180 | if ( count ) |
253 | if ( new_count ) | 181 | skip_input( this, resample_wrapper( this, this->sample_buf, &count, this->buf, this->write_pos ) ); |
254 | skip_input( this, resample_wrapper( this, this->sample_buf, &new_count, this->buf, this->write_pos ) ); | 182 | assert( count == this->sample_buf_size ); |
255 | assert( new_count == (long) this->sample_buf_size ); | 183 | |
256 | 184 | mix_samples( this, blip_buf, out ); | |
257 | int bufs_used = stereo_buf->stereo_added | stereo_buf->was_stereo; | 185 | Blip_remove_samples( blip_buf, pair_count ); |
258 | if ( bufs_used <= 1 ) { | ||
259 | mix_mono( this, stereo_buf, out ); | ||
260 | Blip_remove_samples( &stereo_buf->bufs [0], pair_count ); | ||
261 | Blip_remove_silence( &stereo_buf->bufs [1], pair_count ); | ||
262 | Blip_remove_silence( &stereo_buf->bufs [2], pair_count ); | ||
263 | } | ||
264 | else if ( bufs_used & 1 ) { | ||
265 | mix_stereo( this, stereo_buf, out ); | ||
266 | Blip_remove_samples( &stereo_buf->bufs [0], pair_count ); | ||
267 | Blip_remove_samples( &stereo_buf->bufs [1], pair_count ); | ||
268 | Blip_remove_samples( &stereo_buf->bufs [2], pair_count ); | ||
269 | } | ||
270 | else { | ||
271 | mix_stereo_no_center( this, stereo_buf, out ); | ||
272 | Blip_remove_silence( &stereo_buf->bufs [0], pair_count ); | ||
273 | Blip_remove_samples( &stereo_buf->bufs [1], pair_count ); | ||
274 | Blip_remove_samples( &stereo_buf->bufs [2], pair_count ); | ||
275 | } | ||
276 | |||
277 | // to do: this might miss opportunities for optimization | ||
278 | if ( !Blip_samples_avail( &stereo_buf->bufs [0] ) ) | ||
279 | { | ||
280 | stereo_buf->was_stereo = stereo_buf->stereo_added; | ||
281 | stereo_buf->stereo_added = 0; | ||
282 | } | ||
283 | |||
284 | /* mix_mono( this, stereo_buf, out ); | ||
285 | Blip_remove_samples( &stereo_buf->bufs [0], pair_count ); */ | ||
286 | } | 186 | } |
287 | 187 | ||
288 | void Resampler_play( struct Resampler* this, long count, dsample_t* out, struct Stereo_Buffer* stereo_buf ) | 188 | void Resampler_play( struct Resampler* this, int count, sample_t* out, struct Blip_Buffer* blip_buf ) |
289 | { | 189 | { |
290 | // empty extra buffer | 190 | // empty extra buffer |
291 | long remain = this->sample_buf_size - this->buf_pos; | 191 | int remain = this->sample_buf_size - this->buf_pos; |
292 | if ( remain ) | 192 | if ( remain ) |
293 | { | 193 | { |
294 | if ( remain > count ) | 194 | if ( remain > count ) |
295 | remain = count; | 195 | remain = count; |
296 | count -= remain; | 196 | count -= remain; |
297 | memcpy( out, &this->sample_buf [this->buf_pos], remain * sizeof *out ); | 197 | memcpy( out, &this->sample_buf [this->buf_pos], remain * sizeof *out ); |
298 | out += remain; | 198 | out += remain; |
299 | this->buf_pos += remain; | 199 | this->buf_pos += remain; |
300 | } | 200 | } |
301 | 201 | ||
302 | // entire frames | 202 | // entire frames |
303 | while ( count >= (long) this->sample_buf_size ) | 203 | while ( count >= this->sample_buf_size ) |
304 | { | 204 | { |
305 | play_frame_( this, stereo_buf, out ); | 205 | play_frame_( this, blip_buf, out ); |
306 | out += this->sample_buf_size; | 206 | out += this->sample_buf_size; |
307 | count -= this->sample_buf_size; | 207 | count -= this->sample_buf_size; |
308 | } | 208 | } |
309 | 209 | ||
310 | // extra | 210 | // extra |
311 | if ( count ) | 211 | if ( count ) |
312 | { | 212 | { |
313 | play_frame_( this, stereo_buf, this->sample_buf ); | 213 | play_frame_( this, blip_buf, this->sample_buf ); |
314 | this->buf_pos = count; | 214 | this->buf_pos = count; |
315 | memcpy( out, this->sample_buf, count * sizeof *out ); | 215 | memcpy( out, this->sample_buf, count * sizeof *out ); |
316 | out += count; | 216 | out += count; |
317 | } | 217 | } |
318 | } | 218 | } |
diff --git a/apps/codecs/libgme/resampler.h b/apps/codecs/libgme/resampler.h index 3106b84d35..1d8f86670b 100644 --- a/apps/codecs/libgme/resampler.h +++ b/apps/codecs/libgme/resampler.h | |||
@@ -4,10 +4,10 @@ | |||
4 | #ifndef RESAMPLER_H | 4 | #ifndef RESAMPLER_H |
5 | #define RESAMPLER_H | 5 | #define RESAMPLER_H |
6 | 6 | ||
7 | #include "blargg_config.h" | 7 | #include "blargg_common.h" |
8 | #include "multi_buffer.h" | 8 | #include "multi_buffer.h" |
9 | 9 | ||
10 | typedef short dsample_t; | 10 | typedef short sample_t; |
11 | 11 | ||
12 | enum { stereo = 2 }; | 12 | enum { stereo = 2 }; |
13 | enum { max_buf_size = 3960 }; | 13 | enum { max_buf_size = 3960 }; |
@@ -15,54 +15,62 @@ enum { max_resampler_size = 5942 }; | |||
15 | enum { write_offset = 8 * stereo }; | 15 | enum { write_offset = 8 * stereo }; |
16 | enum { gain_bits = 14 }; | 16 | enum { gain_bits = 14 }; |
17 | 17 | ||
18 | struct Resampler { | 18 | struct Resampler { |
19 | int (*callback)( void*, blip_time_t, int, dsample_t* ); | 19 | int (*callback)( void*, blip_time_t, int, sample_t* ); |
20 | void* callback_data; | 20 | void* callback_data; |
21 | 21 | ||
22 | dsample_t sample_buf [max_buf_size]; | 22 | int sample_buffer_size; |
23 | int sample_buf_size; | 23 | int sample_buf_size; |
24 | int oversamples_per_frame; | 24 | int oversamples_per_frame; |
25 | int buf_pos; | 25 | int buf_pos; |
26 | int resampler_size; | 26 | int resampler_size; |
27 | int gain_; | 27 | int gain_; |
28 | 28 | ||
29 | // Internal resampler | 29 | int buffer_size; |
30 | dsample_t buf [max_resampler_size]; | 30 | int write_pos; |
31 | int buffer_size; | 31 | |
32 | 32 | int pos; | |
33 | int write_pos; | 33 | int step; |
34 | int rate_; | 34 | |
35 | 35 | int rate_; | |
36 | int pos; | 36 | |
37 | int step; | 37 | sample_t sample_buf [max_buf_size]; |
38 | sample_t buf [max_resampler_size]; // Internal resampler | ||
38 | }; | 39 | }; |
39 | 40 | ||
40 | static inline void Resampler_init( struct Resampler* this ) | 41 | static inline void Resampler_init( struct Resampler* this ) |
41 | { | 42 | { |
42 | this->pos = 0; | 43 | this->pos = 0; |
43 | this->write_pos = 0; | 44 | this->write_pos = 0; |
44 | this->rate_ = 0; | 45 | this->rate_ = 0; |
46 | this->sample_buf_size = 0; | ||
47 | this->sample_buffer_size = 0; | ||
48 | this->oversamples_per_frame = 0; | ||
45 | } | 49 | } |
46 | 50 | ||
47 | blargg_err_t Resampler_reset( struct Resampler* this, int max_pairs ); | 51 | blargg_err_t Resampler_reset( struct Resampler* this, int max_pairs ); |
48 | void Resampler_resize( struct Resampler* this, int pairs_per_frame ); | 52 | void Resampler_resize( struct Resampler* this, int pairs_per_frame ); |
49 | 53 | void Resampler_play( struct Resampler* this, int count, sample_t* out, struct Blip_Buffer* ); | |
50 | void Resampler_play( struct Resampler* this, long count, dsample_t* out, struct Stereo_Buffer* ); | ||
51 | 54 | ||
52 | static inline void Resampler_set_callback(struct Resampler* this, int (*func)( void*, blip_time_t, int, dsample_t* ), void* user_data ) | 55 | static inline void Resampler_set_callback(struct Resampler* this, int (*func)( void*, blip_time_t, int, sample_t* ), void* user_data ) |
53 | { | 56 | { |
54 | this->callback = func; | 57 | this->callback = func; |
55 | this->callback_data = user_data; | 58 | this->callback_data = user_data; |
56 | } | 59 | } |
57 | 60 | ||
58 | blargg_err_t Resampler_setup( struct Resampler* this, int fm_rate, int fm_gain, int rate, int gain ); | 61 | blargg_err_t Resampler_setup( struct Resampler* this, int fm_rate, int fm_gain, int rate, int gain ); |
59 | 62 | ||
60 | static inline void Resampler_clear( struct Resampler* this ) | 63 | static inline void Resampler_clear( struct Resampler* this ) |
61 | { | 64 | { |
62 | this->buf_pos = this->sample_buf_size; | 65 | this->buf_pos = this->sample_buf_size; |
66 | |||
67 | this->pos = 0; | ||
68 | this->write_pos = 0; | ||
69 | } | ||
63 | 70 | ||
64 | this->pos = 0; | 71 | static inline int Resampler_rate( struct Resampler* this ) |
65 | this->write_pos = 0; | 72 | { |
73 | return this->rate_; | ||
66 | } | 74 | } |
67 | 75 | ||
68 | #endif | 76 | #endif |
diff --git a/apps/codecs/libgme/vgm_emu.c b/apps/codecs/libgme/vgm_emu.c index d599056bca..391bd02d73 100644 --- a/apps/codecs/libgme/vgm_emu.c +++ b/apps/codecs/libgme/vgm_emu.c | |||
@@ -89,8 +89,7 @@ void Vgm_init( struct Vgm_Emu* this ) | |||
89 | Synth_init( &this->pcm ); | 89 | Synth_init( &this->pcm ); |
90 | 90 | ||
91 | Buffer_init( &this->buf ); | 91 | Buffer_init( &this->buf ); |
92 | Buffer_init( &this->stereo_buf ); | 92 | Blip_init( &this->blip_buf ); |
93 | this->blip_buf = &this->stereo_buf.bufs [0]; | ||
94 | 93 | ||
95 | // Init fm chips | 94 | // Init fm chips |
96 | Ym2413_init( &this->ym2413 ); | 95 | Ym2413_init( &this->ym2413 ); |
@@ -279,7 +278,7 @@ blargg_err_t Vgm_load_mem( struct Vgm_Emu* this, byte const* new_data, long new_ | |||
279 | if ( !this->psg_rate ) | 278 | if ( !this->psg_rate ) |
280 | this->psg_rate = 3579545; | 279 | this->psg_rate = 3579545; |
281 | 280 | ||
282 | Buffer_clock_rate( &this->stereo_buf, this->psg_rate ); | 281 | Blip_set_clock_rate( &this->blip_buf, this->psg_rate ); |
283 | 282 | ||
284 | // Disable FM | 283 | // Disable FM |
285 | this->fm_rate = 0; | 284 | this->fm_rate = 0; |
@@ -342,14 +341,14 @@ blargg_err_t setup_fm( struct Vgm_Emu* this ) | |||
342 | { | 341 | { |
343 | int fm_rate = 0; | 342 | int fm_rate = 0; |
344 | if ( !this->disable_oversampling ) | 343 | if ( !this->disable_oversampling ) |
345 | this->fm_rate = (this->sample_rate * 3) / 2; // oversample factor = 1.5 | 344 | fm_rate = (this->sample_rate * 3) / 2; // oversample factor = 1.5 |
346 | RETURN_ERR( init_fm( this, &fm_rate ) ); | 345 | RETURN_ERR( init_fm( this, &fm_rate ) ); |
347 | 346 | ||
348 | if ( uses_fm( this ) ) | 347 | if ( uses_fm( this ) ) |
349 | { | 348 | { |
350 | this->voice_count = 8; | 349 | this->voice_count = 8; |
351 | RETURN_ERR( Resampler_setup( &this->resampler, fm_rate, fm_gain, this->sample_rate, this->gain ) ); | 350 | RETURN_ERR( Resampler_setup( &this->resampler, fm_rate, fm_gain, this->sample_rate, this->gain ) ); |
352 | RETURN_ERR( Resampler_reset( &this->resampler, Buffer_length( &this->stereo_buf ) * this->sample_rate / 1000 ) ); | 351 | RETURN_ERR( Resampler_reset( &this->resampler, Blip_length( &this->blip_buf ) * this->sample_rate / 1000 ) ); |
353 | Sms_apu_volume( &this->psg, ((this->gain/5)-(this->gain*5)/1000) * fm_gain ); | 352 | Sms_apu_volume( &this->psg, ((this->gain/5)-(this->gain*5)/1000) * fm_gain ); |
354 | } | 353 | } |
355 | else | 354 | else |
@@ -399,7 +398,7 @@ static blargg_err_t play_( struct Vgm_Emu* this, long count, sample_t* out ) | |||
399 | return 0; | 398 | return 0; |
400 | } | 399 | } |
401 | 400 | ||
402 | Resampler_play( &this->resampler, count, out, &this->stereo_buf ); | 401 | Resampler_play( &this->resampler, count, out, &this->blip_buf ); |
403 | return 0; | 402 | return 0; |
404 | } | 403 | } |
405 | 404 | ||
@@ -428,19 +427,16 @@ static inline blip_time_t to_psg_time( struct Vgm_Emu* this, vgm_time_t t ) | |||
428 | 427 | ||
429 | static void write_pcm( struct Vgm_Emu* this, vgm_time_t vgm_time, int amp ) | 428 | static void write_pcm( struct Vgm_Emu* this, vgm_time_t vgm_time, int amp ) |
430 | { | 429 | { |
431 | if ( this->blip_buf ) | 430 | check( amp >= 0 ); |
432 | { | 431 | blip_time_t blip_time = to_psg_time( this, vgm_time ); |
433 | check( amp >= 0 ); | 432 | int old = this->dac_amp; |
434 | blip_time_t blip_time = to_psg_time( this, vgm_time ); | 433 | int delta = amp - old; |
435 | int old = this->dac_amp; | 434 | this->dac_amp = amp; |
436 | int delta = amp - old; | 435 | Blip_set_modified( &this->blip_buf ); |
437 | this->dac_amp = amp; | 436 | if ( old >= 0 ) // first write is ignored, to avoid click |
438 | Blip_set_modified( this->blip_buf ); | 437 | Synth_offset_inline( &this->pcm, blip_time, delta, &this->blip_buf ); |
439 | if ( old >= 0 ) // first write is ignored, to avoid click | 438 | else |
440 | Synth_offset_inline( &this->pcm, blip_time, delta, this->blip_buf ); | 439 | this->dac_amp |= this->dac_disabled; |
441 | else | ||
442 | this->dac_amp |= this->dac_disabled; | ||
443 | } | ||
444 | } | 440 | } |
445 | 441 | ||
446 | blip_time_t run( struct Vgm_Emu* this, vgm_time_t end_time ) | 442 | blip_time_t run( struct Vgm_Emu* this, vgm_time_t end_time ) |
@@ -514,22 +510,7 @@ blip_time_t run( struct Vgm_Emu* this, vgm_time_t end_time ) | |||
514 | 510 | ||
515 | case cmd_ym2612_port1: | 511 | case cmd_ym2612_port1: |
516 | if ( Ym2612_run_until( &this->ym2612, to_fm_time( this, vgm_time ) ) ) | 512 | if ( Ym2612_run_until( &this->ym2612, to_fm_time( this, vgm_time ) ) ) |
517 | { | ||
518 | if ( pos [0] == ym2612_dac_pan_port ) | ||
519 | { | ||
520 | struct Blip_Buffer* blip_buf = NULL; | ||
521 | switch ( pos [1] >> 6 ) | ||
522 | { | ||
523 | case 0: blip_buf = NULL; break; | ||
524 | case 1: blip_buf = &this->stereo_buf.bufs [2]; break; | ||
525 | case 2: blip_buf = &this->stereo_buf.bufs [1]; break; | ||
526 | case 3: blip_buf = &this->stereo_buf.bufs [0]; break; | ||
527 | } | ||
528 | this->blip_buf = blip_buf; | ||
529 | } | ||
530 | |||
531 | Ym2612_write1( &this->ym2612, pos [0], pos [1] ); | 513 | Ym2612_write1( &this->ym2612, pos [0], pos [1] ); |
532 | } | ||
533 | pos += 2; | 514 | pos += 2; |
534 | break; | 515 | break; |
535 | 516 | ||
@@ -664,7 +645,7 @@ void update_fm_rates( struct Vgm_Emu* this, int* ym2413_rate, int* ym2612_rate ) | |||
664 | blargg_err_t Vgm_set_sample_rate( struct Vgm_Emu* this, long rate ) | 645 | blargg_err_t Vgm_set_sample_rate( struct Vgm_Emu* this, long rate ) |
665 | { | 646 | { |
666 | require( !this->sample_rate ); // sample rate can't be changed once set | 647 | require( !this->sample_rate ); // sample rate can't be changed once set |
667 | RETURN_ERR( Buffer_set_sample_rate( &this->stereo_buf, rate, 1000 / 30 ) ); | 648 | RETURN_ERR( Blip_set_sample_rate( &this->blip_buf, rate, 1000 / 30 ) ); |
668 | RETURN_ERR( Buffer_set_sample_rate( &this->buf, rate, 1000 / 20 ) ); | 649 | RETURN_ERR( Buffer_set_sample_rate( &this->buf, rate, 1000 / 20 ) ); |
669 | 650 | ||
670 | // Set bass frequency | 651 | // Set bass frequency |
@@ -712,7 +693,7 @@ void Sound_mute_voices( struct Vgm_Emu* this, int mask ) | |||
712 | if ( uses_fm( this ) ) | 693 | if ( uses_fm( this ) ) |
713 | { | 694 | { |
714 | for ( i = sms_osc_count; --i >= 0; ) | 695 | for ( i = sms_osc_count; --i >= 0; ) |
715 | Sms_apu_set_output( &this->psg, i, ( mask & 0x80 ) ? 0 : &this->stereo_buf.bufs [0], NULL, NULL ); | 696 | Sms_apu_set_output( &this->psg, i, ( mask & 0x80 ) ? 0 : &this->blip_buf, NULL, NULL ); |
716 | if ( Ym2612_enabled( &this->ym2612 ) ) | 697 | if ( Ym2612_enabled( &this->ym2612 ) ) |
717 | { | 698 | { |
718 | Synth_volume( &this->pcm, (mask & 0x40) ? 0 : (int)((long long)(0.1115*FP_ONE_VOLUME) / 256 * fm_gain * this->gain / FP_ONE_VOLUME) ); | 699 | Synth_volume( &this->pcm, (mask & 0x40) ? 0 : (int)((long long)(0.1115*FP_ONE_VOLUME) / 256 * fm_gain * this->gain / FP_ONE_VOLUME) ); |
@@ -743,7 +724,7 @@ void Sound_set_tempo( struct Vgm_Emu* this, int t ) | |||
743 | if ( this->file_begin ) | 724 | if ( this->file_begin ) |
744 | { | 725 | { |
745 | this->vgm_rate = (long) ((44100LL * t) / FP_ONE_TEMPO); | 726 | this->vgm_rate = (long) ((44100LL * t) / FP_ONE_TEMPO); |
746 | this->blip_time_factor = (int) (((1LL << blip_time_bits) * Blip_clock_rate( &this->stereo_buf.bufs [0] )) / this->vgm_rate); | 727 | this->blip_time_factor = (int) (((1LL << blip_time_bits) * Blip_clock_rate( &this->blip_buf )) / this->vgm_rate); |
747 | //debug_printf( "blip_time_factor: %ld\n", blip_time_factor ); | 728 | //debug_printf( "blip_time_factor: %ld\n", blip_time_factor ); |
748 | //debug_printf( "vgm_rate: %ld\n", vgm_rate ); | 729 | //debug_printf( "vgm_rate: %ld\n", vgm_rate ); |
749 | // TODO: remove? calculates vgm_rate more accurately (above differs at most by one Hz only) | 730 | // TODO: remove? calculates vgm_rate more accurately (above differs at most by one Hz only) |
@@ -761,8 +742,6 @@ blargg_err_t Vgm_start_track( struct Vgm_Emu* this ) | |||
761 | 742 | ||
762 | Sms_apu_reset( &this->psg, get_le16( header( this )->noise_feedback ), header( this )->noise_width ); | 743 | Sms_apu_reset( &this->psg, get_le16( header( this )->noise_feedback ), header( this )->noise_width ); |
763 | 744 | ||
764 | this->blip_buf = &this->stereo_buf.bufs [0]; | ||
765 | |||
766 | this->dac_disabled = -1; | 745 | this->dac_disabled = -1; |
767 | this->pos = this->file_begin + header_size; | 746 | this->pos = this->file_begin + header_size; |
768 | this->pcm_data = this->pos; | 747 | this->pcm_data = this->pos; |
@@ -785,7 +764,7 @@ blargg_err_t Vgm_start_track( struct Vgm_Emu* this ) | |||
785 | if ( Ym2612_enabled( &this->ym2612 ) ) | 764 | if ( Ym2612_enabled( &this->ym2612 ) ) |
786 | Ym2612_reset( &this->ym2612 ); | 765 | Ym2612_reset( &this->ym2612 ); |
787 | 766 | ||
788 | Buffer_clear( &this->stereo_buf ); | 767 | Blip_clear( &this->blip_buf, 1 ); |
789 | Resampler_clear( &this->resampler ); | 768 | Resampler_clear( &this->resampler ); |
790 | } | 769 | } |
791 | 770 | ||
diff --git a/apps/codecs/libgme/vgm_emu.h b/apps/codecs/libgme/vgm_emu.h index bc04086e9d..773b850a09 100644 --- a/apps/codecs/libgme/vgm_emu.h +++ b/apps/codecs/libgme/vgm_emu.h | |||
@@ -12,7 +12,6 @@ | |||
12 | #include "ym2612_emu.h" | 12 | #include "ym2612_emu.h" |
13 | #include "sms_apu.h" | 13 | #include "sms_apu.h" |
14 | 14 | ||
15 | typedef short sample_t; | ||
16 | typedef int vgm_time_t; | 15 | typedef int vgm_time_t; |
17 | typedef int fm_time_t; | 16 | typedef int fm_time_t; |
18 | 17 | ||
@@ -85,7 +84,7 @@ struct Vgm_Emu { | |||
85 | int dac_amp; | 84 | int dac_amp; |
86 | int dac_disabled; // -1 if disabled | 85 | int dac_disabled; // -1 if disabled |
87 | 86 | ||
88 | struct Blip_Buffer* blip_buf; | 87 | struct Blip_Buffer blip_buf; |
89 | 88 | ||
90 | // general | 89 | // general |
91 | long clock_rate_; | 90 | long clock_rate_; |
@@ -124,10 +123,7 @@ struct Vgm_Emu { | |||
124 | 123 | ||
125 | struct Sms_Apu psg; | 124 | struct Sms_Apu psg; |
126 | struct Blip_Synth pcm; | 125 | struct Blip_Synth pcm; |
127 | struct Stereo_Buffer stereo_buf; | ||
128 | |||
129 | struct Resampler resampler; | 126 | struct Resampler resampler; |
130 | |||
131 | struct Stereo_Buffer buf; | 127 | struct Stereo_Buffer buf; |
132 | }; | 128 | }; |
133 | 129 | ||