20 |
20 |
21 #ifdef __CPLUSPLUS |
21 #ifdef __CPLUSPLUS |
22 extern "C" { |
22 extern "C" { |
23 #endif |
23 #endif |
24 |
24 |
25 extern int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes); |
|
26 extern long ov_read(OggVorbis_File *vf,char *buffer,int length,int bigendianp,int word,int sgned,int *bitstream); |
|
27 extern ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i); |
|
28 extern long ov_read(OggVorbis_File *vf,char *buffer,int length,int bigendianp,int word,int sgned,int *bitstream); |
|
29 extern vorbis_info *ov_info(OggVorbis_File *vf,int link); |
|
30 extern vorbis_comment *ov_comment(OggVorbis_File *f, int num); |
|
31 |
|
32 int load_WavPcm (const char *filename, ALenum *format, uint8_t** data, ALsizei *bitsize, ALsizei *freq) { |
25 int load_WavPcm (const char *filename, ALenum *format, uint8_t** data, ALsizei *bitsize, ALsizei *freq) { |
33 WAV_header_t WAVHeader; |
26 WAV_header_t WAVHeader; |
34 FILE *wavfile; |
27 FILE *wavfile; |
35 int t, n = 0; |
28 int t, n = 0; |
36 |
29 |
64 fprintf(stderr, "ByteRate: %d\n", WAVHeader.ByteRate); |
57 fprintf(stderr, "ByteRate: %d\n", WAVHeader.ByteRate); |
65 fprintf(stderr, "BlockAlign: %d\n", WAVHeader.BlockAlign); |
58 fprintf(stderr, "BlockAlign: %d\n", WAVHeader.BlockAlign); |
66 fprintf(stderr, "BitsPerSample: %d\n", WAVHeader.BitsPerSample); |
59 fprintf(stderr, "BitsPerSample: %d\n", WAVHeader.BitsPerSample); |
67 #endif |
60 #endif |
68 |
61 |
69 do { //remove useless header chunks (plenty room for improvements) |
62 do { /*remove useless header chunks (plenty room for improvements)*/ |
70 t = fread(&WAVHeader.Subchunk2ID, sizeof(uint32_t), 1, wavfile); |
63 t = fread(&WAVHeader.Subchunk2ID, sizeof(uint32_t), 1, wavfile); |
71 if (invert_endianness(WAVHeader.Subchunk2ID) == 0x64617461) |
64 if (invert_endianness(WAVHeader.Subchunk2ID) == 0x64617461) |
72 break; |
65 break; |
73 if (t <= 0) { //eof found |
66 if (t <= 0) { /*eof*/ |
74 fprintf(stderr, "ERROR: wrong WAV header\n"); |
67 fprintf(stderr, "ERROR: wrong WAV header\n"); |
75 return AL_FALSE; |
68 return AL_FALSE; |
76 } |
69 } |
77 } while (1); |
70 } while (1); |
78 fread(&WAVHeader.Subchunk2Size, sizeof(uint32_t), 1, wavfile); |
71 fread(&WAVHeader.Subchunk2Size, sizeof(uint32_t), 1, wavfile); |
82 fprintf(stderr, "Subchunk2Size: %d\n", WAVHeader.Subchunk2Size); |
75 fprintf(stderr, "Subchunk2Size: %d\n", WAVHeader.Subchunk2Size); |
83 #endif |
76 #endif |
84 |
77 |
85 *data = (uint8_t*) malloc (sizeof(uint8_t) * WAVHeader.Subchunk2Size); |
78 *data = (uint8_t*) malloc (sizeof(uint8_t) * WAVHeader.Subchunk2Size); |
86 |
79 |
87 //this could be improved |
80 /*this could be improved*/ |
88 do { |
81 do { |
89 n += fread(&((*data)[n]), sizeof(uint8_t), 1, wavfile); |
82 n += fread(&((*data)[n]), sizeof(uint8_t), 1, wavfile); |
90 } while (n < WAVHeader.Subchunk2Size); |
83 } while (n < WAVHeader.Subchunk2Size); |
91 |
84 |
92 fclose(wavfile); |
85 fclose(wavfile); |
94 #ifdef DEBUG |
87 #ifdef DEBUG |
95 fprintf(stderr, "Last two bytes of data: %X%X\n", (*data)[n-2], (*data)[n-1]); |
88 fprintf(stderr, "Last two bytes of data: %X%X\n", (*data)[n-2], (*data)[n-1]); |
96 #endif |
89 #endif |
97 |
90 |
98 /*remaining parameters*/ |
91 /*remaining parameters*/ |
99 //Valid formats are AL_FORMAT_MONO8, AL_FORMAT_MONO16, AL_FORMAT_STEREO8, and AL_FORMAT_STEREO16. |
92 /*Valid formats are AL_FORMAT_MONO8, AL_FORMAT_MONO16, AL_FORMAT_STEREO8, and AL_FORMAT_STEREO16*/ |
100 if (WAVHeader.NumChannels == 1) { |
93 if (WAVHeader.NumChannels == 1) { |
101 if (WAVHeader.BitsPerSample == 8) |
94 if (WAVHeader.BitsPerSample == 8) |
102 *format = AL_FORMAT_MONO8; |
95 *format = AL_FORMAT_MONO8; |
103 else { |
96 else { |
104 if (WAVHeader.BitsPerSample == 16) |
97 if (WAVHeader.BitsPerSample == 16) |
130 *freq = WAVHeader.SampleRate; |
123 *freq = WAVHeader.SampleRate; |
131 return AL_TRUE; |
124 return AL_TRUE; |
132 } |
125 } |
133 |
126 |
134 int load_OggVorbis (const char *filename, ALenum *format, uint8_t**data, ALsizei *bitsize, ALsizei *freq) { |
127 int load_OggVorbis (const char *filename, ALenum *format, uint8_t**data, ALsizei *bitsize, ALsizei *freq) { |
135 //implementation inspired from http://www.devmaster.net/forums/showthread.php?t=1153 |
128 /*implementation inspired from http://www.devmaster.net/forums/showthread.php?t=1153 */ |
136 FILE *oggFile; // ogg handle |
129 FILE *oggFile; /*ogg handle*/ |
137 OggVorbis_File oggStream; // stream handle |
130 OggVorbis_File oggStream; /*stream handle*/ |
138 vorbis_info *vorbisInfo; // some formatting data |
131 vorbis_info *vorbisInfo; /*some formatting data*/ |
139 int64_t pcm_length; // length of the decoded data |
132 int64_t pcm_length; /*length of the decoded data*/ |
140 int size = 0; |
133 int size = 0; |
141 int section, result; |
134 int section, result; |
142 #ifdef DEBUG |
135 #ifdef DEBUG |
143 int i; |
136 int i; |
144 vorbis_comment *vorbisComment; // other less useful data |
137 vorbis_comment *vorbisComment; /*other less useful data*/ |
145 #endif |
138 #endif |
146 |
139 |
147 oggFile = Fopen(filename, "rb"); |
140 oggFile = Fopen(filename, "rb"); |
148 result = ov_open(oggFile, &oggStream, NULL, 0); |
141 result = ov_open(oggFile, &oggStream, NULL, 0); |
149 //TODO: check returning value of result |
142 /*TODO: check returning value of result*/ |
150 |
143 |
151 vorbisInfo = ov_info(&oggStream, -1); |
144 vorbisInfo = ov_info(&oggStream, -1); |
152 pcm_length = ov_pcm_total(&oggStream,-1) << vorbisInfo->channels; |
145 pcm_length = ov_pcm_total(&oggStream,-1) << vorbisInfo->channels; |
153 |
146 |
154 #ifdef DEBUG |
147 #ifdef DEBUG |
165 fprintf(stderr, "# comment: %d\n", vorbisComment->comments); |
158 fprintf(stderr, "# comment: %d\n", vorbisComment->comments); |
166 for (i = 0; i < vorbisComment->comments; i++) |
159 for (i = 0; i < vorbisComment->comments; i++) |
167 fprintf(stderr, "\tComment %d: %s\n", i, vorbisComment->user_comments[i]); |
160 fprintf(stderr, "\tComment %d: %s\n", i, vorbisComment->user_comments[i]); |
168 #endif |
161 #endif |
169 |
162 |
170 //allocates enough room for the decoded data |
163 /*allocates enough room for the decoded data*/ |
171 *data = (uint8_t*) malloc (sizeof(uint8_t) * pcm_length); |
164 *data = (uint8_t*) malloc (sizeof(uint8_t) * pcm_length); |
172 |
165 |
173 //there *should* not be ogg at 8 bits |
166 /*there *should* not be ogg at 8 bits*/ |
174 if (vorbisInfo->channels == 1) |
167 if (vorbisInfo->channels == 1) |
175 *format = AL_FORMAT_MONO16; |
168 *format = AL_FORMAT_MONO16; |
176 else { |
169 else { |
177 if (vorbisInfo->channels == 2) |
170 if (vorbisInfo->channels == 2) |
178 *format = AL_FORMAT_STEREO16; |
171 *format = AL_FORMAT_STEREO16; |
181 return AL_FALSE; |
174 return AL_FALSE; |
182 } |
175 } |
183 } |
176 } |
184 |
177 |
185 while(size < pcm_length) { |
178 while(size < pcm_length) { |
186 //ov_read decodes the ogg stream and storse the pcm in data |
179 /*ov_read decodes the ogg stream and storse the pcm in data*/ |
187 result = ov_read (&oggStream, *data + size, pcm_length - size, 0, 2, 1, §ion); |
180 result = ov_read (&oggStream, *data + size, pcm_length - size, 0, 2, 1, §ion); |
188 if(result > 0) { |
181 if(result > 0) { |
189 size += result; |
182 size += result; |
190 } else { |
183 } else { |
191 if (result == 0) |
184 if (result == 0) |