home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 3
/
AACD03.BIN
/
AACD
/
Sound
/
SoX
/
Source
/
sf.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-07-18
|
6KB
|
223 lines
/*
* July 5, 1991
* Copyright 1991 Lance Norskog And Sundry Contributors
* This source code is freely redistributable and may be used for
* any purpose. This copyright notice must be maintained.
* Lance Norskog And Sundry Contributors are not responsible for
* the consequences of using this software.
*/
/*
* Sound Tools IRCAM SoundFile format handler.
*
* Derived from: Sound Tools skeleton handler file.
*/
#define IRCAM
#include "st.h"
#ifdef IRCAM
#include "sfircam.h"
#ifndef SIZEOF_BSD_HEADER
#define SIZEOF_BSD_HEADER 1024
#endif
#else
#include "sfheader.h"
#endif
#include <string.h>
#include <stdlib.h>
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
/* Private data for SF file */
typedef struct sfstuff {
struct sfinfo info;
} *sf_t;
/*
* Read the codes from the sound file, allocate space for the comment and
* assign its pointer to the comment field in ft.
*/
void readcodes(ft, sfhead)
ft_t ft;
SFHEADER *sfhead;
{
char *commentbuf = NULL, *sfcharp, *newline;
short bsize, finished = 0;
SFCODE *sfcodep;
sfcodep = (SFCODE *) &sfcodes(sfhead);
do {
sfcharp = (char *) sfcodep + sizeof(SFCODE);
if (ft->swap) {
sfcodep->bsize = swapl(sfcodep->bsize);
sfcodep->code = swapl(sfcodep->code);
}
bsize = sfcodep->bsize - sizeof(SFCODE);
switch(sfcodep->code) {
case SF_END:
finished = 1;
break;
case SF_COMMENT:
if((commentbuf = (char *) malloc(bsize + 1)) != NULL) {
memcpy(commentbuf, sfcharp, bsize);
report("IRCAM comment: %s", sfcharp);
commentbuf[bsize] = '\0';
if((newline = strchr(commentbuf, '\n')) != NULL)
*newline = '\0';
}
break;
}
sfcodep = (SFCODE *) (sfcharp + bsize);
} while(!finished);
if(commentbuf != NULL) /* handles out of memory condition as well */
ft->comment = commentbuf;
}
/*
* Do anything required before you start reading samples.
* Read file header.
* Find out sampling rate,
* size and style of samples,
* mono/stereo/quad.
*/
void sfstartread(ft)
ft_t ft;
{
sf_t sf = (sf_t) ft->priv;
SFHEADER sfhead;
/* Needed for rawread() */
rawstartread(ft);
if (fread(&sfhead, 1, sizeof(SFHEADER), ft->fp) != sizeof(SFHEADER))
fail("unexpected EOF in SF header");
memcpy(&sf->info, &sfhead.sfinfo, sizeof(struct sfinfo));
if (ft->swap) {
#ifdef IRCAM
sf->info.sf_srate = swapf(sf->info.sf_srate);
#else
sf->info.sf_magic = swapl(sf->info.sf_magic);
sf->info.sf_srate = swapl(sf->info.sf_srate);
#endif
sf->info.sf_packmode = swapl(sf->info.sf_packmode);
sf->info.sf_chans = swapl(sf->info.sf_chans);
}
#ifdef IRCAM
if ((sfmagic1(&sfhead) != SF_MAGIC1) ||
(sfmagic2(&sfhead) != SF_MAGIC2))
fail(
"SF %s file: can't read, it is byte-swapped or it is not an IRCAM SoundFile",
ft->filename);
#else
if (sf->info.sf_magic != SF_MAGIC)
if (sf->info.sf_magic == swapl(SF_MAGIC))
fail("SF %s file: can't read, it is probably byte-swapped");
else
fail("SF %s file: can't read, it is not an IRCAM SoundFile");
#endif
/*
* If your format specifies or your file header contains
* any of the following information.
*/
ft->info.rate = sf->info.sf_srate;
switch(sf->info.sf_packmode) {
case SF_SHORT:
ft->info.size = WORD;
ft->info.style = SIGN2;
break;
case SF_FLOAT:
ft->info.size = FLOAT;
ft->info.style = SIGN2;
break;
default:
fail("Soundfile input: unknown format 0x%x\n",
sf->info.sf_packmode);
}
ft->info.channels = (int) sf->info.sf_chans;
/* Read codes and print as comments. */
readcodes(ft, &sfhead);
}
void sfstartwrite(ft)
ft_t ft;
{
sf_t sf = (sf_t) ft->priv;
SFHEADER sfhead;
SFCODE *sfcodep;
char *sfcharp;
int littlendian = 1;
char *endptr;
/* Needed for rawwrite() */
rawstartwrite(ft);
#ifdef IRCAM
sf->info.magic_union._magic_bytes.sf_magic1 = SF_MAGIC1;
sf->info.magic_union._magic_bytes.sf_magic2 = SF_MAGIC2;
sf->info.magic_union._magic_bytes.sf_param = 0;
/* computer musicians can't code worth a damn */
/* you don't see this kind of junk in any other format */
endptr = (char *) &littlendian;
*endptr = 1;
if (littlendian == 1)
sf->info.magic_union._magic_bytes.sf_machine = SF_VAX;
else
sf->info.magic_union._magic_bytes.sf_machine = SF_SUN;
#else
sf->info.sf_magic = SF_MAGIC;
#endif
sf->info.sf_srate = ft->info.rate;
#ifdef LATER
/*
* CSound sound-files have many formats.
* We stick with the IRCAM short-or-float scheme.
*/
if (ft->info.size == WORD) {
sf->info.sf_packmode = SF_SHORT;
ft->info.style = SIGN2; /* Default to signed words */
} else if (ft->info.size == FLOAT)
sf->info.sf_packmode = SF_FLOAT;
else
fail("SoundFile %s: must set output as signed shorts or floats",
ft->filename);
#else
if (ft->info.size == FLOAT) {
sf->info.sf_packmode = SF_FLOAT;
ft->info.size = FLOAT;
} else {
sf->info.sf_packmode = SF_SHORT;
ft->info.size = WORD;
ft->info.style = SIGN2; /* Default to signed words */
}
#endif
sf->info.sf_chans = ft->info.channels;
/* Clean out structure so unused areas will remain constain */
/* between different coverts and not rely on memory contents */
memset (&sfhead, 0, sizeof(SFHEADER));
memcpy(&sfhead.sfinfo, &sf->info, sizeof(struct sfinfo));
sfcodep = (SFCODE *) &sfcodes(&sfhead);
sfcodep->code = SF_COMMENT;
sfcodep->bsize = strlen(ft->comment) + sizeof(SFCODE);
while (sfcodep->bsize % 4)
sfcodep->bsize++;
sfcharp = (char *) sfcodep;
strcpy(sfcharp + sizeof(SFCODE), ft->comment);
sfcodep = (SFCODE *) (sfcharp + sfcodep->bsize);
sfcodep->code = SF_END;
sfcodep->bsize = sizeof(SFCODE);
sfcharp = (char *) sfcodep + sizeof(SFCODE);
while(sfcharp < (char *) &sfhead + SIZEOF_BSD_HEADER)
*sfcharp++ = '\0';
(void) fwrite(&sfhead, 1, sizeof(SFHEADER), ft->fp);
}
/* Read and write are supplied by raw.c */