Mercurial > hg > xmms-sid
comparison src/xs_sidplay2.cpp @ 957:0e60e5d56fdd
Change how the backend emulator library is initialized for libSIDPlay2 and
FP, as it seems the engine configuration has some persistence despite
reconfiguration between loaded files if same engine object is retained. This
caused, for example, 2SID stereo tunes being played "mono" if played after a
normal 1-SID tune. Duh.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 20 Nov 2012 22:13:48 +0200 |
parents | a5b118c853f5 |
children | 828dce1195e6 |
comparison
equal
deleted
inserted
replaced
956:fbcd069663e5 | 957:0e60e5d56fdd |
---|---|
99 | 99 |
100 /* Initialize SIDPlay2 | 100 /* Initialize SIDPlay2 |
101 */ | 101 */ |
102 gboolean xs_sidplay2_init(XSEngineState * state) | 102 gboolean xs_sidplay2_init(XSEngineState * state) |
103 { | 103 { |
104 | |
105 | |
106 return TRUE; | |
107 } | |
108 | |
109 | |
110 /* Close SIDPlay2 engine | |
111 */ | |
112 void xs_sidplay2_close(XSEngineState * state) | |
113 { | |
114 XSSIDPlay2 *engine = (XSSIDPlay2 *) state->internal; | |
115 | |
116 XSDEBUG("SIDPlay2 backend shutdown.\n"); | |
117 | |
118 xs_sidplay2_delete(state); | |
119 } | |
120 | |
121 | |
122 /* Initialize current song and sub-tune | |
123 */ | |
124 gboolean xs_sidplay2_initsong(XSEngineState * state) | |
125 { | |
126 XSSIDPlay2 *engine = (XSSIDPlay2 *) state->internal; | |
127 | |
128 if (!engine) | |
129 return FALSE; | |
130 | |
131 if (!engine->tune.selectSong(state->currSong)) | |
132 { | |
133 xs_error("[SIDPlay2] tune.selectSong() failed\n"); | |
134 return FALSE; | |
135 } | |
136 | |
137 if (engine->emu.load(&(engine->tune)) < 0) | |
138 { | |
139 xs_error("[SIDPlay2] emu.load() failed\n"); | |
140 return FALSE; | |
141 } | |
142 | |
143 if (engine->emu.config(engine->config) < 0) | |
144 { | |
145 xs_error("[SIDPlay2] Emulator engine configuration failed!\n"); | |
146 return FALSE; | |
147 } | |
148 | |
149 return TRUE; | |
150 } | |
151 | |
152 | |
153 /* Emulate and render audio data to given buffer | |
154 */ | |
155 guint xs_sidplay2_fillbuffer(XSEngineState * state, gchar * audioBuffer, guint audioBufSize) | |
156 { | |
157 XSSIDPlay2 *engine = (XSSIDPlay2 *) state->internal; | |
158 | |
159 if (!engine) | |
160 return 0; | |
161 | |
162 return engine->emu.play(audioBuffer, audioBufSize); | |
163 } | |
164 | |
165 | |
166 /* Load a given SID-tune file | |
167 */ | |
168 gboolean xs_sidplay2_load(XSEngineState * state, gchar * filename) | |
169 { | |
104 XSSIDPlay2 *engine; | 170 XSSIDPlay2 *engine; |
105 sid_filter_t tmpFilter; | 171 guint8 *buf = NULL; |
106 xs_sid_filter_t *f; | 172 size_t bufSize; |
107 gint i; | 173 gint i; |
108 assert(state); | |
109 | 174 |
110 XSDEBUG("SIDPlay2 backend initializing.\n"); | 175 XSDEBUG("SIDPlay2 backend initializing.\n"); |
111 | 176 |
112 /* Allocate internal structures */ | 177 /* Allocate internal structures */ |
113 engine = new XSSIDPlay2(); | 178 engine = new XSSIDPlay2(); |
114 state->internal = engine; | 179 state->internal = engine; |
115 if (!engine) | 180 if (!engine) |
116 return FALSE; | 181 { |
182 xs_error("Allocating XSSIDPlay2 compound backend object failed.\n"); | |
183 goto error; | |
184 } | |
117 | 185 |
118 /* Get current configuration */ | 186 /* Get current configuration */ |
119 XSDEBUG("SIDPlay2 emulation configuration\n"); | 187 XSDEBUG("SIDPlay2 emulation configuration\n"); |
120 engine->config = engine->emu.config(); | 188 engine->config = engine->emu.config(); |
121 | 189 |
203 break; | 271 break; |
204 } | 272 } |
205 break; | 273 break; |
206 } | 274 } |
207 | 275 |
208 /* Convert filter */ | |
209 f = &(xs_cfg.sid2Filter); | |
210 XSDEBUG("using filter '%s', %d points\n", f->name, f->npoints); | |
211 if (f->npoints > XS_SIDPLAY2_NFPOINTS) | |
212 { | |
213 xs_error("[SIDPlay2] Invalid number of filter curve points (%d > %d)\n", | |
214 f->npoints, XS_SIDPLAY2_NFPOINTS); | |
215 f->npoints = XS_SIDPLAY2_NFPOINTS; | |
216 } | |
217 | |
218 tmpFilter.points = f->npoints; | |
219 for (i = 0; i < f->npoints; i++) | |
220 { | |
221 tmpFilter.cutoff[i][0] = f->points[i].x; | |
222 tmpFilter.cutoff[i][1] = f->points[i].y; | |
223 } | |
224 | |
225 /* Clockspeed settings */ | 276 /* Clockspeed settings */ |
226 switch (xs_cfg.clockSpeed) | 277 switch (xs_cfg.clockSpeed) |
227 { | 278 { |
228 case XS_CLOCK_NTSC: | 279 case XS_CLOCK_NTSC: |
229 engine->config.clockDefault = SID2_CLOCK_NTSC; | 280 engine->config.clockDefault = SID2_CLOCK_NTSC; |
311 { | 362 { |
312 xs_error("[SIDPlay2] Could not initialize SIDBuilder object.\n"); | 363 xs_error("[SIDPlay2] Could not initialize SIDBuilder object.\n"); |
313 return FALSE; | 364 return FALSE; |
314 } | 365 } |
315 | 366 |
316 #if 0 | |
317 // Setup filter | |
318 engine->config.sidEmulation->filter(xs_cfg.emulateFilters); | |
319 if (!*(engine->config.sidEmulation)) | |
320 { | |
321 xs_error("builder->filter(%d) failed.\n", xs_cfg.emulateFilters); | |
322 return FALSE; | |
323 } | |
324 #endif | |
325 | |
326 XSDEBUG("%s\n", engine->config.sidEmulation->credits()); | 367 XSDEBUG("%s\n", engine->config.sidEmulation->credits()); |
327 | 368 |
328 | |
329 return TRUE; | |
330 } | |
331 | |
332 | |
333 /* Close SIDPlay2 engine | |
334 */ | |
335 void xs_sidplay2_close(XSEngineState * state) | |
336 { | |
337 XSSIDPlay2 *engine = (XSSIDPlay2 *) state->internal; | |
338 | |
339 XSDEBUG("SIDPlay2 backend shutdown.\n"); | |
340 | |
341 xs_sidplay2_delete(state); | |
342 | |
343 if (engine) | |
344 { | |
345 delete engine; | |
346 engine = NULL; | |
347 } | |
348 | |
349 state->internal = NULL; | |
350 } | |
351 | |
352 | |
353 /* Initialize current song and sub-tune | |
354 */ | |
355 gboolean xs_sidplay2_initsong(XSEngineState * state) | |
356 { | |
357 XSSIDPlay2 *engine = (XSSIDPlay2 *) state->internal; | |
358 | |
359 if (!engine) | |
360 return FALSE; | |
361 | |
362 if (!engine->tune.selectSong(state->currSong)) | |
363 { | |
364 xs_error("[SIDPlay2] tune.selectSong() failed\n"); | |
365 return FALSE; | |
366 } | |
367 | |
368 if (engine->emu.load(&(engine->tune)) < 0) | |
369 { | |
370 xs_error("[SIDPlay2] emu.load() failed\n"); | |
371 return FALSE; | |
372 } | |
373 | |
374 if (engine->emu.config(engine->config) < 0) | |
375 { | |
376 xs_error("[SIDPlay2] Emulator engine configuration failed!\n"); | |
377 return FALSE; | |
378 } | |
379 | |
380 return TRUE; | |
381 } | |
382 | |
383 | |
384 /* Emulate and render audio data to given buffer | |
385 */ | |
386 guint xs_sidplay2_fillbuffer(XSEngineState * state, gchar * audioBuffer, guint audioBufSize) | |
387 { | |
388 XSSIDPlay2 *engine = (XSSIDPlay2 *) state->internal; | |
389 | |
390 if (!engine) | |
391 return 0; | |
392 | |
393 return engine->emu.play(audioBuffer, audioBufSize); | |
394 } | |
395 | |
396 | |
397 /* Load a given SID-tune file | |
398 */ | |
399 gboolean xs_sidplay2_load(XSEngineState * state, gchar * filename) | |
400 { | |
401 XSSIDPlay2 *engine = (XSSIDPlay2 *) state->internal; | |
402 gboolean res = FALSE; | |
403 guint8 *buf = NULL; | |
404 size_t bufSize; | |
405 | |
406 if (!engine) | |
407 return FALSE; | |
408 | 369 |
409 if (!xs_fload_buffer(filename, &buf, &bufSize, XS_SIDBUF_SIZE, TRUE)) | 370 if (!xs_fload_buffer(filename, &buf, &bufSize, XS_SIDBUF_SIZE, TRUE)) |
410 goto error; | 371 goto error; |
411 | 372 |
412 engine->tune.read(buf, bufSize); | 373 engine->tune.read(buf, bufSize); |
427 | 388 |
428 /* Delete INTERNAL information | 389 /* Delete INTERNAL information |
429 */ | 390 */ |
430 void xs_sidplay2_delete(XSEngineState * state) | 391 void xs_sidplay2_delete(XSEngineState * state) |
431 { | 392 { |
432 (void) state; | 393 XSSIDPlay2 *engine = (XSSIDPlay2 *) state->internal; |
433 // XSSIDPlay2 *engine = (XSSIDPlay2 *) state->internal; | 394 |
395 if (engine) | |
396 delete engine; | |
397 state->internal = NULL; | |
434 } | 398 } |
435 | 399 |
436 | 400 |
437 /* Hardware backend flushing | 401 /* Hardware backend flushing |
438 */ | 402 */ |