/* Mixing function */
static void mix_channels(void *udata, Uint8 *stream, int len)
{
	int i;
	Uint32 sdl_ticks;

#if SDL_VERSION_ATLEAST(1, 3, 0)
	/* Need to initialize the stream in SDL 1.3+ */
	memset(stream, mixer.silence, len);
#endif

	/* Mix the music (must be done before the channels are added) */
	if ( (mix_music_compat_channel.playing) && ( ! mix_music_compat_channel.paused ) ) {
		if (mix_compat_music != NULL) {
			mix_compat_music(music_compat_data, stream, len);
		} else {
			mix_music(music_data, mix_music_compat_channel.music, stream, len, MUSIC_COMPAT_MAGIC_CHANNEL);
		}
	}
	for ( i=0; i<num_channels; ++i ) {
		if ((mix_channel[i].is_music) && (mix_channel[i].playing) && ( ! mix_channel[i].paused )) {
			mix_music(music_data, mix_channel[i].music, stream, len, i);
		}
	}

	/* Mix any playing channels... */
	sdl_ticks = SDL_GetTicks();
	for ( i=0; i<num_channels; ++i ) {
		if ((! mix_channel[i].is_music) && ( ! mix_channel[i].paused )) {
			do_mix_channel(udata, stream, len, &mix_channel[i], mix_channel[i].sound, i, sdl_ticks);
		}
	}

	/* rcg06122001 run posteffects... */
	Mix_DoEffects(MIX_CHANNEL_POST, stream, len);

	if ( mix_postmix ) {
		mix_postmix(mix_postmix_data, stream, len);
	}
}
예제 #2
0
파일: mixer.c 프로젝트: iaco79/IrrGameDemo
/* Mixing function */
static void mix_channels(void *udata, Uint8 *stream, int len)
{
	Uint8 *mix_input;
	int i, mixable, volume = SDL_MIX_MAXVOLUME;
	Uint32 sdl_ticks;

#if SDL_VERSION_ATLEAST(1, 3, 0)
	/* Need to initialize the stream in SDL 1.3+ */
	memset(stream, mixer.silence, len);
#endif

	/* Mix the music (must be done before the channels are added) */
	if ( music_active || (mix_music != music_mixer) ) {
		mix_music(music_data, stream, len);
	}

	/* Mix any playing channels... */
	sdl_ticks = SDL_GetTicks();
	for ( i=0; i<num_channels; ++i ) {
		if( ! mix_channel[i].paused ) {
			if ( mix_channel[i].expire > 0 && mix_channel[i].expire < sdl_ticks ) {
				/* Expiration delay for that channel is reached */
				mix_channel[i].playing = 0;
				mix_channel[i].looping = 0;
				mix_channel[i].fading = MIX_NO_FADING;
				mix_channel[i].expire = 0;
				_Mix_channel_done_playing(i);
			} else if ( mix_channel[i].fading != MIX_NO_FADING ) {
				Uint32 ticks = sdl_ticks - mix_channel[i].ticks_fade;
				if( ticks > mix_channel[i].fade_length ) {
				    Mix_Volume(i, mix_channel[i].fade_volume_reset); /* Restore the volume */
					if( mix_channel[i].fading == MIX_FADING_OUT ) {
						mix_channel[i].playing = 0;
						mix_channel[i].looping = 0;
						mix_channel[i].expire = 0;
						_Mix_channel_done_playing(i);
					}
					mix_channel[i].fading = MIX_NO_FADING;
				} else {
					if( mix_channel[i].fading == MIX_FADING_OUT ) {
						Mix_Volume(i, (mix_channel[i].fade_volume * (mix_channel[i].fade_length-ticks))
								   / mix_channel[i].fade_length );
					} else {
						Mix_Volume(i, (mix_channel[i].fade_volume * ticks) / mix_channel[i].fade_length );
					}
				}
			}
			if ( mix_channel[i].playing > 0 ) {
				int index = 0;
				int remaining = len;
				while (mix_channel[i].playing > 0 && index < len) {
					remaining = len - index;
					volume = (mix_channel[i].volume*mix_channel[i].chunk->volume) / MIX_MAX_VOLUME;
					mixable = mix_channel[i].playing;
					if ( mixable > remaining ) {
						mixable = remaining;
					}

					mix_input = Mix_DoEffects(i, mix_channel[i].samples, mixable);
					SDL_MixAudio(stream+index,mix_input,mixable,volume);
					if (mix_input != mix_channel[i].samples)
						SDL_free(mix_input);

					mix_channel[i].samples += mixable;
					mix_channel[i].playing -= mixable;
					index += mixable;

					/* rcg06072001 Alert app if channel is done playing. */
					if (!mix_channel[i].playing && !mix_channel[i].looping) {
						_Mix_channel_done_playing(i);
					}
				}

				/* If looping the sample and we are at its end, make sure
				   we will still return a full buffer */
				while ( mix_channel[i].looping && index < len ) {
					int alen = mix_channel[i].chunk->alen;
					remaining = len - index;
					if (remaining > alen) {
						remaining = alen;
					}

					mix_input = Mix_DoEffects(i, mix_channel[i].chunk->abuf, remaining);
					SDL_MixAudio(stream+index, mix_input, remaining, volume);
					if (mix_input != mix_channel[i].chunk->abuf)
						SDL_free(mix_input);

					--mix_channel[i].looping;
					mix_channel[i].samples = mix_channel[i].chunk->abuf + remaining;
					mix_channel[i].playing = mix_channel[i].chunk->alen - remaining;
					index += remaining;
				}
				if ( ! mix_channel[i].playing && mix_channel[i].looping ) {
					--mix_channel[i].looping;
					mix_channel[i].samples = mix_channel[i].chunk->abuf;
					mix_channel[i].playing = mix_channel[i].chunk->alen;
				}
			}
		}
	}

	/* rcg06122001 run posteffects... */
	Mix_DoEffects(MIX_CHANNEL_POST, stream, len);

	if ( mix_postmix ) {
		mix_postmix(mix_postmix_data, stream, len);
	}
}