6 wavefile_t *waveopen(char *filename, char **errorstring)
8 int validfmt, position, length, l;
12 unsigned char buffer[1024];
14 file = fopen(filename, "rb");
17 w = malloc(sizeof(*w));
18 memset(w, 0, sizeof(*w));
22 if (fread(buffer, 12, 1, w->file))
24 if (!memcmp(buffer, "RIFF", 4))
26 if (!memcmp(buffer + 8, "WAVE", 4))
31 if (!fread(buffer, 8, 1, w->file))
33 //error = "error reading chunk\n");
36 position = ftell(w->file);
37 length = buffer[4] | (buffer[5] << 8) | (buffer[6] << 16) | (buffer[7] << 24);
38 if (!memcmp(buffer, "fmt ", 4))
44 if (!fread(buffer, l, 1, w->file))
46 error = "error reading \"fmt \" chunk\n";
49 w->info_format = buffer[0] | (buffer[1] << 8);
50 if (w->info_format != 1)
52 error = "only PCM format supported\n";
55 w->info_channels = buffer[2] | (buffer[3] << 8);
56 if (w->info_channels != 1 && w->info_channels != 2)
58 error = "only mono and stereo supported\n";
61 w->info_rate = buffer[4] | (buffer[5] << 8) | (buffer[6] << 16) | (buffer[7] << 24);
64 error = "only rates 1hz-100khz supported\n";
67 w->info_bits = buffer[14] | (buffer[15] << 8);
68 if (w->info_bits != 8 && w->info_bits != 16)
70 error = "only 8bit and 16bit supported\n";
75 else if (!memcmp(buffer, "data", 4))
79 w->datalength = length;
80 w->dataposition = position;
83 // other chunks that might be of interest:
84 // "cue " (for looping)
85 if (fseek(w->file, position + length, SEEK_SET))
87 error = "error seeking to next chunk\n";
91 if (w->datalength && validfmt)
93 w->info_bytesperchannel = w->info_bits / 8;
94 w->info_bytespersample = w->info_channels * w->info_bytesperchannel;
95 w->length = w->datalength / w->info_bytespersample;
97 fseek(w->file, w->dataposition, SEEK_SET);
102 error = "not a RIFF WAVE file\n";
105 error = "not a RIFF file\n";
108 error = "error reading file\n";
112 error = "unable to allocate memory\n";
116 error = "unable to open file\n";
118 *errorstring = error;
122 void waveclose(wavefile_t *f)
131 unsigned int waveread16stereo(wavefile_t *w, short *soundbuffer, unsigned int samples)
138 if (length > w->length - w->position)
139 length = w->length - w->position;
140 if (w->bufferlength < length)
144 w->bufferlength = length + 100;
145 w->buffer = malloc(w->bufferlength * w->info_bytespersample);
147 length = fread(w->buffer, w->info_bytespersample, length, w->file);
148 w->position += length;
151 if (w->info_bytesperchannel == 2)
153 if (w->info_channels == 2)
155 for (i = 0, in = w->buffer, out = soundbuffer;i < length;i++, in += 4, out += 2)
157 out[0] = in[0] | (in[1] << 8);
158 out[1] = in[2] | (in[3] << 8);
162 for (i = 0, in = w->buffer, out = soundbuffer;i < length;i++, in += 2, out += 2)
163 out[0] = out[1] = in[0] | (in[1] << 8);
167 if (w->info_channels == 2)
169 for (i = 0, in = w->buffer, out = soundbuffer;i < length;i++, in += 2, out += 2)
171 out[0] = (in[0] - 128) << 8;
172 out[1] = (in[1] - 128) << 8;
176 for (i = 0, in = w->buffer, out = soundbuffer;i < length;i++, in += 1, out += 2)
177 out[0] = out[1] = (in[0] - 128) << 8;
183 unsigned int waveseek(wavefile_t *w, unsigned int samples)
185 if (samples > w->datalength)
189 w->position = samples;
190 fseek(w->file, w->dataposition + w->position * w->info_bytespersample, SEEK_SET);