put example files to dedicated dir
[monster.git] / song_player.c
blobf16b429b47647c2585ba6dc7a54a127cf88e70e9
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*****************************************************************************
4 * Play one song and be able to stop playback
5 * This file is part of monster
7 * Copyright (C) 2006,2007 Nedko Arnaudov <nedko@arnaudov.name>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2 of the License
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
22 *****************************************************************************/
24 #include <unistd.h>
25 #include <pthread.h>
26 #include <libxml/parser.h>
27 #include <string.h>
28 #include <libgen.h>
30 #define DISABLE_DEBUG_OUTPUT
32 #include "media_source.h"
33 #include "player.h"
34 #include "media_source_dv.h"
35 #include "media_source_wav.h"
36 #include "media_source_midi.h"
37 #include "player_video1394.h"
38 #include "player_alsa_pcm.h"
39 #include "player_alsa_midi.h"
40 #include "log.h"
41 #include "xml.h"
42 #include "song_player.h"
43 #include "conf.h"
44 #include "path.h"
46 #define XPATH_SONG_NAME_EXPRESSION "/song/name"
48 #define EOD_CONTEXT_VIDEO 1
49 #define EOD_CONTEXT_AUDIO 2
50 #define EOD_CONTEXT_MIDI 4
52 pthread_mutex_t g_real_mask_mutex;
53 unsigned int g_real_mask;
54 eos_t g_eos;
55 struct media_source * g_media_source_dv_ptr;
56 struct media_source * g_media_source_wav_ptr;
57 struct media_source * g_media_source_midi_ptr;
58 struct player * g_player_video1394_ptr;
59 struct player * g_player_alsa_pcm_ptr;
60 struct player * g_player_alsa_midi_ptr;
61 struct song_descriptor * g_song_descriptor_ptr;
63 void
64 eod(unsigned int context)
66 switch (context)
68 case EOD_CONTEXT_VIDEO:
69 DEBUG_OUT("eod: video");
70 break;
71 case EOD_CONTEXT_AUDIO:
72 DEBUG_OUT("eod: audio");
73 break;
74 case EOD_CONTEXT_MIDI:
75 DEBUG_OUT("eod: MIDI");
76 break;
77 default:
78 DEBUG_OUT("eod: %u", context);
81 pthread_mutex_lock(&g_real_mask_mutex);
82 g_real_mask &= ~context;
83 if (g_real_mask == 0)
85 OUTPUT_MESSAGE("====== End of song");
86 g_eos();
88 pthread_mutex_unlock(&g_real_mask_mutex);
91 struct song_descriptor
93 char * name_ptr;
94 char * media_video_filename_ptr;
95 char * media_audio_filename_ptr;
96 char * media_midi_filename_ptr;
97 int start_offset_video;
98 int start_offset_audio;
99 int start_offset_midi;
102 void
103 free_song_descriptor(
104 struct song_descriptor * song_descriptor_ptr)
106 free(song_descriptor_ptr->name_ptr);
108 if (song_descriptor_ptr->media_video_filename_ptr != NULL)
110 free(song_descriptor_ptr->media_video_filename_ptr);
113 if (song_descriptor_ptr->media_audio_filename_ptr != NULL)
115 free(song_descriptor_ptr->media_audio_filename_ptr);
118 if (song_descriptor_ptr->media_midi_filename_ptr != NULL)
120 free(song_descriptor_ptr->media_midi_filename_ptr);
123 free(song_descriptor_ptr);
126 void
127 dump_song_descriptor(
128 struct song_descriptor * song_descriptor_ptr)
130 NOTICE_OUT("Song name: \"%s\"", song_descriptor_ptr->name_ptr);
132 if (song_descriptor_ptr->media_video_filename_ptr != NULL)
134 NOTICE_OUT("Video media: \"%s\"", song_descriptor_ptr->media_video_filename_ptr);
137 if (song_descriptor_ptr->media_audio_filename_ptr != NULL)
139 NOTICE_OUT("Audio media: \"%s\"", song_descriptor_ptr->media_audio_filename_ptr);
142 if (song_descriptor_ptr->media_midi_filename_ptr != NULL)
144 NOTICE_OUT("MIDI media: \"%s\"", song_descriptor_ptr->media_midi_filename_ptr);
149 get_song_name(
150 const char * song_filename_ptr,
151 char ** song_name_ptr_ptr)
153 int ret;
154 xmlDocPtr doc_ptr;
156 doc_ptr = xmlParseFile(song_filename_ptr);
157 if (doc_ptr == NULL)
159 ERROR_OUT("Failed to parse song \"%s\"", song_filename_ptr);
160 ret = -1;
161 goto exit;
164 ret = xml_get_string_dup(doc_ptr, XPATH_SONG_NAME_EXPRESSION, song_name_ptr_ptr);
165 if (ret != 0)
167 ERROR_OUT("Cannot find song name within \"%s\"", song_filename_ptr);
168 ret = -1;
169 goto free_doc;
172 ret = 0;
174 free_doc:
175 xmlFreeDoc(doc_ptr);
177 exit:
178 return ret;
182 get_song_descriptor(
183 const char * song_filename_ptr,
184 struct song_descriptor ** song_descriptor_ptr_ptr)
186 int ret, midi, audio, video;
187 xmlDocPtr doc_ptr;
188 struct song_descriptor * song_descriptor_ptr;
189 char * media_filename_ptr;
190 char * song_filename_copy_ptr;
191 const char * song_dirname_ptr;
192 size_t song_dirname_size;
193 size_t temp_size;
195 DEBUG_OUT("Parsing %s", song_filename_ptr);
197 song_filename_copy_ptr = strdup(song_filename_ptr);
198 if (song_filename_copy_ptr == NULL)
200 ERROR_OUT("strdup() failed");
201 ret = -1;
202 goto exit;
205 song_dirname_ptr = dirname(song_filename_copy_ptr);
207 DEBUG_OUT("song dirname is \"%s\"", song_dirname_ptr);
209 song_dirname_size = strlen(song_dirname_ptr);
211 doc_ptr = xmlParseFile(song_filename_ptr);
212 if (doc_ptr == NULL)
214 ERROR_OUT("Failed to parse song \"%s\"", song_filename_ptr);
215 ret = -1;
216 goto free_song_copy;
219 song_descriptor_ptr = (struct song_descriptor *)malloc(sizeof(struct song_descriptor));
220 if (song_descriptor_ptr == NULL)
222 ERROR_OUT("Cannot allocate song descriptor");
223 ret = -1;
224 goto free_doc;
227 midi = xml_check_path(doc_ptr, "/song/midi");
228 if (midi < 0)
230 ERROR_OUT("xml_check_path() failed.");
231 ret = -1;
232 goto free_doc;
235 audio = xml_check_path(doc_ptr, "/song/audio");
236 if (audio < 0)
238 ERROR_OUT("xml_check_path() failed.");
239 ret = -1;
240 goto free_doc;
243 video = xml_check_path(doc_ptr, "/song/video");
244 if (video < 0)
246 ERROR_OUT("xml_check_path() failed.");
247 ret = -1;
248 goto free_doc;
251 if (midi > 1)
253 ERROR_OUT("Only one MIDI media allowed.");
254 ret = -1;
255 goto free_doc;
258 if (audio > 1)
260 ERROR_OUT("Only one audio media allowed.");
261 ret = -1;
262 goto free_doc;
265 if (video > 1)
267 ERROR_OUT("Only one video media allowed.");
268 ret = -1;
269 goto free_doc;
272 if (midi != 0)
274 ret = xml_get_string_dup(doc_ptr, "/song/midi/media", &media_filename_ptr);
275 if (ret != 0)
277 ERROR_OUT("Cannot find MIDI media filename within \"%s\"", song_filename_ptr);
278 ret = -1;
279 goto exit_free_song_descriptor;
282 NOTICE_OUT("MIDI present");
284 if (media_filename_ptr[0] == '/')
286 song_descriptor_ptr->media_midi_filename_ptr = media_filename_ptr;
288 else
290 temp_size = strlen(media_filename_ptr);
292 song_descriptor_ptr->media_midi_filename_ptr = (char *)malloc(song_dirname_size + 1 + temp_size + 1);
293 if (song_descriptor_ptr->media_midi_filename_ptr == NULL)
295 ERROR_OUT("malloc() failed.");
296 ret = -1;
297 goto exit_free_song_descriptor;
300 memcpy(song_descriptor_ptr->media_midi_filename_ptr, song_dirname_ptr, song_dirname_size);
301 song_descriptor_ptr->media_midi_filename_ptr[song_dirname_size] = '/';
302 memcpy(song_descriptor_ptr->media_midi_filename_ptr + song_dirname_size + 1, media_filename_ptr, temp_size);
303 song_descriptor_ptr->media_midi_filename_ptr[song_dirname_size + 1 + temp_size] = 0;
305 path_normalize(song_descriptor_ptr->media_midi_filename_ptr);
308 else
310 song_descriptor_ptr->media_midi_filename_ptr = NULL;
311 NOTICE_OUT("MIDI absent");
314 if (audio != 0)
316 ret = xml_get_string_dup(doc_ptr, "/song/audio/media", &media_filename_ptr);
317 if (ret != 0)
319 ERROR_OUT("Cannot find audio media filename within \"%s\"", song_filename_ptr);
320 ret = -1;
321 goto free_midi_filename;
324 NOTICE_OUT("Audio present");
326 if (media_filename_ptr[0] == '/')
328 song_descriptor_ptr->media_audio_filename_ptr = media_filename_ptr;
330 else
332 temp_size = strlen(media_filename_ptr);
334 song_descriptor_ptr->media_audio_filename_ptr = (char *)malloc(song_dirname_size + 1 + temp_size + 1);
335 if (song_descriptor_ptr->media_audio_filename_ptr == NULL)
337 ERROR_OUT("malloc() failed.");
338 ret = -1;
339 goto exit_free_song_descriptor;
342 memcpy(song_descriptor_ptr->media_audio_filename_ptr, song_dirname_ptr, song_dirname_size);
343 song_descriptor_ptr->media_audio_filename_ptr[song_dirname_size] = '/';
344 memcpy(song_descriptor_ptr->media_audio_filename_ptr + song_dirname_size + 1, media_filename_ptr, temp_size);
345 song_descriptor_ptr->media_audio_filename_ptr[song_dirname_size + 1 + temp_size] = 0;
347 path_normalize(song_descriptor_ptr->media_audio_filename_ptr);
350 else
352 song_descriptor_ptr->media_audio_filename_ptr = NULL;
353 NOTICE_OUT("Audio absent");
356 if (video != 0)
358 ret = xml_get_string_dup(doc_ptr, "/song/video/media", &media_filename_ptr);
359 if (ret != 0)
361 ERROR_OUT("Cannot find video media filename within \"%s\"", song_filename_ptr);
362 ret = -1;
363 goto free_audio_filename;
366 NOTICE_OUT("Video present");
368 if (media_filename_ptr[0] == '/')
370 song_descriptor_ptr->media_video_filename_ptr = media_filename_ptr;
372 else
374 temp_size = strlen(media_filename_ptr);
376 song_descriptor_ptr->media_video_filename_ptr = (char *)malloc(song_dirname_size + 1 + temp_size + 1);
377 if (song_descriptor_ptr->media_video_filename_ptr == NULL)
379 ERROR_OUT("malloc() failed.");
380 ret = -1;
381 goto exit_free_song_descriptor;
384 memcpy(song_descriptor_ptr->media_video_filename_ptr, song_dirname_ptr, song_dirname_size);
385 song_descriptor_ptr->media_video_filename_ptr[song_dirname_size] = '/';
386 memcpy(song_descriptor_ptr->media_video_filename_ptr + song_dirname_size + 1, media_filename_ptr, temp_size);
387 song_descriptor_ptr->media_video_filename_ptr[song_dirname_size + 1 + temp_size] = 0;
389 path_normalize(song_descriptor_ptr->media_video_filename_ptr);
392 else
394 song_descriptor_ptr->media_video_filename_ptr = NULL;
395 NOTICE_OUT("Video absent");
398 ret = xml_get_string_dup(doc_ptr, XPATH_SONG_NAME_EXPRESSION, &song_descriptor_ptr->name_ptr);
399 if (ret != 0)
401 ERROR_OUT("Cannot find song name within \"%s\"", song_filename_ptr);
402 ret = -1;
403 goto free_video_filename;
406 ret = xml_get_int(doc_ptr, "/song/start_offsets/video", &song_descriptor_ptr->start_offset_video);
407 if (ret != 0)
409 DEBUG_OUT("song video start offset is not supplied, defaulting to 0");
410 song_descriptor_ptr->start_offset_video = 0;
412 else
414 DEBUG_OUT("song video start offset is %d microseconds", song_descriptor_ptr->start_offset_video);
417 ret = xml_get_int(doc_ptr, "/song/start_offsets/audio", &song_descriptor_ptr->start_offset_audio);
418 if (ret != 0)
420 DEBUG_OUT("song audio start offset is not supplied, defaulting to 0");
421 song_descriptor_ptr->start_offset_audio = 0;
423 else
425 DEBUG_OUT("song audio start offset is %d microseconds", song_descriptor_ptr->start_offset_audio);
428 ret = xml_get_int(doc_ptr, "/song/start_offsets/midi", &song_descriptor_ptr->start_offset_midi);
429 if (ret != 0)
431 DEBUG_OUT("song midi start offset is not supplied, defaulting to 0");
432 song_descriptor_ptr->start_offset_midi = 0;
434 else
436 DEBUG_OUT("song midi start offset is %d microseconds", song_descriptor_ptr->start_offset_midi);
439 *song_descriptor_ptr_ptr = song_descriptor_ptr;
440 ret = 0;
441 goto free_doc;
443 free_video_filename:
444 free(song_descriptor_ptr->media_video_filename_ptr);
446 free_audio_filename:
447 free(song_descriptor_ptr->media_audio_filename_ptr);
449 free_midi_filename:
450 free(song_descriptor_ptr->media_midi_filename_ptr);
452 exit_free_song_descriptor:
453 free(song_descriptor_ptr);
455 free_doc:
456 xmlFreeDoc(doc_ptr);
458 free_song_copy:
459 free(song_filename_copy_ptr);
461 exit:
462 return ret;
466 play_song(
467 const char * song_filename_ptr,
468 eos_t eos)
470 int ret, ret1;
471 int start_offsets[3];
472 struct player * players[3];
473 int i;
474 int j;
475 struct player * player_temp_ptr;
476 int start_offset_temp;
477 int global_start_offset_video;
478 int global_start_offset_audio;
479 int global_start_offset_midi;
481 DEBUG_OUT("play_song(%s) called.", song_filename_ptr);
483 ret = conf_file_get_int("/conf/start_offsets/video", &global_start_offset_video);
484 if (ret != 0)
486 ERROR_OUT("failed to read from configuration what global video start offset to use");
487 ret = -1;
488 goto exit;
491 ret = conf_file_get_int("/conf/start_offsets/audio", &global_start_offset_audio);
492 if (ret != 0)
494 ERROR_OUT("failed to read from configuration what global audio start offset to use");
495 ret = -1;
496 goto exit;
499 ret = conf_file_get_int("/conf/start_offsets/midi", &global_start_offset_midi);
500 if (ret != 0)
502 ERROR_OUT("failed to read from configuration what global midi start offset to use");
503 ret = -1;
504 goto exit;
507 DEBUG_OUT("Using global video start offset of %d microseconds", global_start_offset_video);
508 DEBUG_OUT("Using global audio start offset of %d microseconds", global_start_offset_audio);
509 DEBUG_OUT("Using global midi start offset of %d microseconds", global_start_offset_midi);
511 ret = get_song_descriptor(song_filename_ptr, &g_song_descriptor_ptr);
512 if (ret != 0)
514 ERROR_OUT("Failed to get song descriptor (%d)", ret);
515 ret = -1;
516 goto exit;
519 OUTPUT_MESSAGE("====== Play \"%s\"", g_song_descriptor_ptr->name_ptr);
521 dump_song_descriptor(g_song_descriptor_ptr);
523 DEBUG_OUT("Initializing...");
525 g_real_mask = 0;
527 if (g_song_descriptor_ptr->media_video_filename_ptr != NULL)
529 g_real_mask |= EOD_CONTEXT_VIDEO;
532 if (g_song_descriptor_ptr->media_audio_filename_ptr != NULL)
534 g_real_mask |= EOD_CONTEXT_AUDIO;
537 if (g_song_descriptor_ptr->media_midi_filename_ptr != NULL)
539 g_real_mask |= EOD_CONTEXT_MIDI;
542 ret = pthread_mutex_init(&g_real_mask_mutex, NULL);
543 if (ret != 0)
545 ERROR_OUT("Failed to init real mask mutex (%d)", ret);
546 ret = -1;
547 goto exit_free_song_descriptor;
550 if (g_song_descriptor_ptr->media_video_filename_ptr != NULL)
552 ret = media_source_dv(g_song_descriptor_ptr->media_video_filename_ptr, &g_media_source_dv_ptr);
553 if (ret < 0)
555 ERROR_OUT("failed to create the DV source");
556 ret = 1;
557 goto exit_destroy_mutex;
561 if (g_song_descriptor_ptr->media_audio_filename_ptr != NULL)
563 ret = media_source_wav(g_song_descriptor_ptr->media_audio_filename_ptr, &g_media_source_wav_ptr);
564 if (ret < 0)
566 ERROR_OUT("failed to create the WAV source");
567 ret = 1;
568 goto exit_destroy_media_source_dv;
572 if (g_song_descriptor_ptr->media_midi_filename_ptr != NULL)
574 ret = media_source_midi(g_song_descriptor_ptr->media_midi_filename_ptr, &g_media_source_midi_ptr);
575 if (ret < 0)
577 ERROR_OUT("failed to create the MIDI source");
578 ret = 1;
579 goto exit_destroy_media_source_wav;
583 if (g_song_descriptor_ptr->media_video_filename_ptr != NULL)
585 ret = player_video1394(g_media_source_dv_ptr, eod, EOD_CONTEXT_VIDEO, &g_player_video1394_ptr);
586 if (ret < 0)
588 ERROR_OUT("failed to create the firewire player");
589 ret = 1;
590 goto exit_destroy_media_source_midi;
593 else
595 g_player_video1394_ptr = NULL;
598 if (g_song_descriptor_ptr->media_audio_filename_ptr != NULL)
600 ret = player_alsa_pcm(g_media_source_wav_ptr, eod, EOD_CONTEXT_AUDIO, &g_player_alsa_pcm_ptr);
601 if (ret < 0)
603 ERROR_OUT("failed to create the ALSA PCM player");
604 ret = 1;
605 goto exit_destroy_video_1394_player;
608 else
610 g_player_alsa_pcm_ptr = NULL;
613 if (g_song_descriptor_ptr->media_midi_filename_ptr != NULL)
615 ret = player_alsa_midi(g_media_source_midi_ptr, eod, EOD_CONTEXT_MIDI, &g_player_alsa_midi_ptr);
616 if (ret < 0)
618 ERROR_OUT("failed to create the ALSA MIDI player");
619 ret = 1;
620 goto exit_destroy_alsa_pcm_player;
623 else
625 g_player_alsa_midi_ptr = NULL;
628 players[0] = g_player_video1394_ptr;
629 start_offsets[0] = global_start_offset_video + g_song_descriptor_ptr->start_offset_video;
631 players[1] = g_player_alsa_pcm_ptr;
632 start_offsets[1] = global_start_offset_audio + g_song_descriptor_ptr->start_offset_audio;
634 players[2] = g_player_alsa_midi_ptr;
635 start_offsets[2] = global_start_offset_midi + g_song_descriptor_ptr->start_offset_midi;
637 DEBUG_OUT("Preparing...");
639 for (i = 0 ; i < 3 ; i++)
641 //ERROR_OUT("Preparing %s player", players[i]->name);
642 if (players[i] != NULL)
644 ret = player_start_prepare(players[i]);
645 if (ret < 0)
647 ERROR_OUT("failed to prepare %s player for start", players[i]->name);
648 ret = 1;
649 goto exit_destroy_players;
654 /* sort players by start offset */
655 for (i = 0 ; i < 3 ; i++)
657 for (j = i + 1 ; j < 3 ; j++)
659 //DEBUG_OUT("Comparing %i (%i) and %i (%i)", j, start_offsets[j], i, start_offsets[i]);
660 if (start_offsets[j] < start_offsets[i])
662 //DEBUG_OUT("Exchanging %i and %i", i, j);
663 start_offset_temp = start_offsets[i];
664 player_temp_ptr = players[i];
666 start_offsets[i] = start_offsets[j];
667 players[i] = players[j];
669 start_offsets[j] = start_offset_temp;
670 players[j] = player_temp_ptr;
675 /* DEBUG_OUT("------ sorted players"); */
676 /* for (i = 0 ; i < 3 ; i++) */
677 /* { */
678 /* DEBUG_OUT("%s player, start offset %d", players[i]->name, start_offsets[i]); */
679 /* } */
681 /* normalize offsets and make start offsets relative */
682 start_offset_temp = start_offsets[0];
683 for (i = 0 ; i < 3 ; i++)
685 start_offsets[i] -= start_offset_temp;
688 for (i = 1 ; i < 3 ; i++)
690 start_offsets[i] -= start_offsets[i-1];
693 /* DEBUG_OUT("------ normalized players"); */
694 /* for (i = 0 ; i < 3 ; i++) */
695 /* { */
696 /* DEBUG_OUT("%s player, start offset %d", players[i]->name, start_offsets[i]); */
697 /* } */
699 /* show startup plan */
700 DEBUG_OUT("------ players startup plan");
701 for (i = 0 ; i < 3 ; i++)
703 if (start_offsets[i] != 0)
705 DEBUG_OUT("Wait %d microseconds", start_offsets[i]);
706 if (start_offsets[i] < 0)
708 ERROR_OUT("Cannot reverse the time (sort and/or normalize failed)");
709 goto exit_destroy_players;
713 if (players[i] != NULL)
715 DEBUG_OUT("Start %s player", players[i]->name);
719 g_eos = eos;
721 OUTPUT_MESSAGE("...... GO!");
722 for (i = 0 ; i < 3 ; i++)
724 if (start_offsets[i] != 0)
726 //DEBUG_OUT("Waiting %d microseconds", start_offsets[i]);
727 usleep(start_offsets[i]);
730 if (players[i] != NULL)
732 //DEBUG_OUT("Starting %s player", players[i]->name);
733 ret = player_start(players[i]);
734 if (ret < 0)
736 ERROR_OUT("failed to start %s player", players[i]->name);
737 ret = 1;
738 goto exit_destroy_players;
743 ret = 0;
744 goto exit;
746 exit_destroy_players:
747 //exit_destroy_alsa_midi_player:
748 if (g_song_descriptor_ptr->media_midi_filename_ptr != NULL)
750 player_destroy(g_player_alsa_midi_ptr);
753 exit_destroy_alsa_pcm_player:
754 if (g_song_descriptor_ptr->media_audio_filename_ptr != NULL)
756 player_destroy(g_player_alsa_pcm_ptr);
759 exit_destroy_video_1394_player:
760 if (g_song_descriptor_ptr->media_video_filename_ptr != NULL)
762 player_destroy(g_player_video1394_ptr);
765 exit_destroy_media_source_midi:
766 if (g_song_descriptor_ptr->media_midi_filename_ptr != NULL)
768 media_source_destroy(g_media_source_midi_ptr);
771 exit_destroy_media_source_wav:
772 if (g_song_descriptor_ptr->media_audio_filename_ptr != NULL)
774 media_source_destroy(g_media_source_wav_ptr);
777 exit_destroy_media_source_dv:
778 if (g_song_descriptor_ptr->media_video_filename_ptr != NULL)
780 media_source_destroy(g_media_source_dv_ptr);
783 exit_destroy_mutex:
784 ret1 = pthread_mutex_destroy(&g_real_mask_mutex);
785 if (ret1 != 0)
787 ERROR_OUT("Failed to destroy real mask mutex (%d)", ret1);
790 exit_free_song_descriptor:
791 free_song_descriptor(g_song_descriptor_ptr);
793 exit:
794 return ret;
797 void
798 end_song()
800 DEBUG_OUT("------ STOP!");
802 pthread_mutex_lock(&g_real_mask_mutex);
803 if (g_real_mask != 0)
805 OUTPUT_MESSAGE("====== Stopping...");
807 pthread_mutex_unlock(&g_real_mask_mutex);
809 if (g_song_descriptor_ptr->media_midi_filename_ptr != NULL)
810 player_destroy(g_player_alsa_midi_ptr);
812 if (g_song_descriptor_ptr->media_audio_filename_ptr != NULL)
813 player_destroy(g_player_alsa_pcm_ptr);
815 if (g_song_descriptor_ptr->media_video_filename_ptr != NULL)
816 player_destroy(g_player_video1394_ptr);
818 if (g_song_descriptor_ptr->media_midi_filename_ptr != NULL)
819 media_source_destroy(g_media_source_midi_ptr);
821 if (g_song_descriptor_ptr->media_audio_filename_ptr != NULL)
822 media_source_destroy(g_media_source_wav_ptr);
824 if (g_song_descriptor_ptr->media_video_filename_ptr != NULL)
825 media_source_destroy(g_media_source_dv_ptr);
827 pthread_mutex_destroy(&g_real_mask_mutex);
829 free_song_descriptor(g_song_descriptor_ptr);
831 g_player_alsa_midi_ptr = NULL;
832 g_player_alsa_pcm_ptr = NULL;
833 g_player_video1394_ptr = NULL;
834 g_media_source_midi_ptr = NULL;
835 g_media_source_wav_ptr = NULL;
836 g_media_source_dv_ptr = NULL;
837 g_song_descriptor_ptr = NULL;
839 if (g_real_mask != 0)
841 OUTPUT_MESSAGE("====== Stopped");