SFHEADER

Section: IRCAM Soundfile System (5)
Updated: IRCAM
Index Return to Main Contents
 

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, making 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 */
                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;                             

        /*
         * 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 %s,prog,name); \
        result = -1;  \
} \
else if (rheader(fd,&sfh)){ \
        fprintf(stderr,"%s: cannot read header from %s,prog,name); \
        result = -1;  \
} \
else if (!ismagic(&sfh)){ \
        fprintf(stderr,"%s: %s not a soundfile,prog,name); \
        result = -1;  \
} \
else if (stat(name,&sfst)){ \
        fprintf(stderr,"%s: cannot get status on %s,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 %s,prog,name);  \
        result = -1;  \
}  \
else if(wheader(sfd,&sfh)){  \
        fprintf(stderr,"%s: cannot write header on %s,  \
                        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 %s,prog,name); \
        result = -1;  \
} \
else if (rheader(fd,&sfh)){ \
        fprintf(stderr,"%s: cannot read header from %s,prog,name); \
        result = -1;  \
} \
else if (!ismagic(&sfh)){ \
        fprintf(stderr,"%s: %s not a soundfile,prog,name); \
        result = -1;  \
} \
else if (stat(name,&sfst)){ \
        fprintf(stderr,"%s: cannot get status on %s,prog,name); \
        result = -1;  \
} \
else result = 0;
extern  char    *getsfname();
extern  SFMAXAMP *getsfmaxamp();
extern  SFCODE  *getsfcode();




 

Index

NAME
SYNOPSIS
DESCRIPTION

This document was created by man2html, using the manual pages.
Time: 00:08:36 GMT, November 05, 2022