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 */