Blame example/paranoia.c

Packit cb6d3d
/*
Packit cb6d3d
  Copyright (C) 2005, 2006, 2008, 2009, 2010, 2011, 2012
Packit cb6d3d
   Rocky Bernstein <rocky@gnu.org>
Packit cb6d3d
Packit cb6d3d
  This program is free software: you can redistribute it and/or modify
Packit cb6d3d
  it under the terms of the GNU General Public License as published by
Packit cb6d3d
  the Free Software Foundation, either version 3 of the License, or
Packit cb6d3d
  (at your option) any later version.
Packit cb6d3d
Packit cb6d3d
  This program is distributed in the hope that it will be useful,
Packit cb6d3d
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit cb6d3d
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit cb6d3d
  GNU General Public License for more details.
Packit cb6d3d
Packit cb6d3d
  You should have received a copy of the GNU General Public License
Packit cb6d3d
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit cb6d3d
*/
Packit cb6d3d
Packit cb6d3d
/* Simple program to show using libcdio's version of the CD-DA paranoia.
Packit cb6d3d
   library. */
Packit cb6d3d
Packit cb6d3d
/* config.h has to come first else _FILE_OFFSET_BITS are redefined in
Packit cb6d3d
   say opensolaris. */
Packit cb6d3d
#ifdef HAVE_CONFIG_H
Packit cb6d3d
# include "config.h"
Packit cb6d3d
# define __CDIO_CONFIG_H__ 1
Packit cb6d3d
#endif
Packit cb6d3d
Packit cb6d3d
#ifdef HAVE_ASSERT_H
Packit cb6d3d
# include <assert.h>
Packit cb6d3d
#endif
Packit cb6d3d
#ifdef HAVE_STDIO_H
Packit cb6d3d
# include <stdio.h>
Packit cb6d3d
#endif
Packit cb6d3d
#ifdef HAVE_STDLIB_H
Packit cb6d3d
# include <stdlib.h>
Packit cb6d3d
#endif
Packit cb6d3d
#ifdef HAVE_UNISTD_H
Packit cb6d3d
# include <unistd.h>
Packit cb6d3d
#endif
Packit cb6d3d
# ifdef HAVE_SYS_TYPES_H
Packit cb6d3d
# include <sys/types.h>
Packit cb6d3d
#endif
Packit cb6d3d
#ifdef HAVE_SYS_STAT_H
Packit cb6d3d
# include <sys/stat.h>
Packit cb6d3d
#endif
Packit cb6d3d
#include <fcntl.h>
Packit cb6d3d
Packit cb6d3d
#include <cdio/paranoia/paranoia.h>
Packit cb6d3d
#include <cdio/cd_types.h>
Packit cb6d3d
Packit cb6d3d
static void
Packit cb6d3d
put_num(long int num, int f, int bytes)
Packit cb6d3d
{
Packit cb6d3d
  unsigned int i;
Packit cb6d3d
  unsigned char c;
Packit cb6d3d
Packit cb6d3d
  for (i=0; bytes--; i++) {
Packit cb6d3d
    c = (num >> (i<<3)) & 0xff;
Packit cb6d3d
    if (write(f, &c, 1)==-1) {
Packit cb6d3d
      perror("Could not write to output.");
Packit cb6d3d
      exit(1);
Packit cb6d3d
    }
Packit cb6d3d
  }
Packit cb6d3d
}
Packit cb6d3d
Packit cb6d3d
#define writestr(fd, s) \
Packit cb6d3d
  write(fd, s, sizeof(s)-1)  /* Subtract 1 for trailing '\0'. */
