music.c
changeset 4 5c4485704b30
parent 3 f6dabb779e45
child 7 e73da9dc4bdc
     1.1 --- a/music.c	Sat Oct 23 00:39:09 1999 +0000
     1.2 +++ b/music.c	Sat Oct 23 03:31:21 1999 +0000
     1.3 @@ -57,9 +57,11 @@
     1.4  static char *music_cmd = NULL;
     1.5  static int samplesize;
     1.6  static Mix_Music *music_playing = 0;
     1.7 +static SDL_mutex *music_lock;
     1.8  static int music_volume;
     1.9  static int music_swap8;
    1.10  static int music_swap16;
    1.11 +
    1.12  struct _Mix_Music {
    1.13  	enum {
    1.14  		MUS_CMD,
    1.15 @@ -85,6 +87,10 @@
    1.16  		SMPEG *mp3;
    1.17  #endif
    1.18  	} data;
    1.19 +	Mix_Fading fading;
    1.20 +	int fade_volume;
    1.21 +	int fade_length;
    1.22 +	Uint32 ticks_fade;
    1.23  	int error;
    1.24  };
    1.25  static int timidity_ok;
    1.26 @@ -95,6 +101,26 @@
    1.27  	int i;
    1.28  
    1.29  	if ( music_playing ) {
    1.30 +		if( music_playing->fading != MIX_NO_FADING ) {
    1.31 +			Uint32 ticks = SDL_GetTicks() - music_playing->ticks_fade;
    1.32 +			if( ticks > music_playing->fade_length ) {
    1.33 +				if ( music_playing->fading == MIX_FADING_OUT ) {
    1.34 +					music_volume = music_playing->fade_volume;
    1.35 +					music_playing->fading = MIX_NO_FADING;
    1.36 +					Mix_HaltMusic();
    1.37 +					return;
    1.38 +				}
    1.39 +				music_playing->fading = MIX_NO_FADING;
    1.40 +			} else {
    1.41 +				if ( music_playing->fading == MIX_FADING_OUT ) {
    1.42 +					Mix_VolumeMusic((music_playing->fade_volume * (music_playing->fade_length-ticks)) 
    1.43 +									/ music_playing->fade_length);
    1.44 +				} else { /* Fading in */
    1.45 +					Mix_VolumeMusic((music_playing->fade_volume * ticks) 
    1.46 +									/ music_playing->fade_length);
    1.47 +				}
    1.48 +			}
    1.49 +		}
    1.50  		switch (music_playing->type) {
    1.51  #ifdef CMD_MUSIC
    1.52  			case MUS_CMD:
    1.53 @@ -227,6 +253,9 @@
    1.54  	used_mixer = *mixer;
    1.55  #endif
    1.56  	music_playing = 0;
    1.57 +
    1.58 +	/* Initialize the music lock */
    1.59 +	music_lock = SDL_CreateMutex();
    1.60  	if ( music_error ) {
    1.61  		return(-1);
    1.62  	}
    1.63 @@ -340,7 +369,13 @@
    1.64  	if ( music ) {
    1.65  		/* Caution: If music is playing, mixer will crash */
    1.66  		if ( music == music_playing ) {
    1.67 -			Mix_HaltMusic();
    1.68 +			if ( music->fading == MIX_FADING_OUT ) {
    1.69 +				/* Wait for the fade out to finish */
    1.70 +				while(music->fading == MIX_FADING_OUT)
    1.71 +					SDL_Delay(100);
    1.72 +			} else {
    1.73 +				Mix_HaltMusic(); /* Stop it immediately */
    1.74 +			}
    1.75  		}
    1.76  		switch (music->type) {
    1.77  #ifdef CMD_MUSIC
    1.78 @@ -384,6 +419,10 @@
    1.79  	if ( music == NULL ) {
    1.80  		return(-1);
    1.81  	}
    1.82 +	/* If the current music is fading out, wait for the fade to complete */
    1.83 +	while ( music_playing && music_playing->fading==MIX_FADING_OUT ) {
    1.84 +		SDL_Delay(100);
    1.85 +	}
    1.86  	switch (music->type) {
    1.87  #ifdef CMD_MUSIC
    1.88  		case MUS_CMD:
    1.89 @@ -425,6 +464,22 @@
    1.90  	}
    1.91  	music_active = 1;
    1.92  	music_playing = music;
    1.93 +	music_playing->fading = MIX_NO_FADING;
    1.94 +	return(0);
    1.95 +}
    1.96 +
    1.97 +/* Fade in a music over "ms" milliseconds */
    1.98 +int Mix_FadeInMusic(Mix_Music *music, int loops, int ms)
    1.99 +{
   1.100 +	if ( music && music_volume > 0 ) { /* No need to fade if we can't hear it */
   1.101 +		music->fade_volume = music_volume;
   1.102 +		music_volume = 0;
   1.103 +		if(Mix_PlayMusic(music,loops)<0)
   1.104 +			return(-1);
   1.105 +		music_playing->fading = MIX_FADING_IN;
   1.106 +		music_playing->fade_length = ms;
   1.107 +		music_playing->ticks_fade = SDL_GetTicks();
   1.108 +	}
   1.109  	return(0);
   1.110  }
   1.111  
   1.112 @@ -434,42 +489,43 @@
   1.113  	int prev_volume;
   1.114  
   1.115  	prev_volume = music_volume;
   1.116 -	if ( volume >= 0 ) {
   1.117 -		if ( volume > SDL_MIX_MAXVOLUME ) {
   1.118 -			volume = SDL_MIX_MAXVOLUME;
   1.119 -		}
   1.120 -		music_volume = volume;
   1.121 -		if ( music_playing ) {
   1.122 -			switch (music_playing->type) {
   1.123 +	if ( volume < 0 ) {
   1.124 +		volume = 0;
   1.125 +	}
   1.126 +	if ( volume > SDL_MIX_MAXVOLUME ) {
   1.127 +		volume = SDL_MIX_MAXVOLUME;
   1.128 +	}
   1.129 +	music_volume = volume;
   1.130 +	if ( music_playing ) {
   1.131 +		switch (music_playing->type) {
   1.132  #ifdef CMD_MUSIC
   1.133 -				case MUS_CMD:
   1.134 -					MusicCMD_SetVolume(music_volume);
   1.135 -					break;
   1.136 +		case MUS_CMD:
   1.137 +			MusicCMD_SetVolume(music_volume);
   1.138 +			break;
   1.139  #endif
   1.140  #ifdef WAV_MUSIC
   1.141 -				case MUS_WAV:
   1.142 -					WAVStream_SetVolume(music_volume);
   1.143 -					break;
   1.144 +		case MUS_WAV:
   1.145 +			WAVStream_SetVolume(music_volume);
   1.146 +			break;
   1.147  #endif
   1.148  #ifdef MOD_MUSIC
   1.149 -				case MUS_MOD:
   1.150 -					Player_SetVolume(music_volume);
   1.151 -					break;
   1.152 +		case MUS_MOD:
   1.153 +			Player_SetVolume(music_volume);
   1.154 +			break;
   1.155  #endif
   1.156  #ifdef MID_MUSIC
   1.157 -				case MUS_MID:
   1.158 -					Timidity_SetVolume(music_volume);
   1.159 -					break;
   1.160 +		case MUS_MID:
   1.161 +			Timidity_SetVolume(music_volume);
   1.162 +			break;
   1.163  #endif
   1.164  #ifdef MP3_MUSIC
   1.165 -			    case MUS_MP3:
   1.166 -					SMPEG_setvolume(music_playing->data.mp3,((float)music_volume/(float)MIX_MAX_VOLUME)*100.0);
   1.167 -					break;
   1.168 +		case MUS_MP3:
   1.169 +			SMPEG_setvolume(music_playing->data.mp3,((float)music_volume/(float)MIX_MAX_VOLUME)*100.0);
   1.170 +			break;
   1.171  #endif
   1.172 -				default:
   1.173 -					/* Unknown music type?? */
   1.174 -					break;
   1.175 -			}
   1.176 +		default:
   1.177 +			/* Unknown music type?? */
   1.178 +			break;
   1.179  		}
   1.180  	}
   1.181  	return(prev_volume);
   1.182 @@ -478,6 +534,10 @@
   1.183  /* Halt playing of music */
   1.184  int Mix_HaltMusic(void)
   1.185  {
   1.186 +	/* This function can be called both from the main program thread
   1.187 +	   and from the SDL audio thread (when fading), so we need to ensure 
   1.188 +	   that only one thread is running it at once */
   1.189 +	SDL_mutexP(music_lock);
   1.190  	if ( music_playing ) {
   1.191  		switch (music_playing->type) {
   1.192  #ifdef CMD_MUSIC
   1.193 @@ -507,13 +567,40 @@
   1.194  #endif
   1.195  			default:
   1.196  				/* Unknown music type?? */
   1.197 +				SDL_mutexV(music_lock);
   1.198  				return(-1);
   1.199  		}
   1.200 +		if(music_playing->fading != MIX_NO_FADING) /* Restore volume */
   1.201 +			music_volume = music_playing->fade_volume;
   1.202 +		music_playing->fading = MIX_NO_FADING;
   1.203  		music_playing = 0;
   1.204  	}
   1.205 +	SDL_mutexV(music_lock);
   1.206  	return(0);
   1.207  }
   1.208  
   1.209 +/* Progressively stop the music */
   1.210 +int Mix_FadeOutMusic(int ms)
   1.211 +{
   1.212 +	if ( music_playing && music_playing->fading==MIX_NO_FADING ) {
   1.213 +		if ( music_volume>0 ) {
   1.214 +			music_playing->fading = MIX_FADING_OUT;
   1.215 +			music_playing->fade_volume = music_volume;
   1.216 +			music_playing->fade_length = ms;
   1.217 +			music_playing->ticks_fade = SDL_GetTicks();
   1.218 +			return(1);
   1.219 +		}
   1.220 +	}
   1.221 +	return(0);
   1.222 +}
   1.223 +
   1.224 +Mix_Fading Mix_FadingMusic(void)
   1.225 +{
   1.226 +	if( music_playing )
   1.227 +		return music_playing->fading;
   1.228 +	return MIX_NO_FADING;
   1.229 +}
   1.230 +
   1.231  /* Pause/Resume the music stream */
   1.232  void Mix_PauseMusic(void)
   1.233  {
   1.234 @@ -533,6 +620,7 @@
   1.235  	}
   1.236  	music_active = 0;
   1.237  }
   1.238 +
   1.239  void Mix_ResumeMusic(void)
   1.240  {
   1.241  	if ( music_playing ) {