mixer.c
changeset 561 87bdb4c81c0b
parent 560 0fc8dffb86c5
child 562 4129f7c1c68f
equal deleted inserted replaced
560:0fc8dffb86c5 561:87bdb4c81c0b
   124 	return(chunk_decoders[index]);
   124 	return(chunk_decoders[index]);
   125 }
   125 }
   126 
   126 
   127 static void add_chunk_decoder(const char *decoder)
   127 static void add_chunk_decoder(const char *decoder)
   128 {
   128 {
   129 	void *ptr = realloc(chunk_decoders, (num_decoders + 1) * sizeof (const char **));
   129 	void *ptr = SDL_realloc(chunk_decoders, (num_decoders + 1) * sizeof (const char **));
   130 	if (ptr == NULL) {
   130 	if (ptr == NULL) {
   131 		return;  /* oh well, go on without it. */
   131 		return;  /* oh well, go on without it. */
   132 	}
   132 	}
   133 	chunk_decoders = (const char **) ptr;
   133 	chunk_decoders = (const char **) ptr;
   134 	chunk_decoders[num_decoders++] = decoder;
   134 	chunk_decoders[num_decoders++] = decoder;
   225 		Mix_QuitOgg();
   225 		Mix_QuitOgg();
   226 	}
   226 	}
   227 #endif
   227 #endif
   228 #ifdef MID_MUSIC
   228 #ifdef MID_MUSIC
   229 	if (soundfont_paths) {
   229 	if (soundfont_paths) {
   230 		free(soundfont_paths);
   230 		SDL_free(soundfont_paths);
   231 	}
   231 	}
   232 #endif
   232 #endif
   233 	initialized = 0;
   233 	initialized = 0;
   234 }
   234 }
   235 
   235 
   261 	void *buf = snd;
   261 	void *buf = snd;
   262 
   262 
   263 	if (e != NULL) {    /* are there any registered effects? */
   263 	if (e != NULL) {    /* are there any registered effects? */
   264 		/* if this is the postmix, we can just overwrite the original. */
   264 		/* if this is the postmix, we can just overwrite the original. */
   265 		if (!posteffect) {
   265 		if (!posteffect) {
   266 			buf = malloc(len);
   266 			buf = SDL_malloc(len);
   267 			if (buf == NULL) {
   267 			if (buf == NULL) {
   268 				return(snd);
   268 				return(snd);
   269 			}
   269 			}
   270 		    memcpy(buf, snd, len);
   270 			memcpy(buf, snd, len);
   271 		}
   271 		}
   272 
   272 
   273 		for (; e != NULL; e = e->next) {
   273 		for (; e != NULL; e = e->next) {
   274 			if (e->callback != NULL) {
   274 			if (e->callback != NULL) {
   275 				e->callback(chan, buf, len, e->udata);
   275 				e->callback(chan, buf, len, e->udata);
   276 			}
   276 			}
   277 		}
   277 		}
   278 	}
   278 	}
   279 
   279 
   280 	/* be sure to free() the return value if != snd ... */
   280 	/* be sure to SDL_free() the return value if != snd ... */
   281 	return(buf);
   281 	return(buf);
   282 }
   282 }
   283 
   283 
   284 
   284 
   285 /* Mixing function */
   285 /* Mixing function */
   342 					}
   342 					}
   343 
   343 
   344 					mix_input = Mix_DoEffects(i, mix_channel[i].samples, mixable);
   344 					mix_input = Mix_DoEffects(i, mix_channel[i].samples, mixable);
   345 					SDL_MixAudio(stream+index,mix_input,mixable,volume);
   345 					SDL_MixAudio(stream+index,mix_input,mixable,volume);
   346 					if (mix_input != mix_channel[i].samples)
   346 					if (mix_input != mix_channel[i].samples)
   347 						free(mix_input);
   347 						SDL_free(mix_input);
   348 
   348 
   349 					mix_channel[i].samples += mixable;
   349 					mix_channel[i].samples += mixable;
   350 					mix_channel[i].playing -= mixable;
   350 					mix_channel[i].playing -= mixable;
   351 					index += mixable;
   351 					index += mixable;
   352 
   352 
   366 					}
   366 					}
   367 
   367 
   368 					mix_input = Mix_DoEffects(i, mix_channel[i].chunk->abuf, remaining);
   368 					mix_input = Mix_DoEffects(i, mix_channel[i].chunk->abuf, remaining);
   369 					SDL_MixAudio(stream+index, mix_input, remaining, volume);
   369 					SDL_MixAudio(stream+index, mix_input, remaining, volume);
   370 					if (mix_input != mix_channel[i].chunk->abuf)
   370 					if (mix_input != mix_channel[i].chunk->abuf)
   371 						free(mix_input);
   371 						SDL_free(mix_input);
   372 
   372 
   373 					--mix_channel[i].looping;
   373 					--mix_channel[i].looping;
   374 					mix_channel[i].samples = mix_channel[i].chunk->abuf + remaining;
   374 					mix_channel[i].samples = mix_channel[i].chunk->abuf + remaining;
   375 					mix_channel[i].playing = mix_channel[i].chunk->alen - remaining;
   375 					mix_channel[i].playing = mix_channel[i].chunk->alen - remaining;
   376 					index += remaining;
   376 					index += remaining;
   441 		SDL_CloseAudio();
   441 		SDL_CloseAudio();
   442 		return(-1);
   442 		return(-1);
   443 	}
   443 	}
   444 
   444 
   445 	num_channels = MIX_CHANNELS;
   445 	num_channels = MIX_CHANNELS;
   446 	mix_channel = (struct _Mix_Channel *) malloc(num_channels * sizeof(struct _Mix_Channel));
   446 	mix_channel = (struct _Mix_Channel *) SDL_malloc(num_channels * sizeof(struct _Mix_Channel));
   447 
   447 
   448 	/* Clear out the audio channels */
   448 	/* Clear out the audio channels */
   449 	for ( i=0; i<num_channels; ++i ) {
   449 	for ( i=0; i<num_channels; ++i ) {
   450 		mix_channel[i].chunk = NULL;
   450 		mix_channel[i].chunk = NULL;
   451 		mix_channel[i].playing = 0;
   451 		mix_channel[i].playing = 0;
   495 			Mix_UnregisterAllEffects(i);
   495 			Mix_UnregisterAllEffects(i);
   496 			Mix_HaltChannel(i);
   496 			Mix_HaltChannel(i);
   497 		}
   497 		}
   498 	}
   498 	}
   499 	SDL_LockAudio();
   499 	SDL_LockAudio();
   500 	mix_channel = (struct _Mix_Channel *) realloc(mix_channel, numchans * sizeof(struct _Mix_Channel));
   500 	mix_channel = (struct _Mix_Channel *) SDL_realloc(mix_channel, numchans * sizeof(struct _Mix_Channel));
   501 	if ( numchans > num_channels ) {
   501 	if ( numchans > num_channels ) {
   502 		/* Initialize the new channels */
   502 		/* Initialize the new channels */
   503 		int i;
   503 		int i;
   504 		for(i=num_channels; i < numchans; i++) {
   504 		for(i=num_channels; i < numchans; i++) {
   505 			mix_channel[i].chunk = NULL;
   505 			mix_channel[i].chunk = NULL;
   566 		}
   566 		}
   567 		return(NULL);
   567 		return(NULL);
   568 	}
   568 	}
   569 
   569 
   570 	/* Allocate the chunk memory */
   570 	/* Allocate the chunk memory */
   571 	chunk = (Mix_Chunk *)malloc(sizeof(Mix_Chunk));
   571 	chunk = (Mix_Chunk *)SDL_malloc(sizeof(Mix_Chunk));
   572 	if ( chunk == NULL ) {
   572 	if ( chunk == NULL ) {
   573 		SDL_SetError("Out of memory");
   573 		SDL_SetError("Out of memory");
   574 		if ( freesrc ) {
   574 		if ( freesrc ) {
   575 			SDL_RWclose(src);
   575 			SDL_RWclose(src);
   576 		}
   576 		}
   611 		default:
   611 		default:
   612 			SDL_SetError("Unrecognized sound file type");
   612 			SDL_SetError("Unrecognized sound file type");
   613 			return(0);			
   613 			return(0);			
   614 	}
   614 	}
   615 	if ( !loaded ) {
   615 	if ( !loaded ) {
   616 		free(chunk);
   616 		SDL_free(chunk);
   617 		if ( freesrc ) {
   617 		if ( freesrc ) {
   618 			SDL_RWclose(src);
   618 			SDL_RWclose(src);
   619 		}
   619 		}
   620 		return(NULL);
   620 		return(NULL);
   621 	}
   621 	}
   630 		 wavespec.channels != mixer.channels ||
   630 		 wavespec.channels != mixer.channels ||
   631 		 wavespec.freq != mixer.freq ) {
   631 		 wavespec.freq != mixer.freq ) {
   632 		if ( SDL_BuildAudioCVT(&wavecvt,
   632 		if ( SDL_BuildAudioCVT(&wavecvt,
   633 				wavespec.format, wavespec.channels, wavespec.freq,
   633 				wavespec.format, wavespec.channels, wavespec.freq,
   634 				mixer.format, mixer.channels, mixer.freq) < 0 ) {
   634 				mixer.format, mixer.channels, mixer.freq) < 0 ) {
   635 			SDL_FreeWAV(chunk->abuf);
   635 			SDL_free(chunk->abuf);
   636 			free(chunk);
   636 			SDL_free(chunk);
   637 			return(NULL);
   637 			return(NULL);
   638 		}
   638 		}
   639 		samplesize = ((wavespec.format & 0xFF)/8)*wavespec.channels;
   639 		samplesize = ((wavespec.format & 0xFF)/8)*wavespec.channels;
   640 		wavecvt.len = chunk->alen & ~(samplesize-1);
   640 		wavecvt.len = chunk->alen & ~(samplesize-1);
   641 		wavecvt.buf = (Uint8 *)calloc(1, wavecvt.len*wavecvt.len_mult);
   641 		wavecvt.buf = (Uint8 *)SDL_calloc(1, wavecvt.len*wavecvt.len_mult);
   642 		if ( wavecvt.buf == NULL ) {
   642 		if ( wavecvt.buf == NULL ) {
   643 			SDL_SetError("Out of memory");
   643 			SDL_SetError("Out of memory");
   644 			SDL_FreeWAV(chunk->abuf);
   644 			SDL_free(chunk->abuf);
   645 			free(chunk);
   645 			SDL_free(chunk);
   646 			return(NULL);
   646 			return(NULL);
   647 		}
   647 		}
   648 		memcpy(wavecvt.buf, chunk->abuf, chunk->alen);
   648 		memcpy(wavecvt.buf, chunk->abuf, chunk->alen);
   649 		SDL_FreeWAV(chunk->abuf);
   649 		SDL_free(chunk->abuf);
   650 
   650 
   651 		/* Run the audio converter */
   651 		/* Run the audio converter */
   652 		if ( SDL_ConvertAudio(&wavecvt) < 0 ) {
   652 		if ( SDL_ConvertAudio(&wavecvt) < 0 ) {
   653 			free(wavecvt.buf);
   653 			SDL_free(wavecvt.buf);
   654 			free(chunk);
   654 			SDL_free(chunk);
   655 			return(NULL);
   655 			return(NULL);
   656 		}
   656 		}
   657 	}
   657 	}
   658 
   658 
   659 	chunk->allocated = 1;
   659 	chunk->allocated = 1;
   675 		SDL_SetError("Audio device hasn't been opened");
   675 		SDL_SetError("Audio device hasn't been opened");
   676 		return(NULL);
   676 		return(NULL);
   677 	}
   677 	}
   678 
   678 
   679 	/* Allocate the chunk memory */
   679 	/* Allocate the chunk memory */
   680 	chunk = (Mix_Chunk *)calloc(1,sizeof(Mix_Chunk));
   680 	chunk = (Mix_Chunk *)SDL_calloc(1,sizeof(Mix_Chunk));
   681 	if ( chunk == NULL ) {
   681 	if ( chunk == NULL ) {
   682 		SDL_SetError("Out of memory");
   682 		SDL_SetError("Out of memory");
   683 		return(NULL);
   683 		return(NULL);
   684 	}
   684 	}
   685 
   685 
   709 		SDL_SetError("Audio device hasn't been opened");
   709 		SDL_SetError("Audio device hasn't been opened");
   710 		return(NULL);
   710 		return(NULL);
   711 	}
   711 	}
   712 
   712 
   713 	/* Allocate the chunk memory */
   713 	/* Allocate the chunk memory */
   714 	chunk = (Mix_Chunk *)malloc(sizeof(Mix_Chunk));
   714 	chunk = (Mix_Chunk *)SDL_malloc(sizeof(Mix_Chunk));
   715 	if ( chunk == NULL ) {
   715 	if ( chunk == NULL ) {
   716 		SDL_SetError("Out of memory");
   716 		SDL_SetError("Out of memory");
   717 		return(NULL);
   717 		return(NULL);
   718 	}
   718 	}
   719 
   719 
   744 			}
   744 			}
   745 		}
   745 		}
   746 		SDL_UnlockAudio();
   746 		SDL_UnlockAudio();
   747 		/* Actually free the chunk */
   747 		/* Actually free the chunk */
   748 		if ( chunk->allocated ) {
   748 		if ( chunk->allocated ) {
   749 			free(chunk->abuf);
   749 			SDL_free(chunk->abuf);
   750 		}
   750 		}
   751 		free(chunk);
   751 		SDL_free(chunk);
   752 	}
   752 	}
   753 }
   753 }
   754 
   754 
   755 /* Set a function that is called after all mixing is performed.
   755 /* Set a function that is called after all mixing is performed.
   756    This can be used to provide real-time visual display of the audio stream
   756    This can be used to provide real-time visual display of the audio stream
  1133 			Mix_UnregisterAllEffects(MIX_CHANNEL_POST);
  1133 			Mix_UnregisterAllEffects(MIX_CHANNEL_POST);
  1134 			close_music();
  1134 			close_music();
  1135 			Mix_HaltChannel(-1);
  1135 			Mix_HaltChannel(-1);
  1136 			_Mix_DeinitEffects();
  1136 			_Mix_DeinitEffects();
  1137 			SDL_CloseAudio();
  1137 			SDL_CloseAudio();
  1138 			free(mix_channel);
  1138 			SDL_free(mix_channel);
  1139 			mix_channel = NULL;
  1139 			mix_channel = NULL;
  1140 
  1140 
  1141 			/* rcg06042009 report available decoders at runtime. */
  1141 			/* rcg06042009 report available decoders at runtime. */
  1142 			free(chunk_decoders);
  1142 			SDL_free(chunk_decoders);
  1143 			chunk_decoders = NULL;
  1143 			chunk_decoders = NULL;
  1144 			num_decoders = 0;
  1144 			num_decoders = 0;
  1145 		}
  1145 		}
  1146 		--audio_opened;
  1146 		--audio_opened;
  1147 	}
  1147 	}
  1309 	if (f == NULL) {
  1309 	if (f == NULL) {
  1310 		Mix_SetError("NULL effect callback");
  1310 		Mix_SetError("NULL effect callback");
  1311 		return(0);
  1311 		return(0);
  1312 	}
  1312 	}
  1313 
  1313 
  1314 	new_e = malloc(sizeof (effect_info));
  1314 	new_e = SDL_malloc(sizeof (effect_info));
  1315 	if (new_e == NULL) {
  1315 	if (new_e == NULL) {
  1316 		Mix_SetError("Out of memory");
  1316 		Mix_SetError("Out of memory");
  1317 		return(0);
  1317 		return(0);
  1318 	}
  1318 	}
  1319 
  1319 
  1356 		if (cur->callback == f) {
  1356 		if (cur->callback == f) {
  1357 			next = cur->next;
  1357 			next = cur->next;
  1358 			if (cur->done_callback != NULL) {
  1358 			if (cur->done_callback != NULL) {
  1359 				cur->done_callback(channel, cur->udata);
  1359 				cur->done_callback(channel, cur->udata);
  1360 			}
  1360 			}
  1361 			free(cur);
  1361 			SDL_free(cur);
  1362 
  1362 
  1363 			if (prev == NULL) {   /* removing first item of list? */
  1363 			if (prev == NULL) {   /* removing first item of list? */
  1364 				*e = next;
  1364 				*e = next;
  1365 			} else {
  1365 			} else {
  1366 				prev->next = next;
  1366 				prev->next = next;
  1389 	for (cur = *e; cur != NULL; cur = next) {
  1389 	for (cur = *e; cur != NULL; cur = next) {
  1390 		next = cur->next;
  1390 		next = cur->next;
  1391 		if (cur->done_callback != NULL) {
  1391 		if (cur->done_callback != NULL) {
  1392 			cur->done_callback(channel, cur->udata);
  1392 			cur->done_callback(channel, cur->udata);
  1393 		}
  1393 		}
  1394 		free(cur);
  1394 		SDL_free(cur);
  1395 	}
  1395 	}
  1396 	*e = NULL;
  1396 	*e = NULL;
  1397 
  1397 
  1398 	return(1);
  1398 	return(1);
  1399 }
  1399 }