openalbridge/loaders.c
changeset 2212 6b5da1a2765a
parent 2210 1cb7118a77dd
child 2213 bd51bbf06033
equal deleted inserted replaced
2211:288360b78f30 2212:6b5da1a2765a
    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, &section);
   180 			result = ov_read (&oggStream, *data + size, pcm_length - size, 0, 2, 1, &section);
   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)
   195 					return AL_FALSE;
   188 					return AL_FALSE;
   196 				}
   189 				}
   197 			}
   190 			}
   198 		}
   191 		}
   199 		
   192 		
   200 		//records the last fields
   193 		/*records the last fields*/
   201 		*bitsize = size;
   194 		*bitsize = size;
   202 		*freq = vorbisInfo->rate;
   195 		*freq = vorbisInfo->rate;
   203 		return AL_TRUE;
   196 		return AL_TRUE;
   204 	}
   197 	}
   205 	
   198