Mercurial > hg > xmms-sid
comparison src/xs_sidplay2.cc @ 660:b0743dc9165d
Change tabs to 4 spaces, everywhere.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 02 Apr 2008 22:10:05 +0300 |
parents | acaba070cf49 |
children | 0126579b6652 |
comparison
equal
deleted
inserted
replaced
659:04ea91a61225 | 660:b0743dc9165d |
---|---|
37 #include <sidplay/builders/hardsid.h> | 37 #include <sidplay/builders/hardsid.h> |
38 #endif | 38 #endif |
39 | 39 |
40 | 40 |
41 typedef struct { | 41 typedef struct { |
42 sidplay2 *currEng; | 42 sidplay2 *currEng; |
43 sidbuilder *currBuilder; | 43 sidbuilder *currBuilder; |
44 sid2_config_t currConfig; | 44 sid2_config_t currConfig; |
45 SidTune *currTune; | 45 SidTune *currTune; |
46 guint8 *buf; | 46 guint8 *buf; |
47 size_t bufSize; | 47 size_t bufSize; |
48 } xs_sidplay2_t; | 48 } xs_sidplay2_t; |
49 | 49 |
50 | 50 |
51 /* We need to 'export' all this pseudo-C++ crap */ | 51 /* We need to 'export' all this pseudo-C++ crap */ |
52 extern "C" { | 52 extern "C" { |
53 | 53 |
54 | 54 |
55 /* Return song information | 55 /* Return song information |
56 */ | 56 */ |
57 #define TFUNCTION xs_sidplay2_getinfo | 57 #define TFUNCTION xs_sidplay2_getinfo |
58 #define TFUNCTION2 xs_sidplay2_updateinfo | 58 #define TFUNCTION2 xs_sidplay2_updateinfo |
59 #define TTUNEINFO SidTuneInfo | 59 #define TTUNEINFO SidTuneInfo |
60 #define TTUNE SidTune | 60 #define TTUNE SidTune |
61 #define TENGINE xs_sidplay2_t | 61 #define TENGINE xs_sidplay2_t |
62 #include "xs_sidplay.h" | 62 #include "xs_sidplay.h" |
63 | 63 |
64 | 64 |
65 /* Check if we can play the given file | 65 /* Check if we can play the given file |
66 */ | 66 */ |
67 gboolean xs_sidplay2_probe(xs_file_t *f) | 67 gboolean xs_sidplay2_probe(xs_file_t *f) |
68 { | 68 { |
69 gchar tmpBuf[4]; | 69 gchar tmpBuf[4]; |
70 | 70 |
71 if (!f) return FALSE; | 71 if (!f) return FALSE; |
72 | 72 |
73 if (xs_fread(tmpBuf, sizeof(gchar), 4, f) != 4) | 73 if (xs_fread(tmpBuf, sizeof(gchar), 4, f) != 4) |
74 return FALSE; | 74 return FALSE; |
75 | 75 |
76 if (!strncmp(tmpBuf, "PSID", 4) || !strncmp(tmpBuf, "RSID", 4)) | 76 if (!strncmp(tmpBuf, "PSID", 4) || !strncmp(tmpBuf, "RSID", 4)) |
77 return TRUE; | 77 return TRUE; |
78 else | 78 else |
79 return FALSE; | 79 return FALSE; |
80 } | 80 } |
81 | 81 |
82 | 82 |
83 /* Initialize SIDPlay2 | 83 /* Initialize SIDPlay2 |
84 */ | 84 */ |
85 gboolean xs_sidplay2_init(xs_status_t * myStatus) | 85 gboolean xs_sidplay2_init(xs_status_t * myStatus) |
86 { | 86 { |
87 gint tmpFreq, i; | 87 gint tmpFreq, i; |
88 xs_sidplay2_t *myEngine; | 88 xs_sidplay2_t *myEngine; |
89 sid_filter_t tmpFilter; | 89 sid_filter_t tmpFilter; |
90 t_xs_sid2_filter *f; | 90 t_xs_sid2_filter *f; |
91 assert(myStatus); | 91 assert(myStatus); |
92 | 92 |
93 /* Allocate internal structures */ | 93 /* Allocate internal structures */ |
94 myEngine = (xs_sidplay2_t *) g_malloc0(sizeof(xs_sidplay2_t)); | 94 myEngine = (xs_sidplay2_t *) g_malloc0(sizeof(xs_sidplay2_t)); |
95 myStatus->sidEngine = myEngine; | 95 myStatus->sidEngine = myEngine; |
96 if (!myEngine) return FALSE; | 96 if (!myEngine) return FALSE; |
97 | 97 |
98 /* Initialize the engine */ | 98 /* Initialize the engine */ |
99 myEngine->currEng = new sidplay2; | 99 myEngine->currEng = new sidplay2; |
100 if (!myEngine->currEng) { | 100 if (!myEngine->currEng) { |
101 xs_error("[SIDPlay2] Could not initialize emulation engine.\n"); | 101 xs_error("[SIDPlay2] Could not initialize emulation engine.\n"); |
102 return FALSE; | 102 return FALSE; |
103 } | 103 } |
104 | 104 |
105 /* Get current configuration */ | 105 /* Get current configuration */ |
106 myEngine->currConfig = myEngine->currEng->config(); | 106 myEngine->currConfig = myEngine->currEng->config(); |
107 | 107 |
108 /* Configure channels and stuff */ | 108 /* Configure channels and stuff */ |
109 switch (myStatus->audioChannels) { | 109 switch (myStatus->audioChannels) { |
110 | 110 |
111 case XS_CHN_AUTOPAN: | 111 case XS_CHN_AUTOPAN: |
112 myEngine->currConfig.playback = sid2_stereo; | 112 myEngine->currConfig.playback = sid2_stereo; |
113 break; | 113 break; |
114 | 114 |
115 case XS_CHN_STEREO: | 115 case XS_CHN_STEREO: |
116 myEngine->currConfig.playback = sid2_stereo; | 116 myEngine->currConfig.playback = sid2_stereo; |
117 break; | 117 break; |
118 | 118 |
119 case XS_CHN_MONO: | 119 case XS_CHN_MONO: |
120 default: | 120 default: |
121 myEngine->currConfig.playback = sid2_mono; | 121 myEngine->currConfig.playback = sid2_mono; |
122 myStatus->audioChannels = XS_CHN_MONO; | 122 myStatus->audioChannels = XS_CHN_MONO; |
123 break; | 123 break; |
124 } | 124 } |
125 | 125 |
126 | 126 |
127 /* Memory mode settings */ | 127 /* Memory mode settings */ |
128 switch (xs_cfg.memoryMode) { | 128 switch (xs_cfg.memoryMode) { |
129 case XS_MPU_BANK_SWITCHING: | 129 case XS_MPU_BANK_SWITCHING: |
130 myEngine->currConfig.environment = sid2_envBS; | 130 myEngine->currConfig.environment = sid2_envBS; |
131 break; | 131 break; |
132 | 132 |
133 case XS_MPU_TRANSPARENT_ROM: | 133 case XS_MPU_TRANSPARENT_ROM: |
134 myEngine->currConfig.environment = sid2_envTP; | 134 myEngine->currConfig.environment = sid2_envTP; |
135 break; | 135 break; |
136 | 136 |
137 case XS_MPU_PLAYSID_ENVIRONMENT: | 137 case XS_MPU_PLAYSID_ENVIRONMENT: |
138 myEngine->currConfig.environment = sid2_envPS; | 138 myEngine->currConfig.environment = sid2_envPS; |
139 break; | 139 break; |
140 | 140 |
141 case XS_MPU_REAL: | 141 case XS_MPU_REAL: |
142 default: | 142 default: |
143 myEngine->currConfig.environment = sid2_envR; | 143 myEngine->currConfig.environment = sid2_envR; |
144 xs_cfg.memoryMode = XS_MPU_REAL; | 144 xs_cfg.memoryMode = XS_MPU_REAL; |
145 break; | 145 break; |
146 } | 146 } |
147 | 147 |
148 | 148 |
149 /* Audio parameters sanity checking and setup */ | 149 /* Audio parameters sanity checking and setup */ |
150 myEngine->currConfig.precision = myStatus->audioBitsPerSample; | 150 myEngine->currConfig.precision = myStatus->audioBitsPerSample; |
151 tmpFreq = myStatus->audioFrequency; | 151 tmpFreq = myStatus->audioFrequency; |
152 | 152 |
153 if (myStatus->oversampleEnable) | 153 if (myStatus->oversampleEnable) |
154 tmpFreq = (tmpFreq * myStatus->oversampleFactor); | 154 tmpFreq = (tmpFreq * myStatus->oversampleFactor); |
155 | 155 |
156 myEngine->currConfig.frequency = tmpFreq; | 156 myEngine->currConfig.frequency = tmpFreq; |
157 | 157 |
158 switch (myStatus->audioBitsPerSample) { | 158 switch (myStatus->audioBitsPerSample) { |
159 case XS_RES_8BIT: | 159 case XS_RES_8BIT: |
160 myStatus->audioFormat = FMT_U8; | 160 myStatus->audioFormat = FMT_U8; |
161 myEngine->currConfig.sampleFormat = SID2_LITTLE_UNSIGNED; | 161 myEngine->currConfig.sampleFormat = SID2_LITTLE_UNSIGNED; |
162 break; | 162 break; |
163 | 163 |
164 case XS_RES_16BIT: | 164 case XS_RES_16BIT: |
165 default: | 165 default: |
166 switch (myStatus->audioFormat) { | 166 switch (myStatus->audioFormat) { |
167 case FMT_U16_LE: | 167 case FMT_U16_LE: |
168 myEngine->currConfig.sampleFormat = SID2_LITTLE_UNSIGNED; | 168 myEngine->currConfig.sampleFormat = SID2_LITTLE_UNSIGNED; |
169 break; | 169 break; |
170 | 170 |
171 case FMT_U16_BE: | 171 case FMT_U16_BE: |
172 myEngine->currConfig.sampleFormat = SID2_BIG_UNSIGNED; | 172 myEngine->currConfig.sampleFormat = SID2_BIG_UNSIGNED; |
173 break; | 173 break; |
174 | 174 |
175 case FMT_U16_NE: | 175 case FMT_U16_NE: |
176 #if G_BYTE_ORDER == G_BIG_ENDIAN | 176 #if G_BYTE_ORDER == G_BIG_ENDIAN |
177 myEngine->currConfig.sampleFormat = SID2_BIG_UNSIGNED; | 177 myEngine->currConfig.sampleFormat = SID2_BIG_UNSIGNED; |
178 #else | 178 #else |
179 #if G_BYTE_ORDER == G_LITTLE_ENDIAN | 179 #if G_BYTE_ORDER == G_LITTLE_ENDIAN |
180 myEngine->currConfig.sampleFormat = SID2_LITTLE_UNSIGNED; | 180 myEngine->currConfig.sampleFormat = SID2_LITTLE_UNSIGNED; |
181 #else | 181 #else |
182 #error Unsupported endianess! | 182 #error Unsupported endianess! |
183 #endif | 183 #endif |
184 #endif | 184 #endif |
185 break; | 185 break; |
186 | 186 |
187 case FMT_S16_LE: | 187 case FMT_S16_LE: |
188 myEngine->currConfig.sampleFormat = SID2_LITTLE_SIGNED; | 188 myEngine->currConfig.sampleFormat = SID2_LITTLE_SIGNED; |
189 break; | 189 break; |
190 | 190 |
191 case FMT_S16_BE: | 191 case FMT_S16_BE: |
192 myEngine->currConfig.sampleFormat = SID2_BIG_SIGNED; | 192 myEngine->currConfig.sampleFormat = SID2_BIG_SIGNED; |
193 break; | 193 break; |
194 | 194 |
195 default: | 195 default: |
196 myStatus->audioFormat = FMT_S16_NE; | 196 myStatus->audioFormat = FMT_S16_NE; |
197 #if G_BYTE_ORDER == G_BIG_ENDIAN | 197 #if G_BYTE_ORDER == G_BIG_ENDIAN |
198 myEngine->currConfig.sampleFormat = SID2_BIG_SIGNED; | 198 myEngine->currConfig.sampleFormat = SID2_BIG_SIGNED; |
199 #else | 199 #else |
200 #if G_BYTE_ORDER == G_LITTLE_ENDIAN | 200 #if G_BYTE_ORDER == G_LITTLE_ENDIAN |
201 myEngine->currConfig.sampleFormat = SID2_LITTLE_SIGNED; | 201 myEngine->currConfig.sampleFormat = SID2_LITTLE_SIGNED; |
202 #else | 202 #else |
203 #error Unsupported endianess! | 203 #error Unsupported endianess! |
204 #endif | 204 #endif |
205 #endif | 205 #endif |
206 break; | 206 break; |
207 | 207 |
208 } | 208 } |
209 break; | 209 break; |
210 } | 210 } |
211 | 211 |
212 /* Convert filter */ | 212 /* Convert filter */ |
213 f = &(xs_cfg.sid2Filter); | 213 f = &(xs_cfg.sid2Filter); |
214 XSDEBUG("using filter '%s', %d points\n", f->name, f->npoints); | 214 XSDEBUG("using filter '%s', %d points\n", f->name, f->npoints); |
215 if (f->npoints > XS_SIDPLAY2_NFPOINTS) { | 215 if (f->npoints > XS_SIDPLAY2_NFPOINTS) { |
216 xs_error("[SIDPlay2] Invalid number of filter curve points (%d > %d)\n", | 216 xs_error("[SIDPlay2] Invalid number of filter curve points (%d > %d)\n", |
217 f->npoints, XS_SIDPLAY2_NFPOINTS); | 217 f->npoints, XS_SIDPLAY2_NFPOINTS); |
218 f->npoints = XS_SIDPLAY2_NFPOINTS; | 218 f->npoints = XS_SIDPLAY2_NFPOINTS; |
219 } | 219 } |
220 | 220 |
221 tmpFilter.points = f->npoints; | 221 tmpFilter.points = f->npoints; |
222 for (i = 0; i < f->npoints; i++) { | 222 for (i = 0; i < f->npoints; i++) { |
223 tmpFilter.cutoff[i][0] = f->points[i].x; | 223 tmpFilter.cutoff[i][0] = f->points[i].x; |
224 tmpFilter.cutoff[i][1] = f->points[i].y; | 224 tmpFilter.cutoff[i][1] = f->points[i].y; |
225 } | 225 } |
226 | 226 |
227 /* Initialize builder object */ | 227 /* Initialize builder object */ |
228 XSDEBUG("init builder #%i, maxsids=%i\n", xs_cfg.sid2Builder, (myEngine->currEng->info()).maxsids); | 228 XSDEBUG("init builder #%i, maxsids=%i\n", xs_cfg.sid2Builder, (myEngine->currEng->info()).maxsids); |
229 #ifdef HAVE_RESID_BUILDER | 229 #ifdef HAVE_RESID_BUILDER |
230 if (xs_cfg.sid2Builder == XS_BLD_RESID) { | 230 if (xs_cfg.sid2Builder == XS_BLD_RESID) { |
231 ReSIDBuilder *rs = new ReSIDBuilder("ReSID builder"); | 231 ReSIDBuilder *rs = new ReSIDBuilder("ReSID builder"); |
232 myEngine->currBuilder = (sidbuilder *) rs; | 232 myEngine->currBuilder = (sidbuilder *) rs; |
233 if (rs) { | 233 if (rs) { |
234 /* Builder object created, initialize it */ | 234 /* Builder object created, initialize it */ |
235 rs->create((myEngine->currEng->info()).maxsids); | 235 rs->create((myEngine->currEng->info()).maxsids); |
236 if (!*rs) { | 236 if (!*rs) { |
237 xs_error("reSID->create() failed.\n"); | 237 xs_error("reSID->create() failed.\n"); |
238 return FALSE; | 238 return FALSE; |
239 } | 239 } |
240 | 240 |
241 rs->filter(xs_cfg.emulateFilters); | 241 rs->filter(xs_cfg.emulateFilters); |
242 if (!*rs) { | 242 if (!*rs) { |
243 xs_error("reSID->filter(%d) failed.\n", xs_cfg.emulateFilters); | 243 xs_error("reSID->filter(%d) failed.\n", xs_cfg.emulateFilters); |
244 return FALSE; | 244 return FALSE; |
245 } | 245 } |
246 | 246 |
247 // FIXME FIX ME: support other configurable parameters ... | 247 // FIXME FIX ME: support other configurable parameters ... |
248 // ... WHEN/IF resid-builder+libsidplay2 gets fixed | 248 // ... WHEN/IF resid-builder+libsidplay2 gets fixed |
249 rs->sampling(tmpFreq); | 249 rs->sampling(tmpFreq); |
250 if (!*rs) { | 250 if (!*rs) { |
251 xs_error("reSID->sampling(%d) failed.\n", tmpFreq); | 251 xs_error("reSID->sampling(%d) failed.\n", tmpFreq); |
252 return FALSE; | 252 return FALSE; |
253 } | 253 } |
254 | 254 |
255 if (tmpFilter.points > 0) | 255 if (tmpFilter.points > 0) |
256 rs->filter((sid_filter_t *) &tmpFilter); | 256 rs->filter((sid_filter_t *) &tmpFilter); |
257 else | 257 else |
258 rs->filter((sid_filter_t *) NULL); | 258 rs->filter((sid_filter_t *) NULL); |
259 | 259 |
260 if (!*rs) { | 260 if (!*rs) { |
261 xs_error("reSID->filter(NULL) failed.\n"); | 261 xs_error("reSID->filter(NULL) failed.\n"); |
262 return FALSE; | 262 return FALSE; |
263 } | 263 } |
264 } | 264 } |
265 } | 265 } |
266 #endif | 266 #endif |
267 #ifdef HAVE_HARDSID_BUILDER | 267 #ifdef HAVE_HARDSID_BUILDER |
268 if (xs_cfg.sid2Builder == XS_BLD_HARDSID) { | 268 if (xs_cfg.sid2Builder == XS_BLD_HARDSID) { |
269 HardSIDBuilder *hs = new HardSIDBuilder("HardSID builder"); | 269 HardSIDBuilder *hs = new HardSIDBuilder("HardSID builder"); |
270 myEngine->currBuilder = (sidbuilder *) hs; | 270 myEngine->currBuilder = (sidbuilder *) hs; |
271 if (hs) { | 271 if (hs) { |
272 /* Builder object created, initialize it */ | 272 /* Builder object created, initialize it */ |
273 hs->create((myEngine->currEng->info()).maxsids); | 273 hs->create((myEngine->currEng->info()).maxsids); |
274 if (!*hs) { | 274 if (!*hs) { |
275 xs_error("hardSID->create() failed.\n"); | 275 xs_error("hardSID->create() failed.\n"); |
276 return FALSE; | 276 return FALSE; |
277 } | 277 } |
278 | 278 |
279 hs->filter(xs_cfg.emulateFilters); | 279 hs->filter(xs_cfg.emulateFilters); |
280 if (!*hs) { | 280 if (!*hs) { |
281 xs_error("hardSID->filter(%d) failed.\n", xs_cfg.emulateFilters); | 281 xs_error("hardSID->filter(%d) failed.\n", xs_cfg.emulateFilters); |
282 return FALSE; | 282 return FALSE; |
283 } | 283 } |
284 } | 284 } |
285 } | 285 } |
286 #endif | 286 #endif |
287 | 287 |
288 if (!myEngine->currBuilder) { | 288 if (!myEngine->currBuilder) { |
289 xs_error("[SIDPlay2] Could not initialize SIDBuilder object.\n"); | 289 xs_error("[SIDPlay2] Could not initialize SIDBuilder object.\n"); |
290 return FALSE; | 290 return FALSE; |
291 } | 291 } |
292 | 292 |
293 XSDEBUG("%s\n", myEngine->currBuilder->credits()); | 293 XSDEBUG("%s\n", myEngine->currBuilder->credits()); |
294 | 294 |
295 | 295 |
296 /* Clockspeed settings */ | 296 /* Clockspeed settings */ |
297 switch (xs_cfg.clockSpeed) { | 297 switch (xs_cfg.clockSpeed) { |
298 case XS_CLOCK_NTSC: | 298 case XS_CLOCK_NTSC: |
299 myEngine->currConfig.clockDefault = SID2_CLOCK_NTSC; | 299 myEngine->currConfig.clockDefault = SID2_CLOCK_NTSC; |
300 break; | 300 break; |
301 | 301 |
302 default: | 302 default: |
303 xs_error("[SIDPlay2] Invalid clockSpeed=%d, falling back to PAL.\n", | 303 xs_error("[SIDPlay2] Invalid clockSpeed=%d, falling back to PAL.\n", |
304 xs_cfg.clockSpeed); | 304 xs_cfg.clockSpeed); |
305 | 305 |
306 case XS_CLOCK_PAL: | 306 case XS_CLOCK_PAL: |
307 myEngine->currConfig.clockDefault = SID2_CLOCK_PAL; | 307 myEngine->currConfig.clockDefault = SID2_CLOCK_PAL; |
308 xs_cfg.clockSpeed = XS_CLOCK_PAL; | 308 xs_cfg.clockSpeed = XS_CLOCK_PAL; |
309 break; | 309 break; |
310 } | 310 } |
311 | 311 |
312 | 312 |
313 /* Configure rest of the emulation */ | 313 /* Configure rest of the emulation */ |
314 myEngine->currConfig.sidEmulation = myEngine->currBuilder; | 314 myEngine->currConfig.sidEmulation = myEngine->currBuilder; |
315 | 315 |
316 if (xs_cfg.forceSpeed) { | 316 if (xs_cfg.forceSpeed) { |
317 myEngine->currConfig.clockForced = true; | 317 myEngine->currConfig.clockForced = true; |
318 myEngine->currConfig.clockSpeed = myEngine->currConfig.clockDefault; | 318 myEngine->currConfig.clockSpeed = myEngine->currConfig.clockDefault; |
319 } else { | 319 } else { |
320 myEngine->currConfig.clockForced = false; | 320 myEngine->currConfig.clockForced = false; |
321 myEngine->currConfig.clockSpeed = SID2_CLOCK_CORRECT; | 321 myEngine->currConfig.clockSpeed = SID2_CLOCK_CORRECT; |
322 } | 322 } |
323 | 323 |
324 if ((xs_cfg.sid2OptLevel >= 0) && (xs_cfg.sid2OptLevel <= SID2_MAX_OPTIMISATION)) | 324 if ((xs_cfg.sid2OptLevel >= 0) && (xs_cfg.sid2OptLevel <= SID2_MAX_OPTIMISATION)) |
325 myEngine->currConfig.optimisation = xs_cfg.sid2OptLevel; | 325 myEngine->currConfig.optimisation = xs_cfg.sid2OptLevel; |
326 else { | 326 else { |
327 xs_error("Invalid sid2OptLevel=%d, falling back to %d.\n", | 327 xs_error("Invalid sid2OptLevel=%d, falling back to %d.\n", |
328 xs_cfg.sid2OptLevel, SID2_DEFAULT_OPTIMISATION); | 328 xs_cfg.sid2OptLevel, SID2_DEFAULT_OPTIMISATION); |
329 | 329 |
330 xs_cfg.sid2OptLevel = | 330 xs_cfg.sid2OptLevel = |
331 myEngine->currConfig.optimisation = SID2_DEFAULT_OPTIMISATION; | 331 myEngine->currConfig.optimisation = SID2_DEFAULT_OPTIMISATION; |
332 } | 332 } |
333 | 333 |
334 if (xs_cfg.mos8580) | 334 if (xs_cfg.mos8580) |
335 myEngine->currConfig.sidDefault = SID2_MOS8580; | 335 myEngine->currConfig.sidDefault = SID2_MOS8580; |
336 else | 336 else |
337 myEngine->currConfig.sidDefault = SID2_MOS6581; | 337 myEngine->currConfig.sidDefault = SID2_MOS6581; |
338 | 338 |
339 if (xs_cfg.forceModel) | 339 if (xs_cfg.forceModel) |
340 myEngine->currConfig.sidModel = myEngine->currConfig.sidDefault; | 340 myEngine->currConfig.sidModel = myEngine->currConfig.sidDefault; |
341 else | 341 else |
342 myEngine->currConfig.sidModel = SID2_MODEL_CORRECT; | 342 myEngine->currConfig.sidModel = SID2_MODEL_CORRECT; |
343 | 343 |
344 | 344 |
345 /* XXX: Should this be configurable? libSIDPlay1 does not support it, though */ | 345 /* XXX: Should this be configurable? libSIDPlay1 does not support it, though */ |
346 myEngine->currConfig.sidSamples = TRUE; | 346 myEngine->currConfig.sidSamples = TRUE; |
347 | 347 |
348 | 348 |
349 /* Now set the emulator configuration */ | 349 /* Now set the emulator configuration */ |
350 if (myEngine->currEng->config(myEngine->currConfig) < 0) { | 350 if (myEngine->currEng->config(myEngine->currConfig) < 0) { |
351 xs_error("[SIDPlay2] Emulator engine configuration failed!\n"); | 351 xs_error("[SIDPlay2] Emulator engine configuration failed!\n"); |
352 return FALSE; | 352 return FALSE; |
353 } | 353 } |
354 | 354 |
355 /* Create the sidtune */ | 355 /* Create the sidtune */ |
356 myEngine->currTune = new SidTune(0); | 356 myEngine->currTune = new SidTune(0); |
357 if (!myEngine->currTune) { | 357 if (!myEngine->currTune) { |
358 xs_error("[SIDPlay2] Could not initialize SIDTune object.\n"); | 358 xs_error("[SIDPlay2] Could not initialize SIDTune object.\n"); |
359 return FALSE; | 359 return FALSE; |
360 } | 360 } |
361 | 361 |
362 return TRUE; | 362 return TRUE; |
363 } | 363 } |
364 | 364 |
365 | 365 |
366 /* Close SIDPlay2 engine | 366 /* Close SIDPlay2 engine |
367 */ | 367 */ |
368 void xs_sidplay2_close(xs_status_t * myStatus) | 368 void xs_sidplay2_close(xs_status_t * myStatus) |
369 { | 369 { |
370 xs_sidplay2_t *myEngine; | 370 xs_sidplay2_t *myEngine; |
371 assert(myStatus); | 371 assert(myStatus); |
372 | 372 |
373 myEngine = (xs_sidplay2_t *) myStatus->sidEngine; | 373 myEngine = (xs_sidplay2_t *) myStatus->sidEngine; |
374 | 374 |
375 /* Free internals */ | 375 /* Free internals */ |
376 if (myEngine->currBuilder) { | 376 if (myEngine->currBuilder) { |
377 delete myEngine->currBuilder; | 377 delete myEngine->currBuilder; |
378 myEngine->currBuilder = NULL; | 378 myEngine->currBuilder = NULL; |
379 } | 379 } |
380 | 380 |
381 if (myEngine->currEng) { | 381 if (myEngine->currEng) { |
382 delete myEngine->currEng; | 382 delete myEngine->currEng; |
383 myEngine->currEng = NULL; | 383 myEngine->currEng = NULL; |
384 } | 384 } |
385 | 385 |
386 if (myEngine->currTune) { | 386 if (myEngine->currTune) { |
387 delete myEngine->currTune; | 387 delete myEngine->currTune; |
388 myEngine->currTune = NULL; | 388 myEngine->currTune = NULL; |
389 } | 389 } |
390 | 390 |
391 xs_sidplay2_delete(myStatus); | 391 xs_sidplay2_delete(myStatus); |
392 | 392 |
393 g_free(myEngine); | 393 g_free(myEngine); |
394 myStatus->sidEngine = NULL; | 394 myStatus->sidEngine = NULL; |
395 } | 395 } |
396 | 396 |
397 | 397 |
398 /* Initialize current song and sub-tune | 398 /* Initialize current song and sub-tune |
399 */ | 399 */ |
400 gboolean xs_sidplay2_initsong(xs_status_t * myStatus) | 400 gboolean xs_sidplay2_initsong(xs_status_t * myStatus) |
401 { | 401 { |
402 xs_sidplay2_t *myEngine; | 402 xs_sidplay2_t *myEngine; |
403 assert(myStatus); | 403 assert(myStatus); |
404 | 404 |
405 myEngine = (xs_sidplay2_t *) myStatus->sidEngine; | 405 myEngine = (xs_sidplay2_t *) myStatus->sidEngine; |
406 if (!myEngine) return FALSE; | 406 if (!myEngine) return FALSE; |
407 | 407 |
408 if (!myEngine->currTune->selectSong(myStatus->currSong)) { | 408 if (!myEngine->currTune->selectSong(myStatus->currSong)) { |
409 xs_error("[SIDPlay2] currTune->selectSong() failed\n"); | 409 xs_error("[SIDPlay2] currTune->selectSong() failed\n"); |
410 return FALSE; | 410 return FALSE; |
411 } | 411 } |
412 | 412 |
413 if (myEngine->currEng->load(myEngine->currTune) < 0) { | 413 if (myEngine->currEng->load(myEngine->currTune) < 0) { |
414 xs_error("[SIDPlay2] currEng->load() failed\n"); | 414 xs_error("[SIDPlay2] currEng->load() failed\n"); |
415 return FALSE; | 415 return FALSE; |
416 } | 416 } |
417 | 417 |
418 myStatus->isInitialized = TRUE; | 418 myStatus->isInitialized = TRUE; |
419 | 419 |
420 return TRUE; | 420 return TRUE; |
421 } | 421 } |
422 | 422 |
423 | 423 |
424 /* Emulate and render audio data to given buffer | 424 /* Emulate and render audio data to given buffer |
425 */ | 425 */ |
426 guint xs_sidplay2_fillbuffer(xs_status_t * myStatus, gchar * audioBuffer, guint audioBufSize) | 426 guint xs_sidplay2_fillbuffer(xs_status_t * myStatus, gchar * audioBuffer, guint audioBufSize) |
427 { | 427 { |
428 xs_sidplay2_t *myEngine; | 428 xs_sidplay2_t *myEngine; |
429 assert(myStatus); | 429 assert(myStatus); |
430 | 430 |
431 myEngine = (xs_sidplay2_t *) myStatus->sidEngine; | 431 myEngine = (xs_sidplay2_t *) myStatus->sidEngine; |
432 if (!myEngine) return 0; | 432 if (!myEngine) return 0; |
433 | 433 |
434 return myEngine->currEng->play(audioBuffer, audioBufSize); | 434 return myEngine->currEng->play(audioBuffer, audioBufSize); |
435 } | 435 } |
436 | 436 |
437 | 437 |
438 /* Load a given SID-tune file | 438 /* Load a given SID-tune file |
439 */ | 439 */ |
440 gboolean xs_sidplay2_load(xs_status_t * myStatus, gchar * pcFilename) | 440 gboolean xs_sidplay2_load(xs_status_t * myStatus, gchar * pcFilename) |
441 { | 441 { |
442 xs_sidplay2_t *myEngine; | 442 xs_sidplay2_t *myEngine; |
443 assert(myStatus); | 443 assert(myStatus); |
444 myStatus->isInitialized = FALSE; | 444 myStatus->isInitialized = FALSE; |
445 | 445 |
446 myEngine = (xs_sidplay2_t *) myStatus->sidEngine; | 446 myEngine = (xs_sidplay2_t *) myStatus->sidEngine; |
447 if (!myEngine) return FALSE; | 447 if (!myEngine) return FALSE; |
448 | 448 |
449 /* Try to get the tune */ | 449 /* Try to get the tune */ |
450 if (!pcFilename) return FALSE; | 450 if (!pcFilename) return FALSE; |
451 | 451 |
452 if (xs_fload_buffer(pcFilename, &(myEngine->buf), &(myEngine->bufSize)) != 0) | 452 if (xs_fload_buffer(pcFilename, &(myEngine->buf), &(myEngine->bufSize)) != 0) |
453 return FALSE; | 453 return FALSE; |
454 | 454 |
455 if (!myEngine->currTune->read(myEngine->buf, myEngine->bufSize)) | 455 if (!myEngine->currTune->read(myEngine->buf, myEngine->bufSize)) |
456 return FALSE; | 456 return FALSE; |
457 | 457 |
458 return TRUE; | 458 return TRUE; |
459 } | 459 } |
460 | 460 |
461 | 461 |
462 /* Delete INTERNAL information | 462 /* Delete INTERNAL information |
463 */ | 463 */ |
464 void xs_sidplay2_delete(xs_status_t * myStatus) | 464 void xs_sidplay2_delete(xs_status_t * myStatus) |
465 { | 465 { |
466 xs_sidplay2_t *myEngine; | 466 xs_sidplay2_t *myEngine; |
467 assert(myStatus); | 467 assert(myStatus); |
468 | 468 |
469 myEngine = (xs_sidplay2_t *) myStatus->sidEngine; | 469 myEngine = (xs_sidplay2_t *) myStatus->sidEngine; |
470 if (!myEngine) return; | 470 if (!myEngine) return; |
471 | 471 |
472 g_free(myEngine->buf); | 472 g_free(myEngine->buf); |
473 myEngine->buf = NULL; | 473 myEngine->buf = NULL; |
474 myEngine->bufSize = 0; | 474 myEngine->bufSize = 0; |
475 } | 475 } |
476 | 476 |
477 | 477 |
478 /* Hardware backend flushing | 478 /* Hardware backend flushing |
479 */ | 479 */ |
480 void xs_sidplay2_flush(xs_status_t * myStatus) | 480 void xs_sidplay2_flush(xs_status_t * myStatus) |
481 { | 481 { |
482 assert(myStatus); | 482 assert(myStatus); |
483 | 483 |
484 #ifdef HAVE_HARDSID_BUILDER | 484 #ifdef HAVE_HARDSID_BUILDER |
485 #ifdef HSID_SID2_COM | 485 #ifdef HSID_SID2_COM |
486 IfPtr<HardSIDBuilder> hs(myStatus->currBuilder); | 486 IfPtr<HardSIDBuilder> hs(myStatus->currBuilder); |
487 if (hs) | 487 if (hs) |
488 hs->flush(); | 488 hs->flush(); |
489 #else | 489 #else |
490 if (xs_cfg.sid2Builder == XS_BLD_HARDSID) | 490 if (xs_cfg.sid2Builder == XS_BLD_HARDSID) |
491 ((HardSIDBuilder *) myStatus->currBuilder)->flush(); | 491 ((HardSIDBuilder *) myStatus->currBuilder)->flush(); |
492 #endif | 492 #endif |
493 #endif | 493 #endif |
494 } | 494 } |
495 | 495 |
496 | 496 |
497 } /* extern "C" */ | 497 } /* extern "C" */ |
498 #endif /* HAVE_SIDPLAY2 */ | 498 #endif /* HAVE_SIDPLAY2 */ |