├── sfubar-9 ├── test-success │ ├── aif.aif │ ├── aif.raw │ ├── raw.raw │ ├── wav.raw │ ├── wav.wav │ ├── test.mid │ ├── test.sf2 │ ├── test1.wav │ ├── test3.sf2 │ ├── wav.txt │ ├── wav.txt.orig │ ├── aif.txt │ ├── test.txt │ ├── test3.txt │ ├── test.txt.orig │ ├── ieee80.tst │ └── aif.txt.orig ├── sfubar.h ├── include │ ├── sfubar.h │ ├── aifutil.h │ ├── wavutil.h │ ├── riffraff │ │ ├── ieee80.h │ │ ├── bio.h │ │ ├── wav.h │ │ ├── bits.h │ │ ├── rifftypes.h │ │ ├── riff.h │ │ └── aif.h │ ├── trap.h │ ├── parsetxt.h │ └── sfutil.h ├── aifutil.h ├── wavutil.h ├── libriffraff-7 │ ├── ieee80.h │ ├── include │ │ ├── riffraff │ │ │ ├── ieee80.h │ │ │ ├── bio.h │ │ │ ├── wav.h │ │ │ ├── bits.h │ │ │ ├── rifftypes.h │ │ │ ├── riff.h │ │ │ └── aif.h │ │ ├── trap.h │ │ └── parsetxt.h │ ├── bio.h │ ├── README │ ├── wav.h │ ├── Makefile │ ├── bits.h │ ├── rifftypes.h │ ├── riff.h │ ├── aif.h │ ├── bio.c │ ├── rifftypes.c │ ├── wav.c │ ├── ieee80.c.orig │ ├── ieee80.c │ ├── riff.c │ └── aif.c ├── trap.h ├── libparsetxt-4 │ ├── include │ │ ├── trap.h │ │ └── parsetxt.h │ ├── Makefile │ ├── parsetxt.h │ ├── README │ └── parsetxt.c ├── trap.c ├── gensine.c ├── main.c ├── Makefile ├── sfutil.h ├── test.sh ├── wavutil.c ├── README └── aifutil.c ├── README.md └── pysf-2 ├── test.py ├── pysf.xsd ├── README.md └── readme.html /sfubar-9/test-success/aif.aif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freepats/old-tools/HEAD/sfubar-9/test-success/aif.aif -------------------------------------------------------------------------------- /sfubar-9/test-success/aif.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freepats/old-tools/HEAD/sfubar-9/test-success/aif.raw -------------------------------------------------------------------------------- /sfubar-9/test-success/raw.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freepats/old-tools/HEAD/sfubar-9/test-success/raw.raw -------------------------------------------------------------------------------- /sfubar-9/test-success/wav.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freepats/old-tools/HEAD/sfubar-9/test-success/wav.raw -------------------------------------------------------------------------------- /sfubar-9/test-success/wav.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freepats/old-tools/HEAD/sfubar-9/test-success/wav.wav -------------------------------------------------------------------------------- /sfubar-9/test-success/test.mid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freepats/old-tools/HEAD/sfubar-9/test-success/test.mid -------------------------------------------------------------------------------- /sfubar-9/test-success/test.sf2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freepats/old-tools/HEAD/sfubar-9/test-success/test.sf2 -------------------------------------------------------------------------------- /sfubar-9/test-success/test1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freepats/old-tools/HEAD/sfubar-9/test-success/test1.wav -------------------------------------------------------------------------------- /sfubar-9/test-success/test3.sf2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freepats/old-tools/HEAD/sfubar-9/test-success/test3.sf2 -------------------------------------------------------------------------------- /sfubar-9/sfubar.h: -------------------------------------------------------------------------------- 1 | #ifndef __SFUBAR_H__ 2 | #define __SFUBAR_H__ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #endif 8 | -------------------------------------------------------------------------------- /sfubar-9/include/sfubar.h: -------------------------------------------------------------------------------- 1 | #ifndef __SFUBAR_H__ 2 | #define __SFUBAR_H__ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #endif 8 | -------------------------------------------------------------------------------- /sfubar-9/aifutil.h: -------------------------------------------------------------------------------- 1 | #ifndef __AIFUTIL_H__ 2 | #define __AIFUTIL_H__ 3 | extern void aif_to_txt(char *, char *, int); 4 | extern void txt_to_aif(char *, char *); 5 | #define AIFUTIL_VERSION 1 6 | #endif 7 | -------------------------------------------------------------------------------- /sfubar-9/wavutil.h: -------------------------------------------------------------------------------- 1 | #ifndef __WAVUTIL_H__ 2 | #define __WAVUTIL_H__ 3 | extern void wav_to_txt(char *, char *, int); 4 | extern void txt_to_wav(char *, char *); 5 | #define WAVUTIL_VERSION 1 6 | #endif 7 | -------------------------------------------------------------------------------- /sfubar-9/include/aifutil.h: -------------------------------------------------------------------------------- 1 | #ifndef __AIFUTIL_H__ 2 | #define __AIFUTIL_H__ 3 | extern void aif_to_txt(char *, char *, int); 4 | extern void txt_to_aif(char *, char *); 5 | #define AIFUTIL_VERSION 1 6 | #endif 7 | -------------------------------------------------------------------------------- /sfubar-9/include/wavutil.h: -------------------------------------------------------------------------------- 1 | #ifndef __WAVUTIL_H__ 2 | #define __WAVUTIL_H__ 3 | extern void wav_to_txt(char *, char *, int); 4 | extern void txt_to_wav(char *, char *); 5 | #define WAVUTIL_VERSION 1 6 | #endif 7 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/ieee80.h: -------------------------------------------------------------------------------- 1 | #ifndef __IEEE80_H__ 2 | #define __IEEE80_H__ 3 | extern double ieee_80_to_double(unsigned char *p); 4 | extern void double_to_ieee_80(double val, unsigned char *p); 5 | #endif 6 | -------------------------------------------------------------------------------- /sfubar-9/include/riffraff/ieee80.h: -------------------------------------------------------------------------------- 1 | #ifndef __IEEE80_H__ 2 | #define __IEEE80_H__ 3 | extern double ieee_80_to_double(unsigned char *p); 4 | extern void double_to_ieee_80(double val, unsigned char *p); 5 | #endif 6 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/include/riffraff/ieee80.h: -------------------------------------------------------------------------------- 1 | #ifndef __IEEE80_H__ 2 | #define __IEEE80_H__ 3 | extern double ieee_80_to_double(unsigned char *p); 4 | extern void double_to_ieee_80(double val, unsigned char *p); 5 | #endif 6 | -------------------------------------------------------------------------------- /sfubar-9/test-success/wav.txt: -------------------------------------------------------------------------------- 1 | RIFF.fmt.wFormatTag=1 2 | RIFF.fmt.wChannels=1 3 | RIFF.fmt.dwSamplesPerSec=44100 4 | RIFF.fmt.dwAvgBytesPerSec=88200 5 | RIFF.fmt.wBlockAlign=2 6 | RIFF.fmt.wBitsPerSample=16 7 | RIFF.data.size=4410 8 | RIFF.data.file=tmp/wav.raw 9 | -------------------------------------------------------------------------------- /sfubar-9/test-success/wav.txt.orig: -------------------------------------------------------------------------------- 1 | RIFF.fmt.wFormatTag=1 2 | RIFF.fmt.wChannels=1 3 | RIFF.fmt.dwSamplesPerSec=44100 4 | RIFF.fmt.dwAvgBytesPerSec=88200 5 | RIFF.fmt.wBlockAlign=2 6 | RIFF.fmt.wBitsPerSample=16 7 | RIFF.data.size=4410 8 | RIFF.data.file=tmp/wav.raw 9 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/bio.h: -------------------------------------------------------------------------------- 1 | #ifndef __BIO_H__ 2 | #define __BIO_H__ 3 | extern FILE *bens_fopen(const char *, const char *); 4 | extern void bens_fclose(FILE *); 5 | extern void bens_fread(void *, size_t, size_t, FILE *); 6 | extern void bens_fwrite(void *, size_t, size_t, FILE *); 7 | extern void data_copy(FILE *, FILE *, int, int); 8 | #endif 9 | -------------------------------------------------------------------------------- /sfubar-9/include/riffraff/bio.h: -------------------------------------------------------------------------------- 1 | #ifndef __BIO_H__ 2 | #define __BIO_H__ 3 | extern FILE *bens_fopen(const char *, const char *); 4 | extern void bens_fclose(FILE *); 5 | extern void bens_fread(void *, size_t, size_t, FILE *); 6 | extern void bens_fwrite(void *, size_t, size_t, FILE *); 7 | extern void data_copy(FILE *, FILE *, int, int); 8 | #endif 9 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/include/riffraff/bio.h: -------------------------------------------------------------------------------- 1 | #ifndef __BIO_H__ 2 | #define __BIO_H__ 3 | extern FILE *bens_fopen(const char *, const char *); 4 | extern void bens_fclose(FILE *); 5 | extern void bens_fread(void *, size_t, size_t, FILE *); 6 | extern void bens_fwrite(void *, size_t, size_t, FILE *); 7 | extern void data_copy(FILE *, FILE *, int, int); 8 | #endif 9 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/README: -------------------------------------------------------------------------------- 1 | Intro 2 | Build Instructions 3 | 4 | Intro 5 | ===== 6 | The riffraff library is my brute-force riff library. 7 | It depends on the math library. 8 | At the moment it is read-only. 9 | My email address is collver@peak.org. 10 | 11 | I will document it at a later date. 12 | 13 | Build Instructions 14 | ================== 15 | If you are building on a big-endian machine that is not running NetBSD, 16 | then change MY_BYTE_ORDER in bits.h 17 | -------------------------------------------------------------------------------- /sfubar-9/trap.h: -------------------------------------------------------------------------------- 1 | #ifndef __TRAP_H__ 2 | #define __TRAP_H__ 3 | #include 4 | #define TRAP_BUFLEN 1024 5 | extern char trap_message[]; 6 | extern void (*trap_global)(int); 7 | extern txt_t *trap_txt; 8 | #define trap_warn(args...) do { \ 9 | snprintf(trap_message, TRAP_BUFLEN, args); \ 10 | trap_global(0); \ 11 | } while (0) 12 | #define trap_exit(args...) do { \ 13 | snprintf(trap_message, TRAP_BUFLEN, args); \ 14 | trap_global(1); \ 15 | } while (0) 16 | #endif 17 | -------------------------------------------------------------------------------- /sfubar-9/include/trap.h: -------------------------------------------------------------------------------- 1 | #ifndef __TRAP_H__ 2 | #define __TRAP_H__ 3 | #include 4 | #define TRAP_BUFLEN 1024 5 | extern char trap_message[]; 6 | extern void (*trap_global)(int); 7 | extern txt_t *trap_txt; 8 | #define trap_warn(args...) do { \ 9 | snprintf(trap_message, TRAP_BUFLEN, args); \ 10 | trap_global(0); \ 11 | } while (0) 12 | #define trap_exit(args...) do { \ 13 | snprintf(trap_message, TRAP_BUFLEN, args); \ 14 | trap_global(1); \ 15 | } while (0) 16 | #endif 17 | -------------------------------------------------------------------------------- /sfubar-9/libparsetxt-4/include/trap.h: -------------------------------------------------------------------------------- 1 | #ifndef __TRAP_H__ 2 | #define __TRAP_H__ 3 | #include 4 | #define TRAP_BUFLEN 1024 5 | extern char trap_message[]; 6 | extern void (*trap_global)(int); 7 | extern txt_t *trap_txt; 8 | #define trap_warn(args...) do { \ 9 | snprintf(trap_message, TRAP_BUFLEN, args); \ 10 | trap_global(0); \ 11 | } while (0) 12 | #define trap_exit(args...) do { \ 13 | snprintf(trap_message, TRAP_BUFLEN, args); \ 14 | trap_global(1); \ 15 | } while (0) 16 | #endif 17 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/include/trap.h: -------------------------------------------------------------------------------- 1 | #ifndef __TRAP_H__ 2 | #define __TRAP_H__ 3 | #include 4 | #define TRAP_BUFLEN 1024 5 | extern char trap_message[]; 6 | extern void (*trap_global)(int); 7 | extern txt_t *trap_txt; 8 | #define trap_warn(args...) do { \ 9 | snprintf(trap_message, TRAP_BUFLEN, args); \ 10 | trap_global(0); \ 11 | } while (0) 12 | #define trap_exit(args...) do { \ 13 | snprintf(trap_message, TRAP_BUFLEN, args); \ 14 | trap_global(1); \ 15 | } while (0) 16 | #endif 17 | -------------------------------------------------------------------------------- /sfubar-9/libparsetxt-4/Makefile: -------------------------------------------------------------------------------- 1 | PREFIX?=. 2 | CFLAGS?= -O0 -g -Wall -I$(PREFIX)/include 3 | 4 | AR=$(TOOLDIR)ar 5 | CC=$(TOOLDIR)gcc 6 | RANLIB=$(TOOLDIR)ranlib 7 | 8 | PT=parsetxt-4 9 | 10 | OBJS= parsetxt.o 11 | 12 | lib$(PT).a: install-headers $(OBJS) 13 | ${AR} -r lib${PT}.a ${OBJS} 14 | ${RANLIB} lib${PT}.a 15 | 16 | clean: 17 | rm -f *.o lib${PT}.a 18 | 19 | install: lib$(PT).a 20 | cp lib${PT}.a ${PREFIX}/lib/ 21 | 22 | install-headers: parsetxt.h 23 | cp parsetxt.h ${PREFIX}/include/ 24 | 25 | parsetxt.o: parsetxt.c 26 | -------------------------------------------------------------------------------- /sfubar-9/trap.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | void trap_default(int severity) 7 | { 8 | /* print severity */ 9 | if (severity == 0) { 10 | fprintf(stderr, "warning: "); 11 | } else { 12 | fprintf(stderr, "error: "); 13 | } 14 | 15 | /* print line number of last line read */ 16 | if (trap_txt != NULL) 17 | fprintf(stderr, "%d: ", trap_txt->l); 18 | 19 | /* print error message */ 20 | fprintf(stderr, "%s\n", trap_message); 21 | 22 | /* exit */ 23 | if (severity != 0) 24 | exit(1); 25 | } 26 | 27 | char trap_message[TRAP_BUFLEN]; 28 | void (*trap_global)(int) = trap_default; 29 | txt_t *trap_txt = NULL; 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tools - FreePats project 2 | 3 | https://github.com/freepats/tools 4 | 5 | This repository contains tools for SoundFont, MIDI, and audio processing. The original web pages and repositories of some of these tools don't seem to exist anymore. They were previously hosted in the FreePats web archive and now are moved to a git repository to factilitate contributions. 6 | 7 | * sfubar-9: Create and edit SoundFont 2 files with the command line. 8 | * pysf-2: Python utility that supersedes sfubar. Create and edit SoundFont 2 9 | files with the command line, using XML configuration files. 10 | 11 | Other tools: 12 | 13 | * midicomp: Its repository is now at https://github.com/markc/midicomp 14 | -------------------------------------------------------------------------------- /sfubar-9/include/parsetxt.h: -------------------------------------------------------------------------------- 1 | #ifndef __PARSETXT_H__ 2 | #define __PARSETXT_H__ 3 | #include 4 | #define BUFLEN 256 5 | 6 | typedef struct { 7 | int line_number; 8 | char *key; 9 | char *data; 10 | int used; 11 | } txt_line_t; 12 | 13 | typedef struct { 14 | int line_count; 15 | txt_line_t **lines; 16 | int l; /* number of last line found by find_key */ 17 | void (*destroy)(void *); 18 | int (*find_key)(void *, char *); 19 | char *(*get_data)(void *, char *); 20 | void (*add_data)(void *, char *, char *, int); 21 | void (*add_line)(void *, char *, int, int); 22 | void (*read_lines)(void *, FILE *); 23 | void (*warn_unused)(void *); 24 | } txt_t; 25 | 26 | extern txt_t *txt_new(void); 27 | #endif 28 | -------------------------------------------------------------------------------- /sfubar-9/libparsetxt-4/parsetxt.h: -------------------------------------------------------------------------------- 1 | #ifndef __PARSETXT_H__ 2 | #define __PARSETXT_H__ 3 | #include 4 | #define BUFLEN 256 5 | 6 | typedef struct { 7 | int line_number; 8 | char *key; 9 | char *data; 10 | int used; 11 | } txt_line_t; 12 | 13 | typedef struct { 14 | int line_count; 15 | txt_line_t **lines; 16 | int l; /* number of last line found by find_key */ 17 | void (*destroy)(void *); 18 | int (*find_key)(void *, char *); 19 | char *(*get_data)(void *, char *); 20 | void (*add_data)(void *, char *, char *, int); 21 | void (*add_line)(void *, char *, int, int); 22 | void (*read_lines)(void *, FILE *); 23 | void (*warn_unused)(void *); 24 | } txt_t; 25 | 26 | extern txt_t *txt_new(void); 27 | #endif 28 | -------------------------------------------------------------------------------- /sfubar-9/libparsetxt-4/include/parsetxt.h: -------------------------------------------------------------------------------- 1 | #ifndef __PARSETXT_H__ 2 | #define __PARSETXT_H__ 3 | #include 4 | #define BUFLEN 256 5 | 6 | typedef struct { 7 | int line_number; 8 | char *key; 9 | char *data; 10 | int used; 11 | } txt_line_t; 12 | 13 | typedef struct { 14 | int line_count; 15 | txt_line_t **lines; 16 | int l; /* number of last line found by find_key */ 17 | void (*destroy)(void *); 18 | int (*find_key)(void *, char *); 19 | char *(*get_data)(void *, char *); 20 | void (*add_data)(void *, char *, char *, int); 21 | void (*add_line)(void *, char *, int, int); 22 | void (*read_lines)(void *, FILE *); 23 | void (*warn_unused)(void *); 24 | } txt_t; 25 | 26 | extern txt_t *txt_new(void); 27 | #endif 28 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/include/parsetxt.h: -------------------------------------------------------------------------------- 1 | #ifndef __PARSETXT_H__ 2 | #define __PARSETXT_H__ 3 | #include 4 | #define BUFLEN 256 5 | 6 | typedef struct { 7 | int line_number; 8 | char *key; 9 | char *data; 10 | int used; 11 | } txt_line_t; 12 | 13 | typedef struct { 14 | int line_count; 15 | txt_line_t **lines; 16 | int l; /* number of last line found by find_key */ 17 | void (*destroy)(void *); 18 | int (*find_key)(void *, char *); 19 | char *(*get_data)(void *, char *); 20 | void (*add_data)(void *, char *, char *, int); 21 | void (*add_line)(void *, char *, int, int); 22 | void (*read_lines)(void *, FILE *); 23 | void (*warn_unused)(void *); 24 | } txt_t; 25 | 26 | extern txt_t *txt_new(void); 27 | #endif 28 | -------------------------------------------------------------------------------- /sfubar-9/test-success/aif.txt: -------------------------------------------------------------------------------- 1 | FORM.FVER.timestamp=2726318400 2 | FORM.COMM.numChannels=1 3 | FORM.COMM.sampleSize=16 4 | FORM.COMM.sampleRate=44100 5 | FORM.COMM.compressionType.str=NONE 6 | FORM.COMM.compressionName.str=not compressed 7 | FORM.MARK.1.id=91 8 | FORM.MARK.1.pos=100 9 | FORM.MARK.1.name=start sustain loop 10 | FORM.MARK.2.id=92 11 | FORM.MARK.2.pos=200 12 | FORM.MARK.2.name=end sustain loop 13 | FORM.INST.baseNote=69 14 | FORM.INST.detune=0 15 | FORM.INST.lowNote=0 16 | FORM.INST.highNote=127 17 | FORM.INST.lowVelocity=1 18 | FORM.INST.highVelocity=127 19 | FORM.INST.gain=0 20 | FORM.INST.sustainLoop.playMode=1 21 | FORM.INST.sustainLoop.beginLoop=91 22 | FORM.INST.sustainLoop.endLoop=92 23 | FORM.INST.releaseLoop.playMode=0 24 | FORM.INST.releaseLoop.beginLoop=0 25 | FORM.INST.releaseLoop.endLoop=0 26 | FORM.SSND.file=tmp/aif.raw 27 | -------------------------------------------------------------------------------- /sfubar-9/test-success/test.txt: -------------------------------------------------------------------------------- 1 | RIFF.LIST.isng.zstr=EMU8000 2 | RIFF.LIST.INAM.zstr=sine bank 3 | RIFF.LIST.ICRD.zstr=Nov 08, 2005 4 | RIFF.LIST.IPRD.zstr=SBAWE32 5 | RIFF.LIST.ISFT.zstr=Compressed ImpulseTracker 2.14:mod2cs-0.2 6 | SF2.wt.1.wav=tmp/test1.wav 7 | SF2.wt.1.name=sine wavetable 8 | SF2.wt.1.loopstart=100 9 | SF2.wt.1.loopend=200 10 | SF2.wt.1.pitch=69 11 | SF2.in.1.name=sine instrument 12 | SF2.in.1.zone.1.keyRange=12,120 13 | SF2.in.1.zone.1.overridingRootKey=69 14 | SF2.in.1.zone.1.wt=1 15 | SF2.in.1.zone.2.keyRange=121,126 16 | SF2.in.1.zone.2.overridingRootKey=69 17 | SF2.in.1.zone.2.wt=1 18 | SF2.in.2.name=sine instrument 2 19 | SF2.in.2.zone.1.keyRange=12,126 20 | SF2.in.2.zone.1.overridingRootKey=69 21 | SF2.in.2.zone.1.wt=1 22 | SF2.ps.1.name=sine preset 23 | SF2.ps.1.bank=0 24 | SF2.ps.1.zone.1.keyRange=0,127 25 | SF2.ps.1.zone.1.in=1 26 | -------------------------------------------------------------------------------- /sfubar-9/test-success/test3.txt: -------------------------------------------------------------------------------- 1 | RIFF.LIST.isng.zstr=EMU8000 2 | RIFF.LIST.INAM.zstr=sine bank 3 | RIFF.LIST.ICRD.zstr=Nov 08, 2005 4 | RIFF.LIST.IPRD.zstr=SBAWE32 5 | RIFF.LIST.ISFT.zstr=Compressed ImpulseTracker 2.14:mod2cs-0.2 6 | SF2.wt.1.aif=tmp/aif.aif 7 | SF2.wt.1.name=sine wavetable 8 | SF2.wt.1.loopstart=100 9 | SF2.wt.1.loopend=200 10 | SF2.wt.1.pitch=69 11 | SF2.in.1.name=sine instrument 12 | SF2.in.1.zone.1.keyRange=12,120 13 | SF2.in.1.zone.1.overridingRootKey=69 14 | SF2.in.1.zone.1.wt=1 15 | SF2.in.1.zone.2.keyRange=121,126 16 | SF2.in.1.zone.2.overridingRootKey=69 17 | SF2.in.1.zone.2.wt=1 18 | SF2.in.2.name=sine instrument 2 19 | SF2.in.2.zone.1.keyRange=12,126 20 | SF2.in.2.zone.1.overridingRootKey=69 21 | SF2.in.2.zone.1.wt=1 22 | SF2.ps.1.name=sine preset 23 | SF2.ps.1.bank=0 24 | SF2.ps.1.zone.1.keyRange=0,127 25 | SF2.ps.1.zone.1.in=1 26 | -------------------------------------------------------------------------------- /sfubar-9/test-success/test.txt.orig: -------------------------------------------------------------------------------- 1 | RIFF.LIST.isng.zstr=EMU8000 2 | RIFF.LIST.INAM.zstr=sine bank 3 | RIFF.LIST.ICRD.zstr=Nov 08, 2005 4 | RIFF.LIST.IPRD.zstr=SBAWE32 5 | RIFF.LIST.ISFT.zstr=Compressed ImpulseTracker 2.14:mod2cs-0.2 6 | SF2.wt.1.wav=tmp/test1.wav 7 | SF2.wt.1.name=sine wavetable 8 | SF2.wt.1.loopstart=100 9 | SF2.wt.1.loopend=200 10 | SF2.wt.1.pitch=69 11 | SF2.in.1.name=sine instrument 12 | SF2.in.1.zone.1.keyRange=12,120 13 | SF2.in.1.zone.1.overridingRootKey=69 14 | SF2.in.1.zone.1.wt=1 15 | SF2.in.1.zone.2.keyRange=121,126 16 | SF2.in.1.zone.2.overridingRootKey=69 17 | SF2.in.1.zone.2.wt=1 18 | SF2.in.2.name=sine instrument 2 19 | SF2.in.2.zone.1.keyRange=12,126 20 | SF2.in.2.zone.1.overridingRootKey=69 21 | SF2.in.2.zone.1.wt=1 22 | SF2.ps.1.name=sine preset 23 | SF2.ps.1.bank=0 24 | SF2.ps.1.zone.1.keyRange=0,127 25 | SF2.ps.1.zone.1.in=1 26 | -------------------------------------------------------------------------------- /sfubar-9/test-success/ieee80.tst: -------------------------------------------------------------------------------- 1 | log of 2.000000 is 0.693147 2 | log of 1.000000 is 0.000000 3 | 0.000000: 00000000000000000000 0.000000 4 | -1.000000: BFFF8000000000000000 -1.000000 5 | 1.000000: 3FFF8000000000000000 1.000000 6 | 2.000000: 40008000000000000000 2.000000 7 | 4.000000: 40018000000000000000 4.000000 8 | 0.500000: 3FFE8000000000000000 0.500000 9 | 0.250000: 3FFD8000000000000000 0.250000 10 | 0.125000: 3FFC8000000000000000 0.125000 11 | 3.141593: 4000C90FDAA22168C000 3.141593 12 | 10000.000000: 400C9C40000000000000 10000.000000 13 | 22000.000000: 400DABE0000000000000 22000.000000 14 | 44100.000000: 400EAC44000000000000 44100.000000 15 | 65536.000000: 400F8000000000000000 65536.000000 16 | 134072.768000: 401082EE3126E978D800 134072.768000 17 | 3540001.900000: 4014D810879999999800 3540001.900000 18 | 4294967295.000000: 401EFFFFFFFF00000000 4294967295.000000 19 | -------------------------------------------------------------------------------- /sfubar-9/test-success/aif.txt.orig: -------------------------------------------------------------------------------- 1 | FORM.FVER.timestamp=2726318400 2 | FORM.COMM.numChannels=1 3 | FORM.COMM.sampleSize=16 4 | FORM.COMM.sampleRate=44100 5 | FORM.COMM.compressionType.str=NONE 6 | FORM.COMM.compressionName.str=not compressed 7 | FORM.MARK.1.id=91 8 | FORM.MARK.1.pos=100 9 | FORM.MARK.1.name=start sustain loop 10 | FORM.MARK.2.id=92 11 | FORM.MARK.2.pos=200 12 | FORM.MARK.2.name=end sustain loop 13 | FORM.INST.baseNote=69 14 | FORM.INST.detune=0 15 | FORM.INST.lowNote=0 16 | FORM.INST.highNote=127 17 | FORM.INST.lowVelocity=1 18 | FORM.INST.highVelocity=127 19 | FORM.INST.gain=0 20 | FORM.INST.sustainLoop.playMode=1 21 | FORM.INST.sustainLoop.beginLoop=91 22 | FORM.INST.sustainLoop.endLoop=92 23 | FORM.INST.releaseLoop.playMode=0 24 | FORM.INST.releaseLoop.beginLoop=0 25 | FORM.INST.releaseLoop.endLoop=0 26 | FORM.SSND.file=tmp/aif.raw 27 | FORM.SSND.byteswap=1 28 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/wav.h: -------------------------------------------------------------------------------- 1 | #ifndef __WAV_H__ 2 | #define __WAV_H__ 3 | #include "rifftypes.h" 4 | 5 | #ifndef WAVE_FORMAT_PCM 6 | #define WAVE_FORMAT_PCM 0x0001 7 | #endif 8 | 9 | typedef struct { 10 | myWORD wFormatTag; 11 | myWORD wChannels; 12 | myDWORD dwSamplesPerSec; 13 | myDWORD dwAvgBytesPerSec; 14 | myWORD wBlockAlign; 15 | myWORD wBitsPerSample; 16 | } fmt_t; 17 | 18 | typedef struct { 19 | long offset; /* bytes */ 20 | long size; /* bytes */ 21 | } data_t; 22 | 23 | typedef struct { 24 | fmt_t fmt; 25 | data_t data; 26 | void (*destroy)(void *); 27 | void (*header_set)(void *, myWORD, myWORD, myDWORD, long); 28 | int (*header_read)(void *, FILE *); 29 | void (*header_write)(void *, FILE *); 30 | chunk_t *src; 31 | chunk_t *dst; 32 | chunk_t *tmp; 33 | tree_t *tree; 34 | } wav_t; 35 | 36 | extern wav_t *wav_new(void); 37 | #endif 38 | -------------------------------------------------------------------------------- /sfubar-9/include/riffraff/wav.h: -------------------------------------------------------------------------------- 1 | #ifndef __WAV_H__ 2 | #define __WAV_H__ 3 | #include "rifftypes.h" 4 | 5 | #ifndef WAVE_FORMAT_PCM 6 | #define WAVE_FORMAT_PCM 0x0001 7 | #endif 8 | 9 | typedef struct { 10 | myWORD wFormatTag; 11 | myWORD wChannels; 12 | myDWORD dwSamplesPerSec; 13 | myDWORD dwAvgBytesPerSec; 14 | myWORD wBlockAlign; 15 | myWORD wBitsPerSample; 16 | } fmt_t; 17 | 18 | typedef struct { 19 | long offset; /* bytes */ 20 | long size; /* bytes */ 21 | } data_t; 22 | 23 | typedef struct { 24 | fmt_t fmt; 25 | data_t data; 26 | void (*destroy)(void *); 27 | void (*header_set)(void *, myWORD, myWORD, myDWORD, long); 28 | int (*header_read)(void *, FILE *); 29 | void (*header_write)(void *, FILE *); 30 | chunk_t *src; 31 | chunk_t *dst; 32 | chunk_t *tmp; 33 | tree_t *tree; 34 | } wav_t; 35 | 36 | extern wav_t *wav_new(void); 37 | #endif 38 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/include/riffraff/wav.h: -------------------------------------------------------------------------------- 1 | #ifndef __WAV_H__ 2 | #define __WAV_H__ 3 | #include "rifftypes.h" 4 | 5 | #ifndef WAVE_FORMAT_PCM 6 | #define WAVE_FORMAT_PCM 0x0001 7 | #endif 8 | 9 | typedef struct { 10 | myWORD wFormatTag; 11 | myWORD wChannels; 12 | myDWORD dwSamplesPerSec; 13 | myDWORD dwAvgBytesPerSec; 14 | myWORD wBlockAlign; 15 | myWORD wBitsPerSample; 16 | } fmt_t; 17 | 18 | typedef struct { 19 | long offset; /* bytes */ 20 | long size; /* bytes */ 21 | } data_t; 22 | 23 | typedef struct { 24 | fmt_t fmt; 25 | data_t data; 26 | void (*destroy)(void *); 27 | void (*header_set)(void *, myWORD, myWORD, myDWORD, long); 28 | int (*header_read)(void *, FILE *); 29 | void (*header_write)(void *, FILE *); 30 | chunk_t *src; 31 | chunk_t *dst; 32 | chunk_t *tmp; 33 | tree_t *tree; 34 | } wav_t; 35 | 36 | extern wav_t *wav_new(void); 37 | #endif 38 | -------------------------------------------------------------------------------- /sfubar-9/gensine.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | double fpart(double x) 9 | { 10 | double retval; 11 | retval = x - floor(x); 12 | return retval; 13 | } 14 | 15 | int main(int argc, char *argv[]) 16 | { 17 | int sr = 44100; 18 | int sample_count = 2205; 19 | int iamp = 10000; 20 | int freq = 440; 21 | int s; 22 | double sample_period = (double)sr / (double)freq; 23 | double arg; 24 | mySHORT value; 25 | char buffer[2]; 26 | 27 | #define OUTFD 1 28 | 29 | #ifdef __MINGW32__ 30 | _setmode(OUTFD, _O_BINARY); 31 | #endif 32 | 33 | for (s = 0; s < sample_count; s++) { 34 | arg = (double)s / sample_period; 35 | arg = fpart(arg); 36 | arg = 2 * M_PI * arg; 37 | value = sin(arg) * iamp; 38 | my_put_SHORT_LE(&value, buffer); 39 | write(OUTFD, buffer, 2); 40 | } 41 | exit(0); 42 | } 43 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/Makefile: -------------------------------------------------------------------------------- 1 | SRCDIR?=.. 2 | PREFIX?=. 3 | CFLAGS?= -O0 -g -Wall -I$(PREFIX)/include 4 | 5 | AR=$(TOOLDIR)ar 6 | CC=$(TOOLDIR)gcc 7 | RANLIB=$(TOOLDIR)ranlib 8 | 9 | PT= parsetxt-4 10 | RR= riffraff-7 11 | 12 | HEADERS= aif.h bio.h bits.h riff.h rifftypes.h wav.h ieee80.h 13 | OBJS= aif.o bio.o riff.o rifftypes.o wav.o ieee80.o 14 | 15 | lib$(RR).a: $(PREFIX)/lib/lib$(PT).a ieee80-test $(OBJS) 16 | ${AR} -r lib${RR}.a ${OBJS} 17 | ${RANLIB} lib${RR}.a 18 | 19 | clean: 20 | rm -f *.o lib${RR}.a ieee80-test 21 | cd ${SRCDIR}/lib${PT} && ${MAKE} clean 22 | 23 | $(PREFIX)/lib/lib$(PT).a: 24 | cd ${SRCDIR}/lib${PT} && \ 25 | PREFIX=${PREFIX} CFLAGS="${CFLAGS}" TOOLDIR=${TOOLDIR} ${MAKE} install 26 | 27 | ieee80-test: ieee80.c 28 | ${CC} ${CFLAGS} -D_DO_TEST -o $@ ieee80.c -lm 29 | 30 | install: lib$(RR).a 31 | mkdir -p ${PREFIX}/include/riffraff/ 32 | cp ${HEADERS} ${PREFIX}/include/riffraff/ 33 | cp lib${RR}.a ${PREFIX}/lib/ 34 | cp ieee80-test ${PREFIX}/bin/ 35 | 36 | aif.o: aif.c 37 | bio.o: bio.c 38 | ieee80.o: ieee80.c 39 | riff.o: riff.c 40 | rifftypes.o: rifftypes.c 41 | wav.o: wav.c 42 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/bits.h: -------------------------------------------------------------------------------- 1 | #ifndef __BITS_H__ 2 | #define __BITS_H__ 3 | 4 | #include 5 | 6 | #define MY_LITTLE_ENDIAN 1234 7 | #define MY_BIG_ENDIAN 4321 8 | 9 | #if !defined(MY_BYTE_ORDER) 10 | #if defined(__NetBSD__) 11 | #if _BYTE_ORDER == _LITTLE_ENDIAN 12 | #define MY_BYTE_ORDER MY_LITTLE_ENDIAN 13 | #else /* _BIG_ENDIAN */ 14 | #define MY_BYTE_ORDER MY_BIG_ENDIAN 15 | #endif 16 | #endif 17 | #endif 18 | 19 | #if !defined(MY_BYTE_ORDER) 20 | /* --- uncomment one of these, the 1st for i386, the 2nd for ppc :) */ 21 | #define MY_BYTE_ORDER MY_LITTLE_ENDIAN 22 | /* #define MY_BYTE_ORDER MY_BIG_ENDIAN */ 23 | #endif 24 | 25 | #define XCHG16(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF)) 26 | #define XCHG32(x) ((((x)&0xFF)<<24) | (((x)&0xFF00)<<8) | \ 27 | (((x)&0xFF0000)>>8) | (((x)>>24)&0xFF)) 28 | 29 | #if MY_BYTE_ORDER == MY_LITTLE_ENDIAN 30 | #define HLE16(x) (x) 31 | #define HLE32(x) (x) 32 | #define HBE16(x) XCHG16(x) 33 | #define HBE32(x) XCHG32(x) 34 | #define LE16H(x) (x) 35 | #define LE32H(x) (x) 36 | #define BE16H(x) XCHG16(x) 37 | #define BE32H(x) XCHG32(x) 38 | #else /* _BIG_ENDIAN */ 39 | #define HBE16(x) (x) 40 | #define HBE32(x) (x) 41 | #define HLE16(x) XCHG16(x) 42 | #define HLE32(x) XCHG32(x) 43 | #define LE16H(x) XCHG16(x) 44 | #define LE32H(x) XCHG32(x) 45 | #define BE16H(x) (x) 46 | #define BE32H(x) (x) 47 | #endif 48 | 49 | #define is_even(x) (((x) % 2) == 0) 50 | #define BITS_PER_BYTE 8 51 | #endif 52 | -------------------------------------------------------------------------------- /sfubar-9/include/riffraff/bits.h: -------------------------------------------------------------------------------- 1 | #ifndef __BITS_H__ 2 | #define __BITS_H__ 3 | 4 | #include 5 | 6 | #define MY_LITTLE_ENDIAN 1234 7 | #define MY_BIG_ENDIAN 4321 8 | 9 | #if !defined(MY_BYTE_ORDER) 10 | #if defined(__NetBSD__) 11 | #if _BYTE_ORDER == _LITTLE_ENDIAN 12 | #define MY_BYTE_ORDER MY_LITTLE_ENDIAN 13 | #else /* _BIG_ENDIAN */ 14 | #define MY_BYTE_ORDER MY_BIG_ENDIAN 15 | #endif 16 | #endif 17 | #endif 18 | 19 | #if !defined(MY_BYTE_ORDER) 20 | /* --- uncomment one of these, the 1st for i386, the 2nd for ppc :) */ 21 | #define MY_BYTE_ORDER MY_LITTLE_ENDIAN 22 | /* #define MY_BYTE_ORDER MY_BIG_ENDIAN */ 23 | #endif 24 | 25 | #define XCHG16(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF)) 26 | #define XCHG32(x) ((((x)&0xFF)<<24) | (((x)&0xFF00)<<8) | \ 27 | (((x)&0xFF0000)>>8) | (((x)>>24)&0xFF)) 28 | 29 | #if MY_BYTE_ORDER == MY_LITTLE_ENDIAN 30 | #define HLE16(x) (x) 31 | #define HLE32(x) (x) 32 | #define HBE16(x) XCHG16(x) 33 | #define HBE32(x) XCHG32(x) 34 | #define LE16H(x) (x) 35 | #define LE32H(x) (x) 36 | #define BE16H(x) XCHG16(x) 37 | #define BE32H(x) XCHG32(x) 38 | #else /* _BIG_ENDIAN */ 39 | #define HBE16(x) (x) 40 | #define HBE32(x) (x) 41 | #define HLE16(x) XCHG16(x) 42 | #define HLE32(x) XCHG32(x) 43 | #define LE16H(x) XCHG16(x) 44 | #define LE32H(x) XCHG32(x) 45 | #define BE16H(x) (x) 46 | #define BE32H(x) (x) 47 | #endif 48 | 49 | #define is_even(x) (((x) % 2) == 0) 50 | #define BITS_PER_BYTE 8 51 | #endif 52 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/include/riffraff/bits.h: -------------------------------------------------------------------------------- 1 | #ifndef __BITS_H__ 2 | #define __BITS_H__ 3 | 4 | #include 5 | 6 | #define MY_LITTLE_ENDIAN 1234 7 | #define MY_BIG_ENDIAN 4321 8 | 9 | #if !defined(MY_BYTE_ORDER) 10 | #if defined(__NetBSD__) 11 | #if _BYTE_ORDER == _LITTLE_ENDIAN 12 | #define MY_BYTE_ORDER MY_LITTLE_ENDIAN 13 | #else /* _BIG_ENDIAN */ 14 | #define MY_BYTE_ORDER MY_BIG_ENDIAN 15 | #endif 16 | #endif 17 | #endif 18 | 19 | #if !defined(MY_BYTE_ORDER) 20 | /* --- uncomment one of these, the 1st for i386, the 2nd for ppc :) */ 21 | #define MY_BYTE_ORDER MY_LITTLE_ENDIAN 22 | /* #define MY_BYTE_ORDER MY_BIG_ENDIAN */ 23 | #endif 24 | 25 | #define XCHG16(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF)) 26 | #define XCHG32(x) ((((x)&0xFF)<<24) | (((x)&0xFF00)<<8) | \ 27 | (((x)&0xFF0000)>>8) | (((x)>>24)&0xFF)) 28 | 29 | #if MY_BYTE_ORDER == MY_LITTLE_ENDIAN 30 | #define HLE16(x) (x) 31 | #define HLE32(x) (x) 32 | #define HBE16(x) XCHG16(x) 33 | #define HBE32(x) XCHG32(x) 34 | #define LE16H(x) (x) 35 | #define LE32H(x) (x) 36 | #define BE16H(x) XCHG16(x) 37 | #define BE32H(x) XCHG32(x) 38 | #else /* _BIG_ENDIAN */ 39 | #define HBE16(x) (x) 40 | #define HBE32(x) (x) 41 | #define HLE16(x) XCHG16(x) 42 | #define HLE32(x) XCHG32(x) 43 | #define LE16H(x) XCHG16(x) 44 | #define LE32H(x) XCHG32(x) 45 | #define BE16H(x) (x) 46 | #define BE32H(x) (x) 47 | #endif 48 | 49 | #define is_even(x) (((x) % 2) == 0) 50 | #define BITS_PER_BYTE 8 51 | #endif 52 | -------------------------------------------------------------------------------- /sfubar-9/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "sfubar.h" 5 | 6 | void usage(void) 7 | { 8 | fprintf(stderr, "\nsfubar version %d\n\n", SFUTIL_VERSION); 9 | fprintf(stderr, "%s", 10 | "Usage: sfubar [conversion] [infile] [outfile]\n" 11 | "\tconversion := --sf2txt | --txt2sf | --sfdebug\n" 12 | "\tconversion := --aif2txt | --txt2aif | --aifdebug\n" 13 | "\tconversion := --wav2txt | --txt2wav | --wavdebug\n\n"); 14 | exit(0); 15 | } 16 | 17 | int main(int argc, char *argv[]) 18 | { 19 | if (argc != 4) 20 | usage(); 21 | 22 | if (strcmp(argv[1], "--sf2txt") == 0) { 23 | sf_to_txt(argv[2], argv[3], 0); 24 | } else if (strcmp(argv[1], "--txt2sf") == 0) { 25 | txt_to_sf(argv[2], argv[3]); 26 | } else if (strcmp(argv[1], "--sfdebug") == 0) { 27 | sf_to_txt(argv[2], argv[3], 1); 28 | } else if (strcmp(argv[1], "--aif2txt") == 0) { 29 | aif_to_txt(argv[2], argv[3], 0); 30 | } else if (strcmp(argv[1], "--txt2aif") == 0) { 31 | txt_to_aif(argv[2], argv[3]); 32 | } else if (strcmp(argv[1], "--aifdebug") == 0) { 33 | aif_to_txt(argv[2], argv[3], 1); 34 | } else if (strcmp(argv[1], "--wav2txt") == 0) { 35 | wav_to_txt(argv[2], argv[3], 0); 36 | } else if (strcmp(argv[1], "--txt2wav") == 0) { 37 | txt_to_wav(argv[2], argv[3]); 38 | } else if (strcmp(argv[1], "--wavdebug") == 0) { 39 | wav_to_txt(argv[2], argv[3], 1); 40 | } else { 41 | usage(); 42 | } 43 | exit(0); 44 | } 45 | -------------------------------------------------------------------------------- /sfubar-9/libparsetxt-4/README: -------------------------------------------------------------------------------- 1 | Intro 2 | ===== 3 | The parsetxt library is my brute-force configuration file library. 4 | At the moment it is read-only. 5 | My email address is collver@peak.org. 6 | 7 | Brief explanation of configuration file format 8 | ============================================== 9 | The file is strictly line-based and there are no line continuations. 10 | Blank lines and comments are ignored. 11 | Comments are lines that begin with the character ';' or '#'. 12 | Each configuration line has a key and a value. 13 | Each key must be unique, no duplicates allowed. 14 | From the beginning of the line to a '=' character is the key. 15 | From the '=' character to the end of the line is the value. 16 | A key may not contain a '=' character. 17 | 18 | Brief explanation of library usage 19 | ================================== 20 | Create a variable to hold the structure. 21 | txt_t *txt; 22 | 23 | Initialize the variable. 24 | txt = txt_new(); 25 | 26 | To read a configuration file, open it with fopen. Pass the file handle. 27 | FILE *ifp; 28 | char txtfile[] = "bens.conf"; 29 | ifp = fopen(txtfile, "r"); 30 | txt->read_lines(txt, ifp); 31 | 32 | To see if a key exists. 33 | int n; 34 | char key[] = "keyname"; 35 | if (txt->find_key(txt, key) == -1) puts("key does not exist"); 36 | 37 | To get the value of a key. 38 | char *value; 39 | value = txt->get_data(txt, key); 40 | /* get_data returns a pointer to internal data which will be lost 41 | once the txt structure is destroyed. */ 42 | 43 | History 44 | ======= 45 | version 1 46 | - split off from sfubar utility 47 | 48 | version 2 49 | - added feature to track last line looked up 50 | -------------------------------------------------------------------------------- /sfubar-9/Makefile: -------------------------------------------------------------------------------- 1 | # unix and cygwin: make test 2 | 3 | # uncomment for debugging 4 | CFLAGS= -O0 -g 5 | 6 | # uncomment for cygwin 7 | #CFLAGS+= -mno-cygwin -mwindows 8 | 9 | 10 | 11 | # .CURDIR is already set in bmake, use a gmake extension to set it in gmake 12 | .CURDIR?= $(shell pwd) 13 | 14 | PREFIX?= $(.CURDIR) 15 | SRCDIR?= $(.CURDIR) 16 | PT= parsetxt-4 17 | RR= riffraff-7 18 | SF= sfubar-9 19 | OBJS= trap.o sfutil.o aifutil.o wavutil.o 20 | 21 | CC= $(TOOLDIR)gcc 22 | AR= $(TOOLDIR)ar 23 | RANLIB= $(TOOLDIR)ranlib 24 | STRIP= $(TOOLDIR)strip 25 | 26 | CFLAGS+= -Wall -I$(PREFIX)/include 27 | LDLIBS+= -L$(PREFIX)/lib -l$(SF) -lm 28 | 29 | all: sfubar gensine 30 | 31 | $(PREFIX)/lib/lib$(SF).a: install-includes $(PREFIX)/lib/lib$(RR).a $(OBJS) 32 | cp ${PREFIX}/lib/lib${PT}.a ${PREFIX}/lib/lib${RR}.a ${OBJS} tmp/ ; \ 33 | cd tmp ; \ 34 | ${AR} -x lib${PT}.a ; \ 35 | ${AR} -x lib${RR}.a ; \ 36 | ${AR} -r ${PREFIX}/lib/lib${SF}.a *.o ; \ 37 | ${RANLIB} ${PREFIX}/lib/lib${SF}.a ; \ 38 | rm *.[ao] 39 | 40 | install-includes: 41 | cp aifutil.h sfubar.h sfutil.h trap.h wavutil.h ${PREFIX}/include/ 42 | cp trap.h ${SRCDIR}/lib${PT}/include 43 | cp trap.h ${SRCDIR}/lib${RR}/include 44 | cp trap.h ${PREFIX}/include 45 | 46 | sfubar: $(PREFIX)/lib/lib$(SF).a main.o 47 | ${CC} ${CFLAGS} -o $@ main.o ${LDLIBS} 48 | 49 | gensine: $(PREFIX)/lib/lib$(SF).a gensine.o 50 | ${CC} ${CFLAGS} -o $@ gensine.o ${LDLIBS} 51 | 52 | $(PREFIX)/lib/lib$(RR).a: 53 | cd ${SRCDIR}/lib${RR} && \ 54 | PREFIX=${PREFIX} CFLAGS="${CFLAGS}" TOOLDIR=${TOOLDIR} ${MAKE} install 55 | 56 | clean: 57 | rm -f *.o sfubar gensine *.core bin/ieee80-test tmp/* lib/* 58 | cd ${SRCDIR}/lib${RR} && \ 59 | PREFIX=${PREFIX} TOOLDIR=${TOOLDIR} ${MAKE} clean 60 | 61 | test: all 62 | chmod u+x ./test.sh 63 | ./test.sh 64 | 65 | sfutil.o: sfutil.c 66 | main.o: main.c 67 | aifutil.o: aifutil.c 68 | wavutil.o: wavutil.c 69 | gensine.o: gensine.c 70 | trap.o: trap.c 71 | -------------------------------------------------------------------------------- /sfubar-9/include/riffraff/rifftypes.h: -------------------------------------------------------------------------------- 1 | #ifndef __RIFF_TYPES_H__ 2 | #define __RIFF_TYPES_H__ 3 | 4 | #ifdef uint8_t 5 | typedef uint8_t myBYTE; 6 | typedef int8_t myCHAR; 7 | typedef int16_t mySHORT; 8 | typedef uint16_t myWORD; 9 | typedef uint32_t myDWORD; 10 | #else 11 | typedef unsigned char myBYTE; 12 | typedef char myCHAR; 13 | typedef char* myZSTR; 14 | typedef unsigned int myDWORD; 15 | typedef short int mySHORT; 16 | typedef unsigned short int myWORD; 17 | #endif 18 | 19 | typedef union { 20 | char str[4]; 21 | myDWORD dword; 22 | } myFOURCC; 23 | 24 | typedef unsigned char myIEEE80[10]; 25 | 26 | #define PSTRING_STR_MAXLEN 256 27 | typedef struct { 28 | int count; /* pascal string, maximum value for count is 255 */ 29 | char str[PSTRING_STR_MAXLEN]; /* also zero-terminate this string */ 30 | } myPSTRING; 31 | 32 | extern void *my_get_CHAR(char *, void *, int); 33 | extern void *my_get_ZSTR(char **, void *, int); 34 | extern void *my_get_DWORD_LE(myDWORD *, void *); 35 | extern void *my_get_WORD_LE(myWORD *, void *); 36 | extern void *my_get_SHORT_LE(mySHORT *, void *); 37 | extern void *my_get_DWORD_BE(myDWORD *, void *); 38 | extern void *my_get_WORD_BE(myWORD *, void *); 39 | extern void *my_get_SHORT_BE(mySHORT *, void *); 40 | extern void *my_get_BYTE(myBYTE *, void *); 41 | extern void *my_get_IEEE80(myIEEE80 *, void *); 42 | extern void *my_get_PSTRING(myPSTRING *, void *); 43 | extern void *my_put_CHAR(char *, void *, int); 44 | #define my_put_ZSTR my_put_CHAR 45 | extern void *my_put_DWORD_LE(myDWORD *, void *); 46 | extern void *my_put_WORD_LE(myWORD *, void *); 47 | extern void *my_put_SHORT_LE(mySHORT *, void *); 48 | extern void *my_put_DWORD_BE(myDWORD *, void *); 49 | extern void *my_put_WORD_BE(myWORD *, void *); 50 | extern void *my_put_SHORT_BE(mySHORT *, void *); 51 | extern void *my_put_BYTE(myBYTE *, void *); 52 | extern void *my_put_IEEE80(myIEEE80 *, void *); 53 | extern void *my_put_PSTRING(myPSTRING *, void *); 54 | extern int my_size_PSTRING(myPSTRING *); 55 | #endif 56 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/rifftypes.h: -------------------------------------------------------------------------------- 1 | #ifndef __RIFF_TYPES_H__ 2 | #define __RIFF_TYPES_H__ 3 | 4 | #ifdef uint8_t 5 | typedef uint8_t myBYTE; 6 | typedef int8_t myCHAR; 7 | typedef int16_t mySHORT; 8 | typedef uint16_t myWORD; 9 | typedef uint32_t myDWORD; 10 | #else 11 | typedef unsigned char myBYTE; 12 | typedef char myCHAR; 13 | typedef char* myZSTR; 14 | typedef unsigned int myDWORD; 15 | typedef short int mySHORT; 16 | typedef unsigned short int myWORD; 17 | #endif 18 | 19 | typedef union { 20 | char str[4]; 21 | myDWORD dword; 22 | } myFOURCC; 23 | 24 | typedef unsigned char myIEEE80[10]; 25 | 26 | #define PSTRING_STR_MAXLEN 256 27 | typedef struct { 28 | int count; /* pascal string, maximum value for count is 255 */ 29 | char str[PSTRING_STR_MAXLEN]; /* also zero-terminate this string */ 30 | } myPSTRING; 31 | 32 | extern void *my_get_CHAR(char *, void *, int); 33 | extern void *my_get_ZSTR(char **, void *, int); 34 | extern void *my_get_DWORD_LE(myDWORD *, void *); 35 | extern void *my_get_WORD_LE(myWORD *, void *); 36 | extern void *my_get_SHORT_LE(mySHORT *, void *); 37 | extern void *my_get_DWORD_BE(myDWORD *, void *); 38 | extern void *my_get_WORD_BE(myWORD *, void *); 39 | extern void *my_get_SHORT_BE(mySHORT *, void *); 40 | extern void *my_get_BYTE(myBYTE *, void *); 41 | extern void *my_get_IEEE80(myIEEE80 *, void *); 42 | extern void *my_get_PSTRING(myPSTRING *, void *); 43 | extern void *my_put_CHAR(char *, void *, int); 44 | #define my_put_ZSTR my_put_CHAR 45 | extern void *my_put_DWORD_LE(myDWORD *, void *); 46 | extern void *my_put_WORD_LE(myWORD *, void *); 47 | extern void *my_put_SHORT_LE(mySHORT *, void *); 48 | extern void *my_put_DWORD_BE(myDWORD *, void *); 49 | extern void *my_put_WORD_BE(myWORD *, void *); 50 | extern void *my_put_SHORT_BE(mySHORT *, void *); 51 | extern void *my_put_BYTE(myBYTE *, void *); 52 | extern void *my_put_IEEE80(myIEEE80 *, void *); 53 | extern void *my_put_PSTRING(myPSTRING *, void *); 54 | extern int my_size_PSTRING(myPSTRING *); 55 | #endif 56 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/include/riffraff/rifftypes.h: -------------------------------------------------------------------------------- 1 | #ifndef __RIFF_TYPES_H__ 2 | #define __RIFF_TYPES_H__ 3 | 4 | #ifdef uint8_t 5 | typedef uint8_t myBYTE; 6 | typedef int8_t myCHAR; 7 | typedef int16_t mySHORT; 8 | typedef uint16_t myWORD; 9 | typedef uint32_t myDWORD; 10 | #else 11 | typedef unsigned char myBYTE; 12 | typedef char myCHAR; 13 | typedef char* myZSTR; 14 | typedef unsigned int myDWORD; 15 | typedef short int mySHORT; 16 | typedef unsigned short int myWORD; 17 | #endif 18 | 19 | typedef union { 20 | char str[4]; 21 | myDWORD dword; 22 | } myFOURCC; 23 | 24 | typedef char myIEEE80[10]; 25 | 26 | #define PSTRING_STR_MAXLEN 256 27 | typedef struct { 28 | int count; /* pascal string, maximum value for count is 255 */ 29 | char str[PSTRING_STR_MAXLEN]; /* also zero-terminate this string */ 30 | } myPSTRING; 31 | 32 | extern void *my_get_CHAR(char *, void *, int); 33 | extern void *my_get_ZSTR(char **, void *, int); 34 | extern void *my_get_DWORD_LE(myDWORD *, void *); 35 | extern void *my_get_WORD_LE(myWORD *, void *); 36 | extern void *my_get_SHORT_LE(mySHORT *, void *); 37 | extern void *my_get_DWORD_BE(myDWORD *, void *); 38 | extern void *my_get_WORD_BE(myWORD *, void *); 39 | extern void *my_get_SHORT_BE(mySHORT *, void *); 40 | extern void *my_get_BYTE(myBYTE *, void *); 41 | extern void *my_get_IEEE80(myIEEE80 *, void *); 42 | extern void *my_get_PSTRING(myPSTRING *, void *); 43 | extern void *my_put_CHAR(char *, void *, int); 44 | #define my_put_ZSTR my_put_CHAR 45 | extern void *my_put_DWORD_LE(myDWORD *, void *); 46 | extern void *my_put_WORD_LE(myWORD *, void *); 47 | extern void *my_put_SHORT_LE(mySHORT *, void *); 48 | extern void *my_put_DWORD_BE(myDWORD *, void *); 49 | extern void *my_put_WORD_BE(myWORD *, void *); 50 | extern void *my_put_SHORT_BE(mySHORT *, void *); 51 | extern void *my_put_BYTE(myBYTE *, void *); 52 | extern void *my_put_IEEE80(myIEEE80 *, void *); 53 | extern void *my_put_PSTRING(myPSTRING *, void *); 54 | extern int my_size_PSTRING(myPSTRING *); 55 | #endif 56 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/riff.h: -------------------------------------------------------------------------------- 1 | #ifndef __RIFF_H__ 2 | #define __RIFF_H__ 3 | 4 | #include 5 | #include "rifftypes.h" 6 | 7 | typedef enum { 8 | ON_DISK = 1, 9 | IN_RAM 10 | } chunk_loc_t; 11 | 12 | #define CHUNK_HEADER_SIZE (sizeof(myFOURCC) + sizeof(myDWORD)) 13 | 14 | typedef struct { 15 | myFOURCC ckID; 16 | myDWORD ckSize; 17 | long offset; 18 | int order; /* order read in file, hierarchical not linear */ 19 | int item; /* order found in riff structure */ 20 | chunk_loc_t location; 21 | void *parent; 22 | void *data; 23 | int endian; 24 | int count; /* count of "records" w/in "data" */ 25 | 26 | void (*data_read_bytes)(void *, FILE *, char *, int); /* fpos change */ 27 | void *(*data_read)(void *, FILE *); /* fpos change */ 28 | void (*data_seek)(void *, FILE *); /* fpos change */ 29 | void (*data_write)(void *, void *, int, FILE *); /* fpos change */ 30 | void (*destroy)(void *); 31 | void (*end_seek)(void *, FILE *); /* fpos change */ 32 | char *(*form_get)(void *, FILE *); /* fpos change */ 33 | int (*form_check)(void *, char *, FILE *); /* fpos change */ 34 | void (*header_read)(void *, FILE *); 35 | void (*header_write)(void *, FILE *); /* fpos change */ 36 | int (*is_end)(void *, FILE *); 37 | int (*pad_write)(void *, FILE *); /* fpos change */ 38 | int (*size)(void *); 39 | void (*start_seek)(void *, FILE *); /* fpos change */ 40 | int (*write)(void *, FILE *); /* fpos change */ 41 | } chunk_t; 42 | 43 | typedef void (*print_funcptr)(void *, chunk_t *, char *); 44 | 45 | typedef struct { 46 | int level; 47 | char ckID[5]; 48 | char *form; 49 | print_funcptr print; 50 | chunk_t *chunk; 51 | } tree_item; 52 | 53 | typedef char tree_container[5]; 54 | 55 | typedef struct { 56 | /* used to describe a RIFF format */ 57 | tree_item *items; 58 | tree_container *containers; 59 | 60 | /* used to navigate a RIFF format */ 61 | int (*ckID_find)(void *, char *, char *, int); 62 | void (*print)(void *, int, char *, char *, FILE *, FILE *); 63 | void (*read)(void *, chunk_t *, int, FILE *); 64 | void (*destroy)(void *); 65 | FILE *ifp; 66 | FILE *ofp; 67 | char *prefix; 68 | char *wt_prefix; 69 | void *parent; 70 | } tree_t; 71 | 72 | extern chunk_t *chunk_new(void *, chunk_loc_t); 73 | extern tree_t *tree_new(tree_item *, tree_container *, void *); 74 | #endif 75 | -------------------------------------------------------------------------------- /sfubar-9/include/riffraff/riff.h: -------------------------------------------------------------------------------- 1 | #ifndef __RIFF_H__ 2 | #define __RIFF_H__ 3 | 4 | #include 5 | #include "rifftypes.h" 6 | 7 | typedef enum { 8 | ON_DISK = 1, 9 | IN_RAM 10 | } chunk_loc_t; 11 | 12 | #define CHUNK_HEADER_SIZE (sizeof(myFOURCC) + sizeof(myDWORD)) 13 | 14 | typedef struct { 15 | myFOURCC ckID; 16 | myDWORD ckSize; 17 | long offset; 18 | int order; /* order read in file, hierarchical not linear */ 19 | int item; /* order found in riff structure */ 20 | chunk_loc_t location; 21 | void *parent; 22 | void *data; 23 | int endian; 24 | int count; /* count of "records" w/in "data" */ 25 | 26 | void (*data_read_bytes)(void *, FILE *, char *, int); /* fpos change */ 27 | void *(*data_read)(void *, FILE *); /* fpos change */ 28 | void (*data_seek)(void *, FILE *); /* fpos change */ 29 | void (*data_write)(void *, void *, int, FILE *); /* fpos change */ 30 | void (*destroy)(void *); 31 | void (*end_seek)(void *, FILE *); /* fpos change */ 32 | char *(*form_get)(void *, FILE *); /* fpos change */ 33 | int (*form_check)(void *, char *, FILE *); /* fpos change */ 34 | void (*header_read)(void *, FILE *); 35 | void (*header_write)(void *, FILE *); /* fpos change */ 36 | int (*is_end)(void *, FILE *); 37 | int (*pad_write)(void *, FILE *); /* fpos change */ 38 | int (*size)(void *); 39 | void (*start_seek)(void *, FILE *); /* fpos change */ 40 | int (*write)(void *, FILE *); /* fpos change */ 41 | } chunk_t; 42 | 43 | typedef void (*print_funcptr)(void *, chunk_t *, char *); 44 | 45 | typedef struct { 46 | int level; 47 | char ckID[5]; 48 | char *form; 49 | print_funcptr print; 50 | chunk_t *chunk; 51 | } tree_item; 52 | 53 | typedef char tree_container[5]; 54 | 55 | typedef struct { 56 | /* used to describe a RIFF format */ 57 | tree_item *items; 58 | tree_container *containers; 59 | 60 | /* used to navigate a RIFF format */ 61 | int (*ckID_find)(void *, char *, char *, int); 62 | void (*print)(void *, int, char *, char *, FILE *, FILE *); 63 | void (*read)(void *, chunk_t *, int, FILE *); 64 | void (*destroy)(void *); 65 | FILE *ifp; 66 | FILE *ofp; 67 | char *prefix; 68 | char *wt_prefix; 69 | void *parent; 70 | } tree_t; 71 | 72 | extern chunk_t *chunk_new(void *, chunk_loc_t); 73 | extern tree_t *tree_new(tree_item *, tree_container *, void *); 74 | #endif 75 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/include/riffraff/riff.h: -------------------------------------------------------------------------------- 1 | #ifndef __RIFF_H__ 2 | #define __RIFF_H__ 3 | 4 | #include 5 | #include "rifftypes.h" 6 | 7 | typedef enum { 8 | ON_DISK = 1, 9 | IN_RAM 10 | } chunk_loc_t; 11 | 12 | #define CHUNK_HEADER_SIZE (sizeof(myFOURCC) + sizeof(myDWORD)) 13 | 14 | typedef struct { 15 | myFOURCC ckID; 16 | myDWORD ckSize; 17 | long offset; 18 | int order; /* order read in file, hierarchical not linear */ 19 | int item; /* order found in riff structure */ 20 | chunk_loc_t location; 21 | void *parent; 22 | void *data; 23 | int endian; 24 | int count; /* count of "records" w/in "data" */ 25 | 26 | void (*data_read_bytes)(void *, FILE *, char *, int); /* fpos change */ 27 | void *(*data_read)(void *, FILE *); /* fpos change */ 28 | void (*data_seek)(void *, FILE *); /* fpos change */ 29 | void (*data_write)(void *, void *, int, FILE *); /* fpos change */ 30 | void (*destroy)(void *); 31 | void (*end_seek)(void *, FILE *); /* fpos change */ 32 | char *(*form_get)(void *, FILE *); /* fpos change */ 33 | int (*form_check)(void *, char *, FILE *); /* fpos change */ 34 | void (*header_read)(void *, FILE *); 35 | void (*header_write)(void *, FILE *); /* fpos change */ 36 | int (*is_end)(void *, FILE *); 37 | int (*pad_write)(void *, FILE *); /* fpos change */ 38 | int (*size)(void *); 39 | void (*start_seek)(void *, FILE *); /* fpos change */ 40 | int (*write)(void *, FILE *); /* fpos change */ 41 | } chunk_t; 42 | 43 | typedef void (*print_funcptr)(void *, chunk_t *, char *); 44 | 45 | typedef struct { 46 | int level; 47 | char ckID[5]; 48 | char *form; 49 | print_funcptr print; 50 | chunk_t *chunk; 51 | } tree_item; 52 | 53 | typedef char tree_container[5]; 54 | 55 | typedef struct { 56 | /* used to describe a RIFF format */ 57 | tree_item *items; 58 | tree_container *containers; 59 | 60 | /* used to navigate a RIFF format */ 61 | int (*ckID_find)(void *, char *, char *, int); 62 | void (*print)(void *, int, char *, char *, FILE *, FILE *); 63 | void (*read)(void *, chunk_t *, int, FILE *); 64 | void (*destroy)(void *); 65 | FILE *ifp; 66 | FILE *ofp; 67 | char *prefix; 68 | char *wt_prefix; 69 | void *parent; 70 | } tree_t; 71 | 72 | extern chunk_t *chunk_new(void *, chunk_loc_t); 73 | extern tree_t *tree_new(tree_item *, tree_container *, void *); 74 | #endif 75 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/aif.h: -------------------------------------------------------------------------------- 1 | #ifndef __AIF_H__ 2 | #define __AIF_H__ 3 | #include "rifftypes.h" 4 | 5 | typedef struct { 6 | myDWORD timestamp; 7 | } fver_t; 8 | 9 | typedef struct { 10 | /* AIFF attributes */ 11 | myWORD numChannels; 12 | myDWORD numSampleFrames; 13 | myWORD sampleSize; /* bits */ 14 | myWORD samplePointSize; /* sampleSize padded and converted to bytes */ 15 | myIEEE80 sampleRate; 16 | double double_sampleRate; 17 | 18 | /* AIFC attributes */ 19 | myFOURCC compressionType; 20 | myPSTRING compressionName; 21 | } comm_t; 22 | 23 | typedef struct { 24 | myDWORD offset; 25 | myDWORD blockSize; 26 | long fpos_WaveformData; 27 | long bytes_WaveformData; 28 | } ssnd_t; 29 | 30 | typedef struct { 31 | myWORD id; 32 | myDWORD position; 33 | myPSTRING markerName; 34 | } mrkr_t; 35 | 36 | typedef struct { 37 | myWORD numMarkers; 38 | mrkr_t **markers; 39 | } mark_t; 40 | 41 | #define AIF_LOOP_NONE 0 42 | #define AIF_LOOP_FORWARD 1 43 | #define AIF_LOOP_PINGPONG 2 44 | #define AIF_LOOP_MAX 2 45 | 46 | typedef struct { 47 | myWORD playMode; 48 | myWORD beginLoop; 49 | myWORD endLoop; 50 | } loop_t; 51 | 52 | typedef struct { 53 | myCHAR baseNote; /* MIDI note 0 to 127 */ 54 | myCHAR detune; /* pitch shift in cents, -50 to 50 */ 55 | myCHAR lowNote; /* MIDI note */ 56 | myCHAR highNote; /* MIDI note */ 57 | myCHAR lowVelocity; /* MIDI velocity 1 to 127 */ 58 | myCHAR highVelocity; /* MIDI velocity */ 59 | mySHORT gain; /* decibels */ 60 | loop_t sustainLoop; 61 | loop_t releaseLoop; 62 | } inst_t; 63 | 64 | typedef struct { 65 | myDWORD timeStamp; 66 | myWORD marker; 67 | myWORD count; 68 | char *text; 69 | } cmnt_t; 70 | 71 | typedef struct { 72 | myWORD numComments; 73 | cmnt_t **comments; 74 | } comt_t; 75 | 76 | typedef struct { 77 | fver_t fver; 78 | comm_t comm; 79 | mark_t mark; 80 | inst_t inst; 81 | comt_t comt; 82 | char *name; 83 | char *auth; 84 | char *copy; 85 | char *anno; 86 | ssnd_t ssnd; 87 | 88 | chunk_t *src; 89 | chunk_t *dst; 90 | chunk_t *tmp; 91 | void (*destroy)(void *); 92 | void (*header_set)(void *, myWORD, myDWORD, myWORD, myIEEE80, myDWORD, 93 | char *, char *); 94 | int (*header_read)(void *, FILE *); 95 | void (*header_write)(void *, FILE *); 96 | void (*sample_calc)(void *); 97 | int (*marker_find)(void *, myWORD); 98 | tree_t *tree; 99 | } aif_t; 100 | 101 | #define ieee80_44100 "\x40\x0E\xAC\x44\x00\x00\x00\x00\x00\x00" 102 | #define AIFC_VERSION1 2726318400UL 103 | #define COMPRESSION_TYPE_NONE "NONE" 104 | #define COMPRESSION_NAME_NOT "not compressed" 105 | extern aif_t *aif_new(void); 106 | #endif 107 | -------------------------------------------------------------------------------- /sfubar-9/include/riffraff/aif.h: -------------------------------------------------------------------------------- 1 | #ifndef __AIF_H__ 2 | #define __AIF_H__ 3 | #include "rifftypes.h" 4 | 5 | typedef struct { 6 | myDWORD timestamp; 7 | } fver_t; 8 | 9 | typedef struct { 10 | /* AIFF attributes */ 11 | myWORD numChannels; 12 | myDWORD numSampleFrames; 13 | myWORD sampleSize; /* bits */ 14 | myWORD samplePointSize; /* sampleSize padded and converted to bytes */ 15 | myIEEE80 sampleRate; 16 | double double_sampleRate; 17 | 18 | /* AIFC attributes */ 19 | myFOURCC compressionType; 20 | myPSTRING compressionName; 21 | } comm_t; 22 | 23 | typedef struct { 24 | myDWORD offset; 25 | myDWORD blockSize; 26 | long fpos_WaveformData; 27 | long bytes_WaveformData; 28 | } ssnd_t; 29 | 30 | typedef struct { 31 | myWORD id; 32 | myDWORD position; 33 | myPSTRING markerName; 34 | } mrkr_t; 35 | 36 | typedef struct { 37 | myWORD numMarkers; 38 | mrkr_t **markers; 39 | } mark_t; 40 | 41 | #define AIF_LOOP_NONE 0 42 | #define AIF_LOOP_FORWARD 1 43 | #define AIF_LOOP_PINGPONG 2 44 | #define AIF_LOOP_MAX 2 45 | 46 | typedef struct { 47 | myWORD playMode; 48 | myWORD beginLoop; 49 | myWORD endLoop; 50 | } loop_t; 51 | 52 | typedef struct { 53 | myCHAR baseNote; /* MIDI note 0 to 127 */ 54 | myCHAR detune; /* pitch shift in cents, -50 to 50 */ 55 | myCHAR lowNote; /* MIDI note */ 56 | myCHAR highNote; /* MIDI note */ 57 | myCHAR lowVelocity; /* MIDI velocity 1 to 127 */ 58 | myCHAR highVelocity; /* MIDI velocity */ 59 | mySHORT gain; /* decibels */ 60 | loop_t sustainLoop; 61 | loop_t releaseLoop; 62 | } inst_t; 63 | 64 | typedef struct { 65 | myDWORD timeStamp; 66 | myWORD marker; 67 | myWORD count; 68 | char *text; 69 | } cmnt_t; 70 | 71 | typedef struct { 72 | myWORD numComments; 73 | cmnt_t **comments; 74 | } comt_t; 75 | 76 | typedef struct { 77 | fver_t fver; 78 | comm_t comm; 79 | mark_t mark; 80 | inst_t inst; 81 | comt_t comt; 82 | char *name; 83 | char *auth; 84 | char *copy; 85 | char *anno; 86 | ssnd_t ssnd; 87 | 88 | chunk_t *src; 89 | chunk_t *dst; 90 | chunk_t *tmp; 91 | void (*destroy)(void *); 92 | void (*header_set)(void *, myWORD, myDWORD, myWORD, myIEEE80, myDWORD, 93 | char *, char *); 94 | int (*header_read)(void *, FILE *); 95 | void (*header_write)(void *, FILE *); 96 | void (*sample_calc)(void *); 97 | int (*marker_find)(void *, myWORD); 98 | tree_t *tree; 99 | } aif_t; 100 | 101 | #define ieee80_44100 "\x40\x0E\xAC\x44\x00\x00\x00\x00\x00\x00" 102 | #define AIFC_VERSION1 2726318400UL 103 | #define COMPRESSION_TYPE_NONE "NONE" 104 | #define COMPRESSION_NAME_NOT "not compressed" 105 | extern aif_t *aif_new(void); 106 | #endif 107 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/include/riffraff/aif.h: -------------------------------------------------------------------------------- 1 | #ifndef __AIF_H__ 2 | #define __AIF_H__ 3 | #include "rifftypes.h" 4 | 5 | typedef struct { 6 | myDWORD timestamp; 7 | } fver_t; 8 | 9 | typedef struct { 10 | /* AIFF attributes */ 11 | myWORD numChannels; 12 | myDWORD numSampleFrames; 13 | myWORD sampleSize; /* bits */ 14 | myWORD samplePointSize; /* sampleSize padded and converted to bytes */ 15 | myIEEE80 sampleRate; 16 | double double_sampleRate; 17 | 18 | /* AIFC attributes */ 19 | myFOURCC compressionType; 20 | myPSTRING compressionName; 21 | } comm_t; 22 | 23 | typedef struct { 24 | myDWORD offset; 25 | myDWORD blockSize; 26 | long fpos_WaveformData; 27 | long bytes_WaveformData; 28 | } ssnd_t; 29 | 30 | typedef struct { 31 | myWORD id; 32 | myDWORD position; 33 | myPSTRING markerName; 34 | } mrkr_t; 35 | 36 | typedef struct { 37 | myWORD numMarkers; 38 | mrkr_t **markers; 39 | } mark_t; 40 | 41 | #define AIF_LOOP_NONE 0 42 | #define AIF_LOOP_FORWARD 1 43 | #define AIF_LOOP_PINGPONG 2 44 | #define AIF_LOOP_MAX 2 45 | 46 | typedef struct { 47 | myWORD playMode; 48 | myWORD beginLoop; 49 | myWORD endLoop; 50 | } loop_t; 51 | 52 | typedef struct { 53 | myCHAR baseNote; /* MIDI note 0 to 127 */ 54 | myCHAR detune; /* pitch shift in cents, -50 to 50 */ 55 | myCHAR lowNote; /* MIDI note */ 56 | myCHAR highNote; /* MIDI note */ 57 | myCHAR lowVelocity; /* MIDI velocity 1 to 127 */ 58 | myCHAR highVelocity; /* MIDI velocity */ 59 | mySHORT gain; /* decibels */ 60 | loop_t sustainLoop; 61 | loop_t releaseLoop; 62 | } inst_t; 63 | 64 | typedef struct { 65 | myDWORD timeStamp; 66 | myWORD marker; 67 | myWORD count; 68 | char *text; 69 | } cmnt_t; 70 | 71 | typedef struct { 72 | myWORD numComments; 73 | cmnt_t **comments; 74 | } comt_t; 75 | 76 | typedef struct { 77 | fver_t fver; 78 | comm_t comm; 79 | mark_t mark; 80 | inst_t inst; 81 | comt_t comt; 82 | char *name; 83 | char *auth; 84 | char *copy; 85 | char *anno; 86 | ssnd_t ssnd; 87 | 88 | chunk_t *src; 89 | chunk_t *dst; 90 | chunk_t *tmp; 91 | void (*destroy)(void *); 92 | void (*header_set)(void *, myWORD, myDWORD, myWORD, myIEEE80, myDWORD, 93 | char *, char *); 94 | int (*header_read)(void *, FILE *); 95 | void (*header_write)(void *, FILE *); 96 | void (*sample_calc)(void *); 97 | int (*marker_find)(void *, myWORD); 98 | tree_t *tree; 99 | } aif_t; 100 | 101 | #define ieee80_44100 "\x40\x0E\xAC\x44\x00\x00\x00\x00\x00\x00" 102 | #define AIFC_VERSION1 2726318400UL 103 | #define COMPRESSION_TYPE_NONE "NONE" 104 | #define COMPRESSION_NAME_NOT "not compressed" 105 | extern aif_t *aif_new(void); 106 | #endif 107 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/bio.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | FILE *bens_fopen(const char *path, const char *mode) 10 | { 11 | char mode2[10]; 12 | FILE *retval; 13 | if (strcmp(path, "-") == 0) { 14 | if (mode[0] == 'r') 15 | retval = stdin; 16 | if (mode[0] == 'w' || mode[0] == 'a') 17 | retval = stdout; 18 | } else { 19 | /* The b is necessary for Windows. */ 20 | snprintf(mode2, 10, "%sb", mode); 21 | retval = fopen(path, mode2); 22 | if (retval == NULL) 23 | trap_exit("sfubar: %s", strerror(errno)); 24 | } 25 | 26 | #ifdef __MINGW32__ 27 | /* this was not necessary when cross-compiling from NetBSD using mingw32 28 | but it is necessary when using -mno-windows on Cygwin. -Ben 29 | */ 30 | _setmode(_fileno(retval), _O_BINARY); 31 | #endif 32 | 33 | return retval; 34 | } 35 | 36 | void bens_fclose(FILE *fp) 37 | { 38 | if (fp != stdin && fp != stdout) 39 | fclose(fp); 40 | } 41 | 42 | void bens_fread(void *buffer, size_t size, size_t nmemb, FILE * fp) 43 | { 44 | int result; 45 | int myerror; 46 | long position; 47 | 48 | position = ftell(fp); 49 | result = fread(buffer, size, nmemb, fp); 50 | if (result != nmemb) { 51 | myerror = ferror(fp); 52 | trap_exit("fread(%p,%zd,%zd,%p) = 0\nerror = %d, position = %ld, eof = %d", 53 | buffer, size, nmemb, fp, myerror, position, feof(fp)); 54 | } 55 | } 56 | 57 | void bens_fwrite(void *buffer, size_t size, size_t nmemb, FILE * fp) 58 | { 59 | int result; 60 | int myerror; 61 | long position; 62 | 63 | position = ftell(fp); 64 | result = fwrite(buffer, size, nmemb, fp); 65 | if (result != nmemb) { 66 | myerror = ferror(fp); 67 | trap_exit("fwrite(%p,%zd,%zd,%p) = 0\nerror = %d, position = %ld, eof = %d", 68 | buffer, size, nmemb, fp, myerror, position, feof(fp)); 69 | } 70 | } 71 | 72 | void buffer_swap(char *buffer, int size) 73 | { 74 | char *p = buffer; 75 | int left = size; 76 | char c; 77 | while (left > 1) { 78 | c = p[1]; 79 | p[1] = p[0]; 80 | p[0] = c; 81 | left -= 2; 82 | p += 2; 83 | } 84 | } 85 | 86 | #define DCLEN 2048 87 | void data_copy(FILE *ifp, FILE *ofp, int length, int swap) 88 | { 89 | char buffer[DCLEN]; 90 | int left = length; 91 | int size; 92 | 93 | while (left > 0) { 94 | if (left > DCLEN) { 95 | size = DCLEN; 96 | } else { 97 | size = left; 98 | } 99 | bens_fread(buffer, size, 1, ifp); 100 | if (swap) 101 | buffer_swap(buffer, size); 102 | bens_fwrite(buffer, size, 1, ofp); 103 | left -= size; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /sfubar-9/sfutil.h: -------------------------------------------------------------------------------- 1 | #ifndef __SFUTIL_H__ 2 | #define __SFUTIL_H__ 3 | #include 4 | extern void sf_to_txt(char *, char *, int); 5 | extern void txt_to_sf(char *, char *); 6 | #define SFUTIL_VERSION 9 7 | 8 | #define SHMIN -32768 9 | #define SHOOBVAL -32769 10 | 11 | typedef enum { 12 | file_type_wav, 13 | file_type_aif, 14 | file_type_end 15 | } file_type_t; 16 | 17 | typedef struct { 18 | myBYTE byLo; 19 | myBYTE byHi; 20 | } rangesType; 21 | 22 | typedef union { 23 | rangesType ranges; 24 | mySHORT shAmount; 25 | myWORD wAmount; 26 | } genAmountType; 27 | 28 | typedef enum { 29 | sfg_0_startAddrsOffset = 0, 30 | sfg_1_endAddrsOffset, 31 | sfg_2_startloopAddrsOffset, 32 | sfg_3_endloopAddrsOffset, 33 | sfg_4_startAddrsCoarseOffset, 34 | sfg_5_modLfoToPitch, 35 | sfg_6_vibLfoToPitchi, 36 | sfg_7_modEnvToPitch, 37 | sfg_8_initialFilterFc, 38 | sfg_9_initialFilterQ, 39 | sfg_10_modLfoToFilterFc, 40 | sfg_11_modEnvToFilterFc, 41 | sfg_12_endAddrsCoarseOffset, 42 | sfg_13_modLfoToVolume, 43 | sfg_14_unused, 44 | sfg_15_chorusEffectsSend, 45 | sfg_16_reverbEffectsSend, 46 | sfg_17_pan, 47 | sfg_18_unused, 48 | sfg_19_unused, 49 | sfg_20_unused, 50 | sfg_21_delayModLFO, 51 | sfg_22_freqModLFO, 52 | sfg_23_delayVibLFO, 53 | sfg_24_freqVibLFO, 54 | sfg_25_delayModEnv, 55 | sfg_26_attackModEnv, 56 | sfg_27_holdModEnv, 57 | sfg_28_decayModEnv, 58 | sfg_29_sustainModEnv, 59 | sfg_30_releaseModEnv, 60 | sfg_31_keynumToModEnvHold, 61 | sfg_32_keynumToModEnvDecay, 62 | sfg_33_delayVolEnv, 63 | sfg_34_attackVolEnv, 64 | sfg_35_holdVolEnv, 65 | sfg_36_decayVolEnv, 66 | sfg_37_sustainVolEnv, 67 | sfg_38_releaseVolEnv, 68 | sfg_39_keynumToVolEnvHold, 69 | sfg_40_keynumToVolEnvDecay, 70 | sfg_41_instrument, 71 | sfg_42_reserved, 72 | sfg_43_keyRange, 73 | sfg_44_velRange, 74 | sfg_45_startloopAddrsCoarseOffset, 75 | sfg_46_keynum, 76 | sfg_47_velocity, 77 | sfg_48_initialAttenuation, 78 | sfg_49_reserved, 79 | sfg_50_endloopAddrsCoarseOffset, 80 | sfg_51_coarseTune, 81 | sfg_52_fineTune, 82 | sfg_53_sampleID, 83 | sfg_54_sampleModes, 84 | sfg_55_reserved, 85 | sfg_56_scaleTuning, 86 | sfg_57_exclusiveClass, 87 | sfg_58_overridingRootKey, 88 | sfg_59_unused, 89 | sfg_60_endOper 90 | } sf_gen_enum_t; 91 | 92 | typedef enum { 93 | sml_loop_none = 0, 94 | sml_loop_continuous, 95 | sml_loop_unused, 96 | sml_loop_release 97 | } sample_modes_enum_t; 98 | 99 | typedef enum { 100 | zt_instrument = 0, 101 | zt_preset 102 | } zone_type_enum_t; 103 | 104 | typedef struct { 105 | zone_type_enum_t zone_type; 106 | char *keyn; 107 | char *key; 108 | char *itemn; 109 | char *item; 110 | int item_max; 111 | int oper; 112 | char *bagc; 113 | char *genc; 114 | char *modc; 115 | char *hdrc; 116 | } zone_type_t; 117 | #endif 118 | -------------------------------------------------------------------------------- /sfubar-9/include/sfutil.h: -------------------------------------------------------------------------------- 1 | #ifndef __SFUTIL_H__ 2 | #define __SFUTIL_H__ 3 | #include 4 | extern void sf_to_txt(char *, char *, int); 5 | extern void txt_to_sf(char *, char *); 6 | #define SFUTIL_VERSION 9 7 | 8 | #define SHMIN -32768 9 | #define SHOOBVAL -32769 10 | 11 | typedef enum { 12 | file_type_wav, 13 | file_type_aif, 14 | file_type_end 15 | } file_type_t; 16 | 17 | typedef struct { 18 | myBYTE byLo; 19 | myBYTE byHi; 20 | } rangesType; 21 | 22 | typedef union { 23 | rangesType ranges; 24 | mySHORT shAmount; 25 | myWORD wAmount; 26 | } genAmountType; 27 | 28 | typedef enum { 29 | sfg_0_startAddrsOffset = 0, 30 | sfg_1_endAddrsOffset, 31 | sfg_2_startloopAddrsOffset, 32 | sfg_3_endloopAddrsOffset, 33 | sfg_4_startAddrsCoarseOffset, 34 | sfg_5_modLfoToPitch, 35 | sfg_6_vibLfoToPitchi, 36 | sfg_7_modEnvToPitch, 37 | sfg_8_initialFilterFc, 38 | sfg_9_initialFilterQ, 39 | sfg_10_modLfoToFilterFc, 40 | sfg_11_modEnvToFilterFc, 41 | sfg_12_endAddrsCoarseOffset, 42 | sfg_13_modLfoToVolume, 43 | sfg_14_unused, 44 | sfg_15_chorusEffectsSend, 45 | sfg_16_reverbEffectsSend, 46 | sfg_17_pan, 47 | sfg_18_unused, 48 | sfg_19_unused, 49 | sfg_20_unused, 50 | sfg_21_delayModLFO, 51 | sfg_22_freqModLFO, 52 | sfg_23_delayVibLFO, 53 | sfg_24_freqVibLFO, 54 | sfg_25_delayModEnv, 55 | sfg_26_attackModEnv, 56 | sfg_27_holdModEnv, 57 | sfg_28_decayModEnv, 58 | sfg_29_sustainModEnv, 59 | sfg_30_releaseModEnv, 60 | sfg_31_keynumToModEnvHold, 61 | sfg_32_keynumToModEnvDecay, 62 | sfg_33_delayVolEnv, 63 | sfg_34_attackVolEnv, 64 | sfg_35_holdVolEnv, 65 | sfg_36_decayVolEnv, 66 | sfg_37_sustainVolEnv, 67 | sfg_38_releaseVolEnv, 68 | sfg_39_keynumToVolEnvHold, 69 | sfg_40_keynumToVolEnvDecay, 70 | sfg_41_instrument, 71 | sfg_42_reserved, 72 | sfg_43_keyRange, 73 | sfg_44_velRange, 74 | sfg_45_startloopAddrsCoarseOffset, 75 | sfg_46_keynum, 76 | sfg_47_velocity, 77 | sfg_48_initialAttenuation, 78 | sfg_49_reserved, 79 | sfg_50_endloopAddrsCoarseOffset, 80 | sfg_51_coarseTune, 81 | sfg_52_fineTune, 82 | sfg_53_sampleID, 83 | sfg_54_sampleModes, 84 | sfg_55_reserved, 85 | sfg_56_scaleTuning, 86 | sfg_57_exclusiveClass, 87 | sfg_58_overridingRootKey, 88 | sfg_59_unused, 89 | sfg_60_endOper 90 | } sf_gen_enum_t; 91 | 92 | typedef enum { 93 | sml_loop_none = 0, 94 | sml_loop_continuous, 95 | sml_loop_unused, 96 | sml_loop_release 97 | } sample_modes_enum_t; 98 | 99 | typedef enum { 100 | zt_instrument = 0, 101 | zt_preset 102 | } zone_type_enum_t; 103 | 104 | typedef struct { 105 | zone_type_enum_t zone_type; 106 | char *keyn; 107 | char *key; 108 | char *itemn; 109 | char *item; 110 | int item_max; 111 | int oper; 112 | char *bagc; 113 | char *genc; 114 | char *modc; 115 | char *hdrc; 116 | } zone_type_t; 117 | #endif 118 | -------------------------------------------------------------------------------- /sfubar-9/libparsetxt-4/parsetxt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include "parsetxt.h" 7 | 8 | void txt_destroy(void *vtxt) 9 | { 10 | int i; 11 | txt_t *txt = vtxt; 12 | for (i = 0; i < txt->line_count; i++) { 13 | free(txt->lines[i]->key); 14 | free(txt->lines[i]->data); 15 | free(txt->lines[i]); 16 | } 17 | free(txt); 18 | } 19 | 20 | int txt_find_key(void *vtxt, char *key) 21 | { 22 | int i; 23 | txt_t *txt = vtxt; 24 | 25 | for (i = 0; i < txt->line_count; i++) { 26 | if (strcmp(txt->lines[i]->key, key) == 0) { 27 | txt->l = txt->lines[i]->line_number; 28 | return i; 29 | } 30 | } 31 | return -1; 32 | } 33 | 34 | char *txt_get_data(void *vtxt, char *key) 35 | { 36 | int n; 37 | txt_t *txt = vtxt; 38 | 39 | n = txt_find_key(txt, key); 40 | if (n == -1) { 41 | return NULL; 42 | } else { 43 | txt->lines[n]->used = 1; 44 | return txt->lines[n]->data; 45 | } 46 | } 47 | 48 | void txt_add_data(void *vtxt, char *key, char *data, int line_number) 49 | { 50 | txt_t *txt = vtxt; 51 | 52 | txt->lines = realloc(txt->lines, 53 | (txt->line_count + 1) * sizeof(txt_line_t *)); 54 | txt->lines[txt->line_count] = malloc(sizeof(txt_line_t)); 55 | txt->lines[txt->line_count]->line_number = line_number; 56 | txt->lines[txt->line_count]->key = strdup(key); 57 | txt->lines[txt->line_count]->data = strdup(data); 58 | txt->lines[txt->line_count]->used = 0; 59 | txt->line_count++; 60 | } 61 | 62 | void txt_add_line(void *vtxt, char *line_data, int line_len, int line_number) 63 | { 64 | char *p; 65 | int n; 66 | txt_t *txt = vtxt; 67 | 68 | /* skip empty lines and comments */ 69 | if (line_len < 1 || line_data[0] == ';' || line_data[0] == '#') 70 | return; 71 | 72 | /* require nonempty keys and data */ 73 | p = strchr(line_data, '='); 74 | if (p == NULL) 75 | trap_exit("line %d invalid", line_number); 76 | *p = '\000'; 77 | p++; 78 | if (strcmp(line_data, "") == 0) 79 | trap_exit("line %d missing key", line_number); 80 | 81 | /* catch duplicate lines */ 82 | n = txt_find_key(txt, line_data); 83 | if (n != -1) 84 | trap_exit("duplicate lines %d and %d", 85 | line_number, txt->lines[n]->line_number); 86 | 87 | txt_add_data(txt, line_data, p, line_number); 88 | } 89 | 90 | void txt_read_lines(void *vtxt, FILE *fp) 91 | { 92 | char line_data[BUFLEN]; 93 | int len; 94 | int line_number = 1; 95 | txt_t *txt = vtxt; 96 | 97 | fgets(line_data, BUFLEN, fp); 98 | line_data[BUFLEN - 1] = '\000'; 99 | len = strlen(line_data); 100 | while (!feof(fp)) { 101 | if (len > 0) { 102 | if (line_data[len - 1] != '\n') { 103 | trap_warn("line %d lacks a newline, perhaps it is too long", 104 | line_number); 105 | } else { 106 | /* remove \n at end of line */ 107 | len--; 108 | line_data[len] = '\000'; 109 | /* deal with DOS newlines */ 110 | if (len > 0 && line_data[len - 1] == '\r') { 111 | len--; 112 | line_data[len] = '\000'; 113 | } 114 | } 115 | } 116 | txt_add_line(txt, line_data, len, line_number); 117 | fgets(line_data, BUFLEN, fp); 118 | line_data[BUFLEN - 1] = '\000'; 119 | len = strlen(line_data); 120 | line_number++; 121 | } 122 | } 123 | 124 | void txt_warn_unused(void *vtxt) 125 | { 126 | txt_t *txt = vtxt; 127 | int i; 128 | 129 | for (i = 0; i < txt->line_count; i++) { 130 | if (txt->lines[i]->used != 1) { 131 | txt->l = txt->lines[i]->line_number; 132 | trap_warn("unrecognized line"); 133 | } 134 | } 135 | } 136 | 137 | txt_t *txt_new(void) 138 | { 139 | txt_t *retval; 140 | 141 | retval = malloc(sizeof(txt_t)); 142 | retval->line_count = 0; 143 | retval->lines = NULL; 144 | retval->destroy = txt_destroy; 145 | retval->find_key = txt_find_key; 146 | retval->get_data = txt_get_data; 147 | retval->add_data = txt_add_data; 148 | retval->add_line = txt_add_line; 149 | retval->read_lines = txt_read_lines; 150 | retval->warn_unused = txt_warn_unused; 151 | return retval; 152 | } 153 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/rifftypes.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include "bits.h" 6 | #include "rifftypes.h" 7 | 8 | void *my_get_CHAR(char *retval, void *data, int size) 9 | { 10 | memcpy(retval, data, size); 11 | return data + size; 12 | } 13 | 14 | void *my_get_ZSTR(char **retval, void *data, int size) 15 | { 16 | char *b = data; 17 | char *p = data + size - 1; 18 | *retval = data; 19 | if (p[0] != '\000') { 20 | while (*b && b < p) 21 | b++; 22 | b[0] = '\000'; 23 | trap_warn("Unterminated ZSTR"); 24 | } 25 | return data + size; 26 | } 27 | 28 | void *my_get_DWORD_LE(myDWORD *retval, void *data) 29 | { 30 | memcpy(retval, data, sizeof(myDWORD)); 31 | *retval = LE32H(*retval); 32 | return data + sizeof(myDWORD); 33 | } 34 | 35 | void *my_get_WORD_LE(myWORD *retval, void *data) 36 | { 37 | memcpy(retval, data, sizeof(myWORD)); 38 | *retval = LE16H(*retval); 39 | return data + sizeof(myWORD); 40 | } 41 | 42 | void *my_get_SHORT_LE(mySHORT *retval, void *data) 43 | { 44 | memcpy(retval, data, sizeof(mySHORT)); 45 | *retval = LE16H(*retval); 46 | return data + sizeof(mySHORT); 47 | } 48 | 49 | void *my_get_DWORD_BE(myDWORD *retval, void *data) 50 | { 51 | memcpy(retval, data, sizeof(myDWORD)); 52 | *retval = BE32H(*retval); 53 | return data + sizeof(myDWORD); 54 | } 55 | 56 | void *my_get_WORD_BE(myWORD *retval, void *data) 57 | { 58 | memcpy(retval, data, sizeof(myWORD)); 59 | *retval = BE16H(*retval); 60 | return data + sizeof(myWORD); 61 | } 62 | 63 | void *my_get_SHORT_BE(mySHORT *retval, void *data) 64 | { 65 | memcpy(retval, data, sizeof(mySHORT)); 66 | *retval = BE16H(*retval); 67 | return data + sizeof(mySHORT); 68 | } 69 | 70 | void *my_get_BYTE(myBYTE *retval, void *data) 71 | { 72 | memcpy(retval, data, sizeof(myBYTE)); 73 | return data + sizeof(myBYTE); 74 | } 75 | 76 | void *my_get_IEEE80(myIEEE80 *retval, void *data) 77 | { 78 | memcpy(retval, data, sizeof(myIEEE80)); 79 | return data + sizeof(myIEEE80); 80 | } 81 | 82 | void *my_get_PSTRING(myPSTRING *retval, void *data) 83 | { 84 | char c; 85 | memset(retval->str, 0, sizeof(retval->str)); 86 | memcpy(&c, data, 1); 87 | retval->count = (int)c; 88 | data++; 89 | memcpy(retval->str, data, retval->count); 90 | data += retval->count; 91 | if ((1 + retval->count) % 2) 92 | data++; 93 | return data; 94 | } 95 | 96 | void *my_put_CHAR(char *retval, void *data, int size) 97 | { 98 | memcpy(data, retval, size); 99 | return data + size; 100 | } 101 | 102 | void *my_put_DWORD_LE(myDWORD *retval, void *data) 103 | { 104 | myDWORD temp = HLE32(*retval); 105 | memcpy(data, &temp, sizeof(myDWORD)); 106 | return data + sizeof(myDWORD); 107 | } 108 | 109 | void *my_put_WORD_LE(myWORD *retval, void *data) 110 | { 111 | myWORD temp = HLE16(*retval); 112 | memcpy(data, &temp, sizeof(myWORD)); 113 | return data + sizeof(myWORD); 114 | } 115 | 116 | void *my_put_SHORT_LE(mySHORT *retval, void *data) 117 | { 118 | mySHORT temp = HLE16(*retval); 119 | memcpy(data, &temp, sizeof(mySHORT)); 120 | return data + sizeof(mySHORT); 121 | } 122 | 123 | void *my_put_DWORD_BE(myDWORD *retval, void *data) 124 | { 125 | myDWORD temp = HBE32(*retval); 126 | memcpy(data, &temp, sizeof(myDWORD)); 127 | return data + sizeof(myDWORD); 128 | } 129 | 130 | void *my_put_WORD_BE(myWORD *retval, void *data) 131 | { 132 | myWORD temp = HBE16(*retval); 133 | memcpy(data, &temp, sizeof(myWORD)); 134 | return data + sizeof(myWORD); 135 | } 136 | 137 | void *my_put_SHORT_BE(mySHORT *retval, void *data) 138 | { 139 | mySHORT temp = HBE16(*retval); 140 | memcpy(data, &temp, sizeof(mySHORT)); 141 | return data + sizeof(mySHORT); 142 | } 143 | 144 | void *my_put_BYTE(myBYTE *retval, void *data) 145 | { 146 | memcpy(data, retval, sizeof(myBYTE)); 147 | return data + sizeof(myBYTE); 148 | } 149 | 150 | void *my_put_IEEE80(myIEEE80 *retval, void *data) 151 | { 152 | memcpy(data, retval, sizeof(myIEEE80)); 153 | return data + sizeof(myIEEE80); 154 | } 155 | 156 | void *my_put_PSTRING(myPSTRING *retval, void *data) 157 | { 158 | char c; 159 | c = (char)retval->count; 160 | memcpy(data, &c, 1); 161 | data++; 162 | memcpy(data, retval->str, retval->count); 163 | data += retval->count; 164 | if (!is_even(1 + retval->count)) { 165 | memset(data, 0, 1); 166 | data++; 167 | } 168 | return data; 169 | } 170 | 171 | int my_size_PSTRING(myPSTRING *pstr) 172 | { 173 | int retval = 1; 174 | retval += pstr->count; 175 | if ((1 + pstr->count) % 2) 176 | retval++; 177 | return retval; 178 | } 179 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/wav.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include "bits.h" 6 | #include "riff.h" 7 | #include "rifftypes.h" 8 | #include "wav.h" 9 | 10 | /* only supports writing the wave header */ 11 | 12 | tree_item wav_items[] = { 13 | { 0, "RIFF", "WAVE", NULL, NULL }, 14 | { 1, "fmt ", NULL, NULL, NULL }, 15 | { 1, "data", NULL, NULL, NULL }, 16 | { 1, "cue ", NULL, NULL, NULL }, 17 | { 1, "plst", NULL, NULL, NULL }, 18 | { 1, "LIST", "adtl", NULL, NULL }, 19 | { 1, "smpl", NULL, NULL, NULL }, 20 | { 1, "inst", NULL, NULL, NULL }, 21 | { 2, "labl", NULL, NULL, NULL }, 22 | { 2, "note", NULL, NULL, NULL }, 23 | { 2, "ltxt", NULL, NULL, NULL }, 24 | { -1, "", NULL, NULL, NULL } 25 | }; 26 | 27 | tree_container wav_containers[] = { "RIFF", "LIST", "" }; 28 | 29 | int wav_header_read(void *vwav, FILE *ifp) 30 | { 31 | void *p; 32 | wav_t *wav = vwav; 33 | int n; 34 | chunk_t *chunk_src; 35 | chunk_t *chunk_tmp; 36 | 37 | chunk_src = chunk_new(NULL, ON_DISK); 38 | chunk_src->header_read(chunk_src, ifp); 39 | wav->tree->read(wav->tree, chunk_src, 0, ifp); 40 | /* chunk_src is freed when wav->tree is destroyed */ 41 | 42 | n = wav->tree->ckID_find(wav->tree, "RIFF", "WAVE", 0); 43 | if (n == -1) { 44 | trap_warn("header_read: no RIFF chunk with WAVE form"); 45 | return 0; 46 | } 47 | 48 | n = wav->tree->ckID_find(wav->tree, "fmt ", NULL, 1); 49 | if (n == -1) { 50 | trap_warn("header_read: no fmt chunk"); 51 | return 0; 52 | } 53 | 54 | chunk_tmp = wav->tree->items[n].chunk; 55 | chunk_tmp->data_read(chunk_tmp, ifp); 56 | p = chunk_tmp->data; 57 | p = my_get_WORD_LE(&(wav->fmt.wFormatTag), p); 58 | p = my_get_WORD_LE(&(wav->fmt.wChannels), p); 59 | p = my_get_DWORD_LE(&(wav->fmt.dwSamplesPerSec), p); 60 | p = my_get_DWORD_LE(&(wav->fmt.dwAvgBytesPerSec), p); 61 | p = my_get_WORD_LE(&(wav->fmt.wBlockAlign), p); 62 | if (wav->fmt.wFormatTag == WAVE_FORMAT_PCM) 63 | p = my_get_WORD_LE(&(wav->fmt.wBitsPerSample), p); 64 | 65 | n = wav->tree->ckID_find(wav->tree, "data", NULL, 1); 66 | if (n == -1) { 67 | trap_warn("header_read: no data chunk"); 68 | return 0; 69 | } 70 | 71 | chunk_tmp = wav->tree->items[n].chunk; 72 | chunk_tmp->data_seek(chunk_tmp, ifp); 73 | wav->data.offset = ftell(ifp); 74 | wav->data.size = chunk_tmp->ckSize; 75 | return 1; 76 | } 77 | 78 | void wav_header_write(void *vwav, FILE *ofp) 79 | { 80 | wav_t *wav = vwav; 81 | void *p; 82 | chunk_t *chunk_tmp; 83 | chunk_t *chunk_dst; 84 | 85 | chunk_dst = chunk_new(NULL, IN_RAM); 86 | strncpy(chunk_dst->ckID.str, "RIFF", 4); 87 | chunk_dst->header_write(chunk_dst, ofp); 88 | chunk_dst->data_write(chunk_dst, "WAVE", 4, ofp); 89 | 90 | chunk_tmp = chunk_new(NULL, IN_RAM); 91 | strncpy(chunk_tmp->ckID.str, "fmt ", 4); 92 | chunk_tmp->ckSize = 16; 93 | chunk_tmp->data = realloc(chunk_tmp->data, chunk_tmp->ckSize); 94 | p = chunk_tmp->data; 95 | p = my_put_WORD_LE(&(wav->fmt.wFormatTag), p); 96 | p = my_put_WORD_LE(&(wav->fmt.wChannels), p); 97 | p = my_put_DWORD_LE(&(wav->fmt.dwSamplesPerSec), p); 98 | p = my_put_DWORD_LE(&(wav->fmt.dwAvgBytesPerSec), p); 99 | p = my_put_WORD_LE(&(wav->fmt.wBlockAlign), p); 100 | p = my_put_WORD_LE(&(wav->fmt.wBitsPerSample), p); 101 | chunk_dst->ckSize += chunk_tmp->write(chunk_tmp, ofp); 102 | chunk_tmp->destroy(chunk_tmp); 103 | 104 | chunk_tmp = chunk_new(NULL, IN_RAM); 105 | strncpy(chunk_tmp->ckID.str, "data", 4); 106 | chunk_tmp->ckSize = wav->data.size; 107 | chunk_tmp->header_write(chunk_tmp, ofp); 108 | chunk_dst->ckSize += CHUNK_HEADER_SIZE + chunk_tmp->ckSize; 109 | chunk_dst->start_seek(chunk_dst, ofp); 110 | chunk_dst->header_write(chunk_dst, ofp); 111 | chunk_tmp->data_seek(chunk_tmp, ofp); 112 | chunk_tmp->destroy(chunk_tmp); 113 | 114 | chunk_dst->destroy(chunk_dst); 115 | } 116 | 117 | void wav_header_set(void *vwav, myWORD channels, 118 | myWORD bytes_per_sample, myDWORD sample_rate, long sample_count) 119 | { 120 | wav_t *wav = vwav; 121 | wav->fmt.wBitsPerSample = bytes_per_sample * BITS_PER_BYTE; 122 | wav->fmt.wFormatTag = WAVE_FORMAT_PCM; 123 | wav->fmt.wChannels = channels; 124 | wav->fmt.dwSamplesPerSec = sample_rate; 125 | wav->fmt.dwAvgBytesPerSec = sample_rate * bytes_per_sample; 126 | wav->fmt.wBlockAlign = channels * bytes_per_sample; 127 | wav->data.offset = 0; 128 | wav->data.size = sample_count * bytes_per_sample; 129 | } 130 | 131 | void wav_destroy(void *vwav) 132 | { 133 | wav_t *wav = vwav; 134 | wav->tree->destroy(wav->tree); 135 | free(wav); 136 | } 137 | 138 | wav_t *wav_new(void) 139 | { 140 | wav_t *retval; 141 | retval = malloc(sizeof(wav_t)); 142 | 143 | wav_header_set(retval, 0, 0, 0, 0); 144 | retval->tree = tree_new(wav_items, wav_containers, retval); 145 | retval->destroy = wav_destroy; 146 | retval->header_read = wav_header_read; 147 | retval->header_write = wav_header_write; 148 | retval->header_set = wav_header_set; 149 | return retval; 150 | } 151 | -------------------------------------------------------------------------------- /pysf-2/test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import logging, math, md5, os, os.path, shutil, sys, struct 3 | import pysf 4 | 5 | def ChecksumGenerate(FileName): 6 | Checksum = md5.new() 7 | BufferSize = 1024 8 | File = open(FileName, 'rb') 9 | while True: 10 | Buffer = File.read(BufferSize) 11 | if len(Buffer) == 0: 12 | break 13 | Checksum.update(Buffer) 14 | File.close() 15 | Retval = Checksum.hexdigest() 16 | return Retval 17 | 18 | def ChecksumVerify(Source, FileName, Control): 19 | Checksum = ChecksumGenerate(FileName) 20 | if Checksum != Control: 21 | logging.error("%s:%s expected %s but see %s" % (Source, FileName, 22 | Control, Checksum)) 23 | sys.exit(1) 24 | 25 | def fpart(Number): 26 | return Number - math.floor(Number) 27 | 28 | def SineGenerate(FileName, SampleFormat, Frequency=440): 29 | SampleRate = 44100.0 30 | SampleCount = 2205 31 | Amplitude = 10000 32 | SamplePeriod = SampleRate / Frequency 33 | File = open(FileName, 'wb') 34 | for I in range(0, SampleCount): 35 | S = int(math.sin(2 * math.pi * fpart(I / SamplePeriod)) * Amplitude) 36 | File.write(struct.pack(SampleFormat, (~S) & 0xFFFF)) 37 | File.close() 38 | 39 | def AudConfGenerate(FileName, RawFileName): 40 | File = open(FileName, 'wb') 41 | File.write(""" 42 | """ + pysf.XmlHeaderStr + """ 43 | 44 | 1 45 | """ + RawFileName + """ 46 | 44100 47 | 16 48 | 49 | 50 | """) 51 | File.close() 52 | 53 | def SfConfGenerate(FileName): 54 | File = open(FileName, 'wb') 55 | File.write(""" 56 | """ + pysf.XmlHeaderStr + """ 57 | 58 | Nov 08, 2005 59 | 60 | 2 61 | 1 62 | 63 | sine bank 64 | SBAWE32 65 | Compressed ImpulseTracker 2.14:mod2cs-0.2 66 | EMU8000 67 | 68 | 69 | 1 70 | stereo sine 71 | 72 | 73 | 74 | 12 75 | 126 76 | 77 | 69 78 | 1 79 | 80 | 81 | 82 | 12 83 | 126 84 | 85 | 69 86 | 2 87 | 88 | 89 | 90 | 91 | 2 92 | mono sine 93 | 94 | 95 | 96 | 12 97 | 120 98 | 99 | 69 100 | 3 101 | 102 | 103 | 104 | 121 105 | 126 106 | 107 | 69 108 | 3 109 | 110 | 111 | 112 | 113 | 114 | 115 | 0 116 | 1 117 | sine preset 118 | 119 | 120 | 1 121 | 122 | 0 123 | 127 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | right 132 | test1.wav 133 | 1 134 | 2 135 | 136 | 100 137 | 200 138 | 139 | A4 sine right 140 | 69 141 | 142 | 143 | left 144 | test2.wav 145 | 2 146 | 1 147 | 148 | 100 149 | 200 150 | 151 | A5 sine left 152 | 69 153 | 154 | 155 | test3.wav 156 | 3 157 | 158 | 100 159 | 200 160 | 161 | A4 sine mono 162 | 69 163 | 164 | 165 | 166 | 167 | """) 168 | File.close() 169 | 170 | def AudTest(Aud, Frequency, CsAud, CsConf, CsRaw): 171 | Base = os.path.splitext(Aud)[0] 172 | Raw = Base + '.raw' 173 | Xml = Base + '.xml' 174 | SineGenerate(Raw, ' 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 102 | 103 | 104 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/ieee80.c.orig: -------------------------------------------------------------------------------- 1 | /* $Id */ 2 | /* $Log */ 3 | /********************************************************************* 4 | 5 | This software module was originally developed by 6 | 7 | Eric D. Scheirer (MIT Media Laboratory) 8 | 9 | in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard 10 | ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an 11 | implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools 12 | as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives 13 | users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this 14 | software module or modifications thereof for use in hardware or 15 | software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio 16 | standards. Those intending to use this software module in hardware or 17 | software products are advised that this use may infringe existing 18 | patents. The original developer of this software module and his/her 19 | company, the subsequent editors and their companies, and ISO/IEC have 20 | no liability for use of this software module or modifications thereof 21 | in an implementation. 22 | 23 | This software module is hereby released into the public domain. 24 | 25 | ***********************************************************************/ 26 | 27 | /***************************************************************\ 28 | * IEEE80.c * 29 | * Convert between "double" and IEEE 80 bit format * 30 | * in machine independent manner. * 31 | * Assumes array of char is a continuous region of 8 bit frames* 32 | * Assumes (unsigned long) has 32 useable bits * 33 | * billg, dpwe @media.mit.edu * 34 | * 01aug91 * 35 | * 19aug91 aldel/dpwe workaround top bit problem in Ultrix * 36 | * cc's double->ulong cast * 37 | * 05feb92 dpwe/billg workaround top bit problem in * 38 | * THINKC4 + 68881 casting * 39 | \***************************************************************/ 40 | 41 | #include 42 | #include "dpwelib.h" 43 | #include "IEEE80.h" 44 | 45 | /* #define MAIN 1 to compile test routines */ 46 | 47 | #define ULPOW2TO31 ((unsigned long)0x80000000L) 48 | #define DPOW2TO31 ((double)2147483648.0) /* 2^31 */ 49 | 50 | /* have to deal with ulong's 32nd bit conditionally as double<->ulong casts 51 | don't work in some C compilers */ 52 | 53 | static double myUlongToDouble PARG((unsigned long ul)); 54 | static unsigned long myDoubleToUlong PARG((double val)); 55 | 56 | static double myUlongToDouble(ul) 57 | unsigned long ul; 58 | { 59 | double val; 60 | 61 | /* in THINK_C, ulong -> double apparently goes via long, so can only 62 | apply to 31 bit numbers. If 32nd bit is set, explicitly add on its 63 | value */ 64 | if(ul & ULPOW2TO31) 65 | val = DPOW2TO31 + (ul & (~ULPOW2TO31)); 66 | else 67 | val = ul; 68 | return val; 69 | } 70 | 71 | static unsigned long myDoubleToUlong(val) 72 | double val; 73 | { 74 | unsigned long ul; 75 | 76 | /* cannot cast negative numbers into unsigned longs */ 77 | if(val < 0) 78 | { 79 | FPRINTF((stderr,"IEEE80:DoubleToUlong: val < 0\n")); 80 | abort(); 81 | } 82 | 83 | /* in ultrix 4.1's cc, double -> unsigned long loses the top bit, 84 | so we do the conversion only on the bottom 31 bits and set the 85 | last one by hand, if val is truly that big */ 86 | /* should maybe test for val > (double)(unsigned long)0xFFFFFFFF ? */ 87 | if(val < DPOW2TO31) 88 | ul = (unsigned long)val; 89 | else 90 | ul = ULPOW2TO31 | (unsigned long)(val-DPOW2TO31); 91 | return ul; 92 | } 93 | 94 | 95 | /* 96 | * Convert IEEE 80 bit floating point to double. 97 | * Should be portable to all C compilers. 98 | */ 99 | double ieee_80_to_double(p) 100 | unsigned char *p; 101 | { 102 | char sign; 103 | short exp = 0; 104 | unsigned long mant1 = 0; 105 | unsigned long mant0 = 0; 106 | double val; 107 | 108 | exp = *p++; 109 | exp <<= 8; 110 | exp |= *p++; 111 | sign = (exp & 0x8000) ? 1 : 0; 112 | exp &= 0x7FFF; 113 | 114 | mant1 = *p++; 115 | mant1 <<= 8; 116 | mant1 |= *p++; 117 | mant1 <<= 8; 118 | mant1 |= *p++; 119 | mant1 <<= 8; 120 | mant1 |= *p++; 121 | 122 | mant0 = *p++; 123 | mant0 <<= 8; 124 | mant0 |= *p++; 125 | mant0 <<= 8; 126 | mant0 |= *p++; 127 | mant0 <<= 8; 128 | mant0 |= *p++; 129 | 130 | /* special test for all bits zero meaning zero 131 | - else pow(2,-16383) bombs */ 132 | if(mant1 == 0 && mant0 == 0 && exp == 0 && sign == 0) 133 | return 0.0; 134 | else{ 135 | val = myUlongToDouble(mant0) * pow(2.0,-63.0); 136 | val += myUlongToDouble(mant1) * pow(2.0,-31.0); 137 | val *= pow(2.0,((double) exp) - 16383.0); 138 | return sign ? -val : val; 139 | } 140 | } 141 | 142 | /* 143 | * Convert double to IEEE 80 bit floating point 144 | * Should be portable to all C compilers. 145 | * 19aug91 aldel/dpwe covered for MSB bug in Ultrix 'cc' 146 | */ 147 | 148 | void double_to_ieee_80(val,p) 149 | double val; 150 | unsigned char *p; 151 | { 152 | char sign = 0; 153 | short exp = 0; 154 | unsigned long mant1 = 0; 155 | unsigned long mant0 = 0; 156 | 157 | if(val < 0.0) { sign = 1; val = -val; } 158 | 159 | if(val != 0.0) /* val identically zero -> all elements zero */ 160 | { 161 | exp = (short)(log(val)/log(2.0) + 16383.0); 162 | val *= pow(2.0, 31.0+16383.0-(double)exp); 163 | mant1 = myDoubleToUlong(val); 164 | val -= myUlongToDouble(mant1); 165 | val *= pow(2.0, 32.0); 166 | mant0 = myDoubleToUlong(val); 167 | } 168 | 169 | *p++ = ((sign<<7)|(exp>>8)); 170 | *p++ = 0xFF & exp; 171 | *p++ = 0xFF & (mant1>>24); 172 | *p++ = 0xFF & (mant1>>16); 173 | *p++ = 0xFF & (mant1>> 8); 174 | *p++ = 0xFF & (mant1); 175 | *p++ = 0xFF & (mant0>>24); 176 | *p++ = 0xFF & (mant0>>16); 177 | *p++ = 0xFF & (mant0>> 8); 178 | *p++ = 0xFF & (mant0); 179 | 180 | } 181 | 182 | #ifdef MAIN 183 | 184 | static void print_hex PARG((unsigned char *p, int n)); 185 | 186 | static void print_hex(p,n) 187 | unsigned char *p; 188 | int n; 189 | { 190 | long i; 191 | for (i = 0; i < n; i++) printf("%02X",*p++); 192 | printf(" "); 193 | } 194 | 195 | double tab[] = { 0, -1.0, 1.0, 2.0 , 4.0, 0.5, 0.25, 0.125, 196 | 3.14159265358979323846, 10000.0, 22000.0, 197 | 44100.0, 65536.0, 134072.768, 3540001.9, 4294967295.0}; 198 | #define NTAB (sizeof(tab)/sizeof(double)) 199 | 200 | main() 201 | { 202 | int i; 203 | double val, lv; 204 | unsigned char eighty[10]; 205 | double *p80; 206 | 207 | p80 = (double *)eighty; 208 | 209 | /* for each number in the test table, print its actual value, 210 | its native hex representation, the 80 bit representation and 211 | the back-converted value (should be the same!) */ 212 | /* I think the hex of PI to all 80 bits is 213 | 4000 C90F DAA2 2168 C233 */ 214 | /* apparently some problem with log */ 215 | val = 2.0; 216 | lv = log(val); 217 | printf("log of %lf is %lf\n", val, lv); 218 | val = 1.0; 219 | lv = log(val); 220 | printf("log of %lf is %lf\n", val, lv); 221 | for (i = 0; i < NTAB; i++) { 222 | printf("%8lf: ",tab[i]); 223 | print_hex((unsigned char *)(tab+i),sizeof(double)); 224 | double_to_ieee_80((double) tab[i], eighty); 225 | print_hex(eighty, 10); 226 | val = ieee_80_to_double(eighty); 227 | printf("%lf\n",val); 228 | } 229 | } 230 | 231 | #endif 232 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/ieee80.c: -------------------------------------------------------------------------------- 1 | /* $Id */ 2 | /* $Log */ 3 | /********************************************************************* 4 | 5 | This software module was originally developed by 6 | 7 | Eric D. Scheirer (MIT Media Laboratory) 8 | 9 | in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard 10 | ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an 11 | implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools 12 | as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives 13 | users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this 14 | software module or modifications thereof for use in hardware or 15 | software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio 16 | standards. Those intending to use this software module in hardware or 17 | software products are advised that this use may infringe existing 18 | patents. The original developer of this software module and his/her 19 | company, the subsequent editors and their companies, and ISO/IEC have 20 | no liability for use of this software module or modifications thereof 21 | in an implementation. 22 | 23 | This software module is hereby released into the public domain. 24 | 25 | ***********************************************************************/ 26 | 27 | /***************************************************************\ 28 | * IEEE80.c * 29 | * Convert between "double" and IEEE 80 bit format * 30 | * in machine independent manner. * 31 | * Assumes array of char is a continuous region of 8 bit frames* 32 | * Assumes (unsigned long) has 32 useable bits * 33 | * billg, dpwe @media.mit.edu * 34 | * 01aug91 * 35 | * 19aug91 aldel/dpwe workaround top bit problem in Ultrix * 36 | * cc's double->ulong cast * 37 | * 05feb92 dpwe/billg workaround top bit problem in * 38 | * THINKC4 + 68881 casting * 39 | \***************************************************************/ 40 | 41 | #include 42 | #include 43 | #include 44 | #if !defined(_DO_TEST) 45 | #include 46 | #endif 47 | #include "ieee80.h" 48 | 49 | /* #define MAIN 1 to compile test routines */ 50 | 51 | #define ULPOW2TO31 ((unsigned long)0x80000000L) 52 | #define DPOW2TO31 ((double)2147483648.0) /* 2^31 */ 53 | 54 | static double myUlongToDouble(unsigned long ul) 55 | { 56 | double val; 57 | 58 | /* in THINK_C, ulong -> double apparently goes via long, so can only 59 | apply to 31 bit numbers. If 32nd bit is set, explicitly add on its 60 | value */ 61 | if (ul & ULPOW2TO31) { 62 | val = DPOW2TO31 + (ul & (~ULPOW2TO31)); 63 | } else { 64 | val = ul; 65 | } 66 | return val; 67 | } 68 | 69 | static unsigned long myDoubleToUlong(double val) 70 | { 71 | unsigned long ul; 72 | 73 | /* cannot cast negative numbers into unsigned longs */ 74 | if (val < 0) { 75 | #if defined(_DO_TEST) 76 | fprintf(stderr,"IEEE80:DoubleToUlong: val < 0\n"); 77 | exit(1); 78 | #else 79 | trap_exit("IEEE80:DoubleToUlong: val < 0"); 80 | #endif 81 | } 82 | 83 | /* in ultrix 4.1's cc, double -> unsigned long loses the top bit, 84 | so we do the conversion only on the bottom 31 bits and set the 85 | last one by hand, if val is truly that big */ 86 | 87 | /* should maybe test for val > (double)(unsigned long)0xFFFFFFFF ? */ 88 | if (val < DPOW2TO31) { 89 | ul = (unsigned long)val; 90 | } else { 91 | ul = ULPOW2TO31 | (unsigned long)(val-DPOW2TO31); 92 | } 93 | return ul; 94 | } 95 | 96 | 97 | /* 98 | * Convert IEEE 80 bit floating point to double. 99 | * Should be portable to all C compilers. 100 | */ 101 | double ieee_80_to_double(unsigned char *p) 102 | { 103 | char sign; 104 | short exp = 0; 105 | unsigned long mant1 = 0; 106 | unsigned long mant0 = 0; 107 | double val; 108 | 109 | exp = *p++; 110 | exp <<= 8; 111 | exp |= *p++; 112 | sign = (exp & 0x8000) ? 1 : 0; 113 | exp &= 0x7FFF; 114 | 115 | mant1 = *p++; 116 | mant1 <<= 8; 117 | mant1 |= *p++; 118 | mant1 <<= 8; 119 | mant1 |= *p++; 120 | mant1 <<= 8; 121 | mant1 |= *p++; 122 | 123 | mant0 = *p++; 124 | mant0 <<= 8; 125 | mant0 |= *p++; 126 | mant0 <<= 8; 127 | mant0 |= *p++; 128 | mant0 <<= 8; 129 | mant0 |= *p++; 130 | 131 | /* special test for all bits zero meaning zero, else pow(2,-16383) bombs */ 132 | if (mant1 == 0 && mant0 == 0 && exp == 0 && sign == 0) { 133 | return 0.0; 134 | } else { 135 | val = myUlongToDouble(mant0) * pow(2.0, -63.0); 136 | val += myUlongToDouble(mant1) * pow(2.0, -31.0); 137 | val *= pow(2.0,((double) exp) - 16383.0); 138 | return sign ? -val : val; 139 | } 140 | } 141 | 142 | /* 143 | * Convert double to IEEE 80 bit floating point 144 | * Should be portable to all C compilers. 145 | * 19aug91 aldel/dpwe covered for MSB bug in Ultrix 'cc' 146 | */ 147 | 148 | void double_to_ieee_80(double val, unsigned char *p) 149 | { 150 | char sign = 0; 151 | short exp = 0; 152 | unsigned long mant1 = 0; 153 | unsigned long mant0 = 0; 154 | 155 | if (val < 0.0) { 156 | sign = 1; 157 | val = -val; 158 | } 159 | 160 | if (val != 0.0) { 161 | /* val identically zero -> all elements zero */ 162 | exp = (short)(log(val) / log(2.0) + 16383.0); 163 | val *= pow(2.0, 31.0 + 16383.0 - (double)exp); 164 | mant1 = myDoubleToUlong(val); 165 | val -= myUlongToDouble(mant1); 166 | val *= pow(2.0, 32.0); 167 | mant0 = myDoubleToUlong(val); 168 | } 169 | 170 | *p++ = ((sign << 7) | (exp >> 8)); 171 | *p++ = 0xFF & exp; 172 | *p++ = 0xFF & (mant1 >> 24); 173 | *p++ = 0xFF & (mant1 >> 16); 174 | *p++ = 0xFF & (mant1 >> 8); 175 | *p++ = 0xFF & (mant1); 176 | *p++ = 0xFF & (mant0 >> 24); 177 | *p++ = 0xFF & (mant0 >> 16); 178 | *p++ = 0xFF & (mant0 >> 8); 179 | *p++ = 0xFF & (mant0); 180 | } 181 | 182 | #if defined(_DO_TEST) 183 | static void print_hex(unsigned char *p, int n) 184 | { 185 | long i; 186 | for (i = 0; i < n; i++) 187 | printf("%02X", *p++); 188 | printf(" "); 189 | } 190 | 191 | #define TAB_END_NUMBER 999 192 | double tab[] = { 193 | 0, -1.0, 1.0, 2.0, 4.0, 0.5, 0.25, 0.125, 3.14159265358979323846, 194 | 10000.0, 22000.0, 44100.0, 65536.0, 134072.768, 3540001.9, 195 | 4294967295.0, TAB_END_NUMBER 196 | }; 197 | 198 | int main(int argc, char *argv[]) 199 | { 200 | int i; 201 | double val; 202 | double lv; 203 | unsigned char eighty[10]; 204 | double *p80; 205 | 206 | p80 = (double *)eighty; 207 | 208 | /* for each number in the test table, print its actual value, 209 | its native hex representation, the 80 bit representation and 210 | the back-converted value (should be the same!) */ 211 | /* I think the hex of PI to all 80 bits is 212 | 4000 C90F DAA2 2168 C233 */ 213 | /* apparently some problem with log */ 214 | val = 2.0; 215 | lv = log(val); 216 | printf("log of %lf is %lf\n", val, lv); 217 | val = 1.0; 218 | lv = log(val); 219 | printf("log of %lf is %lf\n", val, lv); 220 | for (i = 0; tab[i] != TAB_END_NUMBER; i++) { 221 | printf("%8lf: ", tab[i]); 222 | double_to_ieee_80((double)tab[i], eighty); 223 | print_hex(eighty, 10); 224 | val = ieee_80_to_double(eighty); 225 | printf("%lf\n", val); 226 | } 227 | exit(0); 228 | } 229 | #endif /* _DO_TEST */ 230 | -------------------------------------------------------------------------------- /pysf-2/README.md: -------------------------------------------------------------------------------- 1 | # pysf - Python SoundFont utility 2 | 3 | ## Intro 4 | 5 | The pysf utility is a way to create and edit SoundFont 2 files 6 | at the command line. It does this using XML configuration 7 | files and basic audio files (strict sub-set of .wav and .aif). 8 | 9 | Each SoundFont2 file has one or more presets, each preset 10 | containing one or more preset zones, each preset zone mapping 11 | to an instrument, each instrument containing one or more 12 | instrument zones, each instrument zone mapping to a wavetable. 13 | 14 | The pysf utility is released into the public domain. For 15 | countries without a public domain, pysf is released under 16 | the [WTF](href="http://sam.zoy.org/wtfpl/) public license. 17 | 18 | My email address is collver@peak.org 19 | 20 | Many terms will be defined in the SoundFont 2 Standard. 21 | 22 | * http://freepats.opensrc.org/sf2/sfspec24.pdf 23 | 24 | MPEG4-SA is more free, and includes much of the same information. 25 | 26 | * http://sound.media.mit.edu/mpeg4/ 27 | 28 | The SoundFont 2 standard refers to the MIDI standard. 29 | 30 | * http://www.ibiblio.org/emusic-l/info-docs-FAQs/MIDI-doc/ 31 | * http://www.borg.com/~jglatt/tech/midispec.htm 32 | 33 | 34 | ## Usage and Examples 35 | 36 | Usage: pysf.py [conversion] [infile] [outfile] 37 | conversion := --sf2xml | --xml2sf 38 | conversion := --aif2xml | --xml2aif 39 | conversion := --wav2xml | --xml2wav 40 | 41 | Create conf.xml based on old.sf2. Will also create conf%d.wav for 42 | included audio samples 43 | 44 | pysf.py --sf2xml old.sf2 conf.xml 45 | 46 | Create new.sf2 based on conf.xml 47 | 48 | pysf.py --xml2sf conf.xml new.sf2 49 | 50 | Validate conf.xml using xmllint utility from libxml. 51 | 52 | xmllint --noout --schema pysf.xsd conf.xml 53 | 54 | 55 | ## Brief explaination of configuration tags 56 | 57 | tag | description 58 | ------------------ | -------------------------------------- 59 | ISNG | mandatory, optimal target sound engine 60 | INAM | mandatory, name of sound bank 61 | ICRD | file creation date 62 | IPRD | target product 63 | ISFT | software used to create/modify the file 64 | IFIL | contains major and minor version of spec 65 | major | Major version of soundfont specfication used 66 | minor | Minor version of soundfont specfication used 67 | instruments | mandatory, instrument list 68 | instrument | mandatory, instrument section 69 | presets | mandatory, preset list 70 | preset | mandatory, preset section 71 | wavetables | mandatory, wavetable list 72 | wavetable | mandatory, wavetable section 73 | zones | mandatory, zone list for instrument or preset section 74 | zone | mandatory, zone section 75 | id | mandatory, id for instrument or wavetable, referenced by other sections 76 | name | mandatory, descriptive name for instrument preset, or wavetable 77 | keyRange | range of MIDI notes for zone 78 | velRange | range of MIDI velocities for zone 79 | overridingRootKey | base MIDI note for zone 80 | wavetableId | wavetable used by instrument zone 81 | instrumentId | instrument used by preset zone 82 | delayVolEnv | time in seconds for delay section of volume envelope 83 | attackVolEnv | time in seconds for attack section of volume envelope 84 | holdVolEnv | time in seconds for hold section of volume envelope 85 | decayVolEnv | time in seconds for decay section of volume envelope 86 | releaseVolEnv | time in seconds for release section of volume envelope 87 | sustainVolEnv | volume decrease in centibels for decay section 88 | keynumToVolEnvHold | degree, in timecents per KeyNumber units, to which the hold time is degreased. The value of KeyNumber units is found by the difference between the MIDI note number and 60. 89 | exclusiveClass | new notes will silence currently playing notes if the instruments are in the same exclusiveClass 90 | gens | generic generator operator list in zone 91 | gen | generic generator operator 92 | comment | comment describing generator, not used by pysf 93 | hexAmount | hexadecimal unsigned word argument 94 | oper | decimal generator operator number 95 | file | mandatory, name of aif or wav file used by wavetable 96 | loop | loop begin and end point for wavetable 97 | pitch | MIDI note that the wavetable was recorded at 98 | pitchcorr | pitch correction in cents for wavetable 99 | channel | select channel for instrument and/or from stereo audio file 100 | link | link to other wavetable in a stereo instrument 101 | 102 | 103 | ## 24-bit sample width wavetables 104 | 105 | To use 24-bit sample width wavetables, you must set ifil to major 2, minor 4. 106 | If you use 24-bit wavetables, then all wavetables used must be 24-bit. 107 | You can use audacity to convert between 24-bit and other sample widths. 108 | 109 | Theoretically, old software should be able to play 24-bit soundfonts 110 | at lower quality by simply ignoring the sm24 chunk. However, some programs 111 | will refuse to use 24-bit soundfonts. Timidity and fluidsynth do not 112 | support 24-bit soundfonts, and apparently neither does quicktime. 113 | Therefore, this feature is not well tested in pysf. 114 | 115 | 116 | ## Stereo wavetables 117 | 118 | To use a stereo .wav file for a mono wavetable, use the channel tag to 119 | select a channel. If the wavetable is linked, then the channel tag also 120 | determines whether the wavetable is the left or the right channel in a 121 | stereo instrument. A stereo instrument requires two linked wavetables. 122 | Use link tags to link wavetables. Example: 123 | 124 | 125 | right 126 | 1 127 | stereo.wav 128 | 2 129 | 130 | 131 | left 132 | 2 133 | stereo.wav 134 | 1 135 | 136 | 137 | A stereo instrument also requires a zone for each channel. Example: 138 | 139 | 140 | 141 | 142 | 12127 143 | 1 144 | 145 | 146 | 12127 147 | 2 148 | 149 | 150 | 151 | 152 | 153 | ## History 154 | 155 | * Version 1, 2007-Mar-4 156 | * added support for stereo wavetables 157 | * tested on Python 2.3.5 and Python 2.4.4 158 | * Version 2, 2007-Mar-10 159 | * added IFIL configuration tag. for specifying soundfont 2.04 160 | * added support for 24-bit sample width 161 | * added version attribute to XML schema and output files 162 | * tested on Python 2.5 163 | * tested on big-endian system 164 | * using md5 instead of zlib.adler32 for portability reasons. 165 | http://sourceforge.net/tracker/?func=detail&atid=105470&aid=1678102&group_id=5470 166 | 167 | 168 | ## TODO 169 | 170 | * add a gui front-end 171 | -------------------------------------------------------------------------------- /sfubar-9/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | program_seek() 4 | { 5 | program="$1" 6 | fatal="$2" 7 | type $program >/dev/null 2>&1 8 | retval=$? 9 | if [ $retval -ne 0 ] 10 | then 11 | if [ $fatal -ne 0 ] 12 | then 13 | echo ERROR: could not find $program 14 | echo Test failed. 15 | exit 16 | else 17 | echo WARNING: $program not found, a test will be skipped. 18 | fi 19 | fi 20 | return $retval 21 | } 22 | 23 | checksum_verify() 24 | { 25 | source="$1" 26 | filename="$2" 27 | control="$3" 28 | 29 | checksum=$(cksum <"$filename") 30 | if [ "$checksum" != "$control" ] 31 | then 32 | echo ERROR: $source generated unexpected output in $filename 33 | echo Test failed. 34 | exit 35 | fi 36 | } 37 | 38 | raw_create() 39 | { 40 | program_seek ./gensine 1 41 | if [ $? -eq 0 ] 42 | then 43 | ./gensine >tmp/raw.raw 44 | fi 45 | checksum_verify raw_create tmp/raw.raw "3233638796 4410" 46 | } 47 | 48 | aif_conf_create() 49 | { 50 | cat >tmp/aif.txt <<__EOF__ 51 | FORM.FVER.timestamp=2726318400 52 | FORM.COMM.numChannels=1 53 | FORM.COMM.sampleSize=16 54 | FORM.COMM.sampleRate=44100 55 | FORM.COMM.compressionType.str=NONE 56 | FORM.COMM.compressionName.str=not compressed 57 | FORM.MARK.1.id=91 58 | FORM.MARK.1.pos=100 59 | FORM.MARK.1.name=start sustain loop 60 | FORM.MARK.2.id=92 61 | FORM.MARK.2.pos=200 62 | FORM.MARK.2.name=end sustain loop 63 | FORM.INST.baseNote=69 64 | FORM.INST.detune=0 65 | FORM.INST.lowNote=0 66 | FORM.INST.highNote=127 67 | FORM.INST.lowVelocity=1 68 | FORM.INST.highVelocity=127 69 | FORM.INST.gain=0 70 | FORM.INST.sustainLoop.playMode=1 71 | FORM.INST.sustainLoop.beginLoop=91 72 | FORM.INST.sustainLoop.endLoop=92 73 | FORM.INST.releaseLoop.playMode=0 74 | FORM.INST.releaseLoop.beginLoop=0 75 | FORM.INST.releaseLoop.endLoop=0 76 | FORM.SSND.file=tmp/aif.raw 77 | FORM.SSND.byteswap=1 78 | __EOF__ 79 | checksum_verify aif_conf_create tmp/aif.txt "1417919088 732" 80 | } 81 | 82 | wav_conf_create() 83 | { 84 | cat >tmp/wav.txt <<__EOF__ 85 | RIFF.fmt.wFormatTag=1 86 | RIFF.fmt.wChannels=1 87 | RIFF.fmt.dwSamplesPerSec=44100 88 | RIFF.fmt.dwAvgBytesPerSec=88200 89 | RIFF.fmt.wBlockAlign=2 90 | RIFF.fmt.wBitsPerSample=16 91 | RIFF.data.size=4410 92 | RIFF.data.file=tmp/wav.raw 93 | __EOF__ 94 | checksum_verify wav_conf_create tmp/wav.txt "873361169 203" 95 | } 96 | 97 | wav_create() 98 | { 99 | cp tmp/raw.raw tmp/wav.raw 100 | wav_conf_create 101 | ./sfubar --txt2wav tmp/wav.txt tmp/wav.wav 102 | checksum_verify wav_create tmp/wav.wav "656389750 4454" 103 | mv tmp/wav.txt tmp/wav.txt.orig 104 | ./sfubar --wav2txt tmp/wav.wav tmp/wav.txt 105 | checksum_verify sfubar_wav tmp/wav.txt "873361169 203" 106 | checksum_verify sfubar_wav tmp/wav.raw "3233638796 4410" 107 | } 108 | 109 | aif_create() 110 | { 111 | cp tmp/raw.raw tmp/aif.raw 112 | aif_conf_create 113 | ./sfubar --txt2aif tmp/aif.txt tmp/aif.aif 114 | checksum_verify aif_create tmp/aif.aif "1957549582 4584" 115 | mv tmp/aif.txt tmp/aif.txt.orig 116 | ./sfubar --aif2txt tmp/aif.aif tmp/aif.txt 117 | checksum_verify aif_create tmp/aif.txt "4209874723 711" 118 | checksum_verify aif_create tmp/aif.raw "2290835127 4410" 119 | } 120 | 121 | sfubar_conf_cat() 122 | { 123 | filename="$1" 124 | cat <<__EOF__ 125 | RIFF.LIST.isng.zstr=EMU8000 126 | RIFF.LIST.INAM.zstr=sine bank 127 | RIFF.LIST.ICRD.zstr=Nov 08, 2005 128 | RIFF.LIST.IPRD.zstr=SBAWE32 129 | RIFF.LIST.ISFT.zstr=Compressed ImpulseTracker 2.14:mod2cs-0.2 130 | SF2.wt.1.$filename 131 | SF2.wt.1.name=sine wavetable 132 | SF2.wt.1.loopstart=100 133 | SF2.wt.1.loopend=200 134 | SF2.wt.1.pitch=69 135 | SF2.in.1.name=sine instrument 136 | SF2.in.1.zone.1.keyRange=12,120 137 | SF2.in.1.zone.1.overridingRootKey=69 138 | SF2.in.1.zone.1.wt=1 139 | SF2.in.1.zone.2.keyRange=121,126 140 | SF2.in.1.zone.2.overridingRootKey=69 141 | SF2.in.1.zone.2.wt=1 142 | SF2.in.2.name=sine instrument 2 143 | SF2.in.2.zone.1.keyRange=12,126 144 | SF2.in.2.zone.1.overridingRootKey=69 145 | SF2.in.2.zone.1.wt=1 146 | SF2.ps.1.name=sine preset 147 | SF2.ps.1.bank=0 148 | SF2.ps.1.zone.1.keyRange=0,127 149 | SF2.ps.1.zone.1.in=1 150 | __EOF__ 151 | } 152 | 153 | timidity_conf_create() 154 | { 155 | cat >tmp/test.cfg <<__EOF__ 156 | dir . 157 | bank 40 158 | soundfont tmp/test.sf2 159 | __EOF__ 160 | checksum_verify timidity_conf_create tmp/test.cfg "3204808837 37" 161 | } 162 | 163 | abc_score_create() 164 | { 165 | cat >tmp/test.abc <<__EOF__ 166 | %%abc 167 | 168 | X:1 169 | T:test tune 170 | C:Trad 171 | Z:sfubar 172 | M:4/4 173 | L:1/4 174 | K:C 175 | %%MIDI program 0 176 | | D/>D/D E/D//D// C | D/>D/ F/G/ A2 | 177 | __EOF__ 178 | checksum_verify abc_score_create tmp/test.abc "2596554308 111" 179 | } 180 | 181 | csound_csd_create() 182 | { 183 | cat >tmp/test.csd <<__EOF__ 184 | 185 | 186 | 187 | 188 | sr = 44100 189 | kr = 4410 190 | ksmps = 10 191 | nchnls = 1 192 | gifont sfload "tmp/test.sf2" 193 | instr 1 194 | inote notnum 195 | kpitch cpsmidib 196 | iamp ampmidi .5 197 | 198 | iinstr = 0 199 | ioffset = 0 200 | ivel = 0 201 | ixamp = 1 202 | iflag = 1 203 | asig sfinstrm ivel, inote, ixamp, kpitch, iinstr, gifont, iflag, ioffset 204 | out asig * iamp 205 | endin 206 | 207 | 208 | s 209 | f0 4 210 | e 211 | 212 | 213 | __EOF__ 214 | checksum_verify csound_csd_create tmp/test.csd "2914206408 423" 215 | } 216 | 217 | sfubar_sf_test() 218 | { 219 | echo Testing sfubar soundfont code 220 | 221 | raw_create 222 | 223 | wav_create 224 | cp tmp/wav.wav tmp/test1.wav 225 | sfubar_conf_cat wav=tmp/test1.wav >tmp/test.txt 226 | checksum_verify sfubar_sf_wav tmp/test.txt "3532180799 726" 227 | ./sfubar --txt2sf tmp/test.txt tmp/test.sf2 228 | checksum_verify sfubar_sf_wav tmp/test.sf2 "1086717969 5106" 229 | mv tmp/test.txt tmp/test.txt.orig 230 | ./sfubar --sf2txt tmp/test.sf2 tmp/test.txt 231 | checksum_verify sfubar_sf_wav2 tmp/test1.wav "656389750 4454" 232 | checksum_verify sfubar_sf_wav2 tmp/test.txt "3532180799 726" 233 | 234 | aif_create 235 | sfubar_conf_cat aif=tmp/aif.aif >tmp/test3.txt 236 | checksum_verify sfubar_sf_aif tmp/test3.txt "2753237313 724" 237 | ./sfubar --txt2sf tmp/test3.txt tmp/test3.sf2 238 | checksum_verify sfubar_sf_aif tmp/test3.sf2 "1086717969 5106" 239 | ./sfubar --sf2txt tmp/test3.sf2 tmp/test.txt 240 | checksum_verify sfubar_sf_aif2 tmp/test1.wav "656389750 4454" 241 | checksum_verify sfubar_sf_wav2 tmp/test.txt "3532180799 726" 242 | } 243 | 244 | midi_test() 245 | { 246 | echo Testing example SoundFont 2 file with timidity 247 | program_seek abc2midi 0 248 | if [ $? -ne 0 ] 249 | then 250 | cp test-success/test.mid tmp/test.mid 251 | checksum_verify script tmp/test.mid "1881877690 181" 252 | else 253 | abc_score_create 254 | abc2midi tmp/test.abc -o tmp/test.mid >/dev/null 2>&1 255 | checksum_verify abc2midi tmp/test.mid "1881877690 181" 256 | fi 257 | 258 | program_seek timidity 0 259 | if [ $? -ne 0 ] 260 | then 261 | return 262 | fi 263 | timidity_conf_create 264 | timidity -L . -c tmp/test.cfg --force-bank=40 -A440 -OwMs1l -EFns=0 \ 265 | -EFresamp=d -o tmp/song1.wav tmp/test.mid >/dev/null 2>&1 266 | checksum_verify timidity tmp/song1.wav "2854065874 358580" 267 | } 268 | 269 | csound_test() 270 | { 271 | echo Testing example SoundFont 2 file with csound 272 | program_seek csound 0 273 | if [ $? -ne 0 ] 274 | then 275 | return 276 | fi 277 | csound_csd_create 278 | csound -W -K -o tmp/song2.wav -F tmp/test.mid tmp/test.csd >/dev/null 2>&1 279 | checksum_verify csound tmp/song2.wav "3837075942 352844" 280 | } 281 | 282 | ieee80_test() 283 | { 284 | uname -s | grep CYGWIN_95 >/dev/null 2>&1 285 | if [ $? -eq 0 ] 286 | then 287 | echo Windows 95 has printf format bugs. 288 | echo Skipping IEEE80 conversion routine test. 289 | return 290 | fi 291 | echo Testing IEEE80 conversion routines 292 | program_seek ./bin/ieee80-test 1 293 | ./bin/ieee80-test >tmp/ieee80.tst 294 | checksum_verify ieee80-test tmp/ieee80.tst "3195791153 770" 295 | } 296 | 297 | rm -f tmp/* 298 | program_seek ./sfubar 1 299 | ieee80_test 300 | sfubar_sf_test 301 | midi_test 302 | #csound_test 303 | echo Test passed. 304 | -------------------------------------------------------------------------------- /sfubar-9/wavutil.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "wavutil.h" 17 | 18 | #ifndef BUFLEN 19 | #define BUFLEN 256 20 | #endif 21 | 22 | void wp_meta(void *vtree, chunk_t *chunk, char *prefix) 23 | { 24 | tree_t *tree = vtree; 25 | fprintf(tree->ofp, "%s ~ BEGIN\n", prefix); 26 | } 27 | 28 | void wp_ignore(void *vtree, chunk_t *chunk, char *prefix) 29 | { 30 | /* ignore this item, print nothing */ 31 | } 32 | 33 | void wp_fmt(void *vtree, chunk_t *chunk, char *prefix) 34 | { 35 | tree_t *tree = vtree; 36 | wav_t *wav = tree->parent; 37 | fprintf(tree->ofp, "%s.wFormatTag=%u\n", prefix, wav->fmt.wFormatTag); 38 | fprintf(tree->ofp, "%s.wChannels=%u\n", prefix, wav->fmt.wChannels); 39 | fprintf(tree->ofp, "%s.dwSamplesPerSec=%u\n", prefix, 40 | wav->fmt.dwSamplesPerSec); 41 | fprintf(tree->ofp, "%s.dwAvgBytesPerSec=%u\n", prefix, 42 | wav->fmt.dwAvgBytesPerSec); 43 | fprintf(tree->ofp, "%s.wBlockAlign=%u\n", prefix, 44 | wav->fmt.wBlockAlign); 45 | fprintf(tree->ofp, "%s.wBitsPerSample=%u\n", prefix, 46 | wav->fmt.wBitsPerSample); 47 | } 48 | 49 | void wp_data(void *vtree, chunk_t *chunk, char *prefix) 50 | { 51 | tree_t *tree = vtree; 52 | wav_t *wav = tree->parent; 53 | char filename[BUFLEN]; 54 | FILE *sfp; 55 | 56 | snprintf(filename, BUFLEN, "%s.raw", tree->wt_prefix); 57 | fprintf(tree->ofp, "%s.size=%ld\n", prefix, wav->data.size); 58 | fprintf(tree->ofp, "%s.file=%s\n", prefix, filename); 59 | sfp = bens_fopen(filename, "w"); 60 | chunk->data_seek(chunk, tree->ifp); 61 | data_copy(tree->ifp, sfp, wav->data.size, 0); 62 | bens_fclose(sfp); 63 | } 64 | 65 | void wav_to_txt(char *infile, char *outfile, int format) 66 | { 67 | FILE *ifp; 68 | FILE *ofp; 69 | wav_t *wav = wav_new(); 70 | char wt_prefix[BUFLEN]; 71 | char *p; 72 | int n; 73 | int riff_item; 74 | 75 | strncpy(wt_prefix, outfile, BUFLEN - 1); 76 | wt_prefix[BUFLEN - 1] = '\000'; 77 | p = strrchr(wt_prefix, '.'); 78 | if (p != NULL) 79 | *p = '\000'; 80 | 81 | ifp = bens_fopen(infile, "r"); 82 | ofp = bens_fopen(outfile, "w"); 83 | wav->header_read(wav, ifp); 84 | riff_item = n = wav->tree->ckID_find(wav->tree, "RIFF", "WAVE", -1); 85 | wav->tree->items[n].print = (format == 0) ? wp_ignore : wp_meta; 86 | n = wav->tree->ckID_find(wav->tree, "fmt ", NULL, -1); 87 | wav->tree->items[n].print = wp_fmt; 88 | n = wav->tree->ckID_find(wav->tree, "data", NULL, -1); 89 | wav->tree->items[n].print = (format == 0) ? wp_data : wp_ignore; 90 | wav->tree->print(wav->tree, riff_item, "", wt_prefix, ifp, ofp); 91 | 92 | wav->destroy(wav); 93 | bens_fclose(ifp); 94 | bens_fclose(ofp); 95 | } 96 | 97 | void txt_to_wav(char *infile, char *outfile) 98 | { 99 | FILE *ifp; 100 | FILE *ofp; 101 | FILE *sfp; 102 | txt_t *txt; 103 | wav_t *wav; 104 | char *str; 105 | myWORD wFormatTag = -1; 106 | myWORD wChannels = -1; 107 | myDWORD dwSamplesPerSec = -1; 108 | myWORD wBitsPerSample = -1; 109 | long bytes_per_sample; 110 | long data_size = -1; 111 | long sample_count; 112 | int byteswap_do = 0; 113 | 114 | ifp = bens_fopen(infile, "r"); 115 | ofp = bens_fopen(outfile, "w"); 116 | txt = txt_new(); 117 | txt->read_lines(txt, ifp); 118 | 119 | str = txt->get_data(txt, "RIFF.fmt.wFormatTag"); 120 | if (str != NULL) { 121 | wFormatTag = atoi(str); 122 | } 123 | if (wFormatTag != WAVE_FORMAT_PCM) 124 | trap_exit("unsupported wFormatTag"); 125 | 126 | str = txt->get_data(txt, "RIFF.fmt.wChannels"); 127 | if (str != NULL) { 128 | wChannels = atoi(str); 129 | } 130 | if (wChannels < 1) 131 | trap_exit("unsupported wChannels"); 132 | 133 | str = txt->get_data(txt, "RIFF.fmt.dwSamplesPerSec"); 134 | if (str != NULL) { 135 | dwSamplesPerSec = atoi(str); 136 | } 137 | if (dwSamplesPerSec < 1) 138 | trap_exit("unsupported dwSamplesPerSec"); 139 | 140 | str = txt->get_data(txt, "RIFF.fmt.dwAvgBytesPerSec"); 141 | str = txt->get_data(txt, "RIFF.fmt.wBlockAlign"); 142 | str = txt->get_data(txt, "RIFF.fmt.wBitsPerSample"); 143 | if (str != NULL) { 144 | wBitsPerSample = atoi(str); 145 | } 146 | if (wBitsPerSample < 1 || wBitsPerSample % 8 != 0) 147 | trap_exit("unsupported wBitsPerSample"); 148 | bytes_per_sample = wBitsPerSample / 8; 149 | 150 | str = txt->get_data(txt, "RIFF.data.size"); 151 | if (str != NULL) { 152 | data_size = atol(str); 153 | sample_count = data_size / bytes_per_sample; 154 | } 155 | if (data_size % bytes_per_sample != 0) 156 | trap_exit("unsupported data.size"); 157 | 158 | str = txt->get_data(txt, "RIFF.data.byteswap"); 159 | if (str != NULL) 160 | byteswap_do = atoi(str); 161 | 162 | wav = wav_new(); 163 | wav->header_set(wav, wChannels, bytes_per_sample, dwSamplesPerSec, 164 | sample_count); 165 | wav->header_write(wav, ofp); 166 | wav->destroy(wav); 167 | 168 | str = txt->get_data(txt, "RIFF.data.file"); 169 | if (str == NULL) 170 | trap_exit("missing data.file"); 171 | sfp = bens_fopen(str, "r"); 172 | data_copy(sfp, ofp, sample_count * bytes_per_sample, byteswap_do); 173 | bens_fclose(sfp); 174 | 175 | bens_fclose(ifp); 176 | bens_fclose(ofp); 177 | txt->warn_unused(txt); 178 | txt->destroy(txt); 179 | } 180 | 181 | /* move to wav.c 182 | void wp_smpl(void *vtree, chunk_t *chunk, char *prefix) 183 | { 184 | void *data; 185 | void *p; 186 | char filename[] = "sampler.dat"; 187 | FILE *sfp; 188 | 189 | myDWORD dwManufacturer; 190 | myDWORD dwProduct; 191 | myDWORD dwSamplePeriod; 192 | myDWORD dwMIDIUnityNote; 193 | myDWORD dwMIDIPitchFraction; 194 | myDWORD dwSMPTEFormat; 195 | myDWORD dwSMPTEOffset; 196 | myDWORD cSampleLoops; 197 | myDWORD cbSamplerData; 198 | 199 | int i; 200 | myDWORD dwIdentifier; 201 | myDWORD dwType; 202 | myDWORD dwStart; 203 | myDWORD dwEnd; 204 | myDWORD dwFraction; 205 | myDWORD dwPlayCount; 206 | 207 | p = data = chunk->data_read(chunk, ifp); 208 | p = my_get_DWORD_LE(&dwManufacturer, p); 209 | p = my_get_DWORD_LE(&dwProduct, p); 210 | p = my_get_DWORD_LE(&dwSamplePeriod, p); 211 | p = my_get_DWORD_LE(&dwMIDIUnityNote, p); 212 | p = my_get_DWORD_LE(&dwMIDIPitchFraction, p); 213 | p = my_get_DWORD_LE(&dwSMPTEFormat, p); 214 | p = my_get_DWORD_LE(&dwSMPTEOffset, p); 215 | p = my_get_DWORD_LE(&cSampleLoops, p); 216 | p = my_get_DWORD_LE(&cbSamplerData, p); 217 | fprintf(ofp, "%s.dwManufacturer=%u\n", prefix, dwManufacturer); 218 | fprintf(ofp, "%s.dwProduct=%u\n", prefix, dwProduct); 219 | fprintf(ofp, "%s.dwSamplePeriod=%u\n", prefix, dwSamplePeriod); 220 | fprintf(ofp, "%s.dwMIDIUnityNote=%u\n", prefix, dwMIDIUnityNote); 221 | fprintf(ofp, "%s.dwMIDIPitchFraction=%u\n", prefix, dwMIDIPitchFraction); 222 | fprintf(ofp, "%s.dwSMPTEFormat=%u\n", prefix, dwSMPTEFormat); 223 | fprintf(ofp, "%s.dwSMPTEOffset=%u\n", prefix, dwSMPTEOffset); 224 | fprintf(ofp, "%s.cSampleLoops=%u\n", prefix, cSampleLoops); 225 | fprintf(ofp, "%s.cbSamplerData=%u\n", prefix, cbSamplerData); 226 | if (cbSamplerData > 0) { 227 | fprintf(ofp, "%s.SamplerDataFile=%s\n", prefix, filename); 228 | } 229 | 230 | for (i = 0; i < cSampleLoops; i++) { 231 | p = my_get_DWORD_LE(&dwIdentifier, p); 232 | p = my_get_DWORD_LE(&dwType, p); 233 | p = my_get_DWORD_LE(&dwStart, p); 234 | p = my_get_DWORD_LE(&dwEnd, p); 235 | p = my_get_DWORD_LE(&dwFraction, p); 236 | p = my_get_DWORD_LE(&dwPlayCount, p); 237 | fprintf(ofp, "%s.loop.%d.dwIdentifier=%u\n", prefix, i, dwIdentifier); 238 | fprintf(ofp, "%s.loop.%d.dwType=%u\n", prefix, i, dwType); 239 | fprintf(ofp, "%s.loop.%d.dwStart=%u\n", prefix, i, dwStart); 240 | fprintf(ofp, "%s.loop.%d.dwEnd=%u\n", prefix, i, dwEnd); 241 | fprintf(ofp, "%s.loop.%d.dwFraction=%u\n", prefix, i, dwFraction); 242 | fprintf(ofp, "%s.loop.%d.dwPlayCount=%u\n", prefix, i, dwPlayCount); 243 | } 244 | 245 | if (cbSamplerData > 0) { 246 | sfp = bens_fopen(filename, "w"); 247 | bens_fwrite(p, cbSamplerData, 1, sfp); 248 | bens_fclose(sfp); 249 | } 250 | } 251 | */ 252 | 253 | -------------------------------------------------------------------------------- /pysf-2/readme.html: -------------------------------------------------------------------------------- 1 | 2 | pysf - Python SoundFont utility 3 | 4 |

