14 #include <unistd.h> |
14 #include <unistd.h> |
15 #include <signal.h> |
15 #include <signal.h> |
16 #include <sys/stat.h> |
16 #include <sys/stat.h> |
17 #include <errno.h> |
17 #include <errno.h> |
18 |
18 |
19 static struct { |
19 static FMusicDriver_ExtMidi iFMusicDriver_ExtMidi; |
20 char song[MAX_PATH]; |
|
21 pid_t pid; |
|
22 } _midi; |
|
23 |
20 |
24 static void DoPlay(); |
21 const char* MusicDriver_ExtMidi::Start(const char* const * parm) |
25 static void DoStop(); |
|
26 |
|
27 static const char* ExtMidiStart(const char* const * parm) |
|
28 { |
22 { |
29 _midi.song[0] = '\0'; |
23 this->song[0] = '\0'; |
30 _midi.pid = -1; |
24 this->pid = -1; |
31 return NULL; |
25 return NULL; |
32 } |
26 } |
33 |
27 |
34 static void ExtMidiStop() |
28 void MusicDriver_ExtMidi::Stop() |
35 { |
29 { |
36 _midi.song[0] = '\0'; |
30 this->song[0] = '\0'; |
37 DoStop(); |
31 this->DoStop(); |
38 } |
32 } |
39 |
33 |
40 static void ExtMidiPlaySong(const char* filename) |
34 void MusicDriver_ExtMidi::PlaySong(const char* filename) |
41 { |
35 { |
42 ttd_strlcpy(_midi.song, filename, lengthof(_midi.song)); |
36 ttd_strlcpy(this->song, filename, lengthof(this->song)); |
43 DoStop(); |
37 this->DoStop(); |
44 } |
38 } |
45 |
39 |
46 static void ExtMidiStopSong() |
40 void MusicDriver_ExtMidi::StopSong() |
47 { |
41 { |
48 _midi.song[0] = '\0'; |
42 this->song[0] = '\0'; |
49 DoStop(); |
43 this->DoStop(); |
50 } |
44 } |
51 |
45 |
52 static bool ExtMidiIsPlaying() |
46 bool MusicDriver_ExtMidi::IsSongPlaying() |
53 { |
47 { |
54 if (_midi.pid != -1 && waitpid(_midi.pid, NULL, WNOHANG) == _midi.pid) |
48 if (this->pid != -1 && waitpid(this->pid, NULL, WNOHANG) == this->pid) |
55 _midi.pid = -1; |
49 this->pid = -1; |
56 if (_midi.pid == -1 && _midi.song[0] != '\0') DoPlay(); |
50 if (this->pid == -1 && this->song[0] != '\0') this->DoPlay(); |
57 return _midi.pid != -1; |
51 return this->pid != -1; |
58 } |
52 } |
59 |
53 |
60 static void ExtMidiSetVolume(byte vol) |
54 void MusicDriver_ExtMidi::SetVolume(byte vol) |
61 { |
55 { |
62 DEBUG(driver, 1, "extmidi: set volume not implemented"); |
56 DEBUG(driver, 1, "extmidi: set volume not implemented"); |
63 } |
57 } |
64 |
58 |
65 static void DoPlay() |
59 void MusicDriver_ExtMidi::DoPlay() |
66 { |
60 { |
67 _midi.pid = fork(); |
61 this->pid = fork(); |
68 switch (_midi.pid) { |
62 switch (this->pid) { |
69 case 0: { |
63 case 0: { |
70 int d; |
64 int d; |
71 |
65 |
72 close(0); |
66 close(0); |
73 d = open("/dev/null", O_RDONLY); |
67 d = open("/dev/null", O_RDONLY); |
74 if (d != -1 && dup2(d, 1) != -1 && dup2(d, 2) != -1) { |
68 if (d != -1 && dup2(d, 1) != -1 && dup2(d, 2) != -1) { |
75 #if defined(MIDI_ARG) |
69 #if defined(MIDI_ARG) |
76 execlp(msf.extmidi, "extmidi", MIDI_ARG, _midi.song, (char*)0); |
70 execlp(msf.extmidi, "extmidi", MIDI_ARG, this->song, (char*)0); |
77 #else |
71 #else |
78 execlp(msf.extmidi, "extmidi", _midi.song, (char*)0); |
72 execlp(msf.extmidi, "extmidi", this->song, (char*)0); |
79 #endif |
73 #endif |
80 } |
74 } |
81 _exit(1); |
75 _exit(1); |
82 } |
76 } |
83 |
77 |
84 case -1: |
78 case -1: |
85 DEBUG(driver, 0, "extmidi: couldn't fork: %s", strerror(errno)); |
79 DEBUG(driver, 0, "extmidi: couldn't fork: %s", strerror(errno)); |
86 /* FALLTHROUGH */ |
80 /* FALLTHROUGH */ |
87 |
81 |
88 default: |
82 default: |
89 _midi.song[0] = '\0'; |
83 this->song[0] = '\0'; |
90 break; |
84 break; |
91 } |
85 } |
92 } |
86 } |
93 |
87 |
94 static void DoStop() |
88 void MusicDriver_ExtMidi::DoStop() |
95 { |
89 { |
96 if (_midi.pid != -1) kill(_midi.pid, SIGTERM); |
90 if (this->pid != -1) kill(this->pid, SIGTERM); |
97 } |
91 } |
98 |
92 |
99 const HalMusicDriver _extmidi_music_driver = { |
|
100 ExtMidiStart, |
|
101 ExtMidiStop, |
|
102 ExtMidiPlaySong, |
|
103 ExtMidiStopSong, |
|
104 ExtMidiIsPlaying, |
|
105 ExtMidiSetVolume, |
|
106 }; |
|
107 |
|
108 #endif /* __MORPHOS__ */ |
93 #endif /* __MORPHOS__ */ |