Mercurial > hg > xmms-sid
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 } |