comparison src/xmms-sid.c @ 402:f997b79a7251

More work on merging of improved STIL/SLDB handling code with completely dynamic memory allocation.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 01 Jun 2006 02:18:02 +0000
parents b09d74eb71e6
children b2d233cd01ba
comparison
equal deleted inserted replaced
401:30da794755f7 402:f997b79a7251
36 #include <gtk/gtk.h> 36 #include <gtk/gtk.h>
37 37
38 #include "xs_config.h" 38 #include "xs_config.h"
39 #include "xs_length.h" 39 #include "xs_length.h"
40 #include "xs_stil.h" 40 #include "xs_stil.h"
41 #include "xs_title.h"
41 #include "xs_filter.h" 42 #include "xs_filter.h"
42 #include "xs_fileinfo.h" 43 #include "xs_fileinfo.h"
43 #include "xs_interface.h" 44 #include "xs_interface.h"
44 #include "xs_glade.h" 45 #include "xs_glade.h"
45 46
306 /* Initialize */ 307 /* Initialize */
307 XSDEBUG("entering player thread\n"); 308 XSDEBUG("entering player thread\n");
308 XS_MUTEX_LOCK(xs_status); 309 XS_MUTEX_LOCK(xs_status);
309 memcpy(&myStatus, &xs_status, sizeof(t_xs_status)); 310 memcpy(&myStatus, &xs_status, sizeof(t_xs_status));
310 myTune = xs_status.tuneInfo; 311 myTune = xs_status.tuneInfo;
312 for (i = 0; i <= myTune->nsubTunes; i++)
313 myTune->subTunes[i].tunePlayed = FALSE;
311 XS_MUTEX_UNLOCK(xs_status); 314 XS_MUTEX_UNLOCK(xs_status);
312
313 xs_memset(&playedTune, 0, sizeof(playedTune));
314 315
315 /* Allocate audio buffer */ 316 /* Allocate audio buffer */
316 audioBuffer = (gchar *) g_malloc(XS_AUDIOBUF_SIZE); 317 audioBuffer = (gchar *) g_malloc(XS_AUDIOBUF_SIZE);
317 if (audioBuffer == NULL) { 318 if (audioBuffer == NULL) {
318 xs_error("Couldn't allocate memory for audio data buffer!\n"); 319 xs_error("Couldn't allocate memory for audio data buffer!\n");
334 doPlay = TRUE; 335 doPlay = TRUE;
335 while (xs_status.isPlaying && doPlay) { 336 while (xs_status.isPlaying && doPlay) {
336 /* Automatic sub-tune change logic */ 337 /* Automatic sub-tune change logic */
337 XS_MUTEX_LOCK(xs_cfg); 338 XS_MUTEX_LOCK(xs_cfg);
338 XS_MUTEX_LOCK(xs_status); 339 XS_MUTEX_LOCK(xs_status);
339 assert(xs_status.currSong >= 1);
340 assert(xs_status.currSong <= XS_STIL_MAXENTRY);
341 myStatus.isPlaying = TRUE; 340 myStatus.isPlaying = TRUE;
342 341
342 if (xs_status.currSong < 1 || myStatus.currSong < 1) {
343 XS_MUTEX_UNLOCK(xs_status);
344 XS_MUTEX_UNLOCK(xs_cfg);
345 goto xs_err_exit;
346 }
347
343 if (xs_cfg.subAutoEnable && (myStatus.currSong == xs_status.currSong)) { 348 if (xs_cfg.subAutoEnable && (myStatus.currSong == xs_status.currSong)) {
344 /* Check if currently selected sub-tune has been played already */ 349 /* Check if currently selected sub-tune has been played already */
345 if (playedTune[myStatus.currSong]) { 350 if (myTune->subTunes[myStatus.currSong-1].tunePlayed) {
346 /* Find a tune that has not been played */ 351 /* Find a tune that has not been played */
347 XSDEBUG("tune #%i already played, finding next match ...\n", myStatus.currSong); 352 XSDEBUG("tune #%i already played, finding next match ...\n", myStatus.currSong);
348 isFound = FALSE; 353 isFound = FALSE;
349 i = 0; 354 i = 0;
350 while (!isFound && (++i <= myTune->nsubTunes)) { 355 while (!isFound && (++i <= myTune->nsubTunes)) {
351 if (xs_cfg.subAutoMinOnly) { 356 if (xs_cfg.subAutoMinOnly) {
352 /* A tune with minimum length must be found */ 357 /* A tune with minimum length must be found */
353 if (!playedTune[i] 358 if (!myTune->subTunes[i-1].tunePlayed &&
354 && myTune->subTunes[i].tuneLength >= xs_cfg.subAutoMinTime) 359 myTune->subTunes[i-1].tuneLength >= xs_cfg.subAutoMinTime)
355 isFound = TRUE; 360 isFound = TRUE;
356 } else { 361 } else {
357 /* Any unplayed tune is okay */ 362 /* Any unplayed tune is okay */
358 if (!playedTune[i]) 363 if (!myTune->subTunes[i-1].tunePlayed)
359 isFound = TRUE; 364 isFound = TRUE;
360 } 365 }
361 } 366 }
362 367
363 if (isFound) { 368 if (isFound) {
374 } 379 }
375 } 380 }
376 381
377 /* Tell that we are initializing, update sub-tune controls */ 382 /* Tell that we are initializing, update sub-tune controls */
378 myStatus.currSong = xs_status.currSong; 383 myStatus.currSong = xs_status.currSong;
379 playedTune[myStatus.currSong] = TRUE; 384 myTune->subTunes[myStatus.currSong-1].tunePlayed = TRUE;
380 XS_MUTEX_UNLOCK(xs_status); 385 XS_MUTEX_UNLOCK(xs_status);
381 XS_MUTEX_UNLOCK(xs_cfg); 386 XS_MUTEX_UNLOCK(xs_cfg);
382 387
383 XSDEBUG("subtune #%i selected, initializing...\n", myStatus.currSong); 388 XSDEBUG("subtune #%i selected, initializing...\n", myStatus.currSong);
384 389
385 GDK_THREADS_ENTER(); 390 GDK_THREADS_ENTER();
386 xs_subctrl_update(); 391 xs_subctrl_update();
387 GDK_THREADS_LEAVE(); 392 GDK_THREADS_LEAVE();
388 393
389 /* Check minimum playtime */ 394 /* Check minimum playtime */
390 songLength = myTune->subTunes[myStatus.currSong - 1].tuneLength; 395 songLength = myTune->subTunes[myStatus.currSong-1].tuneLength;
391 if (xs_cfg.playMinTimeEnable && (songLength >= 0)) { 396 if (xs_cfg.playMinTimeEnable && (songLength >= 0)) {
392 if (songLength < xs_cfg.playMinTime) 397 if (songLength < xs_cfg.playMinTime)
393 songLength = xs_cfg.playMinTime; 398 songLength = xs_cfg.playMinTime;
394 } 399 }
395 400
414 } 419 }
415 420
416 audioOpen = TRUE; 421 audioOpen = TRUE;
417 422
418 /* Set song information for current subtune */ 423 /* Set song information for current subtune */
419 xs_plugin_ip.set_info(myTune->subTunes[myStatus.currSong - 1].tuneTitle, 424 xs_plugin_ip.set_info(myTune->subTunes[myStatus.currSong-1].tuneTitle,
420 (songLength > 0) ? (songLength * 1000) : 0, 425 (songLength > 0) ? (songLength * 1000) : 0,
421 (myTune->subTunes[myStatus.currSong - 1].tuneSpeed > 426 (myTune->subTunes[myStatus.currSong-1].tuneSpeed > 0) ?
422 0) ? (myTune->subTunes[myStatus.currSong - 1].tuneSpeed * 1000) : -1, 427 (myTune->subTunes[myStatus.currSong-1].tuneSpeed * 1000) : -1,
423 myStatus.audioFrequency, myStatus.audioChannels); 428 myStatus.audioFrequency, myStatus.audioChannels);
424 429
425 430
426 XSDEBUG("playing\n"); 431 XSDEBUG("playing\n");
427 432
428 /* 433 /*
495 /* Now determine if we continue by selecting other subtune or something */ 500 /* Now determine if we continue by selecting other subtune or something */
496 if (!myStatus.isPlaying && !xs_cfg.subAutoEnable) 501 if (!myStatus.isPlaying && !xs_cfg.subAutoEnable)
497 doPlay = FALSE; 502 doPlay = FALSE;
498 } 503 }
499 504
500 xs_err_exit: 505 xs_err_exit:
501 /* Close audio output plugin */ 506 /* Close audio output plugin */
502 if (audioOpen) { 507 if (audioOpen) {
503 XSDEBUG("close audio #2\n"); 508 XSDEBUG("close audio #2\n");
504 xs_plugin_ip.output->close_audio(); 509 xs_plugin_ip.output->close_audio();
505 } 510 }
734 void xs_subctrl_open(void) 739 void xs_subctrl_open(void)
735 { 740 {
736 GtkWidget *frame25, *hbox15, *subctrl_prev, *subctrl_current, *subctrl_next; 741 GtkWidget *frame25, *hbox15, *subctrl_prev, *subctrl_current, *subctrl_next;
737 742
738 XS_MUTEX_LOCK(xs_subctrl); 743 XS_MUTEX_LOCK(xs_subctrl);
739 if (!xs_status.tuneInfo || !xs_status.isPlaying || xs_subctrl || (xs_status.tuneInfo->nsubTunes <= 1)) { 744 if (!xs_status.tuneInfo || !xs_status.isPlaying ||
745 xs_subctrl || (xs_status.tuneInfo->nsubTunes <= 1)) {
740 XS_MUTEX_UNLOCK(xs_subctrl); 746 XS_MUTEX_UNLOCK(xs_subctrl);
741 return; 747 return;
742 } 748 }
743 749
744 /* Create the pop-up window */ 750 /* Create the pop-up window */
900 * which uses xs_plugin_ip.set_info(); 906 * which uses xs_plugin_ip.set_info();
901 */ 907 */
902 void xs_get_song_info(gchar * songFilename, gchar ** songTitle, gint * songLength) 908 void xs_get_song_info(gchar * songFilename, gchar ** songTitle, gint * songLength)
903 { 909 {
904 t_xs_tuneinfo *pInfo; 910 t_xs_tuneinfo *pInfo;
905 gint tmpInt;
906 911
907 /* Get tune information from emulation engine */ 912 /* Get tune information from emulation engine */
908 pInfo = xs_status.sidPlayer->plrGetSIDInfo(songFilename); 913 pInfo = xs_status.sidPlayer->plrGetSIDInfo(songFilename);
909 if (!pInfo) 914 if (!pInfo)
910 return; 915 return;
911 916
912 /* Get sub-tune information, if available */ 917 /* Get sub-tune information, if available */
913 if ((pInfo->startTune > 0) && (pInfo->startTune <= pInfo->nsubTunes)) { 918 if ((pInfo->startTune > 0) && (pInfo->startTune <= pInfo->nsubTunes)) {
914 (*songTitle) = g_strdup(pInfo->subTunes[pInfo->startTune - 1].tuneTitle); 919 gint tmpInt;
915 920
916 tmpInt = pInfo->subTunes[pInfo->startTune - 1].tuneLength; 921 (*songTitle) = g_strdup(pInfo->subTunes[pInfo->startTune-1].tuneTitle);
922
923 tmpInt = pInfo->subTunes[pInfo->startTune-1].tuneLength;
917 if (tmpInt < 0) 924 if (tmpInt < 0)
918 (*songLength) = -1; 925 (*songLength) = -1;
919 else 926 else
920 (*songLength) = (tmpInt * 1000); 927 (*songLength) = (tmpInt * 1000);
921 } 928 }
925 } 932 }
926 933
927 934
928 /* Allocate a new tune information structure 935 /* Allocate a new tune information structure
929 */ 936 */
930 t_xs_tuneinfo *xs_tuneinfo_new(gchar * pcFilename, gint nsubTunes, gint startTune, 937 t_xs_tuneinfo *xs_tuneinfo_new(const gchar * pcFilename,
931 gchar * sidName, gchar * sidComposer, gchar * sidCopyright, 938 gint nsubTunes, gint startTune, const gchar * sidName,
932 gint loadAddr, gint initAddr, gint playAddr, gint dataFileLen) 939 const gchar * sidComposer, const gchar * sidCopyright,
940 gint loadAddr, gint initAddr, gint playAddr,
941 gint dataFileLen, const gchar *sidFormat)
933 { 942 {
934 t_xs_tuneinfo *pResult; 943 t_xs_tuneinfo *pResult;
944 t_xs_sldb_node *tmpLength;
945 gint i;
935 946
936 /* Allocate structure */ 947 /* Allocate structure */
937 pResult = (t_xs_tuneinfo *) g_malloc0(sizeof(t_xs_tuneinfo)); 948 pResult = (t_xs_tuneinfo *) g_malloc0(sizeof(t_xs_tuneinfo));
938 if (!pResult) { 949 if (!pResult) {
939 xs_error("Could not allocate memory for t_xs_tuneinfo ('%s')\n", pcFilename); 950 xs_error("Could not allocate memory for t_xs_tuneinfo ('%s')\n", pcFilename);
946 g_free(pResult); 957 g_free(pResult);
947 return NULL; 958 return NULL;
948 } 959 }
949 960
950 /* Allocate space for subtune information */ 961 /* Allocate space for subtune information */
951 if (nsubTunes > 0) { 962 pResult->subTunes = g_malloc0(sizeof(t_xs_subtuneinfo) * (nsubTunes + 1));
952 pResult->subTunes = g_malloc0(sizeof(t_xs_subtuneinfo) * nsubTunes); 963 if (!pResult->subTunes) {
953 if (!pResult->subTunes) { 964 xs_error("Could not allocate memory for t_xs_subtuneinfo ('%s', %i)\n",
954 xs_error("Could not allocate memory for t_xs_subtuneinfo ('%s', %i)\n", pcFilename, nsubTunes); 965 pcFilename, nsubTunes);
955 966
956 g_free(pResult->sidFilename); 967 g_free(pResult->sidFilename);
957 g_free(pResult); 968 g_free(pResult);
958 return NULL; 969 return NULL;
959 }
960 } 970 }
961 971
962 /* The following allocations don't matter if they fail */ 972 /* The following allocations don't matter if they fail */
963 pResult->sidName = g_strdup(sidName); 973 pResult->sidName = g_strdup(sidName);
964 pResult->sidComposer = g_strdup(sidComposer); 974 pResult->sidComposer = g_strdup(sidComposer);
969 979
970 pResult->loadAddr = loadAddr; 980 pResult->loadAddr = loadAddr;
971 pResult->initAddr = initAddr; 981 pResult->initAddr = initAddr;
972 pResult->playAddr = playAddr; 982 pResult->playAddr = playAddr;
973 pResult->dataFileLen = dataFileLen; 983 pResult->dataFileLen = dataFileLen;
974 984 pResult->sidFormat = g_strdup(sidFormat);
985
986 /* Get length information (NOTE: Do not free this!) */
987 tmpLength = xs_songlen_get(pcFilename);
988
989 /* Fill in sub-tune information */
990 for (i = 0; i < pResult->nsubTunes; i++) {
991 if (tmpLength && (i < tmpLength->nLengths))
992 pResult->subTunes[i].tuneLength = tmpLength->sLengths[i];
993 else
994 pResult->subTunes[i].tuneLength = -1;
995
996 pResult->subTunes[i].tuneTitle = xs_make_titlestring(pResult, i);
997 }
998
975 return pResult; 999 return pResult;
976 } 1000 }
977 1001
978 1002
979 /* Free given tune information structure 1003 /* Free given tune information structure
980 */ 1004 */
981 void xs_tuneinfo_free(t_xs_tuneinfo * pTune) 1005 void xs_tuneinfo_free(t_xs_tuneinfo * pTune)
982 { 1006 {
983 gint i; 1007 gint i;
984 if (!pTune) 1008
985 return; 1009 if (!pTune) return;
986 1010
987 for (i = 0; i < pTune->nsubTunes; i++) { 1011 for (i = 1; i < pTune->nsubTunes; i++) {
988 g_free(pTune->subTunes[i].tuneTitle); 1012 g_free(pTune->subTunes[i].tuneTitle);
989 pTune->subTunes[i].tuneTitle = NULL; 1013 pTune->subTunes[i].tuneTitle = NULL;
990 } 1014 }
991 1015
992 g_free(pTune->subTunes); 1016 g_free(pTune->subTunes);
993 pTune->nsubTunes = 0;
994 g_free(pTune->sidFilename); 1017 g_free(pTune->sidFilename);
995 pTune->sidFilename = NULL;
996 g_free(pTune->sidName); 1018 g_free(pTune->sidName);
997 pTune->sidName = NULL;
998 g_free(pTune->sidComposer); 1019 g_free(pTune->sidComposer);
999 pTune->sidComposer = NULL;
1000 g_free(pTune->sidCopyright); 1020 g_free(pTune->sidCopyright);
1001 pTune->sidCopyright = NULL; 1021 g_free(pTune->sidFormat);
1002 g_free(pTune); 1022 g_free(pTune);
1003 } 1023 }