#include #include #include #include #include #include #include #include #ifdef HAVE_LIBKMID # include #endif /* HAVE_LIBKMID */ #include "../include/string.h" #include "../include/prochandle.h" #include "midi.h" #include "midiiow.h" #include "options.h" int MIDIIOWInit(MIDIAudio *midi_audio); pid_t MIDIIOWPlay(MIDIAudio *midi_audio, const char *path); void MIDIIOWStop(MIDIAudio *midi_audio); pid_t MIDIIOWIsPlaying(MIDIAudio *midi_audio); void MIDIIOWShutdown(MIDIAudio *midi_audio); #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define CLIP(a,l,h) (MIN(MAX((a),(l)),(h))) #define ABSOLUTE(x) (((x) < 0) ? ((x) * -1) : (x)) /* * Midi Play ID, for use with keeping track of the midi play * process using the standard forking of the midi playing program * (if HAVE_LIBKMID is not defined). * * If HAVE_LIBKMID is defined, then this contains a unique play * ID. */ static pid_t midi_play_pid = 0; #if !defined(HAVE_LIBKMID) /* * Checks if the process specified by pid is still running, * returns true if it is or false if it is not. */ int MIDIIOWProcessExist(pid_t pid); #endif /* !defined(HAVE_LIBKMID) */ #if !defined(HAVE_LIBKMID) int MIDIIOWProcessExist(pid_t pid) { struct sched_param sp; /* Cannot be 0 (because it means itself to sched_getparam()). */ if(pid == 0) return(0); if(sched_getparam( pid, &sp ) == 0) return(1); else return(0); } #endif /* !defined(HAVE_LIBKMID) */ /* * Initializes MIDI IO resources. * * This should be called when the recorder is initialized. */ int MIDIIOWInit(MIDIAudio *midi_audio) { if(midi_audio == NULL) return(-1); #ifdef HAVE_LIBKMID if(kMidInit()) { fprintf(stderr, "kMidInit(): Initialization failure, midi support will be unavailable.\n" ); return(-1); } else { printf( "libkmidi: Initialized device number %i.\n", midi_audio->midi_device_number ); } /* Set MIDI device number. */ kMidSetDevice(midi_audio->midi_device_number); /* Set lib data pointer to 1 just so that it's not * checked to be NULL by other functions that use this * value to determine if the library is initialized or not. */ midi_audio->ptr = (void *)1; #else /* HAVE_LIBKMID */ /* Set lib data pointer to 1 just so that it's not * checked to be NULL by other functions that use this * value to determine if the library is initialized or not. */ midi_audio->ptr = (void *)1; #endif /* Reset midi_play_pid. */ midi_play_pid = 0; return(0); } /* * Plays the MIDI file specified by path, returns a unique * id to identify the play or 0 on failure. */ pid_t MIDIIOWPlay(MIDIAudio *midi_audio, const char *path) { if(path == NULL) return(0); if(midi_audio == NULL) return(0); #ifdef HAVE_LIBKMID if(midi_audio->ptr != NULL) { /* Stop incase it is already playing. */ kMidStop(); /* Load and play new MIDI file. */ kMidLoad(path); kMidPlay(); /* Increment midi_play_pid. */ midi_play_pid++; return(midi_play_pid); } else { return(0); } #else /* HAVE_LIBKMID */ if(midi_audio->ptr != NULL) { int len; char *cmd; /* Stop incase it is already playing. */ if(midi_play_pid > 0) MIDIIOWStop(midi_audio); /* Allocate and format play command. */ len = strlen(path) + strlen(option.midi_play_cmd) + 256; cmd = (char *)malloc((len + 1) * sizeof(char)); if(cmd == NULL) return(0); strcpy(cmd, option.midi_play_cmd); substr(cmd, "%f", path); /* Execute command and record midi play pid. */ midi_play_pid = Exec(cmd); if(midi_play_pid == 0) return(0); /* Free command. */ free(cmd); return(midi_play_pid); } else { return(0); } #endif } /* * Stop playing MIDI if it is still playing. */ void MIDIIOWStop(MIDIAudio *midi_audio) { if(midi_audio == NULL) return; #ifdef HAVE_LIBKMID if(midi_audio->ptr != NULL) { /* Stop if currently playing. */ kMidStop(); } #else /* HAVE_LIBKMID */ if(midi_audio->ptr != NULL) { /* Stop any midi's still playing. */ if(midi_play_pid > 0) kill(midi_play_pid, SIGINT); /* Reset midi_play_pid. */ midi_play_pid = 0; } #endif return; } /* * Checks if the MIDI is still being played, returns the pid * of the process if it is still being played or 0 if it is not. */ pid_t MIDIIOWIsPlaying(MIDIAudio *midi_audio) { if(midi_audio == NULL) return(0); #ifdef HAVE_LIBKMID if(midi_audio->ptr != NULL) { int status = kMidIsPlaying(); if(status) return(midi_play_pid); else return(0); } else { return(0); } #else /* HAVE_LIBKMID */ if(midi_audio->ptr != NULL) { /* Check if the midi play process is still running. * This will set midi_play_pid to 0 if the midi play * process no longer exists or leave midi_play_pid as * is if the midi play process is still active. */ if(midi_play_pid > 0) { if(!MIDIIOWProcessExist(midi_play_pid)) midi_play_pid = 0; } return(midi_play_pid); } else { return(0); } #endif } /* * Shuts down all MIDI IO resources. * * This should be called when the recorder is shut down. */ void MIDIIOWShutdown(MIDIAudio *midi_audio) { if(midi_audio == NULL) return; #ifdef HAVE_LIBKMID if(midi_audio->ptr != NULL) { /* Stop any midi's still playing. */ if(MIDIIOWIsPlaying(midi_audio)) MIDIIOWStop(midi_audio); /* Shutdown libkmid. */ kMidDestruct(); /* Reset midi_play_pid. */ midi_play_pid = 0; /* Reset pointer to external resources (never * allcoated). */ midi_audio->ptr = NULL; } #else /* HAVE_LIBKMID */ if(midi_audio->ptr != NULL) { /* Stop any midi's still playing. */ if(midi_play_pid > 0) MIDIIOWStop(midi_audio); /* Reset midi_play_pid (though MIDIIOWStop() probably * already reset it). */ midi_play_pid = 0; /* Reset pointer to external resources (never * allcoated). */ midi_audio->ptr = NULL; } #endif return; }