Mercurial > hg > xmms-sid
comparison src/xs_sidplay2.cc @ 75:653c9b0d1320
SIDPlay2 support "works" now. Borked problems with threads.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 15 Sep 2003 11:10:03 +0000 |
parents | 8cb66a3f75f7 |
children | ab522ab65c85 |
comparison
equal
deleted
inserted
replaced
74:8cb66a3f75f7 | 75:653c9b0d1320 |
---|---|
35 #include <sidplay/sidplay2.h> | 35 #include <sidplay/sidplay2.h> |
36 #ifdef HAVE_RESID_BUILDER | 36 #ifdef HAVE_RESID_BUILDER |
37 #include <sidplay/builders/resid.h> | 37 #include <sidplay/builders/resid.h> |
38 #endif | 38 #endif |
39 #ifdef HAVE_HARDSID_BUILDER | 39 #ifdef HAVE_HARDSID_BUILDER |
40 /* Dummy now */ | 40 #include <sidplay/builders/hardsid.h> |
41 #endif | 41 #endif |
42 | 42 |
43 | 43 |
44 typedef struct { | 44 typedef struct { |
45 sidplay2 *currEng; | 45 sidplay2 *currEng; |
46 sidbuilder *currBuilder; | |
46 sid2_config_t currConfig; | 47 sid2_config_t currConfig; |
47 SidTune *currTune; | 48 SidTune *currTune; |
48 } t_xs_sidplay2; | 49 } t_xs_sidplay2; |
49 | 50 |
50 | 51 |
51 /* | 52 /* |
52 * We need to 'export' all this pseudo-C++ crap | 53 * We need to 'export' all this pseudo-C++ crap |
53 */ | 54 */ |
54 extern "C" { | 55 extern "C" { |
55 | 56 |
57 | |
58 /* | |
59 * Check if we can play the given file | |
60 */ | |
56 gboolean xs_sidplay2_isourfile(gchar *pcFileName) | 61 gboolean xs_sidplay2_isourfile(gchar *pcFileName) |
57 { | 62 { |
58 /* Try to detect via libSIDPlay's detection routine, if required */ | |
59 SidTune *testTune = new SidTune(pcFileName); | 63 SidTune *testTune = new SidTune(pcFileName); |
60 | 64 |
61 if (!testTune) return FALSE; | 65 if (!testTune) return FALSE; |
62 if (!testTune->getStatus()) | 66 if (!testTune->getStatus()) |
63 { | 67 { |
68 delete testTune; | 72 delete testTune; |
69 return TRUE; | 73 return TRUE; |
70 } | 74 } |
71 | 75 |
72 | 76 |
73 void xs_sidplay2_close(t_xs_status *myStatus) | 77 /* |
78 * Initialize SIDPlay2 | |
79 */ | |
80 gboolean xs_sidplay2_init(t_xs_status *myStatus) | |
74 { | 81 { |
75 t_xs_sidplay2 *myPlayer; | 82 t_xs_sidplay2 *myPlayer; |
76 sidbuilder *myBuilder; | 83 assert(myStatus); |
77 | |
78 /* Check pointer */ | |
79 if (!myStatus) return; | |
80 | |
81 /* Free internals */ | |
82 myPlayer = (t_xs_sidplay2 *) myStatus->player; | |
83 | |
84 myBuilder = myPlayer->currConfig.sidEmulation; | |
85 myPlayer->currEng->config(myPlayer->currConfig); | |
86 | |
87 delete myBuilder; | |
88 delete myPlayer->currEng; | |
89 | |
90 xs_sidplay2_deletesid(myStatus); | |
91 | |
92 free(myPlayer); | |
93 myStatus->player = NULL; | |
94 | |
95 /* Miscellaneous */ | |
96 free(myStatus->currFileName); | |
97 myStatus->currFileName = NULL; | |
98 } | |
99 | |
100 | |
101 gboolean xs_sidplay2_init(t_xs_status *myStatus) | |
102 { | |
103 t_xs_sidplay2 *myPlayer; | |
104 | |
105 /* Check pointer */ | |
106 if (!myStatus) return FALSE; | |
107 | 84 |
108 /* Allocate internal structures */ | 85 /* Allocate internal structures */ |
109 myPlayer = (t_xs_sidplay2 *) g_malloc0(sizeof(t_xs_sidplay2)); | 86 myPlayer = (t_xs_sidplay2 *) g_malloc0(sizeof(t_xs_sidplay2)); |
110 if (!myPlayer) return FALSE; | 87 if (!myPlayer) return FALSE; |
111 | 88 |
112 /* Initialize engine */ | 89 |
90 /* Initialize the engine */ | |
113 myPlayer->currEng = new sidplay2; | 91 myPlayer->currEng = new sidplay2; |
114 if (!myPlayer->currEng) | 92 if (!myPlayer->currEng) |
115 { | 93 { |
116 XSERR("Could not initialize libSIDPlay2 emulation engine\n"); | 94 XSERR("Could not initialize libSIDPlay2 emulation engine\n"); |
117 free(myPlayer); | 95 return FALSE; |
118 return FALSE; | 96 } |
119 } | 97 |
120 | 98 /* Initialize builder object */ |
99 /* | |
100 FIXME! we need to select builder by configuration! | |
101 */ | |
102 #ifdef HAVE_RESID_BUILDER | |
103 ReSIDBuilder *tmpb = new ReSIDBuilder("SIDPlay2 suxx and is made by a fag - ReSID builder"); | |
104 | |
105 /* Create the builder -- WHAT IS THIS MEANT FOR??? */ | |
106 tmpb->create(myPlayer->currEng->info().maxsids); | |
107 | |
108 myPlayer->currBuilder = (sidbuilder *) tmpb; | |
109 #endif | |
110 #ifdef HAVE_HARDSID_BUILDER | |
111 #endif | |
112 | |
113 if (!myPlayer->currBuilder) | |
114 { | |
115 XSERR("Could not initialize SIDBuilder object.\n"); | |
116 return FALSE; | |
117 } | |
118 | |
119 XSDEBUG("%s\n", myPlayer->currBuilder->credits()); | |
120 | |
121 | |
122 /* Create the sidtune */ | |
123 myPlayer->currTune = new SidTune(0); | |
124 if (!myPlayer->currTune) | |
125 { | |
126 XSERR("Could not initialize SIDTune object.\n"); | |
127 return FALSE; | |
128 } | |
129 | |
130 /* OK */ | |
121 myStatus->player = myPlayer; | 131 myStatus->player = myPlayer; |
122 return TRUE; | 132 return TRUE; |
123 } | 133 } |
124 | 134 |
125 | 135 |
136 /* | |
137 * Close SIDPlay2 | |
138 */ | |
139 void xs_sidplay2_close(t_xs_status *myStatus) | |
140 { | |
141 t_xs_sidplay2 *myPlayer; | |
142 assert(myStatus); | |
143 | |
144 /* Free internals */ | |
145 myPlayer = (t_xs_sidplay2 *) myStatus->player; | |
146 | |
147 if (myPlayer->currBuilder) | |
148 { | |
149 delete myPlayer->currBuilder; | |
150 myPlayer->currBuilder = NULL; | |
151 } | |
152 | |
153 if (myPlayer->currEng) | |
154 { | |
155 delete myPlayer->currEng; | |
156 myPlayer->currEng = NULL; | |
157 } | |
158 | |
159 if (myPlayer->currTune) | |
160 { | |
161 delete myPlayer->currTune; | |
162 myPlayer->currTune = NULL; | |
163 } | |
164 | |
165 xs_sidplay2_deletesid(myStatus); | |
166 | |
167 g_free(myPlayer); | |
168 myStatus->player = NULL; | |
169 } | |
170 | |
171 | |
126 gboolean xs_sidplay2_initsong(t_xs_status *myStatus) | 172 gboolean xs_sidplay2_initsong(t_xs_status *myStatus) |
127 { | 173 { |
128 t_xs_sidplay2 *myPlayer = (t_xs_sidplay2 *) myStatus->player; | 174 t_xs_sidplay2 *myPlayer = (t_xs_sidplay2 *) myStatus->player; |
129 | 175 |
130 if (!myPlayer || !myPlayer->currTune) return FALSE; | 176 if (!myPlayer) return FALSE; |
131 | 177 |
132 myPlayer->currTune->selectSong(myStatus->currSong); | 178 if (!myPlayer->currTune->selectSong(myStatus->currSong)) |
133 | 179 { |
134 return myPlayer->currEng->load(myPlayer->currTune); | 180 XSERR("ENGINE selectSong() failed\n"); |
181 return FALSE; | |
182 } | |
183 | |
184 if (myPlayer->currEng->load(myPlayer->currTune) < 0) | |
185 { | |
186 XSERR("ENGINE load() failed\n"); | |
187 return FALSE; | |
188 } | |
189 | |
190 return TRUE; | |
135 } | 191 } |
136 | 192 |
137 | 193 |
138 gboolean xs_sidplay2_fillbuffer(t_xs_status *myStatus, gchar *audioBuffer, gint audioBufSize) | 194 gboolean xs_sidplay2_fillbuffer(t_xs_status *myStatus, gchar *audioBuffer, gint audioBufSize) |
139 { | 195 { |
140 t_xs_sidplay2 *myPlayer = (t_xs_sidplay2 *) myStatus->player; | 196 t_xs_sidplay2 *myPlayer = (t_xs_sidplay2 *) myStatus->player; |
141 | 197 |
142 if (!myPlayer) return FALSE; | |
143 | |
144 return (myPlayer->currEng->play(audioBuffer, audioBufSize) == audioBufSize); | 198 return (myPlayer->currEng->play(audioBuffer, audioBufSize) == audioBufSize); |
145 } | 199 } |
146 | 200 |
147 | 201 |
148 gboolean xs_sidplay2_loadsid(t_xs_status *myStatus, gchar *pcFileName) | 202 gboolean xs_sidplay2_loadsid(t_xs_status *myStatus, gchar *pcFileName) |
149 { | 203 { |
150 t_xs_sidplay2 *myPlayer = (t_xs_sidplay2 *) myStatus->player; | 204 t_xs_sidplay2 *myPlayer = (t_xs_sidplay2 *) myStatus->player; |
151 SidTune *newTune; | |
152 SidTuneInfo tuneInfo; | 205 SidTuneInfo tuneInfo; |
206 assert(myStatus); | |
153 | 207 |
154 /* Try to get the tune */ | 208 /* Try to get the tune */ |
155 if (!pcFileName) return FALSE; | 209 if (!pcFileName) return FALSE; |
156 newTune = new SidTune(pcFileName); | 210 if (!myPlayer->currTune->load(pcFileName)) return FALSE; |
157 if (!newTune) return FALSE; | |
158 | 211 |
159 /* Get current configuration */ | 212 /* Get current configuration */ |
160 myPlayer->currConfig = myPlayer->currEng->config(); | 213 myPlayer->currConfig = myPlayer->currEng->config(); |
161 | 214 |
162 /* Configure channels and stuff */ | 215 /* Configure channels and stuff */ |
210 break; | 263 break; |
211 } | 264 } |
212 | 265 |
213 | 266 |
214 /* Configure rest of the emulation */ | 267 /* Configure rest of the emulation */ |
268 myPlayer->currConfig.sidEmulation = myPlayer->currBuilder; | |
215 myPlayer->currConfig.precision = xs_cfg.fmtBitsPerSample; | 269 myPlayer->currConfig.precision = xs_cfg.fmtBitsPerSample; |
216 myPlayer->currConfig.frequency = xs_cfg.fmtFrequency; | 270 myPlayer->currConfig.frequency = xs_cfg.fmtFrequency; |
217 myPlayer->currConfig.clockForced = xs_cfg.forceSpeed; | 271 myPlayer->currConfig.clockForced = xs_cfg.forceSpeed; |
218 myPlayer->currConfig.optimisation = (xs_cfg.optimiseLevel) ? 1 : 0; | 272 myPlayer->currConfig.optimisation = (xs_cfg.optimiseLevel) ? 1 : 0; |
219 myPlayer->currConfig.sidDefault = myPlayer->currConfig.sidModel = (xs_cfg.mos8580) ? SID2_MOS8580 : SID2_MOS6581; | 273 myPlayer->currConfig.sidDefault = myPlayer->currConfig.sidModel = (xs_cfg.mos8580) ? SID2_MOS8580 : SID2_MOS6581; |
220 myPlayer->currConfig.sidSamples = TRUE; // FIXME FIX ME, make configurable! | 274 myPlayer->currConfig.sidSamples = TRUE; // FIXME FIX ME, make configurable! |
221 | 275 |
222 #ifdef HAVE_UNSIGNEDPCM | 276 #ifdef HAVE_UNSIGNEDPCM |
223 #ifdef WORDS_BIGENDIAN | 277 #ifdef WORDS_BIGENDIAN |
224 myPlayer->currConfig.sampleFormat = SID2_BIG_UNSIGNED; | 278 myPlayer->currConfig.sampleFormat = SID2_BIG_UNSIGNED; |
225 #else | 279 #else |
232 myPlayer->currConfig.sampleFormat = SID2_LITTLE_SIGNED; | 286 myPlayer->currConfig.sampleFormat = SID2_LITTLE_SIGNED; |
233 #endif | 287 #endif |
234 #endif | 288 #endif |
235 | 289 |
236 /* Now set the emulator configuration */ | 290 /* Now set the emulator configuration */ |
237 myPlayer->currEng->config(myPlayer->currConfig); | 291 if (myPlayer->currEng->config(myPlayer->currConfig) < 0) |
292 { | |
293 XSERR("Emulator engine configuration failed!\n"); | |
294 return FALSE; | |
295 } | |
238 | 296 |
239 /* Initialize status information */ | 297 /* Initialize status information */ |
240 newTune->getInfo(tuneInfo); | 298 myPlayer->currTune->getInfo(tuneInfo); |
241 | |
242 myStatus->isPlaying = TRUE; | |
243 myStatus->isError = FALSE; | |
244 myStatus->currSong = tuneInfo.startSong; | 299 myStatus->currSong = tuneInfo.startSong; |
245 myStatus->nSongs = tuneInfo.songs; | 300 myStatus->nSongs = tuneInfo.songs; |
246 myPlayer->currTune = newTune; | |
247 myStatus->currFileName = g_strdup(pcFileName); | |
248 | 301 |
249 return TRUE; | 302 return TRUE; |
250 } | 303 } |
251 | 304 |
252 | 305 |
254 * Delete tune | 307 * Delete tune |
255 */ | 308 */ |
256 void xs_sidplay2_deletesid(t_xs_status *myStatus) | 309 void xs_sidplay2_deletesid(t_xs_status *myStatus) |
257 { | 310 { |
258 t_xs_sidplay2 *myPlayer; | 311 t_xs_sidplay2 *myPlayer; |
259 | 312 assert(myStatus); |
260 if (!myStatus) return; | 313 |
261 | 314 /* |
262 if (myStatus->currFileName) | |
263 { | |
264 g_free(myStatus->currFileName); | |
265 myStatus->currFileName = NULL; | |
266 } | |
267 | |
268 myPlayer = (t_xs_sidplay2 *) myStatus->player; | 315 myPlayer = (t_xs_sidplay2 *) myStatus->player; |
269 if (!myPlayer) return; | 316 if (!myPlayer) return; |
270 | 317 |
271 if (myPlayer->currTune) | 318 if (myPlayer->currTune) |
272 { | 319 { |
273 delete myPlayer->currTune; | 320 delete myPlayer->currTune; |
274 myPlayer->currTune = NULL; | 321 myPlayer->currTune = NULL; |
275 } | 322 } |
323 */ | |
276 } | 324 } |
277 | 325 |
278 | 326 |
279 gint xs_sidplay2_gettunespeed(t_xs_status *myStatus) | 327 gint xs_sidplay2_gettunespeed(t_xs_status *myStatus) |
280 { | 328 { |