Intro

5 |

6 | The pysf utility is a way to create and edit SoundFont 2 files 7 | at the command line. It does this using XML configuration 8 | files and basic audio files (strict sub-set of .wav and .aif). 9 |

10 |

11 | Each SoundFont2 file has one or more presets, each preset 12 | containing one or more preset zones, each preset zone mapping 13 | to an instrument, each instrument containing one or more 14 | instrument zones, each instrument zone mapping to a wavetable. 15 |

16 |

17 | The pysf utility is released into the public domain. For 18 | countries without a public domain, pysf is released under 19 | the WTF public license. 20 |

21 |

22 | My email address is collver@peak.org 23 |

24 | 30 | 36 | 45 |

Usage and Examples

46 |

47 |

 48 | Usage: pysf.py [conversion] [infile] [outfile]
 49 |     conversion := --sf2xml | --xml2sf
 50 |     conversion := --aif2xml | --xml2aif
 51 |     conversion := --wav2xml | --xml2wav
 52 | 
53 |

54 |

55 |

pysf.py --sf2xml old.sf2 conf.xml
56 | Create conf.xml based on old.sf2. Will also create conf%d.wav for 57 | included audio samples 58 |

59 |

60 |

pysf.py --xml2sf conf.xml new.sf2
61 | Create new.sf2 based on conf.xml 62 |

