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 }