[comp.music] IRCAM header doc

xjam@cork.berkeley.edu (The Crossjammer) (03/27/91)

A while ago, I asked the net for documentation on IRCAM header files. I got
a few replies, and they all were pretty much reduced to the man pages. A
couple of people asked that I post the results, so here they are. Nothing
impressive at all, just the man page from CMIX essentially. If anyone has
anything more deep and meaningful I'm still all ears.

-------------------------cut here------------------------------

SFHEADER(5) IRCAM Soundfile System SFHEADER(5)

NAME     
 sfheader.h -include file for soundfile programs

SYNOPSIS     
 # include "/musr/H/sfheader.h"

DESCRIPTION     
 sfheader.h contains definitions of constants and macros used by programs that read from or write to
 soundfiles.
 sfheader.h contains the definition of the soundfile header data structure, (typedef SFHEADER), so it
 must be #included in any program which opens soundfiles.

 A soundfile has two parts; a header (typedef SFHEADER), which is always the first 1024 bytes, and the
 rest of the file, the sound samples.

 The header contains information needed by programs that operate on soundfiles. These programs can
 get header information via the macros defined in sfheader.h.

 A soundfile header has two parts. The first four items are fixed: the magic number, the sample rate,
 number of channels, and number of bytes per sample. The last item in a soundfile's header, sf_codes,
 is used to point to any further information which has been added to the header. It is sometimes useful
 to insert further coded information, such as maximum amplitude per channel, into the header. This is
 accomplished by getsfcode() and putsfcode() (see man sfcodes).

 Sflseek() is used to reset the pointer for random access to an open soundfile's samples.

 Rheader() and wheader() return 1 if they fail to read or write a full 1024 bytes.

 Readopensf() is a macro for opening soundfiles for reading. It replaces 17 lines of code with one, mak-
 ing for more readable programs.

 Wropensf() opens a soundfile for writing. If a soundfile with the same name already existed, it will be
 written over. If no such soundfile existed, wropensf() will create one.

 Rdwropensf() opens a soundfile for reading and writing. This is useful for programs that add items to
 the header, or which will write (possibly altered) samples back into their original locations.

 The section from here to the end is the current version of "sfheader.h".

  /\(**
   \(** DEFINITION OF CONSTANTS
   \(**/

 # define SIZEOF_HEADER 1024  /\(** First 1k reserved for header info \(**/
 # define SF_MAGIC 107364   /\(** Code indicating "IS_SOUNDFILE" \(**/ 
 # define SF_SHORT sizeof(short)  /\(** 2 bytes on VAX \(**/
 # define SF_FLOAT sizeof(float)  /\(** 4 bytes on VAX \(**/
 # define SF_BUFSIZE (16\(**1024) /\(** Block size for soundfile reads \(**/ 
 # define SF_MAXCHAN 4  /\(** Max nr chans for playable file \(**/
 # define SFDIR "SFDIR"  /\(** Name of env variable for getsfname() \(**/

  /\(** 
   \(** DEFINITION OF SFHEADER FORMAT
   \(**/

 typedef union sfheader {  
  struct {  
   int  sf_magic;  /\(** Defined above. \(**/
   float  sf_srate;  /\(** Sample rate \(**/ 
   int  sf_chans;  /\(** Number of channels \(**/

1st Edition Last change: IRCAM 1


SFHEADER(5) IRCAM Soundfile System SFHEADER(5)

   int  sf_packmode; /\(** packmodes: SF_SHORT or SF_FLOAT \(**/ 
   char  sf_codes;  /\(** see sfcodes (below) \(**/ 
  } sfinfo;   
  char filler[SIZEOF_HEADER]; /\(** Remaining part of 1k header empty \(**/
 } SFHEADER;

  /\(**
    \(** DEFINITION OF MACROS TO GET HEADER INFO
   \(** x is a pointer to SFHEADER 
   \(**/ 

 # define ismagic(x) ((x)->sfinfo.sf_magic == SF_MAGIC)
 # define sfchans(x) (x)->sfinfo.sf_chans
 # define sfmagic(x) (x)->sfinfo.sf_magic
 # define sfsrate(x) (x)->sfinfo.sf_srate
 # define sfclass(x) (x)->sfinfo.sf_packmode
 # define sfcodes(x) (x)->sfinfo.sf_codes  

  /\(**
   \(** sfbsize() returns the size in bytes of 
   \(** the "sound" portion of a soundfile. 
   \(** sfst is the address of a stat struct. 
   \(** To use sfbsize() you also need (in this order!):
   \(** # include <sys/types.h>
   \(**  # include <sys/stat.h>
   \(**  See the man page for stat
   \(**/

 # define sfbsize(sfst) ((sfst)->st_size - sizeof(SFHEADER))

  /\(**
   \(** DEFINITION OF SFCODE AND RELATED DATA STRUCTS
   \(**
   \(** Two routines in libsf/sfcodes.c, getsfcode() and putsfcode(), 
   \(** are used to insert additional information into a header 
   \(** or to retreive such information. See man sfcodes.
   \(**/

 # define SF_END 0   /\(** Code meaning "no more information" \(**/
 # define SF_MAXAMP 1  /\(** Code meaning "maxamp follows" \(**/ 
 # define SF_COMMENT 2  /\(** Code for "comment line" \(**/
     
 typedef struct sfcode { 
  short code;  /\(** Code for what information follows \(**/ 
  short bsize;  /\(** Total nr bytes of added information \(**/
 } SFCODE;   

 typedef struct sfmaxamp {  
  float value[SF_MAXCHAN]; /\(** peak amp per channel \(**/
  long samploc[SF_MAXCHAN]; /\(** location of maxamp sample \(**/
  long timetag;   /\(** date maxamp was updated \(**/
 } SFMAXAMP;     


1st Edition Last change: IRCAM 2


SFHEADER(5) IRCAM Soundfile System SFHEADER(5)

  /\(**
    \(** DEFINITION OF MACROS FOR GETTING MAXAMP INFO    
   \(**
   \(** sfm is ptr to SFMAXAMP
   \(** sfst is the address of a stat struct 
   \(**/

 # define sfmaxamp(sfm,chan) (sfm)->value[chan]
 # define sfmaxamploc(sfm,chan) (sfm)->samploc[chan]
 # define sfmaxamptime(sfm) (sfm)->timetag
 # define ismaxampgood(sfm,sfst) (sfmaxamptime(sfm) + 2 >= (sfst)->st_mtime)

  /\(**
   \(** DEFINITION OF MACROS FOR SOUNDFILE PROGRAMS
   \(**
   \(** sflseek() is used to reset the pointer for reads and writes:
    \(** x is the file descriptor
   \(** y is the offset in bytes
   \(** z is the starting location for the file pointer as in lseek
   \(**/

 # define sflseek(x,y,z) lseek(x,z != 0 ? y : (y) + sizeof(SFHEADER),z)

  /\(**
   \(** rheader() and wheader() read/write a header from/to a soundfile
   \(** If a header read or write fails, they return 1 
   \(** x is file descriptor 
   \(** y is the address of (pointer to) an SFHEADER struct
   \(**/

 # define rheader(x,y) read(x,y,sizeof(SFHEADER)) != sizeof(SFHEADER)
 # define wheader(x,y) write(x,y,sizeof(SFHEADER)) != sizeof(SFHEADER)

  /\(**
   \(** DEFINITION OF MACROS FOR OPENING SOUNDFILES 
   \(**
   \(** readopensf() opens a soundfile for reading only. It replaces
   \(** 17 lines of code with just one, resulting in more readable 
   \(** and concise code, and provides a consistent method 
   \(** for opening soundfiles. 
   \(**
   \(** char \(**name;   -name is a soundfile name
   \(** int fd;  -fd is file descriptor obtained from open() 
   \(** SFHEADER sfh; -sfh is an SFHEADER struct
   \(** struct stat sfst; -sfst is a stat struct
   \(** int result;  -result is returned to calling program
   \(** prog is the name of the program calling readopensf, usually in
   \(** quotes.
   \(**/

 #define readopensf(name,fd,sfh,sfst,prog,result) \
 if ((fd = open(name, 0)) < 0) { \
  fprintf(stderr,"%s: cannot access file %s0,prog,name); \

1st Edition Last change: IRCAM 3


SFHEADER(5) IRCAM Soundfile System SFHEADER(5)

  result = -1; \
 } \
 else if (rheader(fd,&sfh)){ \
  fprintf(stderr,"%s: cannot read header from %s0,prog,name); \
  result = -1; \
 } \
 else if (!ismagic(&sfh)){ \
  fprintf(stderr,"%s: %s not a soundfile0,prog,name); \
  result = -1; \
 } \
 else if (stat(name,&sfst)){ \
  fprintf(stderr,"%s: cannot get status on %s0,prog,name); \
  result = -1; \
 } \
 else result = 0;

  /\(**
   \(** wropensf() opens a new soundfile for writing into.
   \(** If the file already exists, it will be written over.
   \(**/

 #define wropensf(name,sfd,sfh,prog,result) \
 if((sfd=open(name,O_WRONLY|O_CREAT|O_TRUNC,0644)) < 0){ \
  fprintf(stderr,"%s: cannot open %s0,prog,name); \
  result = -1; \
 } \
 else if(wheader(sfd,&sfh)){ \
  fprintf(stderr,"%s: cannot write header on %s0, \
    prog,name); \
  close(sfd); \
  result = -1; \
 } \
 else result = 0;

  /\(** macro for opening soundfile for reading and writing \(**/

 #define rdwropensf(name,fd,sfh,sfst,prog,result) \
 if ((fd = open(name, O_RDWR)) < 0) { \
  fprintf(stderr,"%s: cannot access file %s0,prog,name); \
  result = -1; \
 } \
 else if (rheader(fd,&sfh)){ \
  fprintf(stderr,"%s: cannot read header from %s0,prog,name); \
  result = -1; \
 } \
 else if (!ismagic(&sfh)){ \
  fprintf(stderr,"%s: %s not a soundfile0,prog,name); \
  result = -1; \
 } \
 else if (stat(name,&sfst)){ \
  fprintf(stderr,"%s: cannot get status on %s0,prog,name); \
  result = -1; \
 } \

1st Edition Last change: IRCAM 4


SFHEADER(5) IRCAM Soundfile System SFHEADER(5)

 else result = 0;
 extern char \(**getsfname();
 extern SFMAXAMP \(**getsfmaxamp();
 extern SFCODE \(**getsfcode();




1st Edition Last change: IRCAM 5

------------------------------end cut---------------------------

--
They can't come on and play me in prime time, 	|Crossjammer ...... OUT!
Cause I know the time, cause I'm gettin' mine.	|xjam@yew.berkeley.edu
I get on the mix late in the night...	<-------------------PUBLIC ENEMY