8 wavefile_t *waveopen(char *filename, char **errorstring)
10 int validfmt, position, length, l;
14 unsigned char buffer[1024];
16 file = FS_Open (filename, "rb", true);
19 w = malloc(sizeof(*w));
20 memset(w, 0, sizeof(*w));
24 if (FS_Read (w->file, buffer, 12))
26 if (!memcmp(buffer, "RIFF", 4))
28 if (!memcmp(buffer + 8, "WAVE", 4))
33 if (!FS_Read(w->file, buffer, 8))
35 //error = "error reading chunk\n");
38 position = FS_Tell(w->file);
39 length = buffer[4] | (buffer[5] << 8) | (buffer[6] << 16) | (buffer[7] << 24);
40 if (!memcmp(buffer, "fmt ", 4))
46 if (!FS_Read(w->file, buffer, l))
48 error = "error reading \"fmt \" chunk\n";
51 w->info_format = buffer[0] | (buffer[1] << 8);
52 if (w->info_format != 1)
54 error = "only PCM format supported\n";
57 w->info_channels = buffer[2] | (buffer[3] << 8);
58 if (w->info_channels != 1 && w->info_channels != 2)
60 error = "only mono and stereo supported\n";
63 w->info_rate = buffer[4] | (buffer[5] << 8) | (buffer[6] << 16) | (buffer[7] << 24);
66 error = "only rates 1hz-100khz supported\n";
69 w->info_bits = buffer[14] | (buffer[15] << 8);
70 if (w->info_bits != 8 && w->info_bits != 16)
72 error = "only 8bit and 16bit supported\n";
77 else if (!memcmp(buffer, "data", 4))
81 w->datalength = length;
82 w->dataposition = position;
85 // other chunks that might be of interest:
86 // "cue " (for looping)
87 if (FS_Seek(w->file, position + length, SEEK_SET))
89 error = "error seeking to next chunk\n";
93 if (w->datalength && validfmt)
95 w->info_bytesperchannel = w->info_bits / 8;
96 w->info_bytespersample = w->info_channels * w->info_bytesperchannel;
97 w->length = w->datalength / w->info_bytespersample;
99 FS_Seek(w->file, w->dataposition, SEEK_SET);
104 error = "not a RIFF WAVE file\n";
107 error = "not a RIFF file\n";
110 error = "error reading file\n";
114 error = "unable to allocate memory\n";
118 error = "unable to open file\n";
120 *errorstring = error;
124 void waveclose(wavefile_t *f)
133 unsigned int waveread16stereo(wavefile_t *w, short *soundbuffer, unsigned int samples)
140 if (length > w->length - w->position)
141 length = w->length - w->position;
142 if (w->bufferlength < length)
146 w->bufferlength = length + 100;
147 w->buffer = malloc(w->bufferlength * w->info_bytespersample);
149 length = FS_Read(w->file, w->buffer, w->info_bytespersample * length);
150 w->position += length;
153 if (w->info_bytesperchannel == 2)
155 if (w->info_channels == 2)
157 for (i = 0, in = w->buffer, out = soundbuffer;i < length;i++, in += 4, out += 2)
159 out[0] = in[0] | (in[1] << 8);
160 out[1] = in[2] | (in[3] << 8);
164 for (i = 0, in = w->buffer, out = soundbuffer;i < length;i++, in += 2, out += 2)
165 out[0] = out[1] = in[0] | (in[1] << 8);
169 if (w->info_channels == 2)
171 for (i = 0, in = w->buffer, out = soundbuffer;i < length;i++, in += 2, out += 2)
173 out[0] = (in[0] - 128) << 8;
174 out[1] = (in[1] - 128) << 8;
178 for (i = 0, in = w->buffer, out = soundbuffer;i < length;i++, in += 1, out += 2)
179 out[0] = out[1] = (in[0] - 128) << 8;
185 unsigned int waveseek(wavefile_t *w, unsigned int samples)
187 if (samples > w->datalength)
191 w->position = samples;
192 FS_Seek(w->file, w->dataposition + w->position * w->info_bytespersample, SEEK_SET);