Packit cb6d3d
Packit cb6d3d
/* Write a the header for a WAV file. */
Packit cb6d3d
static void
Packit cb6d3d
write_WAV_header(int fd, int32_t i_bytecount){
Packit cb6d3d
  ssize_t bytes_ret __attribute__((unused));
Packit cb6d3d
  /* quick and dirty */
Packit cb6d3d
  bytes_ret = writestr(fd, "RIFF");     /*  0-3 */
Packit cb6d3d
  assert(bytes_ret > 0);
Packit cb6d3d
  put_num(i_bytecount+44-8, fd, 4);     /*  4-7 */
Packit cb6d3d
  bytes_ret = writestr(fd, "WAVEfmt "); /*  8-15 */
Packit cb6d3d
  assert(bytes_ret > 0);
Packit cb6d3d
  put_num(16, fd, 4);                   /* 16-19 */
Packit cb6d3d
  put_num(1, fd, 2);                    /* 20-21 */
Packit cb6d3d
  put_num(2, fd, 2);                    /* 22-23 */
Packit cb6d3d
  put_num(44100, fd, 4);                /* 24-27 */
Packit cb6d3d
  put_num(44100*2*2, fd, 4);            /* 28-31 */
Packit cb6d3d
  put_num(4, fd, 2);                    /* 32-33 */
Packit cb6d3d
  put_num(16, fd, 2);                   /* 34-35 */
Packit cb6d3d
  bytes_ret = writestr(fd, "data");     /* 36-39 */
Packit cb6d3d
  assert(bytes_ret > 0);
Packit cb6d3d
  put_num(i_bytecount, fd, 4);          /* 40-43 */
Packit cb6d3d
}
Packit cb6d3d
Packit cb6d3d
int
Packit cb6d3d
main(int argc, const char *argv[])
Packit cb6d3d
{
Packit cb6d3d
  cdrom_drive_t *d = NULL; /* Place to store handle given by cd-paranoia. */
Packit cb6d3d
  char **ppsz_cd_drives;  /* List of all drives with a loaded CDDA in it. */
Packit cb6d3d
Packit cb6d3d
  /* See if we can find a device with a loaded CD-DA in it. */
Packit cb6d3d
  ppsz_cd_drives = cdio_get_devices_with_cap(NULL, CDIO_FS_AUDIO, false);
Packit cb6d3d
Packit cb6d3d
  if (ppsz_cd_drives && *ppsz_cd_drives) {
Packit cb6d3d
    /* Found such a CD-ROM with a CD-DA loaded. Use the first drive in
Packit cb6d3d
       the list. */
Packit cb6d3d
    d=cdda_identify(*ppsz_cd_drives, 1, NULL);
Packit cb6d3d
  } else {
Packit cb6d3d
    printf("Unable find or access a CD-ROM drive with an audio CD in it.\n");
Packit cb6d3d
    exit(77);
Packit cb6d3d
  }
Packit cb6d3d
Packit cb6d3d
  /* Don't need a list of CD's with CD-DA's any more. */
Packit cb6d3d
  cdio_free_device_list(ppsz_cd_drives);
Packit cb6d3d
Packit cb6d3d
  if ( !d ) {
Packit cb6d3d
    printf("Unable to identify audio CD disc.\n");
Packit cb6d3d
    exit(77);
Packit cb6d3d
  }
Packit cb6d3d
Packit cb6d3d
  /* We'll set for verbose paranoia messages. */
Packit cb6d3d
  cdda_verbose_set(d, CDDA_MESSAGE_PRINTIT, CDDA_MESSAGE_PRINTIT);
Packit cb6d3d
Packit cb6d3d
  if ( 0 != cdda_open(d) ) {
Packit cb6d3d
    printf("Unable to open disc.\n");
Packit cb6d3d
    exit(77);
Packit cb6d3d
  }
Packit cb6d3d
Packit cb6d3d
  /* Okay now set up to read up to the first 300 frames of the first
Packit cb6d3d
     audio track of the Audio CD. */
Packit cb6d3d
  {
Packit cb6d3d
    cdrom_paranoia_t *p = paranoia_init(d);
Packit cb6d3d
    lsn_t i_first_lsn = cdda_disc_firstsector(d);
Packit cb6d3d
Packit cb6d3d
    if ( -1 == i_first_lsn ) {
Packit cb6d3d
      printf("Trouble getting starting LSN\n");
Packit cb6d3d
    } else {
Packit cb6d3d
      lsn_t   i_cursor;
Packit cb6d3d
      ssize_t bytes_ret;
Packit cb6d3d
      track_t i_track    = cdda_sector_gettrack(d, i_first_lsn);
Packit cb6d3d
      lsn_t   i_last_lsn = cdda_track_lastsector(d, i_track);
Packit cb6d3d
      int     fd         = creat("track1s.wav", 0644);
Packit cb6d3d
      if (-1 == fd) {
Packit cb6d3d
        printf("Unable to create track1s.wav\n");
Packit cb6d3d
        exit(1);
Packit cb6d3d
      }
Packit cb6d3d
Packit cb6d3d
      /* For demo purposes we'll read only 300 frames (about 4
Packit cb6d3d
	 seconds).  We don't want this to take too long. On the other
Packit cb6d3d
	 hand, I suppose it should be something close to a real test.
Packit cb6d3d
       */
Packit cb6d3d
      if ( i_last_lsn - i_first_lsn > 300) i_last_lsn = i_first_lsn + 299;
Packit cb6d3d
Packit cb6d3d
      printf("Reading track %d from LSN %ld to LSN %ld\n", i_track,
Packit cb6d3d
	     (long int) i_first_lsn, (long int) i_last_lsn);
Packit cb6d3d
Packit cb6d3d
      /* Set reading mode for full paranoia, but allow skipping sectors. */
Packit cb6d3d
      paranoia_modeset(p, PARANOIA_MODE_FULL^PARANOIA_MODE_NEVERSKIP);
Packit cb6d3d
      paranoia_seek(p, i_first_lsn, SEEK_SET);
Packit cb6d3d
      write_WAV_header(fd, (i_last_lsn-i_first_lsn+1) * CDIO_CD_FRAMESIZE_RAW);
Packit cb6d3d
Packit cb6d3d
      for ( i_cursor = i_first_lsn; i_cursor <= i_last_lsn; i_cursor ++) {
Packit cb6d3d
	/* read a sector */
Packit cb6d3d
	int16_t *p_readbuf=paranoia_read(p, NULL);
Packit cb6d3d
	char *psz_err=cdda_errors(d);
Packit cb6d3d
	char *psz_mes=cdda_messages(d);
Packit cb6d3d
Packit cb6d3d
	if (psz_mes || psz_err)
Packit cb6d3d
	  printf("%s%s\n", psz_mes ? psz_mes: "", psz_err ? psz_err: "");
Packit cb6d3d
Packit cb6d3d
	free(psz_err);
Packit cb6d3d
	free(psz_mes);
Packit cb6d3d
	if( !p_readbuf ) {
Packit cb6d3d
	  printf("paranoia read error. Stopping.\n");
Packit cb6d3d
	  break;
Packit cb6d3d
	}
Packit cb6d3d
	bytes_ret = write(fd, p_readbuf, CDIO_CD_FRAMESIZE_RAW);
Packit cb6d3d
	assert(bytes_ret > 0);
Packit cb6d3d
      }
Packit cb6d3d
      close(fd);
Packit cb6d3d
    }
Packit cb6d3d
    paranoia_free(p);
Packit cb6d3d
  }
Packit cb6d3d
Packit cb6d3d
  cdda_close(d);
Packit cb6d3d
Packit cb6d3d
  exit(0);
Packit cb6d3d
}