1
/*******************************************/
4
by Gary P. Scavone, 2000
6
This object inherits from WvOut and is
7
used to write Audio Interchange File
8
Format files with 16-bit data (signed
11
.aif files are always bif-endian.
13
/*******************************************/
16
#ifdef __LITTLE_ENDIAN__
20
/******** Aiff Soundfile Header Struct *******/
22
char form[4]; // "FORM"
23
INT32 form_size; // in bytes
24
char aiff[4]; // "AIFF"
25
char comm[4]; // "COMM"
26
INT32 comm_size; // "COMM" chunk size (should be 18)
27
INT16 num_chans; // number of channels
28
unsigned long sample_frames; // sample frames of audio data
29
INT16 sample_size; // always 16 for STK
30
unsigned char srate[10]; // IEEE 754 floating point format
31
char ssnd[4]; // "SSND"
32
INT32 ssnd_size; // "SSND" chunk size
33
unsigned long offset; // data offset in data block (should be 0)
34
unsigned long block_size; // not used by STK (should be 0)
37
FILE *openAifFile(int chans, char *fileName) {
38
struct aiffhdr hdr = {"FOR",46,"AIF","COM",18,0,0,16,"0","SSN",8,0,0};
44
unsigned long rate = (unsigned long) SRATE;
51
hdr.num_chans = chans;
54
* For AIFF files, the sample reate is stored in a 10-byte, IEEE Standard
55
* 754 floating point number, so we need to convert to that.
57
memset(hdr.srate, 0, 10);
59
for (i=0; i<32; i++) {
64
#ifdef __LITTLE_ENDIAN__
65
swap16((unsigned char *)&i);
67
*(INT16 *)(hdr.srate) = (INT16) i;
70
if (rate & 0x80000000) break;
74
#ifdef __LITTLE_ENDIAN__
75
swap32((unsigned char *)&rate);
77
*(unsigned long *)(hdr.srate+2) = (unsigned long) rate;
79
strcpy(tempName,fileName);
80
if (strstr(tempName,".aif") == NULL) strcat(tempName,".aif");
81
fd = fopen(tempName,"wb");
83
sprintf(msg, "AifWvOut: Could not create soundfile: %s\n", tempName);
84
throw StkError(msg, StkError::FILE_ERROR);
87
#ifdef __LITTLE_ENDIAN__
88
swap32((unsigned char *)&hdr.form_size);
89
swap32((unsigned char *)&hdr.comm_size);
90
swap16((unsigned char *)&hdr.num_chans);
91
swap16((unsigned char *)&hdr.sample_size);
92
swap32((unsigned char *)&hdr.ssnd_size);
93
swap32((unsigned char *)&hdr.offset);
94
swap32((unsigned char *)&hdr.block_size);
97
printf("\nCreating soundfile: %s\n", tempName);
99
/* I found it necessary to break the fwrite() calls as
100
* follows ... a single write of 54 bytes didn't work.
103
fwrite(&hdr.num_chans,2,1,fd);
104
fwrite(&hdr.sample_frames,4,1,fd);
105
fwrite(&hdr.sample_size,2,1,fd);
106
fwrite(&hdr.srate,10,1,fd);
107
fwrite(&hdr.ssnd,4,4,fd);
112
AifWvOut :: AifWvOut(char *fileName, int chans)
116
sprintf(msg, "AifWvOut: number of channels = %d not supported!\n", chans);
117
throw StkError(msg, StkError::FUNCTION_SYNTAX);
120
fd = openAifFile(chans,fileName);
121
data_length = FILE_BUFFER_SIZE*channels;
122
data = (INT16 *) new INT16[data_length];
125
AifWvOut :: ~AifWvOut()
129
unsigned long frames;
131
fwrite(data,2,counter,fd);
132
time = (double) totalCount * ONE_OVER_SRATE;
133
printf("%f Seconds Computed\n\n", time);
135
frames = (unsigned long) totalCount;
136
#ifdef __LITTLE_ENDIAN__
137
swap32((unsigned char *)&frames);
139
fseek(fd,22,SEEK_SET); // jump to "COMM" sample_frames
140
fwrite(&frames,4,1,fd);
142
bytes = totalCount*2*channels + 46;
143
#ifdef __LITTLE_ENDIAN__
144
swap32((unsigned char *)&bytes);
146
fseek(fd,4,SEEK_SET); // jump to file size
147
fwrite(&bytes,4,1,fd);
149
bytes = totalCount*2*channels + 8;
150
#ifdef __LITTLE_ENDIAN__
151
swap32((unsigned char *)&bytes);
153
fseek(fd,42,SEEK_SET); // jump to "SSND" chunk size
154
fwrite(&bytes,4,1,fd);
159
void AifWvOut :: tick(MY_FLOAT sample)
163
isample = (INT16) (sample * 32000.0);
164
#ifdef __LITTLE_ENDIAN__
165
swap16((unsigned char *)&isample);
167
for (int i=0;i<channels;i++)
168
data[counter++] = isample;
171
if (counter == data_length) {
172
fwrite(data,2,data_length,fd);
177
void AifWvOut :: mtick(MY_MULTI samples)
179
for (int i=0;i<channels;i++) {
180
data[counter] = (INT16) (*samples++ * 32000.0);
181
#ifdef __LITTLE_ENDIAN__
182
swap16 ((unsigned char *)&data[counter]);
188
if (counter == data_length) {
189
fwrite(data,2,data_length,fd);