Logo Search packages:      
Sourcecode: yiff version File versions  Download package

midiiow.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
extern int errno;
#include <signal.h>
#include <sched.h>

#ifdef HAVE_LIBKMID
# include <libkmid/libkmid.h>
#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;
}


Generated by  Doxygen 1.6.0   Back to index