63 |

64 |

xmllint --noout --schema pysf.xsd conf.xml
65 | Validate conf.xml using xmllint utility from libxml. 66 |

67 |

Brief explaination of configuration tags

68 |

69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 87 | 88 | 90 | 92 | 93 | 94 | 95 | 96 | 97 | 99 | 101 | 103 | 105 | 107 | 109 | 114 | 115 | 116 | 118 | 119 | 120 | 122 | 123 | 124 | 125 | 127 | 128 |
tagdescription
ISNGmandatory, optimal target sound engine
INAMmandatory, name of sound bank
ICRDfile creation date
IPRDtarget product
ISFTsoftware used to create/modify the file
IFILcontains major and minor version of spec.
majorMajor version of soundfont specfication used.
minorMinor version of soundfont specfication used.
instrumentsmandatory, instrument list
instrumentmandatory, instrument section
presetsmandatory, preset list
presetmandatory, preset section
wavetablesmandatory, wavetable list
wavetablemandatory, wavetable section
zonesmandatory, zone list for instrument or preset 86 | section
zonemandatory, zone section
idmandatory, id for instrument or wavetable, 89 | referenced by other sections
namemandatory, descriptive name for instrument, 91 | preset, or wavetable
keyRangerange of MIDI notes for zone
velRangerange of MIDI velocities for zone
overridingRootKeybase MIDI note for zone
wavetableIdwavetable used by instrument zone
instrumentIdinstrument used by preset zone
delayVolEnvtime in seconds for delay section of 98 | volume envelope
attackVolEnvtime in seconds for attack section of 100 | volume envelope
holdVolEnvtime in seconds for hold section of volume 102 | envelope
decayVolEnvtime in seconds for decay section of 104 | volume envelope
releaseVolEnvtime in seconds for release section of 106 | volume envelope
sustainVolEnvvolume decrease in centibels for decay 108 | section
keynumToVolEnvHolddegree, in timecents per KeyNumber 110 | units, to which the hold time is degreased. The value of KeyNumber 111 | units is found by the difference between the MIDI note number and 60. 112 |
exclusiveClassnew notes will silence currently 113 | playing notes if the instruments are in the same exclusiveClass
gensgeneric generator operator list in zone
gengeneric generator operator
commentcomment describing generator, not used by 117 | pysf
hexAmounthexadecimal unsigned word argument
operdecimal generator operator number
filemandatory, name of aif or wav file used by 121 | wavetable
looploop begin and end point for wavetable
pitchMIDI note that the wavetable was recorded at
pitchcorrpitch correction in cents for wavetable
channelselect channel for instrument and/or from 126 | stereo audio file
linklink to other wavetable in a stereo instrument
129 |

