Mercurial > audlegacy-plugins
comparison src/sid/xmms-sid.c @ 1574:e566e18e9e3d
Huge cleanup and some bugfixes. Temporarily breaks / removes sub-tune
changing.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 03 Sep 2007 06:28:17 +0300 |
parents | 5e4393a4c099 |
children | a5725f7f1a5e |
comparison
equal
deleted
inserted
replaced
1573:82548d92c922 | 1574:e566e18e9e3d |
---|---|
36 #include "xs_filter.h" | 36 #include "xs_filter.h" |
37 #include "xs_fileinfo.h" | 37 #include "xs_fileinfo.h" |
38 #include "xs_interface.h" | 38 #include "xs_interface.h" |
39 #include "xs_glade.h" | 39 #include "xs_glade.h" |
40 #include "xs_player.h" | 40 #include "xs_player.h" |
41 #include "xs_slsup.h" | |
42 | |
41 | 43 |
42 /* | 44 /* |
43 * Include player engines | 45 * Include player engines |
44 */ | 46 */ |
45 #ifdef HAVE_SIDPLAY1 | 47 #ifdef HAVE_SIDPLAY1 |
84 */ | 86 */ |
85 t_xs_status xs_status; | 87 t_xs_status xs_status; |
86 XS_MUTEX(xs_status); | 88 XS_MUTEX(xs_status); |
87 static XS_THREAD_T xs_decode_thread; | 89 static XS_THREAD_T xs_decode_thread; |
88 | 90 |
89 static GtkWidget *xs_subctrl = NULL; | |
90 static GtkObject *xs_subctrl_adj = NULL; | |
91 XS_MUTEX(xs_subctrl); | |
92 | |
93 void xs_subctrl_close(void); | |
94 void xs_subctrl_update(void); | |
95 | |
96 static t_xs_sldb *xs_sldb_db = NULL; | |
97 XS_MUTEX(xs_sldb_db); | |
98 | |
99 gint xs_songlen_init(void); | |
100 void xs_songlen_close(void); | |
101 t_xs_sldb_node *xs_songlen_get(const gchar *); | |
102 | |
103 | 91 |
104 /* | 92 /* |
105 * Error messages | 93 * Error messages |
106 */ | 94 */ |
107 void xs_error(const char *fmt, ...) | 95 void xs_error(const char *fmt, ...) |
108 { | 96 { |
109 va_list ap; | 97 va_list ap; |
110 fprintf(stderr, "XMMS-SID: "); | 98 fprintf(stderr, "AUD-SID: "); |
111 va_start(ap, fmt); | 99 va_start(ap, fmt); |
112 vfprintf(stderr, fmt, ap); | 100 vfprintf(stderr, fmt, ap); |
113 va_end(ap); | 101 va_end(ap); |
114 } | 102 } |
115 | 103 |
292 /* Check the filename */ | 280 /* Check the filename */ |
293 if (pcFilename == NULL) | 281 if (pcFilename == NULL) |
294 return FALSE; | 282 return FALSE; |
295 | 283 |
296 return xs_status.sidPlayer->plrProbe(f); | 284 return xs_status.sidPlayer->plrProbe(f); |
297 } | |
298 | |
299 | |
300 static gboolean xs_schedule_subctrl_update(gpointer unused) | |
301 { | |
302 (void) unused; | |
303 gboolean isPlaying; | |
304 | |
305 XS_MUTEX_LOCK(xs_status); | |
306 isPlaying = xs_status.isPlaying; | |
307 XS_MUTEX_UNLOCK(xs_status); | |
308 | |
309 if (isPlaying) | |
310 xs_subctrl_update(); | |
311 | |
312 return FALSE; | |
313 } | 285 } |
314 | 286 |
315 | 287 |
316 /* | 288 /* |
317 * Main playing thread loop | 289 * Main playing thread loop |
409 XS_MUTEX_UNLOCK(xs_status); | 381 XS_MUTEX_UNLOCK(xs_status); |
410 XS_MUTEX_UNLOCK(xs_cfg); | 382 XS_MUTEX_UNLOCK(xs_cfg); |
411 | 383 |
412 XSDEBUG("subtune #%i selected, initializing...\n", myStatus.currSong); | 384 XSDEBUG("subtune #%i selected, initializing...\n", myStatus.currSong); |
413 | 385 |
414 g_idle_add_full( G_PRIORITY_HIGH_IDLE , xs_schedule_subctrl_update , NULL , NULL ); | |
415 | |
416 /* Check minimum playtime */ | 386 /* Check minimum playtime */ |
417 songLength = myTune->subTunes[myStatus.currSong-1].tuneLength; | 387 songLength = myTune->subTunes[myStatus.currSong-1].tuneLength; |
418 if (xs_cfg.playMinTimeEnable && (songLength >= 0)) { | 388 if (xs_cfg.playMinTimeEnable && (songLength >= 0)) { |
419 if (songLength < xs_cfg.playMinTime) | 389 if (songLength < xs_cfg.playMinTime) |
420 songLength = xs_cfg.playMinTime; | 390 songLength = xs_cfg.playMinTime; |
616 { | 586 { |
617 (void) pb; | 587 (void) pb; |
618 | 588 |
619 XSDEBUG("stop requested\n"); | 589 XSDEBUG("stop requested\n"); |
620 | 590 |
621 /* Close the sub-tune control window, if any */ | |
622 xs_subctrl_close(); | |
623 | |
624 /* Lock xs_status and stop playing thread */ | 591 /* Lock xs_status and stop playing thread */ |
625 XS_MUTEX_LOCK(xs_status); | 592 XS_MUTEX_LOCK(xs_status); |
626 if (xs_status.isPlaying) { | 593 if (xs_status.isPlaying) { |
627 XSDEBUG("stopping...\n"); | 594 XSDEBUG("stopping...\n"); |
628 xs_status.isPlaying = FALSE; | 595 xs_status.isPlaying = FALSE; |
632 XS_MUTEX_UNLOCK(xs_status); | 599 XS_MUTEX_UNLOCK(xs_status); |
633 } | 600 } |
634 | 601 |
635 XSDEBUG("done, updating status\n"); | 602 XSDEBUG("done, updating status\n"); |
636 | 603 |
637 /* Status is now stopped, update the sub-tune | |
638 * controller in fileinfo window (if open) | |
639 */ | |
640 xs_fileinfo_update(); | |
641 | |
642 /* Free tune information */ | 604 /* Free tune information */ |
643 XS_MUTEX_LOCK(xs_status); | 605 XS_MUTEX_LOCK(xs_status); |
644 xs_status.sidPlayer->plrDeleteSID(&xs_status); | 606 xs_status.sidPlayer->plrDeleteSID(&xs_status); |
645 xs_tuneinfo_free(xs_status.tuneInfo); | 607 xs_tuneinfo_free(xs_status.tuneInfo); |
646 xs_status.tuneInfo = NULL; | 608 xs_status.tuneInfo = NULL; |
652 /* | 614 /* |
653 * Pause/unpause the playing | 615 * Pause/unpause the playing |
654 */ | 616 */ |
655 void xs_pause(InputPlayback *pb, short pauseState) | 617 void xs_pause(InputPlayback *pb, short pauseState) |
656 { | 618 { |
657 xs_subctrl_close(); | |
658 xs_fileinfo_update(); | |
659 pb->output->pause(pauseState); | 619 pb->output->pause(pauseState); |
660 } | 620 } |
661 | 621 |
662 | 622 |
663 /* | 623 /* |
664 * Pop-up subtune selector | 624 * A stub seek function (Audacious will crash if seek is NULL) |
665 */ | |
666 void xs_subctrl_setsong(void) | |
667 { | |
668 gint n; | |
669 | |
670 XS_MUTEX_LOCK(xs_status); | |
671 XS_MUTEX_LOCK(xs_subctrl); | |
672 | |
673 if (xs_status.tuneInfo && xs_status.isPlaying) { | |
674 n = (gint) GTK_ADJUSTMENT(xs_subctrl_adj)->value; | |
675 if ((n >= 1) && (n <= xs_status.tuneInfo->nsubTunes)) | |
676 xs_status.currSong = n; | |
677 } | |
678 | |
679 XS_MUTEX_UNLOCK(xs_subctrl); | |
680 XS_MUTEX_UNLOCK(xs_status); | |
681 } | |
682 | |
683 | |
684 void xs_subctrl_prevsong(void) | |
685 { | |
686 XS_MUTEX_LOCK(xs_status); | |
687 | |
688 if (xs_status.tuneInfo && xs_status.isPlaying) { | |
689 if (xs_status.currSong > 1) | |
690 xs_status.currSong--; | |
691 } | |
692 | |
693 XS_MUTEX_UNLOCK(xs_status); | |
694 | |
695 xs_subctrl_update(); | |
696 } | |
697 | |
698 | |
699 void xs_subctrl_nextsong(void) | |
700 { | |
701 XS_MUTEX_LOCK(xs_status); | |
702 | |
703 if (xs_status.tuneInfo && xs_status.isPlaying) { | |
704 if (xs_status.currSong < xs_status.tuneInfo->nsubTunes) | |
705 xs_status.currSong++; | |
706 } | |
707 | |
708 XS_MUTEX_UNLOCK(xs_status); | |
709 | |
710 xs_subctrl_update(); | |
711 } | |
712 | |
713 | |
714 void xs_subctrl_update(void) | |
715 { | |
716 GtkAdjustment *tmpAdj; | |
717 | |
718 XS_MUTEX_LOCK(xs_status); | |
719 XS_MUTEX_LOCK(xs_subctrl); | |
720 | |
721 /* Check if control window exists, we are currently playing and have a tune */ | |
722 if (xs_subctrl) { | |
723 if (xs_status.tuneInfo && xs_status.isPlaying) { | |
724 tmpAdj = GTK_ADJUSTMENT(xs_subctrl_adj); | |
725 | |
726 tmpAdj->value = xs_status.currSong; | |
727 tmpAdj->lower = 1; | |
728 tmpAdj->upper = xs_status.tuneInfo->nsubTunes; | |
729 XS_MUTEX_UNLOCK(xs_status); | |
730 XS_MUTEX_UNLOCK(xs_subctrl); | |
731 gtk_adjustment_value_changed(tmpAdj); | |
732 } else { | |
733 XS_MUTEX_UNLOCK(xs_status); | |
734 XS_MUTEX_UNLOCK(xs_subctrl); | |
735 xs_subctrl_close(); | |
736 } | |
737 } else { | |
738 XS_MUTEX_UNLOCK(xs_subctrl); | |
739 XS_MUTEX_UNLOCK(xs_status); | |
740 } | |
741 | |
742 xs_fileinfo_update(); | |
743 } | |
744 | |
745 | |
746 void xs_subctrl_close(void) | |
747 { | |
748 XS_MUTEX_LOCK(xs_subctrl); | |
749 | |
750 if (xs_subctrl) { | |
751 gtk_widget_destroy(xs_subctrl); | |
752 xs_subctrl = NULL; | |
753 } | |
754 | |
755 XS_MUTEX_UNLOCK(xs_subctrl); | |
756 } | |
757 | |
758 | |
759 gboolean xs_subctrl_keypress(GtkWidget * win, GdkEventKey * ev) | |
760 { | |
761 (void) win; | |
762 | |
763 if (ev->keyval == GDK_Escape) | |
764 xs_subctrl_close(); | |
765 | |
766 return FALSE; | |
767 } | |
768 | |
769 | |
770 void xs_subctrl_open(void) | |
771 { | |
772 GtkWidget *frame25, *hbox15, *subctrl_prev, *subctrl_current, *subctrl_next; | |
773 | |
774 XS_MUTEX_LOCK(xs_subctrl); | |
775 if (!xs_status.tuneInfo || !xs_status.isPlaying || | |
776 xs_subctrl || (xs_status.tuneInfo->nsubTunes <= 1)) { | |
777 XS_MUTEX_UNLOCK(xs_subctrl); | |
778 return; | |
779 } | |
780 | |
781 /* Create the pop-up window */ | |
782 xs_subctrl = gtk_window_new (GTK_WINDOW_TOPLEVEL); | |
783 gtk_window_set_type_hint(GTK_WINDOW(xs_subctrl), GDK_WINDOW_TYPE_HINT_DIALOG); | |
784 gtk_widget_set_name(xs_subctrl, "xs_subctrl"); | |
785 g_object_set_data(G_OBJECT(xs_subctrl), "xs_subctrl", xs_subctrl); | |
786 | |
787 gtk_window_set_title(GTK_WINDOW(xs_subctrl), _("Subtune Control")); | |
788 gtk_window_set_position(GTK_WINDOW(xs_subctrl), GTK_WIN_POS_MOUSE); | |
789 gtk_container_set_border_width(GTK_CONTAINER(xs_subctrl), 0); | |
790 gtk_window_set_policy(GTK_WINDOW(xs_subctrl), FALSE, FALSE, FALSE); | |
791 | |
792 g_signal_connect(G_OBJECT(xs_subctrl), "destroy", G_CALLBACK(gtk_widget_destroyed), &xs_subctrl); | |
793 | |
794 g_signal_connect(G_OBJECT(xs_subctrl), "focus_out_event", G_CALLBACK(xs_subctrl_close), NULL); | |
795 | |
796 gtk_widget_realize(xs_subctrl); | |
797 gdk_window_set_decorations(xs_subctrl->window, (GdkWMDecoration) 0); | |
798 | |
799 | |
800 /* Create the control widgets */ | |
801 frame25 = gtk_frame_new(NULL); | |
802 gtk_container_add(GTK_CONTAINER(xs_subctrl), frame25); | |
803 gtk_container_set_border_width(GTK_CONTAINER(frame25), 2); | |
804 gtk_frame_set_shadow_type(GTK_FRAME(frame25), GTK_SHADOW_OUT); | |
805 | |
806 hbox15 = gtk_hbox_new(FALSE, 4); | |
807 gtk_container_add(GTK_CONTAINER(frame25), hbox15); | |
808 | |
809 subctrl_prev = gtk_button_new_with_label(" < "); | |
810 gtk_widget_set_name(subctrl_prev, "subctrl_prev"); | |
811 gtk_box_pack_start(GTK_BOX(hbox15), subctrl_prev, FALSE, FALSE, 0); | |
812 | |
813 xs_subctrl_adj = gtk_adjustment_new(xs_status.currSong, 1, xs_status.tuneInfo->nsubTunes, 1, 1, 0); | |
814 g_signal_connect(G_OBJECT(xs_subctrl_adj), "value_changed", G_CALLBACK(xs_subctrl_setsong), NULL); | |
815 | |
816 subctrl_current = gtk_hscale_new(GTK_ADJUSTMENT(xs_subctrl_adj)); | |
817 gtk_widget_set_size_request(subctrl_current, 80, -1); | |
818 gtk_widget_set_name(subctrl_current, "subctrl_current"); | |
819 gtk_box_pack_start(GTK_BOX(hbox15), subctrl_current, FALSE, TRUE, 0); | |
820 gtk_scale_set_digits(GTK_SCALE(subctrl_current), 0); | |
821 gtk_range_set_update_policy(GTK_RANGE(subctrl_current), GTK_UPDATE_DELAYED); | |
822 gtk_widget_grab_focus(subctrl_current); | |
823 | |
824 subctrl_next = gtk_button_new_with_label(" > "); | |
825 gtk_widget_set_name(subctrl_next, "subctrl_next"); | |
826 gtk_box_pack_start(GTK_BOX(hbox15), subctrl_next, FALSE, FALSE, 0); | |
827 | |
828 g_signal_connect(G_OBJECT(subctrl_prev), "clicked", G_CALLBACK(xs_subctrl_prevsong), NULL); | |
829 | |
830 g_signal_connect(G_OBJECT(subctrl_next), "clicked", G_CALLBACK(xs_subctrl_nextsong), NULL); | |
831 | |
832 g_signal_connect(G_OBJECT(xs_subctrl), "key_press_event", G_CALLBACK(xs_subctrl_keypress), NULL); | |
833 | |
834 gtk_widget_show_all(xs_subctrl); | |
835 | |
836 XS_MUTEX_UNLOCK(xs_subctrl); | |
837 } | |
838 | |
839 | |
840 /* | |
841 * Set the time-seek position | |
842 * The playing thread will do the "seeking", which means sub-tune | |
843 * changing in XMMS-SID's case. iTime argument is time in seconds, | |
844 * in contrast to milliseconds used in other occasions. | |
845 * | |
846 * This function is called whenever position slider is clicked or | |
847 * other method of seeking is used (keyboard, etc.) | |
848 */ | 625 */ |
849 void xs_seek(InputPlayback *pb, gint iTime) | 626 void xs_seek(InputPlayback *pb, gint iTime) |
850 { | 627 { |
851 /* Check status */ | |
852 XS_MUTEX_LOCK(xs_status); | |
853 if (!xs_status.tuneInfo || !xs_status.isPlaying) { | |
854 XS_MUTEX_UNLOCK(xs_status); | |
855 return; | |
856 } | |
857 | |
858 /* Act according to settings */ | |
859 switch (xs_cfg.subsongControl) { | |
860 case XS_SSC_SEEK: | |
861 if (iTime < xs_status.lastTime) { | |
862 if (xs_status.currSong > 1) | |
863 xs_status.currSong--; | |
864 } else if (iTime > xs_status.lastTime) { | |
865 if (xs_status.currSong < xs_status.tuneInfo->nsubTunes) | |
866 xs_status.currSong++; | |
867 } | |
868 break; | |
869 | |
870 case XS_SSC_POPUP: | |
871 xs_subctrl_open(); | |
872 break; | |
873 | |
874 /* If we have song-position patch, check settings */ | |
875 #ifdef HAVE_SONG_POSITION | |
876 case XS_SSC_PATCH: | |
877 if ((iTime > 0) && (iTime <= xs_status.tuneInfo->nsubTunes)) | |
878 xs_status.currSong = iTime; | |
879 break; | |
880 #endif | |
881 } | |
882 | |
883 XS_MUTEX_UNLOCK(xs_status); | |
884 } | 628 } |
885 | 629 |
886 | 630 |
887 /* | 631 /* |
888 * Return the playing "position/time" | 632 * Return the playing "position/time" |
910 if (!xs_status.isPlaying) { | 654 if (!xs_status.isPlaying) { |
911 XS_MUTEX_UNLOCK(xs_status); | 655 XS_MUTEX_UNLOCK(xs_status); |
912 return -1; | 656 return -1; |
913 } | 657 } |
914 | 658 |
915 /* Let's see what we do */ | |
916 switch (xs_cfg.subsongControl) { | |
917 case XS_SSC_SEEK: | |
918 xs_status.lastTime = (pb->output->output_time() / 1000); | |
919 break; | |
920 | |
921 #ifdef HAVE_SONG_POSITION | |
922 case XS_SSC_PATCH: | |
923 set_song_position(xs_status.currSong, 1, xs_status.tuneInfo->nsubTunes); | |
924 break; | |
925 #endif | |
926 } | |
927 | |
928 XS_MUTEX_UNLOCK(xs_status); | 659 XS_MUTEX_UNLOCK(xs_status); |
929 | 660 |
930 /* Return output time reported by audio output plugin */ | 661 /* Return output time reported by audio output plugin */ |
931 return pb->output->output_time(); | 662 return pb->output->output_time(); |
932 } | 663 } |
933 | 664 |
934 | 665 |
935 #ifndef AUDACIOUS_PLUGIN | 666 /* Return song information Tuple |
936 /* Return song information: called by XMMS when initially loading the playlist. | 667 */ |
937 * Subsequent changes to information are made by the player thread, | |
938 * which uses xs_plugin_ip.set_info(); | |
939 */ | |
940 void xs_get_song_info(gchar * songFilename, gchar ** songTitle, gint * songLength) | |
941 { | |
942 t_xs_tuneinfo *pInfo; | |
943 | |
944 XS_MUTEX_LOCK(xs_status); | |
945 | |
946 /* Get tune information from emulation engine */ | |
947 pInfo = xs_status.sidPlayer->plrGetSIDInfo(songFilename); | |
948 if (!pInfo) { | |
949 XS_MUTEX_UNLOCK(xs_status); | |
950 return; | |
951 } | |
952 | |
953 /* Get sub-tune information, if available */ | |
954 if ((pInfo->startTune > 0) && (pInfo->startTune <= pInfo->nsubTunes)) { | |
955 gint tmpInt; | |
956 | |
957 (*songTitle) = xs_make_titlestring(pInfo, pInfo->startTune); | |
958 | |
959 tmpInt = pInfo->subTunes[pInfo->startTune-1].tuneLength; | |
960 if (tmpInt < 0) | |
961 (*songLength) = -1; | |
962 else | |
963 (*songLength) = (tmpInt * 1000); | |
964 } | |
965 | |
966 /* Free tune information */ | |
967 xs_tuneinfo_free(pInfo); | |
968 XS_MUTEX_UNLOCK(xs_status); | |
969 } | |
970 | |
971 #else | |
972 | |
973 Tuple * xs_get_song_tuple(gchar *songFilename) | 668 Tuple * xs_get_song_tuple(gchar *songFilename) |
974 { | 669 { |
975 t_xs_tuneinfo *pInfo; | 670 t_xs_tuneinfo *pInfo; |
976 Tuple *pResult; | 671 Tuple *pResult; |
977 gchar *tmpStr; | 672 gchar *tmpStr; |
1005 | 700 |
1006 /* Get sub-tune information, if available */ | 701 /* Get sub-tune information, if available */ |
1007 if ((pInfo->startTune > 0) && (pInfo->startTune <= pInfo->nsubTunes)) { | 702 if ((pInfo->startTune > 0) && (pInfo->startTune <= pInfo->nsubTunes)) { |
1008 gint tmpInt = pInfo->subTunes[pInfo->startTune-1].tuneLength; | 703 gint tmpInt = pInfo->subTunes[pInfo->startTune-1].tuneLength; |
1009 tuple_associate_int(pResult, "length", (tmpInt < 0) ? -1 : tmpInt * 1000); | 704 tuple_associate_int(pResult, "length", (tmpInt < 0) ? -1 : tmpInt * 1000); |
1010 | |
1011 } | 705 } |
1012 | 706 |
1013 /* Free tune information */ | 707 /* Free tune information */ |
1014 xs_tuneinfo_free(pInfo); | 708 xs_tuneinfo_free(pInfo); |
1015 XS_MUTEX_UNLOCK(xs_status); | 709 XS_MUTEX_UNLOCK(xs_status); |
1016 return pResult; | 710 return pResult; |
1017 } | 711 } |
1018 #endif | |
1019 | |
1020 | |
1021 /* Allocate a new tune information structure | |
1022 */ | |
1023 t_xs_tuneinfo *xs_tuneinfo_new(const gchar * pcFilename, | |
1024 gint nsubTunes, gint startTune, const gchar * sidName, | |
1025 const gchar * sidComposer, const gchar * sidCopyright, | |
1026 gint loadAddr, gint initAddr, gint playAddr, | |
1027 gint dataFileLen, const gchar *sidFormat, gint sidModel) | |
1028 { | |
1029 t_xs_tuneinfo *pResult; | |
1030 t_xs_sldb_node *tmpLength; | |
1031 gint i; | |
1032 | |
1033 /* Allocate structure */ | |
1034 pResult = (t_xs_tuneinfo *) g_malloc0(sizeof(t_xs_tuneinfo)); | |
1035 if (!pResult) { | |
1036 xs_error(_("Could not allocate memory for t_xs_tuneinfo ('%s')\n"), | |
1037 pcFilename); | |
1038 return NULL; | |
1039 } | |
1040 | |
1041 pResult->sidFilename = g_filename_to_utf8(pcFilename, -1, NULL, NULL, NULL); | |
1042 if (!pResult->sidFilename) { | |
1043 xs_error(_("Could not allocate sidFilename ('%s')\n"), | |
1044 pcFilename); | |
1045 g_free(pResult); | |
1046 return NULL; | |
1047 } | |
1048 | |
1049 /* Allocate space for subtune information */ | |
1050 pResult->subTunes = g_malloc0(sizeof(t_xs_subtuneinfo) * (nsubTunes + 1)); | |
1051 if (!pResult->subTunes) { | |
1052 xs_error(_("Could not allocate memory for t_xs_subtuneinfo ('%s', %i)\n"), | |
1053 pcFilename, nsubTunes); | |
1054 | |
1055 g_free(pResult->sidFilename); | |
1056 g_free(pResult); | |
1057 return NULL; | |
1058 } | |
1059 | |
1060 /* The following allocations don't matter if they fail */ | |
1061 pResult->sidName = XS_CS_SID(sidName); | |
1062 pResult->sidComposer = XS_CS_SID(sidComposer); | |
1063 pResult->sidCopyright = XS_CS_SID(sidCopyright); | |
1064 | |
1065 pResult->nsubTunes = nsubTunes; | |
1066 pResult->startTune = startTune; | |
1067 | |
1068 pResult->loadAddr = loadAddr; | |
1069 pResult->initAddr = initAddr; | |
1070 pResult->playAddr = playAddr; | |
1071 pResult->dataFileLen = dataFileLen; | |
1072 pResult->sidFormat = XS_CS_SID(sidFormat); | |
1073 | |
1074 pResult->sidModel = sidModel; | |
1075 | |
1076 /* Get length information (NOTE: Do not free this!) */ | |
1077 tmpLength = xs_songlen_get(pcFilename); | |
1078 | |
1079 /* Fill in sub-tune information */ | |
1080 for (i = 0; i < pResult->nsubTunes; i++) { | |
1081 if (tmpLength && (i < tmpLength->nLengths)) | |
1082 pResult->subTunes[i].tuneLength = tmpLength->sLengths[i]; | |
1083 else | |
1084 pResult->subTunes[i].tuneLength = -1; | |
1085 | |
1086 pResult->subTunes[i].tuneSpeed = -1; | |
1087 } | |
1088 | |
1089 return pResult; | |
1090 } | |
1091 | |
1092 | |
1093 /* Free given tune information structure | |
1094 */ | |
1095 void xs_tuneinfo_free(t_xs_tuneinfo * pTune) | |
1096 { | |
1097 if (!pTune) return; | |
1098 | |
1099 g_free(pTune->subTunes); | |
1100 g_free(pTune->sidFilename); | |
1101 g_free(pTune->sidName); | |
1102 g_free(pTune->sidComposer); | |
1103 g_free(pTune->sidCopyright); | |
1104 g_free(pTune->sidFormat); | |
1105 g_free(pTune); | |
1106 } | |
1107 | |
1108 | |
1109 /* Song length database handling glue | |
1110 */ | |
1111 gint xs_songlen_init(void) | |
1112 { | |
1113 XS_MUTEX_LOCK(xs_cfg); | |
1114 | |
1115 if (!xs_cfg.songlenDBPath) { | |
1116 XS_MUTEX_UNLOCK(xs_cfg); | |
1117 return -1; | |
1118 } | |
1119 | |
1120 XS_MUTEX_LOCK(xs_sldb_db); | |
1121 | |
1122 /* Check if already initialized */ | |
1123 if (xs_sldb_db) | |
1124 xs_sldb_free(xs_sldb_db); | |
1125 | |
1126 /* Allocate database */ | |
1127 xs_sldb_db = (t_xs_sldb *) g_malloc0(sizeof(t_xs_sldb)); | |
1128 if (!xs_sldb_db) { | |
1129 XS_MUTEX_UNLOCK(xs_cfg); | |
1130 XS_MUTEX_UNLOCK(xs_sldb_db); | |
1131 return -2; | |
1132 } | |
1133 | |
1134 /* Read the database */ | |
1135 if (xs_sldb_read(xs_sldb_db, xs_cfg.songlenDBPath) != 0) { | |
1136 xs_sldb_free(xs_sldb_db); | |
1137 xs_sldb_db = NULL; | |
1138 XS_MUTEX_UNLOCK(xs_cfg); | |
1139 XS_MUTEX_UNLOCK(xs_sldb_db); | |
1140 return -3; | |
1141 } | |
1142 | |
1143 /* Create index */ | |
1144 if (xs_sldb_index(xs_sldb_db) != 0) { | |
1145 xs_sldb_free(xs_sldb_db); | |
1146 xs_sldb_db = NULL; | |
1147 XS_MUTEX_UNLOCK(xs_cfg); | |
1148 XS_MUTEX_UNLOCK(xs_sldb_db); | |
1149 return -4; | |
1150 } | |
1151 | |
1152 XS_MUTEX_UNLOCK(xs_cfg); | |
1153 XS_MUTEX_UNLOCK(xs_sldb_db); | |
1154 return 0; | |
1155 } | |
1156 | |
1157 | |
1158 void xs_songlen_close(void) | |
1159 { | |
1160 XS_MUTEX_LOCK(xs_sldb_db); | |
1161 xs_sldb_free(xs_sldb_db); | |
1162 xs_sldb_db = NULL; | |
1163 XS_MUTEX_UNLOCK(xs_sldb_db); | |
1164 } | |
1165 | |
1166 | |
1167 t_xs_sldb_node *xs_songlen_get(const gchar * pcFilename) | |
1168 { | |
1169 t_xs_sldb_node *pResult; | |
1170 | |
1171 XS_MUTEX_LOCK(xs_sldb_db); | |
1172 | |
1173 if (xs_cfg.songlenDBEnable && xs_sldb_db) | |
1174 pResult = xs_sldb_get(xs_sldb_db, pcFilename); | |
1175 else | |
1176 pResult = NULL; | |
1177 | |
1178 XS_MUTEX_UNLOCK(xs_sldb_db); | |
1179 | |
1180 return pResult; | |
1181 } |