Mercurial > hg > xmms-sid
comparison src/xmms-sid.c @ 73:2bc607888f53
Added libsidplay2 module, lots of reworking of internals, sidplay1 support
now works with the new framework! Getting libsidplay2 support working
shouldn't be too far now...
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sun, 14 Sep 2003 03:14:01 +0000 |
parents | e3b205a6bc7e |
children | 8cb66a3f75f7 |
comparison
equal
deleted
inserted
replaced
72:e3b205a6bc7e | 73:2bc607888f53 |
---|---|
46 #endif | 46 #endif |
47 | 47 |
48 | 48 |
49 typedef struct { | 49 typedef struct { |
50 gint plrIdent; | 50 gint plrIdent; |
51 gboolean (*plrIsOurFile)(gchar *); | |
51 gboolean (*plrInit)(t_xs_status *); | 52 gboolean (*plrInit)(t_xs_status *); |
52 void (*plrClose)(t_xs_status *); | 53 void (*plrClose)(t_xs_status *); |
53 gboolean (*plrInitSong)(t_xs_status *); | 54 gboolean (*plrInitSong)(t_xs_status *); |
54 void (*plrFillBuffer)(t_xs_status *, gchar *, gint); | 55 gboolean (*plrFillBuffer)(t_xs_status *, gchar *, gint); |
55 gboolean (*plrLoadSID)(t_xs_status *, gchar *); | 56 gboolean (*plrLoadSID)(t_xs_status *, gchar *); |
57 gint (*plrGetTuneSpeed)(t_xs_status *); | |
58 void (*plrDeleteSID)(t_xs_status *); | |
59 void (*plrGetSIDInfo)(gchar *, gchar **, gint *); | |
56 } t_xs_player; | 60 } t_xs_player; |
57 | 61 |
58 | 62 |
59 t_xs_player xs_playerlist[] = { | 63 t_xs_player xs_playerlist[] = { |
60 #ifdef HAVE_SIDPLAY1 | 64 #ifdef HAVE_SIDPLAY1 |
61 { XS_ENG_SIDPLAY1, xs_sidplay1_init, xs_sidplay1_close, | 65 { XS_ENG_SIDPLAY1, |
66 xs_sidplay1_isourfile, | |
67 xs_sidplay1_init, xs_sidplay1_close, | |
62 xs_sidplay1_initsong, xs_sidplay1_fillbuffer, | 68 xs_sidplay1_initsong, xs_sidplay1_fillbuffer, |
63 xs_sidplay1_loadsid | 69 xs_sidplay1_loadsid, xs_sidplay1_gettunespeed, |
70 xs_sidplay1_deletesid, xs_sidplay1_getsidinfo | |
64 }, | 71 }, |
65 #endif | 72 #endif |
66 #ifdef HAVE_SIDPLAY2 | 73 #ifdef HAVE_SIDPLAY2 |
67 { XS_ENG_SIDPLAY2, xs_sidplay2_init, xs_sidplay2_close, | 74 { XS_ENG_SIDPLAY2, |
75 xs_sidplay2_isourfile, | |
76 xs_sidplay2_init, xs_sidplay2_close, | |
68 xs_sidplay2_initsong, xs_sidplay2_fillbuffer, | 77 xs_sidplay2_initsong, xs_sidplay2_fillbuffer, |
69 xs_sidplay2_loadsid | 78 xs_sidplay2_loadsid, xs_sidplay2_gettunespeed, |
79 xs_sidplay2_deletesid, xs_sidplay2_getsidinfo | |
80 }, | |
81 #endif | |
82 #ifdef HAVE_NANOSID | |
83 { XS_ENG_NANOSID, | |
84 xs_nanosid_isourfile, | |
85 xs_nanosid_init, xs_nanosid_close, | |
86 xs_nanosid_initsong, xs_nanosid_fillbuffer, | |
87 xs_nanosid_loadsid, xs_nanosid_gettunespeed, | |
88 xs_nanosid_deletesid, xs_nanosid_getsidinfo | |
70 }, | 89 }, |
71 #endif | 90 #endif |
72 }; | 91 }; |
73 | 92 |
74 const gint xs_nplayerlist = (sizeof(xs_playerlist) / sizeof(t_xs_player)); | 93 const gint xs_nplayerlist = (sizeof(xs_playerlist) / sizeof(t_xs_player)); |
115 | 134 |
116 /* Initialize and get configuration */ | 135 /* Initialize and get configuration */ |
117 memset(&xs_cfg, 0, sizeof(xs_cfg)); | 136 memset(&xs_cfg, 0, sizeof(xs_cfg)); |
118 xs_read_configuration(); | 137 xs_read_configuration(); |
119 | 138 |
139 | |
120 /* Initialize status */ | 140 /* Initialize status */ |
121 memset(&xs_status, 0, sizeof(xs_status)); | 141 memset(&xs_status, 0, sizeof(xs_status)); |
122 xs_status.allowNext = TRUE; | 142 xs_status.allowNext = TRUE; |
143 | |
123 | 144 |
124 /* Try to initialize emulator engine */ | 145 /* Try to initialize emulator engine */ |
125 XSDEBUG("initializing emulator engine...\n"); | 146 XSDEBUG("initializing emulator engine...\n"); |
126 | 147 |
127 iPlayer = 0; | 148 iPlayer = 0; |
133 if (xs_playerlist[iPlayer].plrInit(&xs_status)) | 154 if (xs_playerlist[iPlayer].plrInit(&xs_status)) |
134 { | 155 { |
135 isInitialized = TRUE; | 156 isInitialized = TRUE; |
136 xs_player = (t_xs_player *) &xs_playerlist[iPlayer]; | 157 xs_player = (t_xs_player *) &xs_playerlist[iPlayer]; |
137 } | 158 } |
138 } else | 159 } |
139 iPlayer++; | 160 iPlayer++; |
140 } | 161 } |
141 | 162 |
142 | 163 |
143 iPlayer = 0; | 164 iPlayer = 0; |
144 while ((iPlayer < xs_nplayerlist) && !isInitialized) | 165 while ((iPlayer < xs_nplayerlist) && !isInitialized) |
145 { | 166 { |
146 if (xs_playerlist[iPlayer].plrInit(&xs_status)) | 167 if (xs_playerlist[iPlayer].plrInit(&xs_status)) |
147 { | 168 { |
148 isInitialized = TRUE; | 169 isInitialized = TRUE; |
149 xs_player = (t_xs_player *) &xs_playerlist[iPlayer]; | 170 xs_player = (t_xs_player *) &xs_playerlist[iPlayer]; |
150 } else | 171 } |
151 iPlayer++; | 172 iPlayer++; |
152 } | 173 } |
153 | 174 |
154 | 175 |
155 /* Read song-length database */ | 176 /* Read song-length database */ |
156 if (xs_cfg.songlenDBEnable && (xs_songlen_init() < 0)) | 177 if (xs_cfg.songlenDBEnable && (xs_songlen_init() < 0)) |
176 XSDEBUG("xs_close(): shutting down...\n"); | 197 XSDEBUG("xs_close(): shutting down...\n"); |
177 | 198 |
178 /* Stop playing */ | 199 /* Stop playing */ |
179 xs_stop(); | 200 xs_stop(); |
180 | 201 |
202 xs_player->plrDeleteSID(&xs_status); | |
181 xs_player->plrClose(&xs_status); | 203 xs_player->plrClose(&xs_status); |
182 | 204 |
183 /* Close sub-song control window */ | 205 /* Close sub-song control window */ |
184 | 206 |
185 /* Free allocated memory */ | 207 /* Free allocated memory */ |
186 xs_songlen_close(); | 208 xs_songlen_close(); |
187 | 209 |
188 // FIXME FIXME: STIL-entries | 210 // FIXME FIXME: STIL-entries |
189 XSDEBUG("shutdown finished.\n"); | 211 XSDEBUG("shutdown finished.\n"); |
212 } | |
213 | |
214 | |
215 /* | |
216 * Check whether the given file is handled by this plugin | |
217 */ | |
218 gint xs_is_our_file(gchar *pcFileName) | |
219 { | |
220 char *pcExt; | |
221 | |
222 /* Check the filename */ | |
223 if (pcFileName == NULL) | |
224 return FALSE; | |
225 | |
226 /* Try to detect via detection routine, if required */ | |
227 if (xs_cfg.detectMagic && xs_player->plrIsOurFile(pcFileName)) | |
228 return TRUE; | |
229 | |
230 /* Detect just by checking filename extension */ | |
231 pcExt = strrchr(pcFileName, '.'); | |
232 if (pcExt) | |
233 { | |
234 pcExt++; | |
235 if (!strcasecmp(pcExt, "psid")) return TRUE; | |
236 if (!strcasecmp(pcExt, "sid")) return TRUE; | |
237 if (!strcasecmp(pcExt, "dat")) return TRUE; | |
238 if (!strcasecmp(pcExt, "inf")) return TRUE; | |
239 if (!strcasecmp(pcExt, "info")) return TRUE; | |
240 } | |
241 | |
242 return FALSE; | |
190 } | 243 } |
191 | 244 |
192 | 245 |
193 /* | 246 /* |
194 * Main playing thread loop | 247 * Main playing thread loop |
197 { | 250 { |
198 t_xs_status myStatus; | 251 t_xs_status myStatus; |
199 gboolean audioOpen; | 252 gboolean audioOpen; |
200 gint audioFreq, audioChannels, songLength, audioFmt; | 253 gint audioFreq, audioChannels, songLength, audioFmt; |
201 gchar audioBuffer[XS_BUFSIZE]; | 254 gchar audioBuffer[XS_BUFSIZE]; |
202 gchar *tmpStr; | |
203 | 255 |
204 | 256 |
205 pthread_mutex_lock(&xs_mutex); | 257 pthread_mutex_lock(&xs_mutex); |
206 XSDEBUG("entering play thread\n"); | 258 XSDEBUG("entering play thread\n"); |
207 | 259 |
242 pthread_mutex_unlock(&xs_mutex); | 294 pthread_mutex_unlock(&xs_mutex); |
243 | 295 |
244 XSDEBUG("subtune #%i selected, initializing...\n", myStatus.currSong); | 296 XSDEBUG("subtune #%i selected, initializing...\n", myStatus.currSong); |
245 | 297 |
246 | 298 |
247 /* Get song length for current subtune */ | |
248 songLength = xs_songlen_get(myStatus.currFileName, myStatus.currSong); | |
249 | |
250 /* Initialize song */ | 299 /* Initialize song */ |
251 if ((myStatus.currTune == NULL) || !xs_player->plrInitSong(&myStatus)) | 300 if (!xs_player->plrInitSong(&myStatus)) |
252 { | 301 { |
253 XSERR("Couldn't initialize SID-tune '%s' (sub-tune #%i)!\n", | 302 XSERR("Couldn't initialize SID-tune '%s' (sub-tune #%i)!\n", |
254 myStatus.currFileName, myStatus.currSong); | 303 myStatus.currFileName, myStatus.currSong); |
255 goto err_exit; | 304 goto err_exit; |
256 } | 305 } |
257 | 306 |
258 | 307 |
259 /* Set information for current sub-tune */ | 308 /* Get song information for current subtune */ |
260 xs_player->plrGetTuneInfo(&myStatus, &myTuneInfo); | 309 songLength = xs_songlen_get(myStatus.currFileName, myStatus.currSong); |
261 | 310 |
311 /* | |
262 xs_plugin_ip.set_info( | 312 xs_plugin_ip.set_info( |
263 myTuneInfo->titleStr, | 313 myTuneInfo.titleStr, |
264 (songLength > 0) ? (songLength * 1000) : -1, | 314 (songLength > 0) ? (songLength * 1000) : -1, |
265 1000 * myTuneInfo->songSpeed, | 315 1000 * myTuneInfo.songSpeed, |
266 audioFreq, | 316 audioFreq, |
267 audioChannels); | 317 audioChannels); |
268 | 318 */ |
269 | 319 |
270 /* Open the audio output */ | 320 /* Open the audio output */ |
271 if (!xs_plugin_ip.output->open_audio(audioFmt, audioFreq, audioChannels)) | 321 if (!xs_plugin_ip.output->open_audio(audioFmt, audioFreq, audioChannels)) |
272 { | 322 { |
273 XSERR("Couldn't open XMMS audio output!\n"); | 323 XSERR("Couldn't open XMMS audio output!\n"); |
347 { | 397 { |
348 XSDEBUG("close audio #2\n"); | 398 XSDEBUG("close audio #2\n"); |
349 xs_plugin_ip.output->close_audio(); | 399 xs_plugin_ip.output->close_audio(); |
350 } | 400 } |
351 | 401 |
352 if (myStatus.currTune != NULL) | 402 xs_player->plrDeleteSID(&myStatus); |
353 { | |
354 myStatus.currPlayer->plrDeleteTune(&myStatus); | |
355 myStatus.currTune = NULL; | |
356 } | |
357 | 403 |
358 g_free(myStatus.currFileName); | 404 g_free(myStatus.currFileName); |
359 | 405 |
360 /* Exit the playing thread */ | 406 /* Exit the playing thread */ |
361 XSDEBUG("exiting thread, bye.\n"); | 407 XSDEBUG("exiting thread, bye.\n"); |
374 /* | 420 /* |
375 * Start playing the given file | 421 * Start playing the given file |
376 */ | 422 */ |
377 void xs_play_file(gchar *pcFileName) | 423 void xs_play_file(gchar *pcFileName) |
378 { | 424 { |
379 | 425 /* Initialize the tune */ |
426 if (!xs_player->plrLoadSID(&xs_status, pcFileName)) | |
427 return; | |
428 | |
429 /* Start the playing thread! */ | |
430 if (pthread_create(&xs_decode_thread, NULL, xs_play_loop, NULL) < 0) | |
431 { | |
432 XSERR("Couldn't start playing thread! Possible reason reported by system: %s\n", strerror(errno)); | |
433 xs_player->plrDeleteSID(&xs_status); | |
434 } | |
435 | |
436 XSDEBUG("systems should be up?\n"); | |
380 } | 437 } |
381 | 438 |
382 | 439 |
383 /* | 440 /* |
384 * Stop playing | 441 * Stop playing |
447 | 504 |
448 /* Else, return output time reported by audio output plugin */ | 505 /* Else, return output time reported by audio output plugin */ |
449 return xs_plugin_ip.output->output_time(); | 506 return xs_plugin_ip.output->output_time(); |
450 } | 507 } |
451 | 508 |
509 | |
510 /* | |
511 * Return song information | |
512 */ | |
513 void xs_get_song_info(gchar *songFileName, gchar **songTitle, gint *songLength) | |
514 { | |
515 xs_player->plrGetSIDInfo(songFileName, songTitle, songLength); | |
516 } |