130 |

24-bit sample width wavetables

131 |

132 | To use 24-bit sample width wavetables, you must set ifil to major 2, minor 4. 133 | If you use 24-bit wavetables, then all wavetables used must be 24-bit. 134 | You can use audacity to convert between 24-bit and other sample widths. 135 |

136 |

137 | Theoretically, old software should be able to play 24-bit soundfonts 138 | at lower quality by simply ignoring the sm24 chunk. However, some programs 139 | will refuse to use 24-bit soundfonts. Timidity and fluidsynth do not 140 | support 24-bit soundfonts, and apparently neither does quicktime. 141 | Therefore, this feature is not well tested in pysf. 142 |

143 |

Stereo wavetables

144 |

145 | To use a stereo .wav file for a mono wavetable, use the channel tag to 146 | select a channel. If the wavetable is linked, then the channel tag also 147 | determines whether the wavetable is the left or the right channel in a 148 | stereo instrument. A stereo instrument requires two linked wavetables. 149 | Use link tags to link wavetables. Example: 150 |

151 | <wavetable>
152 |   <channel>right</channel>
153 |   <id>1</id>
154 |   <file>stereo.wav</file>
155 |   <link>2</link>
156 | </wavetable>
157 | <wavetable>
158 |   <channel>left</channel>
159 |   <id>2</id>
160 |   <file>stereo.wav</file>
161 |   <link>1</link>
162 | </wavetable> 
163 | 
164 |

