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

audiocd.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#include <unistd.h>
#include "../include/string.h"
#include "../include/fio.h"
#include "../include/prochandle.h"
#include "audiocd.h"

AudioCDContext *AudioCDInit(void);
void AudioCDShutdown(AudioCDContext *ctx);

AudioCDTrack **AudioCDListTracks(AudioCDContext *ctx, int *total);
void AudioCDDeleteTracksList(AudioCDTrack **track, int total);

int AudioCDLastTrack(AudioCDContext *ctx);

void AudioCDPlayTrack(AudioCDContext *ctx, int track_number);
void AudioCDStop(AudioCDContext *ctx);
void AudioCDEject(AudioCDContext *ctx);


#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))


/*
 *    Initializes the audio CD and creates a new context.  This does
 *    not need to be called between audio CD changes.
 */
AudioCDContext *AudioCDInit(void)
{
      AudioCDContext *ctx = (AudioCDContext *)calloc(
          1, sizeof(AudioCDContext)
      );
      if(ctx == NULL)
          return(NULL);

      ctx->prog = strdup("/usr/bin/cdplay");
      ctx->device = strdup("/dev/cdrom");
      ctx->current_track_number = 0;

      return(ctx);
}

/*
 *    Shutsdown the audio cd and deletes the context.
 */
void AudioCDShutdown(AudioCDContext *ctx)
{
      if(ctx == NULL)
          return;

      free(ctx->prog);
      free(ctx->device);
      free(ctx);
}

/*
 *    Returns a list of audio CD tracks.
 */
AudioCDTrack **AudioCDListTracks(AudioCDContext *ctx, int *total)
{
      char *path;
      pid_t p;
      char cmd[PATH_MAX + NAME_MAX + 1024];
      AudioCDTrack **track = NULL, *t;


      if(total == NULL)
          return(track);
      else
          *total = 0;

      if(ctx == NULL)
          return(track);

      if((ctx->prog == NULL) || (ctx->device == NULL))
          return(track);


      /* format audio CD tracks command. */
      sprintf(
          cmd,
          "%s -c \"%s\" -n table",
          ctx->prog, ctx->device
      );

      /* Get tempory file path. */
      path = tempnam(NULL, "stdo");
      if(path == NULL)
          return(track);

      /* Execute command. */
      p = ExecBO(cmd, path);
      if(p > 0)
      {
          /* Command executed successfully. */
          int i, line_num = 0;
          char *buf = NULL;
          FILE *fp = FOpen(path, "rb");

          /* Begin reading all lines from tempory output file. */
          while(1)
          {
            /* Deallocate previous line and read next line. */
            free(buf);
            buf = FGetStringLiteral(fp);
            if(buf == NULL)
                break;

            /* Skip header (first 4 lines). */
            if(line_num > 4)
            {
                int hours, minutes, seconds;
                const char *s = buf;

                /* Seek s to first argument. */
                while(ISBLANK(*s))
                  s++;
                /* Skip '*' character infront of current track. */
                if(*s == '*')
                {
                  s++;
                  while(ISBLANK(*s))
                      s++;
                }

                /* Allocate a new track structure. */
                i = *total;
                *total = i + 1;
                track = (AudioCDTrack **)realloc(
                  track, (*total) * sizeof(AudioCDTrack *)
                );
                if(track == NULL)
                {
                  *total = 0;
                  continue;
                }
                track[i] = t = (AudioCDTrack *)calloc(
                  1, sizeof(AudioCDTrack)
                );
                if(t == NULL)
                  continue;

                /* Begin parsing line. */

                /* Track number. */
                t->number = MAX(atoi(s), 1);
                /* Seek s to next argument. */
                while(!ISBLANK(*s) && (*s != '\0'))
                  s++;
                while(ISBLANK(*s))
                  s++;

                /* Track start. */
                hours = atoi(s);
                while((*s != ':') && (*s != '\0'))
                  s++;
                if(*s == ':')
                  s++;
                minutes = atoi(s);
                while((*s != ':') && (*s != '\0'))
                  s++;
                if(*s == ':')
                  s++;
                seconds = atoi(s);
                t->start_time = (hours * 3600) + (minutes * 60) + seconds;
                /* Seek s to next argument. */
                while(!ISBLANK(*s) && (*s != '\0'))
                  s++;
                while(ISBLANK(*s))
                  s++;

                /* Track length. */
                minutes = atoi(s);
                while((*s != ':') && (*s != '\0'))
                  s++;
                if(*s == ':')
                  s++;
                seconds = atoi(s);
                t->length = (minutes * 60) + seconds;
                /* Seek s to next argument. */
                while(!ISBLANK(*s) && (*s != '\0'))
                  s++;
                while(ISBLANK(*s))
                  s++;

                /* Name (last argument). */
                t->name = strdup(s);
            }

            line_num++;
          }

          /* Close tempory output file. */
          FClose(fp);
      }

      /* Delete tempory file path. */
      if(path != NULL)
      {
          unlink(path);
          free(path);
          path = NULL;
      }

      return(track);
}

/*
 *    Deletes the list of audio CD track list.
 */
void AudioCDDeleteTracksList(AudioCDTrack **track, int total)
{
      int i;
      AudioCDTrack *t;

      for(i = 0; i < total; i++)
      {
          t = track[i];
          if(t == NULL)
            continue;

          free(t->name);
          free(t);
      }
      free(track);
}


/*
 *    Returns the track number that was last played or 0 if stop
 *    or eject was called.
 */
int AudioCDLastTrack(AudioCDContext *ctx)
{
      return((ctx != NULL) ? ctx->current_track_number : 0);
}


/*
 *    Plays the track specified by track_number.
 */
void AudioCDPlayTrack(AudioCDContext *ctx, int track_number)
{
      pid_t p;
      char cmd[PATH_MAX + NAME_MAX + 1024];


      if((ctx == NULL) || (track_number < 1))
          return;

      if((ctx->prog == NULL) || (ctx->device == NULL))
          return;

      /* format audio CD tracks command. */
      sprintf(
          cmd,
          "%s -c \"%s\" play %i",
          ctx->prog, ctx->device, track_number
      );

      /* Execute command. */
      p = Exec(cmd);
      if(p > 0)
          ctx->current_track_number = track_number;
}

/*
 *    Stop playing.
 */
void AudioCDStop(AudioCDContext *ctx)
{
      pid_t p;
      char cmd[PATH_MAX + NAME_MAX + 1024];


      if(ctx == NULL)
          return;

      if((ctx->prog == NULL) || (ctx->device == NULL))
          return;

      /* format audio CD tracks command. */
      sprintf(
          cmd,
          "%s -c \"%s\" -n stop",
          ctx->prog, ctx->device
      );

      /* Execute command. */
      p = Exec(cmd);
      if(p > 0)
          ctx->current_track_number = 0;
}

/*
 *    Ejects audio CD from the device.
 */
void AudioCDEject(AudioCDContext *ctx)
{
      pid_t p;
      char cmd[PATH_MAX + NAME_MAX + 1024];


      if(ctx == NULL)
          return;

      if((ctx->prog == NULL) || (ctx->device == NULL))
          return;

      /* format audio CD tracks command. */
      sprintf(
          cmd,
          "/usr/bin/eject -r \"%s\"",
          ctx->device
      );

      /* Execute command. */
      p = Exec(cmd);
      if(p > 0)
          ctx->current_track_number = 0;
}


Generated by  Doxygen 1.6.0   Back to index