[comp.sources.sun] v02i008: Sound2sun - Mac to SS1 sound file converter

mcgrew@dartagnan.rutgers.edu (Charles Mcgrew) (01/17/90)

Submitted-by: gopstein@soleil.uucp (Rich Gopstein)
Posting-number: Volume 2, Issue 8
Archive-name: sound2sun



This program will convert an audio file in Macintosh format to SS1 uLAW format.
The Mac format that this supports is one-byte-per-sample; each sample is
stored in excess-128 (128 is added to the sample value before storing).
It also knows how to convert to a sample speed of 8000 samples per second,
which is what the SS1 uses (contrary to what the man page says).

This program should be easily adaptable to convert just about any format
to uLAW.  

To build:  save the source as sound2sun.c, and "cc -o sound2sun sound2sun.c"
Usage is:  sound2sun [-f frequency] infile outfile

Where frequency is the rate (in samples per second) of infile -- the
default is 11000.

Rich Gopstein
..!rutgers!soleil!gopstein

[ If anyone converts anything they'd like to share, I'll maintain a
	.au file collection here in the comp.sources.sun archives.
	Just mail me - mcgrew@aramis.rutgers.edu; rutgers!mcgrew -
	(uuencoded) .au files!		-CWM]


---------------------------------- Cut Here --------------------------------

/************************************************************************/
/*      Copyright 1989 by Rich Gopstein and Harris Corporation          */
/*                                                                      */
/*      Permission to use, copy, modify, and distribute this software   */
/*      and its documentation for any purpose and without fee is        */
/*      hereby granted, provided that the above copyright notice        */
/*      appears in all copies and that both that copyright notice and   */
/*      this permission notice appear in supporting documentation, and  */
/*      that the name of Rich Gopstein and Harris Corporation not be    */
/*      used in advertising or publicity pertaining to distribution     */
/*      of the software without specific, written prior permission.     */
/*      Rich Gopstein and Harris Corporation make no representations    */
/*      about the suitability of this software for any purpose.  It     */
/*      provided "as is" without express or implied warranty.           */
/************************************************************************/

/************************************************************************/
/* sound2sun.c - Convert sampled audio files into uLAW format for the   */
/*               Sparcstation 1.                                        */
/*               Send comments to ..!rutgers!soleil!gopstein            */
/************************************************************************/
/*									*/
/*  Modified November 27, 1989 to convert to 8000 samples/sec           */
/*   (contrary to man page)                                             */
/*									*/
/*  Fixed Bug with converting slow sample speeds			*/
/*									*/
/************************************************************************/


#include <stdio.h>

#define DEFAULT_FREQUENCY 11000

FILE *infile, *outfile;

/* convert two's complement ch into uLAW format */

unsigned int cvt(ch)
int ch;
{

  int mask;

  if (ch < 0) {
    ch = -ch;
    mask = 0x7f;
  } else {
    mask = 0xff;
  }

  if (ch < 32) {
    ch = 0xF0 | 15 - (ch / 2);
  } else if (ch < 96) {
    ch = 0xE0 | 15 - (ch - 32) / 4;
  } else if (ch < 224) {
    ch = 0xD0 | 15 - (ch - 96) / 8;
  } else if (ch < 480) {
    ch = 0xC0 | 15 - (ch - 224) / 16;
  } else if (ch < 992) {
    ch = 0xB0 | 15 - (ch - 480) / 32;
  } else if (ch < 2016) {
    ch = 0xA0 | 15 - (ch - 992) / 64;
  } else if (ch < 4064) {
    ch = 0x90 | 15 - (ch - 2016) / 128;
  } else if (ch < 8160) {
    ch = 0x80 | 15 - (ch - 4064) /  256;
  } else {
    ch = 0x80;
  }
return (mask & ch);
}
      
/*******************************************************
/*                                                     */
/* Usage is "sound2sun [-f frequency] infile outfile"  */
/*                                                     */
/* "frequency" is the samples per second of the infile */
/* the outfile is always 8000 samples per second.      */
/*                                                     */
/*******************************************************/

/***********************************************************************/
/*                                                                     */
/* The input file is expected to be a stream of one-byte excess-128    */
/* samples.  Each sample is converted to 2's complement by subtracting */
/* 128, then converted to uLAW and output.  We calculate the proper    */
/* number of input bytes to skip in order to make the sample frequency */
/* convert to 8000/sec properly.  Interpolation could be added, but it */
/* doesn't appear to be necessary.                                     */
/*                                                                     */
/***********************************************************************/


main(argc, argv)
int argc;
char *argv[];
{

  float sum = 0;
  float frequency, increment;

  unsigned char ch;
  unsigned char ulaw;

  int chr;

  if ((argc != 3) && (argc != 5)) {
    fprintf(stderr,"Usage: sound2sun [-f frequency] infile outfile\n");
    exit(1);
  }

  if (argc == 5) {
    if (strcmp(argv[1], "-f") != 0) {
      fprintf(stderr, "Usage: sound2sun [-f frequency] infile outfile\n");
      exit(1);
    } else {
      frequency = atoi(argv[2]);
    }
  } else {
    frequency = DEFAULT_FREQUENCY;
  }

  if ((infile = fopen(argv[argc-2], "r")) == NULL) {
    perror("Error opening infile");
    exit(0);
  }

  if ((outfile = fopen(argv[argc-1], "w")) == NULL) {
    perror("Error opening outfile");
    exit(0);
  }

  /* increment is the number of bytes to read each time */

  increment = frequency / 8000;

  ch = fgetc(infile);

  while (!feof(infile)) {

    /* convert the excess 128 to two's complement */

    chr = 0x80 - ch;

    /* increase the volume */
    /* convert to uLAW */

    ulaw = cvt(chr * 16);

    /* output it */

    fputc((char) ulaw, outfile);

    /* skip enough input bytes to compensate for sampling frequency diff */

    sum += increment;

    while(sum > 0) {
      if (!feof(infile)) ch = fgetc(infile);
      sum--;
    }

  }

  fclose(infile);
  fclose(outfile);
}
---------------------------------- Cut Here --------------------------------
-- 
Rich Gopstein

..!rutgers!soleil!gopstein