165 |

166 | A stereo instrument also requires a zone for each channel. Example: 167 |

168 | <instrument>
169 |   <zones>
170 |     <zone>
171 |       <keyRange><begin>12</begin><end>127</end></keyRange>
172 |       <wavetableId>1</wavetableId>
173 |     </zone>
174 |     <zone>
175 |       <keyRange><begin>12</begin><end>127</end></keyRange>
176 |       <wavetableId>2</wavetableId>
177 |     </zone>
178 |   </zones>
179 | </instrument>
180 | 
181 |

182 |

History

183 |

184 |

    185 |
    • Version 1, 2007-Mar-4 186 |
    • added support for stereo wavetables
    • 187 |
    • tested on Python 2.3.5 and Python 2.4.4
    • 188 |
  • 189 |
    • Version 2, 2007-Mar-10 190 |
    • added IFIL configuration tag. for specifying soundfont 2.04
    • 191 |
    • added support for 24-bit sample width
    • 192 |
    • added version attribute to XML schema and output files
    • 193 |
    • tested on Python 2.5
    • 194 |
    • tested on big-endian system
    • 195 |
    • using md5 instead of zlib.adler32 for portability reasons. 196 | http://sourceforge.net/tracker/?func=detail&atid=105470&aid=1678102&group_id=5470
    • 197 |
  • 198 |
199 |

200 |

TODO

201 |

202 |

    203 |
  • add a gui front-end
  • 204 |
205 |

206 | 207 | 208 | -------------------------------------------------------------------------------- /sfubar-9/README: -------------------------------------------------------------------------------- 1 | Intro 2 | Usage and Examples 3 | Build Instructions 4 | Brief explanation of configuration file format 5 | History 6 | 7 | Intro 8 | ===== 9 | The sfubar utility is a way to create and edit SoundFont 2 files at the 10 | command line. It does this using plain text configuration files and 11 | basic audio files (strict sub-set of .wav, .aif, .raw). It can also be 12 | used to edit meta-data in .wav and .aif files. 13 | 14 | This is part of my project to convert my old Impulse Tracker modules to 15 | csound. The tool only supports a subset of the SoundFont 2 standard. 16 | This is released in the public domain. 17 | 18 | Each SoundFont2 file has one of more presets, each composed of one or 19 | more zones which map to instruments. Each instrument is composed of 20 | one or more zones which map to wavetables. 21 | 22 | My email address is collver@peak.org. 23 | 24 | Many terms will be defined in the SoundFont 2 standard. 25 | http://soundblaster.com/soundfont/sfspec21.pdf 26 | 27 | MPEG4-SA is more free, and includes much of the same information. 28 | http://sound.media.mit.edu/mpeg4/ 29 | 30 | The SoundFont 2 standard refers to the MIDI standard. 31 | http://www.ibiblio.org/emusic-l/info-docs-FAQs/MIDI-doc/ 32 | http://www.borg.com/~jglatt/tech/midispec.htm 33 | 34 | The WAV, AIFF, and AIFC formats are documented here: 35 | http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html 36 | http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/AIFF/AIFF.html 37 | 38 | Both SoundFont 2 and Impulse Tracker refer to a sample as a table of 39 | recorded data used to generate a sound. For example, a .wav file with 40 | 16-bit audio is a table of 16-bit numbers. Common usage of the term 41 | sample refers to the individual numbers that make up the table. In my 42 | opinion, this can cause confusion. From here on, I will refer to the 43 | individual numbers as samples, and the whole table as a wavetable. 44 | 45 | MIDI notes have numbers from 0 to 127, with 60 being C-5. 46 | 47 | Build Instructions 48 | ================== 49 | see libriffraff*/README 50 | 51 | Note that GNU Make cannot handle spaces in paths for targets and 52 | dependencies. Therefore on Windows, you must be careful not to 53 | build under such a path. see http://savannah.gnu.org/bugs/?712 54 | 55 | make 56 | 57 | Usage and Examples 58 | ================== 59 | Usage: sfubar [conversion] [infile] [outfile] 60 | conversion := --sf2txt | --txt2sf | --sfdebug 61 | 62 | sfubar --sf2txt old.sf2 sf_conf.txt 63 | Create sf_conf.txt based on old.sf2 64 | Will also create sf_conf%d.wav for included audio samples 65 | 66 | sfubar --txt2sf sf_conf.txt new.sf2 67 | Create new.sf2 based on configuration in sf_conf.txt 68 | 69 | sfubar --sfdebug new.sf2 - | more 70 | Print debugging information about new.sf2 and pipe to pager. 71 | 72 | Brief explanation of configuration file format 73 | ============================================== 74 | For technical specifics, see libparsetxt-*/README. 75 | 76 | RIFF.LIST.isng.zstr=EMU8000 77 | Sound engine that the file is optimized for. 78 | Mandatory line. 79 | 80 | RIFF.LIST.INAM.zstr=sfubar instruments 81 | Name of the sound bank. 82 | Mandatory line. 83 | 84 | RIFF.LIST.ICRD.zstr=Nov 08, 2005 85 | Date the file was created. 86 | 87 | RIFF.LIST.IPRD.zstr=SBAWE32 88 | Product that the file is intended for. 89 | 90 | RIFF.LIST.ISFT.zstr=Compressed ImpulseTracker 2.14:mod2cs-0.2 91 | Tools used to create and modify the file. 92 | 93 | SF2.wt.1.wav=test1.wav 94 | SF2.wt.1.aif=test1.aif 95 | File name for the first wavetable. 96 | Mandatory for each wavetable. 97 | Key name depends on file format. 98 | The files must be 16-bit, monoaural, uncompressed audio. 99 | The sample rate must be integral and between 400 and 50000 hertz. 100 | Will read loop points, pitch, and pitch correction from aif files. 101 | 102 | SF2.wt.1.name=piano 103 | Descriptive name for the first wavetable. 104 | 105 | SF2.wt.1.loopstart=10 106 | Starting sample for looping in the first wavetable. 107 | Overrides settings read from wavetable file. 108 | 109 | SF2.wt.1.loopstop=164584 110 | Ending sample for looping in the first wavetable. 111 | Overrides settings read from wavetable file. 112 | 113 | SF2.wt.1.pitch=60 114 | MIDI note that the wavetable was recorded at. 115 | Overrides settings read from wavetable file. 116 | 117 | SF2.wt.1.pitchcorr=0 118 | Pitch correction in cents. 119 | Overrides settings read from wavetable file. 120 | 121 | SF2.in.1.name=piano instrument 122 | Descriptive name for the first instrument 123 | 124 | SF2.in.1.zone.1.wt=1 125 | Wavetable used by the first zone of the first instrument. 126 | Each instrument must have at least 1 zone. 127 | 128 | SF2.in.1.zone.1.keyRange=12,127 129 | Range of MIDI notes for the first zone of the first instrument. 130 | 131 | SF2.in.1.zone.1.velRange=0,127 132 | Range of MIDI velocities for the first zone of the first instrument. 133 | 134 | SF2.in.1.zone.1.delayVolEnv=0 135 | SF2.in.1.zone.1.attackVolEnv=0.25 136 | SF2.in.1.zone.1.holdVolEnv=1 137 | SF2.in.1.zone.1.decayVolEnv=1 138 | SF2.in.1.zone.1.releaseVolEnv=1 139 | Time in seconds for delay, attack, hold, and decay sections of volume 140 | envelope. 141 | 142 | SF2.in.1.zone.1.sustainVolEnv=0 143 | Volume decrease in centibels for the decay section. 144 | 145 | SF2.in.1.zone.1.keynumToVolEnvHold=0 146 | Degree, in timecents per KeyNumber units, to which the hold time is 147 | decreased. The value of KeyNumber units is found by the difference 148 | between the note's MIDI key number and 60. 149 | 150 | SF2.in.1.zone.1.keynumToVolEnvDecay=0 151 | Degree, in timecents per KeyNumber units, to which the decay time is 152 | decreased. The value of KeyNumber units is found by the difference 153 | between the note's MIDI key number and 60. 154 | 155 | SF2.in.1.zone.1.overridingRootKey=77 156 | Base MIDI note for the first section of the first instrument. 157 | If a wavetable is recorded at C-5, and the basenote is set to 77, 158 | then the instrument will play C-5 at MIDI note 77. 159 | 160 | SF2.in.1.zone.1.exclusiveClass=1 161 | New notes will silence currently playing notes if the instruments are in 162 | the same exclusiveClass. 163 | 164 | SF2.ps.1.name=Piano preset 165 | Descriptive name for the first preset 166 | 167 | SF2.ps.1.bank=40 168 | Bank for the first preset 169 | 170 | SF2.ps.1.zone.1.in=1 171 | Instrument used by the first zone of the first preset. 172 | Each preset must have at least 1 zone. 173 | 174 | SF2.ps.1.zone.1.keyRange=12,127 175 | Range of MIDI notes for the first zone of the first preset. 176 | 177 | SF2.ps.1.zone.1.velRange=0,127 178 | Range of MIDI velocities for the first zone of the first preset. 179 | 180 | SF2.ps.1.zone.1.delayVolEnv=0 181 | SF2.ps.1.zone.1.attackVolEnv=0.25 182 | SF2.ps.1.zone.1.holdVolEnv=1 183 | SF2.ps.1.zone.1.decayVolEnv=1 184 | SF2.ps.1.zone.1.releaseVolEnv=1 185 | Time in seconds for delay, attack, hold, and decay sections of volume 186 | envelope. 187 | 188 | SF2.ps.1.zone.1.sustainVolEnv=0 189 | Volume decrease in centibels for the decay section. 190 | 191 | SF2.ps.1.zone.1.keynumToVolEnvHold=0 192 | Degree, in timecents per KeyNumber units, to which the hold time is 193 | decreased. The value of KeyNumber units is found by the difference 194 | between the note's MIDI key number and 60. 195 | 196 | SF2.ps.1.zone.1.keynumToVolEnvDecay=0 197 | Degree, in timecents per KeyNumber units, to which the decay time is 198 | decreased. The value of KeyNumber units is found by the difference 199 | between the note's MIDI key number and 60. 200 | 201 | History 202 | ======= 203 | 2006-04-16 version 1 204 | - initial release 205 | 206 | 2006-04-20 version 2 207 | - split off libparsetxt and libriffraff components 208 | - add --wavdebug --wav2txt and --txt2wav commands 209 | - the motivation for --txt2wav was to gain the ability to add the 210 | sampler chunk to a wav file. Then I found csound only supports 211 | reading loop points from aifc files. so I did not finish it. 212 | 213 | 2006-05-08 version 3 214 | - change soundfont2 loop type from continuous to sustain & continue 215 | - change wavetable configuration key to include file format 216 | - add support for aiff and aifc files to libriffraff 217 | - add support for reading sampler settings from aif files when 218 | creating soundfont files. 219 | - add gensine utility, used to replace sox in test script 220 | - add configuration key "byteswap" for adjusting raw samples 221 | 222 | 2006-07-09 version 4 223 | - remove support for reading sampler settings from aif files when 224 | creating soundfont files. It was only writing the settings in 225 | the sample chunks, and omitted writing loop info in hydra. Loop 226 | settings must be set in the --txt2sf text input file. 227 | - add a few files to clean make target 228 | - add trap.c to replace exit(), which should make this more 229 | friendly as a library 230 | - disable csound test, because it varies when I don't expect it 231 | - make first pass at library, libsfubar-4.a and sfubar.h 232 | 233 | 2006-07-16 version 5 234 | - change range to keyRange 235 | - move some soundfont-specific structures from rifftypes.h to sfutil.h 236 | - move some constants from sfutil.c to sfutil.h and changed to enums 237 | - add generators: velRange, delayVolEnv, attackVolEnv, 238 | holdVolEnv, decayVolEnv, sustainVolEnv, releaseVolEnv, 239 | keynumToVolEnvHold, keynumToVolEnvDecay 240 | - new generators minimally tested, please report any bugs! 241 | 242 | 2006-07-29 version 6 243 | - rename map to zone 244 | - rename basenote to overridingRootKey 245 | - remove backward compatibility word "range" 246 | - add support for preset zones 247 | - remove 1:1 relationship for preset and instrument zones 248 | - make overridingRootKey optional instead of required 249 | - since the beginning, sfubar would incorrectly index "maps" when 250 | converting from soundfont2 to text. I did not catch this because my 251 | test case only had a single mapping, and I generally convert from text 252 | to soundfont2, not the other way around. Fixed bug and added test case. 253 | - specify sample type in error message about unsupported types 254 | - fix arithmetic bug when converting volume envelopes to text 255 | - add exclusiveClass generator 256 | 257 | 2006-08-07 version 7 258 | - fix test.sh to match configuration format changes 259 | - fix makefiles to work with GNU make 260 | 261 | 2006-11-13 version 8 262 | - remove -static link flag to accomodate broken compiler shipped with 263 | Mac OS X Tiger. 264 | - make CFLAGS cascade from parent Makefile 265 | - fix ascii/binary file mode issues in Cygwin 266 | - fix regression, the assumption that malloc() clears the memory allocated 267 | 268 | 2007-02-16 version 9 269 | - fix sampleModes bug which has been present since sfubar version 1. 270 | sfubar sets the value for sampleModes depending on the loop points of 271 | the wavetable in the instrument zone. However, sfubar indexed the 272 | wavetable by the instrument number instead of the wavetable number. 273 | Reported by Pete @ Berkeley 274 | - do not include sampleModes in preset zones 275 | - fix signed vs unsigned issue in libriffraff 276 | - added missing make rule for ieee80.o in libriffraff 277 | - skip ieee80 conversion test on Windows 95, because of buggy printf format 278 | - rename generator enumators to include magic numbers 279 | because there are so many, it helps to keep track 280 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/riff.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include "bio.h" 8 | #include "bits.h" 9 | #include "riff.h" 10 | 11 | #ifndef BUFLEN 12 | #define BUFLEN 256 13 | #endif 14 | 15 | void assert_nonull(char *prefix, void *data) 16 | { 17 | if (data == NULL) 18 | trap_exit("%s: null data!", prefix); 19 | } 20 | 21 | int chunk_size(void *vchunk) 22 | { 23 | chunk_t *chunk = vchunk; 24 | int size = CHUNK_HEADER_SIZE + chunk->ckSize; 25 | if (!is_even(size)) 26 | size++; 27 | return size; 28 | } 29 | 30 | void chunk_header_write(void *vchunk, FILE *fp) 31 | { 32 | chunk_t *chunk = vchunk; 33 | myDWORD temp; 34 | if (chunk->endian == MY_LITTLE_ENDIAN) 35 | temp = HLE32(chunk->ckSize); 36 | else 37 | temp = HBE32(chunk->ckSize); 38 | chunk->offset = ftell(fp); 39 | bens_fwrite(chunk->ckID.str, 4, 1, fp); 40 | bens_fwrite(&temp, 4, 1, fp); 41 | } 42 | 43 | void chunk_data_write(void *vchunk, void *data, int length, FILE *fp) 44 | { 45 | chunk_t *chunk = vchunk; 46 | assert_nonull("data_write: fp", fp); 47 | bens_fwrite(data, length, 1, fp); 48 | chunk->ckSize += length; 49 | } 50 | 51 | int chunk_pad_write(void *vchunk, FILE *fp) 52 | { 53 | chunk_t *chunk = vchunk; 54 | if (!is_even(chunk->ckSize)) { 55 | bens_fwrite("\000", 1, 1, fp); 56 | return 1; 57 | } 58 | return 0; 59 | } 60 | 61 | int chunk_write(void *vchunk, FILE *fp) 62 | { 63 | chunk_t *chunk = vchunk; 64 | int retval = 0; 65 | assert_nonull("chunk_write: chunk->data", chunk->data); 66 | assert_nonull("chunk_write: fp", fp); 67 | if (chunk->location == IN_RAM) { 68 | chunk->header_write(chunk, fp); 69 | bens_fwrite(chunk->data, chunk->ckSize, 1, fp); 70 | retval += chunk->pad_write(chunk, fp); 71 | retval += CHUNK_HEADER_SIZE + chunk->ckSize; 72 | } 73 | return retval; 74 | } 75 | 76 | void chunk_header_read(void *vchunk, FILE *fp) 77 | { 78 | chunk_t *chunk = vchunk; 79 | myDWORD temp; 80 | assert_nonull("read: fp", fp); 81 | if (chunk->location == ON_DISK) { 82 | chunk->offset = ftell(fp); 83 | bens_fread(chunk->ckID.str, sizeof(myFOURCC), 1, fp); 84 | bens_fread(&temp, sizeof(myDWORD), 1, fp); 85 | if (chunk->endian == MY_LITTLE_ENDIAN) 86 | chunk->ckSize = LE32H(temp); 87 | else 88 | chunk->ckSize = BE32H(temp); 89 | } 90 | } 91 | 92 | void chunk_data_read_bytes(void *vchunk, FILE *fp, char *dst, int count) 93 | { 94 | chunk_t *chunk = vchunk; 95 | 96 | assert_nonull("data_read_bytes: fp", fp); 97 | if (count > chunk->ckSize) { 98 | trap_warn("data_read_bytes: read past end of chunk, truncating"); 99 | count = chunk->ckSize; 100 | } 101 | if (chunk->location == ON_DISK) { 102 | chunk->data_seek(chunk, fp); 103 | bens_fread(dst, count, 1, fp); 104 | } else { 105 | memcpy(dst, chunk->data, count); 106 | } 107 | } 108 | 109 | void *chunk_data_read(void *vchunk, FILE *fp) 110 | { 111 | chunk_t *chunk = vchunk; 112 | char pad_byte; 113 | 114 | assert_nonull("data_read: fp", fp); 115 | if (chunk->location == ON_DISK) { 116 | if (chunk->data == NULL) { 117 | chunk->data = malloc(chunk->ckSize); 118 | chunk->data_read_bytes(chunk, fp, chunk->data, chunk->ckSize); 119 | if (!is_even(chunk->ckSize)) 120 | bens_fread(&pad_byte, 1, 1, fp); 121 | } 122 | chunk->location = IN_RAM; 123 | } 124 | return chunk->data; 125 | } 126 | 127 | void chunk_destroy(void *vchunk) 128 | { 129 | chunk_t *chunk = vchunk; 130 | if (chunk->data != NULL) 131 | free(chunk->data); 132 | free(chunk); 133 | } 134 | 135 | void chunk_start_seek(void *vchunk, FILE *fp) 136 | { 137 | chunk_t *chunk = vchunk; 138 | fseek(fp, chunk->offset, SEEK_SET); 139 | } 140 | 141 | void chunk_data_seek(void *vchunk, FILE *fp) 142 | { 143 | chunk_t *chunk = vchunk; 144 | fseek(fp, chunk->offset + CHUNK_HEADER_SIZE, SEEK_SET); 145 | } 146 | 147 | void chunk_end_seek(void *vchunk, FILE *fp) 148 | { 149 | chunk_t *chunk = vchunk; 150 | fseek(fp, chunk->offset + CHUNK_HEADER_SIZE + chunk->ckSize, SEEK_SET); 151 | } 152 | 153 | int chunk_is_end(void *vchunk, FILE *fp) 154 | { 155 | chunk_t *chunk = vchunk; 156 | int retval = 0; 157 | long fpos_cur = ftell(fp); 158 | long fpos_end = chunk->offset + CHUNK_HEADER_SIZE + chunk->ckSize; 159 | if (fpos_cur >= fpos_end) 160 | retval = 1; 161 | return retval; 162 | } 163 | 164 | char *chunk_form_get(void *vchunk, FILE *fp) 165 | { 166 | chunk_t *chunk = vchunk; 167 | static char form[5]; 168 | memset(form, 0, sizeof(form)); 169 | if (chunk->ckSize > 3) 170 | chunk->data_read_bytes(chunk, fp, form, 4); 171 | return form; 172 | } 173 | 174 | int chunk_form_check(void *vchunk, char *valid, FILE *fp) 175 | { 176 | chunk_t *chunk = vchunk; 177 | char *form; 178 | int retval; 179 | 180 | if (valid == NULL) { 181 | /* if the valid form is NULL, then match anything */ 182 | retval = 0; 183 | } else { 184 | form = chunk->form_get(chunk, fp); 185 | retval = strncmp(form, valid, 4); 186 | } 187 | return retval; 188 | } 189 | 190 | int chunk_count = 0; 191 | chunk_t *chunk_new(void *vparent, chunk_loc_t location) 192 | { 193 | chunk_t *retval; 194 | chunk_t *parent = vparent; 195 | 196 | retval = malloc(sizeof(chunk_t)); 197 | retval->count = 0; 198 | retval->data = NULL; 199 | retval->ckSize = 0; 200 | retval->parent = parent; 201 | retval->location = location; 202 | retval->order = chunk_count++; 203 | retval->item = -1; 204 | retval->size = chunk_size; 205 | if (parent != NULL) 206 | retval->endian = parent->endian; 207 | else 208 | retval->endian = MY_LITTLE_ENDIAN; 209 | 210 | retval->data_read_bytes = chunk_data_read_bytes; 211 | retval->data_read = chunk_data_read; 212 | retval->data_seek = chunk_data_seek; 213 | retval->data_write = chunk_data_write; 214 | retval->destroy = chunk_destroy; 215 | retval->end_seek = chunk_end_seek; 216 | retval->form_check = chunk_form_check; 217 | retval->form_get = chunk_form_get; 218 | retval->header_read = chunk_header_read; 219 | retval->header_write = chunk_header_write; 220 | retval->is_end = chunk_is_end; 221 | retval->pad_write = chunk_pad_write; 222 | retval->start_seek = chunk_start_seek; 223 | 224 | retval->write = chunk_write; 225 | return retval; 226 | } 227 | 228 | int tree_ckID_find(void *vtree, char *ckID, char *form, int level) 229 | { 230 | tree_t *tree = vtree; 231 | int i = -1; 232 | while (tree->items[++i].level != -1) { 233 | if (tree->items[i].chunk == NULL) 234 | continue; 235 | if (level != -1 && level != tree->items[i].level) 236 | continue; 237 | if (ckID != NULL && strncmp(ckID, tree->items[i].ckID, 4) != 0) 238 | continue; 239 | if (form != NULL && strncmp(form, tree->items[i].form, 4) != 0) 240 | continue; 241 | return i; 242 | } 243 | return -1; 244 | } 245 | 246 | int tree_chunk_find(void *vtree, chunk_t *chunk, int level, FILE *fp) 247 | { 248 | tree_t *tree = vtree; 249 | int i; 250 | 251 | for (i = 0; tree->items[i].level != -1; i++) { 252 | if (tree->items[i].level != level) 253 | continue; 254 | if (strncmp(tree->items[i].ckID, chunk->ckID.str, 4) != 0) 255 | continue; 256 | if (chunk->form_check(chunk, tree->items[i].form, fp) != 0) 257 | continue; 258 | if (tree->items[i].chunk != NULL) 259 | return -1; 260 | chunk->item = i; 261 | tree->items[i].chunk = chunk; 262 | return 1; 263 | } 264 | return 0; 265 | } 266 | 267 | int tree_chunk_is_container(void *vtree, char *str) 268 | { 269 | tree_t *tree = vtree; 270 | int retval = 0; 271 | int i; 272 | for (i = 0; tree->containers[i][0] != '\000'; i++) { 273 | if (strncmp(str, tree->containers[i], 4) == 0) { 274 | retval = 1; 275 | break; 276 | } 277 | } 278 | return retval; 279 | } 280 | 281 | void tree_read(void *vtree, chunk_t *chunk, int level, FILE *fp) 282 | { 283 | tree_t *tree = vtree; 284 | chunk_t *sub_chunk; 285 | char *form; 286 | int found; 287 | long fpos; 288 | 289 | found = tree_chunk_find(tree, chunk, level, fp); 290 | if (found != 1) { 291 | fpos = ftell(fp); 292 | form = chunk->form_get(chunk, fp); 293 | trap_warn("%s, fpos %ld, ckID %c%c%c%c, form %c%c%c%c, level %d", 294 | found == 0 ? "Unknown chunk" : "Duplicate chunk", fpos, 295 | chunk->ckID.str[0], chunk->ckID.str[1], 296 | chunk->ckID.str[2], chunk->ckID.str[3], 297 | form[0], form[1], form[2], form[3], 298 | level); 299 | chunk->end_seek(chunk, fp); 300 | chunk->destroy(chunk); 301 | } else { 302 | if (tree_chunk_is_container(tree, chunk->ckID.str) != 0) { 303 | while (!chunk->is_end(chunk, fp)) { 304 | sub_chunk = chunk_new(chunk, ON_DISK); 305 | sub_chunk->header_read(sub_chunk, fp); 306 | tree->read(tree, sub_chunk, level + 1, fp); 307 | } 308 | } 309 | chunk->end_seek(chunk, fp); 310 | } 311 | } 312 | 313 | void tree_destroy(void *vtree) 314 | { 315 | tree_t *tree = vtree; 316 | int i = 0; 317 | while (tree->items[i].level != -1) { 318 | if (tree->items[i].chunk != NULL) { 319 | tree->items[i].chunk->destroy(tree->items[i].chunk); 320 | tree->items[i].chunk = NULL; 321 | } 322 | i++; 323 | } 324 | } 325 | 326 | char *tree_ckID_normalize(char *ckID) 327 | { 328 | static char retval[5]; 329 | retval[0] = ckID[0]; 330 | retval[1] = ckID[1]; 331 | retval[2] = ckID[2]; 332 | retval[3] = ckID[3]; 333 | retval[4] = '\000'; 334 | if (retval[3] == ' ') { 335 | retval[3] = '\000'; 336 | } 337 | return retval; 338 | } 339 | 340 | void tree_print_recurse(void *vtree, int cursor, char *prefix) 341 | { 342 | tree_t *tree = vtree; 343 | int i; 344 | char *ckID_normal; 345 | char my_prefix[BUFLEN]; 346 | chunk_t *chunk = tree->items[cursor].chunk; 347 | 348 | ckID_normal = tree_ckID_normalize(tree->items[cursor].ckID); 349 | if (prefix[0] == '\000') { 350 | strcpy(my_prefix, ckID_normal); 351 | } else { 352 | snprintf(my_prefix, BUFLEN, "%s.%s", prefix, ckID_normal); 353 | } 354 | 355 | if (tree->items[cursor].print != NULL) 356 | tree->items[cursor].print(tree, chunk, my_prefix); 357 | 358 | for (i = 0; tree->items[i].level != -1; i++) { 359 | if (tree->items[i].chunk != NULL) { 360 | if (tree->items[i].chunk->parent == chunk) { 361 | tree_print_recurse(tree, i, my_prefix); 362 | } 363 | } 364 | } 365 | } 366 | 367 | void tree_print(void *vtree, int cursor, char *prefix, char *wt_prefix, 368 | FILE *ifp, FILE *ofp) 369 | { 370 | tree_t *tree = vtree; 371 | 372 | tree->ifp = ifp; 373 | tree->ofp = ofp; 374 | tree->prefix = prefix; 375 | tree->wt_prefix = wt_prefix; 376 | 377 | tree_print_recurse(tree, cursor, prefix); 378 | } 379 | 380 | tree_t *tree_new(tree_item *items, tree_container *containers, void *parent) 381 | { 382 | tree_t *retval; 383 | 384 | retval = malloc(sizeof(tree_t)); 385 | retval->prefix = NULL; 386 | retval->wt_prefix = NULL; 387 | retval->items = items; 388 | retval->containers = containers; 389 | retval->parent = parent; 390 | retval->ckID_find = tree_ckID_find; 391 | retval->print = tree_print; 392 | retval->read = tree_read; 393 | retval->destroy = tree_destroy; 394 | return retval; 395 | } 396 | -------------------------------------------------------------------------------- /sfubar-9/aifutil.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "aifutil.h" 20 | 21 | #ifndef BUFLEN 22 | #define BUFLEN 256 23 | #endif 24 | 25 | void ap_meta(void *vtree, chunk_t *chunk, char *prefix) 26 | { 27 | tree_t *tree = vtree; 28 | fprintf(tree->ofp, "%s ~ BEGIN\n", prefix); 29 | } 30 | 31 | void ap_ignore(void *vtree, chunk_t *chunk, char *prefix) 32 | { 33 | /* ignore this item, print nothing */ 34 | } 35 | 36 | void ap_fver(void *vtree, chunk_t *chunk, char *prefix) 37 | { 38 | tree_t *tree = vtree; 39 | aif_t *aif = tree->parent; 40 | 41 | fprintf(tree->ofp, "%s.timestamp=%u\n", prefix, aif->fver.timestamp); 42 | } 43 | 44 | void ap_comm(void *vtree, chunk_t *chunk, char *prefix) 45 | { 46 | tree_t *tree = vtree; 47 | aif_t *aif = tree->parent; 48 | char *p; 49 | 50 | fprintf(tree->ofp, "%s.numChannels=%u\n", prefix, aif->comm.numChannels); 51 | fprintf(tree->ofp, "%s.sampleSize=%u\n", prefix, aif->comm.sampleSize); 52 | fprintf(tree->ofp, "%s.sampleRate=%u\n", prefix, 53 | (int)(aif->comm.double_sampleRate)); 54 | p = aif->comm.compressionType.str; 55 | fprintf(tree->ofp, "%s.compressionType.str=%c%c%c%c\n", prefix, 56 | p[0], p[1], p[2], p[3]); 57 | fprintf(tree->ofp, "%s.compressionName.str=%s\n", prefix, 58 | aif->comm.compressionName.str); 59 | } 60 | 61 | void ap_mark(void *vtree, chunk_t *chunk, char *prefix) 62 | { 63 | tree_t *tree = vtree; 64 | aif_t *aif = tree->parent; 65 | int i; 66 | 67 | for (i = 0; i < aif->mark.numMarkers; i++) { 68 | fprintf(tree->ofp, "%s.%d.id=%u\n", prefix, i + 1, 69 | aif->mark.markers[i]->id); 70 | fprintf(tree->ofp, "%s.%d.pos=%u\n", prefix, i + 1, 71 | aif->mark.markers[i]->position); 72 | fprintf(tree->ofp, "%s.%d.name=%s\n", prefix, i + 1, 73 | aif->mark.markers[i]->markerName.str); 74 | } 75 | } 76 | 77 | void ap_inst(void *vtree, chunk_t *chunk, char *prefix) 78 | { 79 | tree_t *tree = vtree; 80 | aif_t *aif = tree->parent; 81 | 82 | fprintf(tree->ofp, "%s.baseNote=%u\n", prefix, aif->inst.baseNote); 83 | fprintf(tree->ofp, "%s.detune=%u\n", prefix, aif->inst.detune); 84 | fprintf(tree->ofp, "%s.lowNote=%u\n", prefix, aif->inst.lowNote); 85 | fprintf(tree->ofp, "%s.highNote=%u\n", prefix, aif->inst.highNote); 86 | fprintf(tree->ofp, "%s.lowVelocity=%u\n", prefix, aif->inst.lowVelocity); 87 | fprintf(tree->ofp, "%s.highVelocity=%u\n", prefix, aif->inst.highVelocity); 88 | fprintf(tree->ofp, "%s.gain=%u\n", prefix, aif->inst.gain); 89 | fprintf(tree->ofp, "%s.sustainLoop.playMode=%u\n", prefix, 90 | aif->inst.sustainLoop.playMode); 91 | fprintf(tree->ofp, "%s.sustainLoop.beginLoop=%u\n", prefix, 92 | aif->inst.sustainLoop.beginLoop); 93 | fprintf(tree->ofp, "%s.sustainLoop.endLoop=%u\n", prefix, 94 | aif->inst.sustainLoop.endLoop); 95 | fprintf(tree->ofp, "%s.releaseLoop.playMode=%u\n", prefix, 96 | aif->inst.releaseLoop.playMode); 97 | fprintf(tree->ofp, "%s.releaseLoop.beginLoop=%u\n", prefix, 98 | aif->inst.releaseLoop.beginLoop); 99 | fprintf(tree->ofp, "%s.releaseLoop.endLoop=%u\n", prefix, 100 | aif->inst.releaseLoop.endLoop); 101 | } 102 | 103 | void ap_comt(void *vtree, chunk_t *chunk, char *prefix) 104 | { 105 | tree_t *tree = vtree; 106 | aif_t *aif = tree->parent; 107 | int i; 108 | char filename[BUFLEN]; 109 | FILE *fp; 110 | 111 | for (i = 0; i < aif->comt.numComments; i++) { 112 | fprintf(tree->ofp, "%s.%d.timeStamp=%u\n", prefix, i + 1, 113 | aif->comt.comments[i]->timeStamp); 114 | fprintf(tree->ofp, "%s.%d.marker=%u\n", prefix, i + 1, 115 | aif->comt.comments[i]->marker); 116 | snprintf(filename, BUFLEN, "comment%d.txt", i + 1); 117 | fprintf(tree->ofp, "%s.%d.file=%s\n", prefix, i + 1, filename); 118 | fp = bens_fopen(filename, "w"); 119 | bens_fwrite(aif->comt.comments[i]->text, 120 | aif->comt.comments[i]->count, 1, fp); 121 | fclose(fp); 122 | } 123 | } 124 | 125 | void ap_iff_text(void *vtree, chunk_t *chunk, char *prefix) 126 | { 127 | tree_t *tree = vtree; 128 | char *p = chunk->data; 129 | int i; 130 | char filename[BUFLEN]; 131 | FILE *fp; 132 | 133 | i = chunk->ckSize; 134 | if (p[i] == '\000') 135 | i--; /* skip pad byte */ 136 | snprintf(filename, BUFLEN, "%u.txt", chunk->ckID.dword); 137 | fprintf(tree->ofp, "%s.file=%s\n", prefix, filename); 138 | fp = bens_fopen(filename, "w"); 139 | bens_fwrite(p, i, 1, fp); 140 | fclose(fp); 141 | } 142 | 143 | void ap_ssnd(void *vtree, chunk_t *chunk, char *prefix) 144 | { 145 | tree_t *tree = vtree; 146 | aif_t *aif = tree->parent; 147 | char filename[BUFLEN]; 148 | FILE *sfp; 149 | 150 | snprintf(filename, BUFLEN, "%s.raw", tree->wt_prefix); 151 | fprintf(tree->ofp, "%s.file=%s\n", prefix, filename); 152 | sfp = bens_fopen(filename, "w"); 153 | fseek(tree->ifp, aif->ssnd.fpos_WaveformData, SEEK_SET); 154 | data_copy(tree->ifp, sfp, aif->ssnd.bytes_WaveformData, 0); 155 | bens_fclose(sfp); 156 | } 157 | 158 | void aif_to_txt(char *infile, char *outfile, int format) 159 | { 160 | FILE *ifp; 161 | FILE *ofp; 162 | aif_t *aif = aif_new(); 163 | char wt_prefix[BUFLEN]; 164 | char *p; 165 | int n; 166 | int riff_item; 167 | 168 | strncpy(wt_prefix, outfile, BUFLEN - 1); 169 | wt_prefix[BUFLEN - 1] = '\000'; 170 | p = strrchr(wt_prefix, '.'); 171 | if (p != NULL) 172 | *p = '\000'; 173 | 174 | ifp = bens_fopen(infile, "r"); 175 | ofp = bens_fopen(outfile, "w"); 176 | aif->header_read(aif, ifp); 177 | riff_item = n = aif->tree->ckID_find(aif->tree, "FORM", "AIFF", -1); 178 | if (n == -1) 179 | riff_item = n = aif->tree->ckID_find(aif->tree, "FORM", "AIFC", -1); 180 | aif->tree->items[n].print = (format == 0) ? ap_ignore : ap_meta; 181 | n = aif->tree->ckID_find(aif->tree, "FVER", NULL, -1); 182 | aif->tree->items[n].print = ap_fver; 183 | n = aif->tree->ckID_find(aif->tree, "COMM", NULL, -1); 184 | aif->tree->items[n].print = ap_comm; 185 | n = aif->tree->ckID_find(aif->tree, "MARK", NULL, -1); 186 | aif->tree->items[n].print = ap_mark; 187 | n = aif->tree->ckID_find(aif->tree, "INST", NULL, -1); 188 | aif->tree->items[n].print = ap_inst; 189 | n = aif->tree->ckID_find(aif->tree, "COMT", NULL, -1); 190 | aif->tree->items[n].print = ap_comt; 191 | n = aif->tree->ckID_find(aif->tree, "NAME", NULL, -1); 192 | aif->tree->items[n].print = ap_iff_text; 193 | n = aif->tree->ckID_find(aif->tree, "AUTH", NULL, -1); 194 | aif->tree->items[n].print = ap_iff_text; 195 | n = aif->tree->ckID_find(aif->tree, "(c) ", NULL, -1); 196 | aif->tree->items[n].print = ap_iff_text; 197 | n = aif->tree->ckID_find(aif->tree, "ANNO", NULL, -1); 198 | aif->tree->items[n].print = ap_iff_text; 199 | n = aif->tree->ckID_find(aif->tree, "SSND", NULL, -1); 200 | aif->tree->items[n].print = (format == 0) ? ap_ssnd : ap_ignore; 201 | aif->tree->print(aif->tree, riff_item, "", wt_prefix, ifp, ofp); 202 | 203 | aif->destroy(aif); 204 | bens_fclose(ifp); 205 | bens_fclose(ofp); 206 | } 207 | 208 | int get_int(txt_t *txt, char *key, int min, int max, int defval) 209 | { 210 | int retval = defval; 211 | char *str; 212 | 213 | str = txt->get_data(txt, key); 214 | if (str == NULL) { 215 | trap_warn("missing %s, defaulting to %d", key, defval); 216 | } else { 217 | retval = atoi(str); 218 | } 219 | if (retval < min || (max > min && retval > max)) 220 | trap_exit("%s %d out of range %d..%d", key, retval, min, max); 221 | return retval; 222 | } 223 | 224 | time_t unix_to_apple_epoch(time_t s) 225 | { 226 | time_t retval = s; 227 | 228 | #define UNIX_YEAR1 1970 229 | #define APPLE_YEAR1 1904 230 | #define DAYS_PER_YEAR 365.25 231 | #define SECONDS_PER_DAY 86400 232 | 233 | retval -= floor((UNIX_YEAR1 - APPLE_YEAR1) * DAYS_PER_YEAR * SECONDS_PER_DAY); 234 | return retval; 235 | } 236 | 237 | void file_read_simple(char *filename, int *count, char **str) 238 | { 239 | FILE *fp; 240 | fp = bens_fopen(*str, "r"); 241 | fseek(fp, 0, SEEK_END); 242 | *count = (int)ftell(fp); 243 | fseek(fp, 0, SEEK_SET); 244 | *str = malloc(*count + 1); 245 | memset(*str, 0, *count + 1); 246 | bens_fread(*str, *count, 1, fp); 247 | fclose(fp); 248 | } 249 | 250 | void loop_check(aif_t *aif, loop_t *loop, char *prefix) 251 | { 252 | int r; 253 | if (loop->playMode == 0) 254 | return; 255 | if (loop->beginLoop == 0 && loop->endLoop == 0) 256 | return; 257 | if (loop->beginLoop == 0 || loop->endLoop == 0) 258 | trap_exit("%s, only one loop point defined", prefix); 259 | r = aif->marker_find(aif, loop->beginLoop); 260 | if (r == -1) 261 | trap_exit("%s.beginLoop invalid", prefix); 262 | r = aif->marker_find(aif, loop->endLoop); 263 | if (r == -1) 264 | trap_exit("%s.endLoop invalid", prefix); 265 | } 266 | 267 | void txt_to_aif(char *infile, char *outfile) 268 | { 269 | FILE *ifp; 270 | FILE *ofp; 271 | FILE *sfp; 272 | txt_t *txt; 273 | aif_t *aif = aif_new(); 274 | char *str; 275 | myDWORD timestamp; 276 | myWORD numChannels; 277 | myDWORD numSampleFrames; 278 | myWORD sampleSize; 279 | myIEEE80 sampleRate; 280 | int n; 281 | long ssnd_size; 282 | myWORD samplePointSize; 283 | char *compressionType; 284 | char *compressionName; 285 | char *endptr; 286 | char buffer[BUFLEN]; 287 | int i; 288 | int r; 289 | int byteswap_do = 0; 290 | 291 | ifp = bens_fopen(infile, "r"); 292 | ofp = bens_fopen(outfile, "w"); 293 | txt = txt_new(); 294 | txt->read_lines(txt, ifp); 295 | 296 | str = txt->get_data(txt, "FORM.FVER.timestamp"); 297 | if (str != NULL) { 298 | timestamp = (myDWORD)(strtoul(str, &endptr, 10)); 299 | } 300 | if (timestamp < AIFC_VERSION1) 301 | trap_warn("unusual fver.timestamp %lu, expected >= %lu", 302 | (unsigned long)timestamp, (unsigned long)AIFC_VERSION1); 303 | 304 | str = txt->get_data(txt, "FORM.COMM.numChannels"); 305 | if (str != NULL) { 306 | numChannels = atoi(str); 307 | } 308 | if (numChannels < 1) 309 | trap_exit("unsupported numChannels"); 310 | 311 | str = txt->get_data(txt, "FORM.COMM.sampleSize"); 312 | if (str != NULL) { 313 | sampleSize = atoi(str); 314 | } 315 | if (sampleSize < 1 || sampleSize % 8 != 0) 316 | trap_exit("unsupported sampleSize"); 317 | samplePointSize = sampleSize / 8; 318 | if (sampleSize % 8) 319 | samplePointSize++; 320 | 321 | str = txt->get_data(txt, "FORM.SSND.file"); 322 | if (str == NULL) 323 | trap_exit("error: missing SSND.file"); 324 | sfp = bens_fopen(str, "r"); 325 | fseek(sfp, 0, SEEK_END); 326 | ssnd_size = ftell(sfp); 327 | fseek(sfp, 0, SEEK_SET); 328 | if (ssnd_size < 1 || ssnd_size % samplePointSize != 0) 329 | trap_exit("unsupported SSND.size"); 330 | numSampleFrames = ssnd_size / samplePointSize; 331 | 332 | str = txt->get_data(txt, "FORM.COMM.sampleRate"); 333 | if (str != NULL) { 334 | n = atoi(str); 335 | double_to_ieee_80((double)n, sampleRate); 336 | } 337 | if (n < 1) 338 | trap_exit("unsupported sampleRate"); 339 | 340 | str = txt->get_data(txt, "FORM.COMM.compressionType.str"); 341 | if (str == NULL) 342 | str = COMPRESSION_TYPE_NONE; 343 | if (strncmp(str, COMPRESSION_TYPE_NONE, sizeof(myFOURCC)) != 0) 344 | trap_exit("unsupported compressionType"); 345 | compressionType = str; 346 | 347 | str = txt->get_data(txt, "FORM.COMM.compressionName.str"); 348 | if (str == NULL) 349 | str = COMPRESSION_NAME_NOT; 350 | if (strcmp(str, COMPRESSION_NAME_NOT) != 0) 351 | trap_warn("unexpected compressionName"); 352 | compressionName = str; 353 | 354 | n = 0; 355 | snprintf(buffer, BUFLEN, "FORM.MARK.%d.id", n + 1); 356 | str = txt->get_data(txt, buffer); 357 | while (str != NULL) { 358 | n++; 359 | snprintf(buffer, BUFLEN, "FORM.MARK.%d.id", n + 1); 360 | str = txt->get_data(txt, buffer); 361 | } 362 | if (n > 0) { 363 | aif->mark.numMarkers = n; 364 | aif->mark.markers = malloc(n * sizeof(mrkr_t *)); 365 | for (i = 0; i < n; i++) { 366 | aif->mark.markers[i] = malloc(sizeof(mrkr_t)); 367 | memset(aif->mark.markers[i], 0, sizeof(mrkr_t)); 368 | snprintf(buffer, BUFLEN, "FORM.MARK.%d.id", i + 1); 369 | str = txt->get_data(txt, buffer); 370 | if (str == NULL) 371 | trap_exit("no id for marker %d", i + 1); 372 | r = aif->mark.markers[i]->id = atoi(str); 373 | if (r < 1) 374 | trap_exit("invalid id (%d) for marker %d", r, i + 1); 375 | r = aif->marker_find(aif, r); 376 | if (r != i) 377 | trap_warn("duplicate marker id %d (%d,%d)", 378 | aif->mark.markers[i]->id, r + 1, i + 1); 379 | 380 | snprintf(buffer, BUFLEN, "FORM.MARK.%d.pos", i + 1); 381 | aif->mark.markers[i]->position = get_int(txt, buffer, 0, 382 | numSampleFrames, 0); 383 | 384 | snprintf(buffer, BUFLEN, "FORM.MARK.%d.name", i + 1); 385 | str = txt->get_data(txt, buffer); 386 | if (str == NULL) { 387 | trap_warn("no name for marker %d", i + 1); 388 | } else { 389 | strncpy(aif->mark.markers[i]->markerName.str, str, 390 | PSTRING_STR_MAXLEN); 391 | aif->mark.markers[i]->markerName.count = 392 | strlen(aif->mark.markers[i]->markerName.str); 393 | } 394 | } 395 | } 396 | 397 | aif->inst.baseNote = get_int(txt, "FORM.INST.baseNote", 0, 127, 60); 398 | aif->inst.detune = get_int(txt, "FORM.INST.detune", -50, 50, 0); 399 | aif->inst.lowNote = get_int(txt, "FORM.INST.lowNote", 0, 127, 0); 400 | aif->inst.highNote = get_int(txt, "FORM.INST.highNote", 401 | aif->inst.lowNote, 127, 127); 402 | aif->inst.lowVelocity = get_int(txt, "FORM.INST.lowVelocity", 1, 127, 1); 403 | aif->inst.highVelocity = get_int(txt, "FORM.INST.highVelocity", 404 | aif->inst.lowVelocity, 127, 127); 405 | aif->inst.gain = get_int(txt, "FORM.INST.gain", -32768, 32767, 0); 406 | aif->inst.sustainLoop.playMode = get_int(txt, 407 | "FORM.INST.sustainLoop.playMode", 0, AIF_LOOP_MAX, 0); 408 | aif->inst.sustainLoop.beginLoop = get_int(txt, 409 | "FORM.INST.sustainLoop.beginLoop", 0, -1, 0); 410 | aif->inst.sustainLoop.endLoop = get_int(txt, 411 | "FORM.INST.sustainLoop.endLoop", 0, -1, 0); 412 | aif->inst.releaseLoop.playMode = get_int(txt, 413 | "FORM.INST.releaseLoop.playMode", 0, AIF_LOOP_MAX, 0); 414 | aif->inst.releaseLoop.beginLoop = get_int(txt, 415 | "FORM.INST.releaseLoop.beginLoop", 0, -1, 0); 416 | aif->inst.releaseLoop.endLoop = get_int(txt, 417 | "FORM.INST.releaseLoop.endLoop", 0, -1, 0); 418 | loop_check(aif, &(aif->inst.sustainLoop), "sustainLoop"); 419 | loop_check(aif, &(aif->inst.releaseLoop), "releaseLoop"); 420 | 421 | n = 0; 422 | snprintf(buffer, BUFLEN, "FORM.COMT.%d.file", n + 1); 423 | str = txt->get_data(txt, buffer); 424 | while (str != NULL) { 425 | n++; 426 | snprintf(buffer, BUFLEN, "FORM.COMT.%d.file", n + 1); 427 | str = txt->get_data(txt, buffer); 428 | } 429 | if (n > 0) { 430 | aif->comt.numComments = n; 431 | aif->comt.comments = malloc(n * sizeof(cmnt_t *)); 432 | for (i = 0; i < n; i++) { 433 | aif->comt.comments[i] = malloc(sizeof(cmnt_t)); 434 | memset(aif->comt.comments[i], 0, sizeof(cmnt_t)); 435 | snprintf(buffer, BUFLEN, "FORM.COMT.%d.timeStamp", i + 1); 436 | aif->comt.comments[i]->timeStamp = get_int(txt, buffer, 0, -1, 437 | unix_to_apple_epoch(time(NULL))); 438 | snprintf(buffer, BUFLEN, "FORM.COMT.%d.marker", i + 1); 439 | aif->comt.comments[i]->marker = get_int(txt, buffer, 0, 440 | aif->mark.numMarkers, 0); 441 | snprintf(buffer, BUFLEN, "FORM.COMT.%d.file", i + 1); 442 | str = txt->get_data(txt, buffer); 443 | if (str == NULL) 444 | trap_exit("no file for comment %d", i + 1); 445 | file_read_simple(str, &r, &(aif->comt.comments[i]->text)); 446 | aif->comt.comments[i]->count = r; 447 | } 448 | } 449 | str = txt->get_data(txt, "FORM.NAME.file"); 450 | if (str != NULL) { 451 | file_read_simple(str, &r, &(aif->name)); 452 | } 453 | str = txt->get_data(txt, "FORM.AUTH.file"); 454 | if (str != NULL) { 455 | file_read_simple(str, &r, &(aif->auth)); 456 | } 457 | str = txt->get_data(txt, "FORM.(c).file"); 458 | if (str != NULL) { 459 | file_read_simple(str, &r, &(aif->copy)); 460 | } 461 | str = txt->get_data(txt, "FORM.ANNO.file"); 462 | if (str != NULL) { 463 | file_read_simple(str, &r, &(aif->anno)); 464 | } 465 | 466 | str = txt->get_data(txt, "FORM.SSND.byteswap"); 467 | if (str != NULL) 468 | byteswap_do = atoi(str); 469 | 470 | aif->header_set(aif, numChannels, numSampleFrames, sampleSize, 471 | sampleRate, timestamp, compressionType, compressionName); 472 | aif->header_write(aif, ofp); 473 | fseek(ofp, aif->ssnd.fpos_WaveformData, SEEK_SET); 474 | aif->destroy(aif); 475 | 476 | data_copy(sfp, ofp, aif->ssnd.bytes_WaveformData, byteswap_do); 477 | bens_fclose(sfp); 478 | 479 | bens_fclose(ifp); 480 | bens_fclose(ofp); 481 | txt->warn_unused(txt); 482 | txt->destroy(txt); 483 | } 484 | -------------------------------------------------------------------------------- /sfubar-9/libriffraff-7/aif.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include "bits.h" 7 | #include "riff.h" 8 | #include "rifftypes.h" 9 | #include "aif.h" 10 | #include "ieee80.h" 11 | 12 | tree_item aif_items[] = { 13 | { 0, "FORM", "AIFF", NULL, NULL }, 14 | { 0, "FORM", "AIFC", NULL, NULL }, 15 | { 1, "FVER", NULL, NULL, NULL }, 16 | { 1, "COMM", NULL, NULL, NULL }, 17 | { 1, "MARK", NULL, NULL, NULL }, 18 | { 1, "INST", NULL, NULL, NULL }, 19 | { 1, "COMT", NULL, NULL, NULL }, 20 | { 1, "NAME", NULL, NULL, NULL }, 21 | { 1, "AUTH", NULL, NULL, NULL }, 22 | { 1, "(c) ", NULL, NULL, NULL }, 23 | { 1, "ANNO", NULL, NULL, NULL }, 24 | { 1, "SSND", NULL, NULL, NULL }, 25 | { -1, "", NULL, NULL, NULL } 26 | }; 27 | 28 | tree_container aif_containers[] = { "FORM", "" }; 29 | 30 | int aif_marker_find(void *vaif, myWORD marker_id) 31 | { 32 | aif_t *aif = vaif; 33 | int i; 34 | int retval = -1; 35 | for (i = 0; i < aif->mark.numMarkers; i++) { 36 | if (aif->mark.markers[i] == NULL) 37 | continue; 38 | if (aif->mark.markers[i]->id != marker_id) 39 | continue; 40 | retval = i; 41 | break; 42 | } 43 | return retval; 44 | } 45 | 46 | char *aif_marker_allocate_and_read(void *vaif, int i, char *p) 47 | { 48 | aif_t *aif = vaif; 49 | mrkr_t *marker = malloc(sizeof(mrkr_t)); 50 | myWORD tw; 51 | myDWORD tdw; 52 | int r; 53 | 54 | p = my_get_WORD_BE(&tw, p); 55 | if (tw < 1) 56 | trap_exit("marker at position %d has invalid id", i + 1); 57 | r = aif_marker_find(aif, tw); 58 | if (r != -1) 59 | trap_warn("duplicate marker id %d (%d, %d)", tw, r + 1, i + 1); 60 | marker->id = tw; 61 | 62 | p = my_get_DWORD_BE(&tdw, p); 63 | if (tdw < 0) { 64 | trap_warn("marker %d too small, adjusting", marker->id); 65 | tdw = 0; 66 | } 67 | if (tdw > aif->comm.numSampleFrames) { 68 | trap_warn("marker %d too large, adjusting", marker->id); 69 | tdw = aif->comm.numSampleFrames; 70 | } 71 | marker->position = tdw; 72 | 73 | p = my_get_PSTRING(&(marker->markerName), p); 74 | 75 | aif->mark.markers[i] = marker; 76 | return p; 77 | } 78 | 79 | char *aif_loop_read(void *vaif, loop_t *loop, const char *prefix, char *p) 80 | { 81 | aif_t *aif = vaif; 82 | int r; 83 | 84 | p = my_get_WORD_BE(&(loop->playMode), p); 85 | if (loop->playMode > AIF_LOOP_MAX) { 86 | trap_warn("%s.playMode invalid (%d), adjusting", prefix, loop->playMode); 87 | aif->inst.sustainLoop.playMode = AIF_LOOP_NONE; 88 | } 89 | p = my_get_WORD_BE(&(loop->beginLoop), p); 90 | if (loop->beginLoop != 0) { 91 | r = aif_marker_find(vaif, loop->beginLoop); 92 | if (r == -1) { 93 | trap_warn("%s.beginLoop invalid marker id (%d), adjusting", prefix, 94 | loop->beginLoop); 95 | loop->beginLoop = 0; 96 | } 97 | } 98 | p = my_get_WORD_BE(&(loop->endLoop), p); 99 | r = aif_marker_find(vaif, loop->endLoop); 100 | if (loop->endLoop != 0) { 101 | if (r == -1) { 102 | trap_warn("%s.endLoop invalid marker id (%d), adjusting", prefix, 103 | loop->endLoop); 104 | loop->endLoop = 0; 105 | } 106 | } 107 | return p; 108 | } 109 | 110 | char *aif_comment_allocate_and_read(void *vaif, int i, char *p) 111 | { 112 | aif_t *aif = vaif; 113 | cmnt_t *comment = malloc(sizeof(cmnt_t)); 114 | char pad; 115 | int r; 116 | 117 | p = my_get_DWORD_BE(&(comment->timeStamp), p); 118 | p = my_get_WORD_BE(&(comment->marker), p); 119 | if (comment->marker != 0) { 120 | r = aif_marker_find(aif, comment->marker); 121 | if (r == -1) 122 | trap_warn("comment %d marker id invalid, ignoring", i + 1); 123 | } 124 | p = my_get_WORD_BE(&(comment->count), p); 125 | comment->text = malloc(comment->count); 126 | p = my_get_CHAR(comment->text, p, comment->count); 127 | if (!is_even(comment->count)) 128 | p = my_get_CHAR(&pad, p, 1); 129 | 130 | aif->comt.comments[i] = comment; 131 | return p; 132 | } 133 | 134 | int aif_header_read(void *vaif, FILE *ifp) 135 | { 136 | void *p; 137 | aif_t *aif = vaif; 138 | char buffer[sizeof(aif->ssnd)]; 139 | int is_aiff = 0; 140 | int is_aifc = 0; 141 | chunk_t *chunk_src; 142 | chunk_t *chunk_tmp; 143 | int n; 144 | int i; 145 | 146 | chunk_src = chunk_new(NULL, ON_DISK); 147 | chunk_src->endian = MY_BIG_ENDIAN; 148 | chunk_src->header_read(chunk_src, ifp); 149 | aif->tree->read(aif->tree, chunk_src, 0, ifp); 150 | /* chunk_src is freed when aif->tree is destroyed */ 151 | 152 | n = aif->tree->ckID_find(aif->tree, "FORM", "AIFF", 0); 153 | if (n > -1) { 154 | is_aiff = 1; 155 | } else { 156 | n = aif->tree->ckID_find(aif->tree, "FORM", "AIFC", 0); 157 | if (n > -1) { 158 | is_aifc = 1; 159 | } 160 | } 161 | 162 | if (n == -1) { 163 | trap_warn("header_read: no FORM chunk with AIFF/C form"); 164 | return 0; 165 | } 166 | 167 | if (is_aifc) { 168 | n = aif->tree->ckID_find(aif->tree, "FVER", NULL, 1); 169 | if (n == -1) { 170 | trap_warn("header_read: no FVER chunk"); 171 | return 0; 172 | } 173 | chunk_tmp = aif->tree->items[n].chunk; 174 | chunk_tmp->data_read(chunk_tmp, ifp); 175 | p = chunk_tmp->data; 176 | p = my_get_DWORD_BE(&(aif->fver.timestamp), p); 177 | } 178 | if (aif->fver.timestamp < AIFC_VERSION1) 179 | trap_warn("header_read: unusual fver.timestamp %lu, expected %lu", 180 | (unsigned long)aif->fver.timestamp, (unsigned long)AIFC_VERSION1); 181 | 182 | n = aif->tree->ckID_find(aif->tree, "COMM", NULL, 1); 183 | if (n == -1) { 184 | trap_warn("header_read: no COMM chunk"); 185 | return 0; 186 | } 187 | chunk_tmp = aif->tree->items[n].chunk; 188 | chunk_tmp->data_read(chunk_tmp, ifp); 189 | p = chunk_tmp->data; 190 | p = my_get_WORD_BE(&(aif->comm.numChannels), p); 191 | p = my_get_DWORD_BE(&(aif->comm.numSampleFrames), p); 192 | p = my_get_WORD_BE(&(aif->comm.sampleSize), p); 193 | p = my_get_IEEE80(&(aif->comm.sampleRate), p); 194 | if (is_aifc) { 195 | p = my_get_CHAR(aif->comm.compressionType.str, p, sizeof(myFOURCC)); 196 | p = my_get_PSTRING(&(aif->comm.compressionName), p); 197 | } 198 | 199 | n = aif->tree->ckID_find(aif->tree, "MARK", NULL, 1); 200 | if (n != -1) { 201 | chunk_tmp = aif->tree->items[n].chunk; 202 | chunk_tmp->data_read(chunk_tmp, ifp); 203 | p = chunk_tmp->data; 204 | p = my_get_WORD_BE(&(aif->mark.numMarkers), p); 205 | aif->mark.markers = malloc(aif->mark.numMarkers * sizeof(mrkr_t *)); 206 | for (i = 0; i < aif->mark.numMarkers; i++) 207 | aif->mark.markers[i] = NULL; 208 | for (i = 0; i < aif->mark.numMarkers; i++) 209 | p = aif_marker_allocate_and_read(aif, i, p); 210 | } 211 | 212 | n = aif->tree->ckID_find(aif->tree, "INST", NULL, 1); 213 | if (n != -1) { 214 | chunk_tmp = aif->tree->items[n].chunk; 215 | chunk_tmp->data_read(chunk_tmp, ifp); 216 | p = chunk_tmp->data; 217 | p = my_get_CHAR(&(aif->inst.baseNote), p, 1); 218 | p = my_get_CHAR(&(aif->inst.detune), p, 1); 219 | p = my_get_CHAR(&(aif->inst.lowNote), p, 1); 220 | p = my_get_CHAR(&(aif->inst.highNote), p, 1); 221 | p = my_get_CHAR(&(aif->inst.lowVelocity), p, 1); 222 | p = my_get_CHAR(&(aif->inst.highVelocity), p, 1); 223 | p = my_get_SHORT_BE(&(aif->inst.gain), p); 224 | p = aif_loop_read(aif, &(aif->inst.sustainLoop), "inst.sustainLoop", p); 225 | p = aif_loop_read(aif, &(aif->inst.releaseLoop), "inst.releaseLoop", p); 226 | } 227 | 228 | n = aif->tree->ckID_find(aif->tree, "COMT", NULL, 1); 229 | if (n != -1) { 230 | chunk_tmp = aif->tree->items[n].chunk; 231 | chunk_tmp->data_read(chunk_tmp, ifp); 232 | p = chunk_tmp->data; 233 | p = my_get_WORD_BE(&(aif->comt.numComments), p); 234 | aif->comt.comments = malloc(aif->comt.numComments * sizeof(cmnt_t *)); 235 | for (i = 0; i < aif->comt.numComments; i++) 236 | p = aif_comment_allocate_and_read(aif, i, p); 237 | } 238 | 239 | n = aif->tree->ckID_find(aif->tree, "NAME", NULL, 1); 240 | if (n != -1) { 241 | chunk_tmp = aif->tree->items[n].chunk; 242 | chunk_tmp->data_read(chunk_tmp, ifp); 243 | i = chunk_tmp->ckSize + 1; 244 | aif->name = malloc(i); 245 | memset(aif->name, 0, i); 246 | memcpy(aif->name, chunk_tmp->data, chunk_tmp->ckSize); 247 | } 248 | 249 | n = aif->tree->ckID_find(aif->tree, "AUTH", NULL, 1); 250 | if (n != -1) { 251 | chunk_tmp = aif->tree->items[n].chunk; 252 | chunk_tmp->data_read(chunk_tmp, ifp); 253 | i = chunk_tmp->ckSize + 1; 254 | aif->auth = malloc(i); 255 | memset(aif->auth, 0, i); 256 | memcpy(aif->auth, chunk_tmp->data, chunk_tmp->ckSize); 257 | } 258 | 259 | n = aif->tree->ckID_find(aif->tree, "(c) ", NULL, 1); 260 | if (n != -1) { 261 | chunk_tmp = aif->tree->items[n].chunk; 262 | chunk_tmp->data_read(chunk_tmp, ifp); 263 | i = chunk_tmp->ckSize + 1; 264 | aif->copy = malloc(i); 265 | memset(aif->copy, 0, i); 266 | memcpy(aif->copy, chunk_tmp->data, chunk_tmp->ckSize); 267 | } 268 | 269 | n = aif->tree->ckID_find(aif->tree, "ANNO", NULL, 1); 270 | if (n != -1) { 271 | chunk_tmp = aif->tree->items[n].chunk; 272 | chunk_tmp->data_read(chunk_tmp, ifp); 273 | i = chunk_tmp->ckSize + 1; 274 | aif->anno = malloc(i); 275 | memset(aif->anno, 0, i); 276 | memcpy(aif->anno, chunk_tmp->data, chunk_tmp->ckSize); 277 | } 278 | 279 | n = aif->tree->ckID_find(aif->tree, "SSND", NULL, 1); 280 | if (n == -1) { 281 | trap_warn("header_read: no SSND chunk"); 282 | return 0; 283 | } 284 | chunk_tmp = aif->tree->items[n].chunk; 285 | chunk_tmp->data_read_bytes(chunk_tmp, ifp, buffer, 2 * sizeof(myDWORD)); 286 | aif->ssnd.fpos_WaveformData = ftell(ifp); 287 | p = buffer; 288 | p = my_get_DWORD_BE(&(aif->ssnd.offset), p); 289 | p = my_get_DWORD_BE(&(aif->ssnd.blockSize), p); 290 | 291 | aif->sample_calc(aif); 292 | return 1; 293 | } 294 | 295 | void aif_header_write(void *vaif, FILE *ofp) 296 | { 297 | aif_t *aif = vaif; 298 | void *p; 299 | chunk_t *chunk_tmp; 300 | chunk_t *chunk_dst; 301 | int i; 302 | int r; 303 | 304 | chunk_dst = chunk_new(NULL, IN_RAM); 305 | chunk_dst->endian = MY_BIG_ENDIAN; 306 | strncpy(chunk_dst->ckID.str, "FORM", 4); 307 | chunk_dst->header_write(chunk_dst, ofp); 308 | chunk_dst->data_write(chunk_dst, "AIFC", 4, ofp); 309 | 310 | chunk_tmp = chunk_new(NULL, IN_RAM); 311 | chunk_tmp->endian = MY_BIG_ENDIAN; 312 | strncpy(chunk_tmp->ckID.str, "FVER", 4); 313 | chunk_tmp->ckSize = sizeof(myDWORD); 314 | chunk_tmp->data = realloc(chunk_tmp->data, chunk_tmp->ckSize); 315 | p = chunk_tmp->data; 316 | p = my_put_DWORD_BE(&(aif->fver.timestamp), p); 317 | chunk_dst->ckSize += chunk_tmp->write(chunk_tmp, ofp); 318 | chunk_tmp->destroy(chunk_tmp); 319 | 320 | chunk_tmp = chunk_new(NULL, IN_RAM); 321 | chunk_tmp->endian = MY_BIG_ENDIAN; 322 | strncpy(chunk_tmp->ckID.str, "COMM", 4); 323 | chunk_tmp->ckSize = sizeof(myWORD) * 2 + sizeof(myDWORD) + 324 | sizeof(myIEEE80) + sizeof(myFOURCC) + 325 | my_size_PSTRING(&(aif->comm.compressionName)); 326 | chunk_tmp->data = realloc(chunk_tmp->data, chunk_tmp->ckSize); 327 | p = chunk_tmp->data; 328 | p = my_put_WORD_BE(&(aif->comm.numChannels), p); 329 | p = my_put_DWORD_BE(&(aif->comm.numSampleFrames), p); 330 | p = my_put_WORD_BE(&(aif->comm.sampleSize), p); 331 | p = my_put_IEEE80(&(aif->comm.sampleRate), p); 332 | p = my_put_CHAR(aif->comm.compressionType.str, p, sizeof(myFOURCC)); 333 | p = my_put_PSTRING(&(aif->comm.compressionName), p); 334 | chunk_dst->ckSize += chunk_tmp->write(chunk_tmp, ofp); 335 | chunk_tmp->destroy(chunk_tmp); 336 | 337 | if (aif->mark.numMarkers > 0) { 338 | chunk_tmp = chunk_new(NULL, IN_RAM); 339 | chunk_tmp->endian = MY_BIG_ENDIAN; 340 | strncpy(chunk_tmp->ckID.str, "MARK", 4); 341 | chunk_tmp->ckSize = sizeof(myWORD); 342 | for (i = 0; i < aif->mark.numMarkers; i++) 343 | chunk_tmp->ckSize += sizeof(myWORD) + sizeof(myDWORD) + 344 | my_size_PSTRING(&(aif->mark.markers[i]->markerName)); 345 | p = chunk_tmp->data = malloc(chunk_tmp->ckSize); 346 | p = my_put_WORD_BE(&(aif->mark.numMarkers), p); 347 | for (i = 0; i < aif->mark.numMarkers; i++) { 348 | p = my_put_WORD_BE(&(aif->mark.markers[i]->id), p); 349 | p = my_put_DWORD_BE(&(aif->mark.markers[i]->position), p); 350 | p = my_put_PSTRING(&(aif->mark.markers[i]->markerName), p); 351 | } 352 | chunk_dst->ckSize += chunk_tmp->write(chunk_tmp, ofp); 353 | chunk_tmp->destroy(chunk_tmp); 354 | } 355 | 356 | if (aif->inst.baseNote > -1) { 357 | chunk_tmp = chunk_new(NULL, IN_RAM); 358 | chunk_tmp->endian = MY_BIG_ENDIAN; 359 | strncpy(chunk_tmp->ckID.str, "INST", 4); 360 | chunk_tmp->ckSize = 6 * sizeof(myCHAR) + 6 * sizeof(myWORD) + 361 | sizeof(mySHORT); 362 | p = chunk_tmp->data = malloc(chunk_tmp->ckSize); 363 | p = my_put_CHAR(&(aif->inst.baseNote), p, 1); 364 | p = my_put_CHAR(&(aif->inst.detune), p, 1); 365 | p = my_put_CHAR(&(aif->inst.lowNote), p, 1); 366 | p = my_put_CHAR(&(aif->inst.highNote), p, 1); 367 | p = my_put_CHAR(&(aif->inst.lowVelocity), p, 1); 368 | p = my_put_CHAR(&(aif->inst.highVelocity), p, 1); 369 | p = my_put_SHORT_BE(&(aif->inst.gain), p); 370 | p = my_put_WORD_BE(&(aif->inst.sustainLoop.playMode), p); 371 | p = my_put_WORD_BE(&(aif->inst.sustainLoop.beginLoop), p); 372 | p = my_put_WORD_BE(&(aif->inst.sustainLoop.endLoop), p); 373 | p = my_put_WORD_BE(&(aif->inst.releaseLoop.playMode), p); 374 | p = my_put_WORD_BE(&(aif->inst.releaseLoop.beginLoop), p); 375 | p = my_put_WORD_BE(&(aif->inst.releaseLoop.endLoop), p); 376 | chunk_dst->ckSize += chunk_tmp->write(chunk_tmp, ofp); 377 | chunk_tmp->destroy(chunk_tmp); 378 | } 379 | 380 | if (aif->comt.numComments > 0) { 381 | chunk_tmp = chunk_new(NULL, IN_RAM); 382 | chunk_tmp->endian = MY_BIG_ENDIAN; 383 | strncpy(chunk_tmp->ckID.str, "COMT", 4); 384 | chunk_tmp->ckSize = sizeof(myWORD); 385 | for (i = 0; i < aif->comt.numComments; i++) { 386 | r = aif->comt.comments[i]->count; 387 | chunk_tmp->ckSize += sizeof(myDWORD) + 2 * sizeof(myWORD) + r; 388 | if (!is_even(r)) 389 | chunk_tmp->ckSize++; 390 | } 391 | p = chunk_tmp->data = malloc(chunk_tmp->ckSize); 392 | p = my_put_WORD_BE(&(aif->comt.numComments), p); 393 | for (i = 0; i < aif->comt.numComments; i++) { 394 | p = my_put_DWORD_BE(&(aif->comt.comments[i]->timeStamp), p); 395 | p = my_put_WORD_BE(&(aif->comt.comments[i]->marker), p); 396 | p = my_put_WORD_BE(&(aif->comt.comments[i]->count), p); 397 | p = my_put_CHAR(aif->comt.comments[i]->text, p, r); 398 | if (!is_even(r)) 399 | p = my_put_CHAR("\000", p, 1); 400 | } 401 | chunk_dst->ckSize += chunk_tmp->write(chunk_tmp, ofp); 402 | chunk_tmp->destroy(chunk_tmp); 403 | } 404 | 405 | if (aif->name != NULL) { 406 | chunk_tmp = chunk_new(NULL, IN_RAM); 407 | chunk_tmp->endian = MY_BIG_ENDIAN; 408 | strncpy(chunk_tmp->ckID.str, "NAME", 4); 409 | r = strlen(aif->name); 410 | chunk_tmp->ckSize = r; 411 | if (!is_even(r)) 412 | chunk_tmp->ckSize++; 413 | p = chunk_tmp->data = malloc(chunk_tmp->ckSize); 414 | p = my_put_CHAR(aif->name, p, r); 415 | if (!is_even(r)) 416 | p = my_put_CHAR("\000", p, 1); 417 | chunk_dst->ckSize += chunk_tmp->write(chunk_tmp, ofp); 418 | chunk_tmp->destroy(chunk_tmp); 419 | } 420 | 421 | if (aif->auth != NULL) { 422 | chunk_tmp = chunk_new(NULL, IN_RAM); 423 | chunk_tmp->endian = MY_BIG_ENDIAN; 424 | strncpy(chunk_tmp->ckID.str, "AUTH", 4); 425 | r = strlen(aif->auth); 426 | chunk_tmp->ckSize = r; 427 | if (!is_even(r)) 428 | chunk_tmp->ckSize++; 429 | p = chunk_tmp->data = malloc(chunk_tmp->ckSize); 430 | p = my_put_CHAR(aif->auth, p, r); 431 | if (!is_even(r)) 432 | p = my_put_CHAR("\000", p, 1); 433 | chunk_dst->ckSize += chunk_tmp->write(chunk_tmp, ofp); 434 | chunk_tmp->destroy(chunk_tmp); 435 | } 436 | 437 | if (aif->copy != NULL) { 438 | chunk_tmp = chunk_new(NULL, IN_RAM); 439 | chunk_tmp->endian = MY_BIG_ENDIAN; 440 | strncpy(chunk_tmp->ckID.str, "(c) ", 4); 441 | r = strlen(aif->copy); 442 | chunk_tmp->ckSize = r; 443 | if (!is_even(r)) 444 | chunk_tmp->ckSize++; 445 | p = chunk_tmp->data = malloc(chunk_tmp->ckSize); 446 | p = my_put_CHAR(aif->copy, p, r); 447 | if (!is_even(r)) 448 | p = my_put_CHAR("\000", p, 1); 449 | chunk_dst->ckSize += chunk_tmp->write(chunk_tmp, ofp); 450 | chunk_tmp->destroy(chunk_tmp); 451 | } 452 | 453 | if (aif->anno != NULL) { 454 | chunk_tmp = chunk_new(NULL, IN_RAM); 455 | chunk_tmp->endian = MY_BIG_ENDIAN; 456 | strncpy(chunk_tmp->ckID.str, "ANNO", 4); 457 | r = strlen(aif->anno); 458 | chunk_tmp->ckSize = r; 459 | if (!is_even(r)) 460 | chunk_tmp->ckSize++; 461 | p = chunk_tmp->data = malloc(chunk_tmp->ckSize); 462 | p = my_put_CHAR(aif->anno, p, r); 463 | if (!is_even(r)) 464 | p = my_put_CHAR("\000", p, 1); 465 | chunk_dst->ckSize += chunk_tmp->write(chunk_tmp, ofp); 466 | chunk_tmp->destroy(chunk_tmp); 467 | } 468 | 469 | chunk_tmp = chunk_new(NULL, IN_RAM); 470 | chunk_tmp->endian = MY_BIG_ENDIAN; 471 | strncpy(chunk_tmp->ckID.str, "SSND", 4); 472 | chunk_tmp->header_write(chunk_tmp, ofp); 473 | chunk_tmp->data = realloc(chunk_tmp->data, sizeof(myDWORD) * 2); 474 | p = chunk_tmp->data; 475 | p = my_put_DWORD_BE(&(aif->ssnd.offset), p); 476 | p = my_put_DWORD_BE(&(aif->ssnd.blockSize), p); 477 | chunk_tmp->data_write(chunk_tmp, chunk_tmp->data, sizeof(myDWORD) * 2, ofp); 478 | aif->ssnd.fpos_WaveformData = ftell(ofp); 479 | chunk_tmp->ckSize += aif->ssnd.bytes_WaveformData; 480 | chunk_tmp->start_seek(chunk_tmp, ofp); 481 | chunk_tmp->header_write(chunk_tmp, ofp); 482 | chunk_dst->ckSize += CHUNK_HEADER_SIZE + chunk_tmp->ckSize; 483 | 484 | chunk_dst->start_seek(chunk_dst, ofp); 485 | chunk_dst->header_write(chunk_dst, ofp); 486 | chunk_tmp->destroy(chunk_tmp); 487 | chunk_dst->destroy(chunk_dst); 488 | } 489 | 490 | void aif_sample_calc(void *vaif) 491 | { 492 | aif_t *aif = vaif; 493 | 494 | aif->comm.double_sampleRate = ieee_80_to_double(aif->comm.sampleRate); 495 | if (aif->comm.double_sampleRate != ceil(aif->comm.double_sampleRate)) { 496 | trap_warn("aif: rounding fractional sample rate"); 497 | aif->comm.double_sampleRate = ceil(aif->comm.double_sampleRate); 498 | double_to_ieee_80(aif->comm.double_sampleRate, aif->comm.sampleRate); 499 | } 500 | aif->comm.samplePointSize = aif->comm.sampleSize / BITS_PER_BYTE; 501 | if (aif->comm.sampleSize % BITS_PER_BYTE) 502 | aif->comm.samplePointSize++; 503 | aif->ssnd.bytes_WaveformData = aif->comm.numChannels * 504 | aif->comm.numSampleFrames * aif->comm.samplePointSize; 505 | } 506 | 507 | void aif_header_set(void *vaif, myWORD numChannels, 508 | myDWORD numSampleFrames, myWORD sampleSize, myIEEE80 sampleRate, 509 | myDWORD timestamp, char *compressionType, char *compressionName) 510 | { 511 | aif_t *aif = vaif; 512 | aif->fver.timestamp = timestamp; 513 | aif->comm.numChannels = numChannels; 514 | aif->comm.numSampleFrames = numSampleFrames; 515 | aif->comm.sampleSize = sampleSize; 516 | memcpy(aif->comm.sampleRate, sampleRate, sizeof(sampleRate)); 517 | memcpy(aif->comm.compressionType.str, compressionType, sizeof(myFOURCC)); 518 | memset(aif->comm.compressionName.str, 0, 519 | sizeof(aif->comm.compressionName.str)); 520 | snprintf(aif->comm.compressionName.str, 521 | sizeof(aif->comm.compressionName.str), "%s", compressionName); 522 | aif->comm.compressionName.count = strlen(aif->comm.compressionName.str); 523 | aif->ssnd.offset = 0; 524 | aif->ssnd.blockSize = 0; 525 | aif->ssnd.fpos_WaveformData = 0; 526 | aif->sample_calc(aif); 527 | } 528 | 529 | void aif_destroy(void *vaif) 530 | { 531 | aif_t *aif = vaif; 532 | int i; 533 | aif->tree->destroy(aif->tree); 534 | if (aif->mark.markers != NULL) { 535 | for (i = 0; i < aif->mark.numMarkers; i++) { 536 | if (aif->mark.markers[i] != NULL) 537 | free(aif->mark.markers[i]); 538 | } 539 | free(aif->mark.markers); 540 | } 541 | if (aif->comt.comments != NULL) { 542 | for (i = 0; i < aif->comt.numComments; i++) { 543 | if (aif->comt.comments[i] != NULL) { 544 | if (aif->comt.comments[i]->text != NULL) 545 | free(aif->comt.comments[i]->text); 546 | free(aif->comt.comments[i]); 547 | } 548 | } 549 | free(aif->comt.comments); 550 | } 551 | if (aif->name != NULL) 552 | free(aif->name); 553 | if (aif->auth != NULL) 554 | free(aif->auth); 555 | if (aif->copy != NULL) 556 | free(aif->copy); 557 | if (aif->anno != NULL) 558 | free(aif->anno); 559 | free(aif); 560 | } 561 | 562 | aif_t *aif_new(void) 563 | { 564 | aif_t *retval; 565 | retval = malloc(sizeof(aif_t)); 566 | 567 | retval->name = NULL; 568 | retval->auth = NULL; 569 | retval->copy = NULL; 570 | retval->anno = NULL; 571 | retval->tree = tree_new(aif_items, aif_containers, retval); 572 | retval->destroy = aif_destroy; 573 | retval->header_read = aif_header_read; 574 | retval->header_write = aif_header_write; 575 | retval->header_set = aif_header_set; 576 | retval->sample_calc = aif_sample_calc; 577 | retval->marker_find = aif_marker_find; 578 | aif_header_set(retval, 0, 0, 0, (unsigned char *)ieee80_44100, 579 | AIFC_VERSION1, COMPRESSION_TYPE_NONE, COMPRESSION_NAME_NOT); 580 | retval->mark.numMarkers = 0; 581 | retval->mark.markers = NULL; 582 | retval->inst.baseNote = -1; 583 | retval->comt.numComments = 0; 584 | retval->comt.comments = NULL; 585 | return retval; 586 | } 587 | --------------------------------------------------------------------------------