|
From: Jeremy M. <jmu...@sl...> - 2000-05-13 03:59:53
|
Update of OpenUT/SDLAudio/Inc
Modified Files:
SDLAudioLibrary.h SDLAudioSubsystem.h
Log Message:
Merged priority and distance-attenuation code from old Audio module.
-------------------------------------------------
Update of OpenUT/SDLAudio/Src
Modified Files:
SDLAudioLibrary.cpp SDLAudioSubsystem.cpp
Log Message:
Merged priority and distance-attenuation code from old Audio module.
-------------------------------------------------
[ cvs rdiff -t -u OpenUT/SDLAudio/Inc/SDLAudioLibrary.h ]
Index: OpenUT/SDLAudio/Inc/SDLAudioLibrary.h
diff -u OpenUT/SDLAudio/Inc/SDLAudioLibrary.h:1.3 OpenUT/SDLAudio/Inc/SDLAudioLibrary.h:1.4
--- OpenUT/SDLAudio/Inc/SDLAudioLibrary.h:1.3 Wed Apr 19 10:36:43 2000
+++ OpenUT/SDLAudio/Inc/SDLAudioLibrary.h Fri May 12 20:58:58 2000
@@ -25,7 +25,7 @@
#define AUDIO_SURPAN 32768
#define AUDIO_MINVOLUME 0
-#define AUDIO_MAXVOLUME 256
+#define AUDIO_MAXVOLUME MIX_MAX_VOLUME
#define AUDIO_DISABLED 0
#define AUDIO_ENABLED 1
@@ -39,8 +39,6 @@
#define AUDIO_MONO_CHANNELS 1
#define AUDIO_STEREO_CHANNELS 2
-#define AUDIO_SAMPLE_SCALE 8
-
/*------------------------------------------------------------------------------------
Flags
------------------------------------------------------------------------------------*/
@@ -132,7 +130,7 @@
extern INT SampleVoices;
// Volume
-extern INT SampleVolume;
+extern FLOAT CurSampleVolume;
// Threads
extern AudioThread MixingThread;
[ cvs rdiff -t -u OpenUT/SDLAudio/Inc/SDLAudioSubsystem.h ]
Index: OpenUT/SDLAudio/Inc/SDLAudioSubsystem.h
diff -u OpenUT/SDLAudio/Inc/SDLAudioSubsystem.h:1.1 OpenUT/SDLAudio/Inc/SDLAudioSubsystem.h:1.2
--- OpenUT/SDLAudio/Inc/SDLAudioSubsystem.h:1.1 Tue Mar 21 07:48:22 2000
+++ OpenUT/SDLAudio/Inc/SDLAudioSubsystem.h Fri May 12 20:58:58 2000
@@ -13,7 +13,7 @@
// Constants.
#define MAX_EFFECTS_CHANNELS 32
#define MUSIC_CHANNELS 32
-#define EFFECT_FACTOR 1.0
+#define EFFECT_FACTOR 0.25
// Utility Macros.
#define safecall(f) \
@@ -36,8 +36,54 @@
------------------------------------------------------------------------------------*/
//
-// The SDL/libmikmod implementation of UAudioSubsystem.
+// Information about a playing sound.
//
+class FPlayingSound
+{
+public:
+ //Voice* Channel;
+ INT PhysChannel;
+ AActor* Actor;
+ INT Id;
+ UBOOL Is3D;
+ USound* Sound;
+ FVector Location;
+ FLOAT Volume;
+ FLOAT Radius;
+ FLOAT Pitch;
+ FLOAT Priority;
+ FPlayingSound()
+ :/* Channel (NULL)
+ ,*/
+ PhysChannel (-1)
+ , Actor (NULL)
+ , Id (0)
+ , Is3D (0)
+ , Sound (0)
+ , Priority(0)
+ , Volume (0)
+ , Radius (0)
+ , Pitch (0)
+ {}
+ FPlayingSound( AActor* InActor, INT InId, USound* InSound, FVector InLocation, FLOAT InVolume, FLOAT InRadius, FLOAT InPitch, FLOAT InPriority )
+ :/* Channel (NULL)
+ ,*/
+ PhysChannel (-1)
+ , Actor (InActor)
+ , Id (InId)
+ , Is3D (0)
+ , Sound (InSound)
+ , Location(InLocation)
+ , Volume (InVolume)
+ , Radius (InRadius)
+ , Pitch (InPitch)
+ , Priority(InPriority)
+ {}
+};
+
+//
+// The SDL_mixer implementation of UAudioSubsystem.
+//
class DLL_EXPORT_CLASS USDLAudioSubsystem : public UAudioSubsystem
{
DECLARE_CLASS(USDLAudioSubsystem,UAudioSubsystem,CLASS_Config)
@@ -64,6 +110,7 @@
// Variables.
UViewport* Viewport;
+ FPlayingSound PlayingSounds[MAX_EFFECTS_CHANNELS];
DOUBLE LastTime;
UMusic* CurrentMusic;
BYTE CurrentCDTrack;
@@ -96,7 +143,22 @@
void PostRender( FSceneNode* Frame );
// Internal functions.
- void SetVolumes();
+ void SetVolumes();
+ void StopSound( INT Index );
+ // Inlines.
+ Sample* GetSound( USound* Sound )
+ {
+ check(Sound);
+ if( !Sound->Handle )
+ RegisterSound( Sound );
+ return (Sample*)Sound->Handle;
+ }
+ FLOAT SoundPriority( UViewport* Viewport, FVector Location, FLOAT Volume, FLOAT Radius )
+ {
+ return Volume * (1.0 - (Location - (Viewport->Actor->ViewTarget ?
+ Viewport->Actor->ViewTarget :
+ Viewport->Actor)->Location).Size()/Radius);
+ }
};
[ cvs rdiff -t -u OpenUT/SDLAudio/Src/SDLAudioLibrary.cpp ]
Index: OpenUT/SDLAudio/Src/SDLAudioLibrary.cpp
diff -u OpenUT/SDLAudio/Src/SDLAudioLibrary.cpp:1.3 OpenUT/SDLAudio/Src/SDLAudioLibrary.cpp:1.4
--- OpenUT/SDLAudio/Src/SDLAudioLibrary.cpp:1.3 Wed Apr 19 10:36:43 2000
+++ OpenUT/SDLAudio/Src/SDLAudioLibrary.cpp Fri May 12 20:58:58 2000
@@ -32,7 +32,7 @@
INT SampleVoices;
// Volume
-INT SampleVolume;
+FLOAT CurSampleVolume;
// Threads
AudioThread MixingThread;
@@ -134,18 +134,34 @@
}
/*------------------------------------------------------------------------------------
+ Sample control.
+------------------------------------------------------------------------------------*/
+
+// Change a sample.
+/*
+void UpdateSample( Voice* InVoice, INT Freq, INT Volume, INT Panning )
+{
+ ALock;
+ InVoice->Volume = Volume;
+ InVoice->Panning = InVoice->Panning + ((Panning - InVoice->Panning)/2);
+ InVoice->BasePanning = InVoice->Panning;
+ AUnlock;
+}
+*/
+
+/*------------------------------------------------------------------------------------
Volume control.
------------------------------------------------------------------------------------*/
UBOOL SetSampleVolume( FLOAT Volume )
{
- Mix_Volume(-1, (int) (Volume/AUDIO_SAMPLE_SCALE));
+ CurSampleVolume = Volume;
return 1;
}
UBOOL SetMusicVolume( FLOAT Volume )
{
- Mix_VolumeMusic((int) Volume);
+ Mix_VolumeMusic((int) (AUDIO_MAXVOLUME*Volume));
return 1;
}
[ cvs rdiff -t -u OpenUT/SDLAudio/Src/SDLAudioSubsystem.cpp ]
Index: OpenUT/SDLAudio/Src/SDLAudioSubsystem.cpp
diff -u OpenUT/SDLAudio/Src/SDLAudioSubsystem.cpp:1.2 OpenUT/SDLAudio/Src/SDLAudioSubsystem.cpp:1.3
--- OpenUT/SDLAudio/Src/SDLAudioSubsystem.cpp:1.2 Wed Apr 19 10:36:43 2000
+++ OpenUT/SDLAudio/Src/SDLAudioSubsystem.cpp Fri May 12 20:58:58 2000
@@ -178,8 +178,8 @@
guard(USDLAudioSubsystem::SetViewport);
// Stop playing sounds.
- //for( INT i=0; i<Channels; i++ )
- //StopSound( i );
+ for( INT i=0; i<Channels; i++ )
+ StopSound( i );
// Remember the viewport.
if( Viewport != InViewport )
@@ -203,14 +203,6 @@
// Start sound output.
guard(AudioStartOutput);
- /*
- if (OutputRate == 0)
- OutputRate = 1;
- else if (OutputRate == 2)
- OutputRate = 3;
- else if ((OutputRate == 4) || (OutputRate = 6))
- OutputRate = 5;
- */
INT Rates[] = {8000, 11025, 16000, 22050, 32000, 44100, 48000};
INT Rate = Rates[OutputRate];
INT Result = AudioStartOutput( Rate, Format, PhysChannels);
@@ -238,21 +230,21 @@
void USDLAudioSubsystem::RegisterMusic( UMusic* Music )
{
- printf("-1-\n");
+ //printf("-1-\n");
guard(USDLAudioSubsystem::RegisterMusic);
- printf("-2-\n");
+ //printf("-2-\n");
checkSlow(Music);
- printf("-3-\n");
+ //printf("-3-\n");
- printf("CurrentMusic = \n");
- printf(" %p\n",CurrentMusic);
+ //printf("CurrentMusic = \n");
+ //printf(" %p\n",CurrentMusic);
//printf(" %s\n",CurrentMusic?CurrentMusic->GetPathName():"");
- printf("(new)Music = \n");
- printf(" %p\n",Music);
- printf(" %s\n",Music->GetPathName());
+ //printf("(new)Music = \n");
+ //printf(" %p\n",Music);
+ //printf(" %s\n",Music->GetPathName());
//CurrentMusic, CurrentMusic?CurrentMusic->GetPathName():"", Music, Music->GetPathName());
- printf("-4-\n");
+ //printf("-4-\n");
// Load music if it hasn't been loaded yet (Handle is non-null if it's been loaded)
if( !Music->Handle )
@@ -261,23 +253,23 @@
Music->Handle = (void*)-1;
// Load the data.
- printf("=0=\n");
+ //printf("=0=\n");
Music->Data.Load();
- printf("=1=\n");
- debugf( NAME_DevMusic, TEXT("Register music: %s (%i)"), Music->GetPathName(), Music->Data.Num() );
- printf("=2=\n");
+ //printf("=1=\n");
+ //debugf( NAME_DevMusic, TEXT("Register music: %s (%i)"), Music->GetPathName(), Music->Data.Num() );
+ //printf("=2=\n");
check(Music->Data.Num()>0);
- printf("=3=\n");
+ //printf("=3=\n");
// Register the sound.
guard(Mix_LoadMUS);
- printf("=4=\n");
+ //printf("=4=\n");
// mikmod segfaults sometimes when it's asked to load one song while
// another is already playing, so just stop the music...
if ( Mix_PlayingMusic() )
{
- printf("-- Halting currently playing music --\n");
+ //printf("-- Halting currently playing music --\n");
Mix_HaltMusic();
}
@@ -286,18 +278,18 @@
// filename to Mix_LoadMUS. It's frickin' HEINOUS!
// FIXME: We need to get some sort of memory-array file-loader going on
// here, but I don't think SDL_mixer exports that interface to mikmod...
- printf("== Register %s ==\n", Music->GetPathName());
+ //printf("== Register %s ==\n", Music->GetPathName());
FILE *ftmp = fopen("/tmp/ut_music", "wb");
fwrite(&Music->Data(0), 1, Music->Data.Num(), ftmp);
fclose(ftmp);
- printf("=5=\n");
+ //printf("=5=\n");
Music->Handle = Mix_LoadMUS("/tmp/ut_music");
- printf("=6=\n");
+ //printf("=6=\n");
unlink("/tmp/ut_music");
- printf("=7=\n");
+ //printf("=7=\n");
unguard;
//unguardf(( TEXT("(%i)"), Music->Data.Num() ));
@@ -355,12 +347,12 @@
check(Music);
if (Music->Handle)
{
- printf("== Unregister %s ==\n", Music->GetPathName() );
+ //printf("== Unregister %s ==\n", Music->GetPathName() );
debugf( NAME_DevMusic, TEXT("Unregister music: %s"), Music->GetPathName() );
// if this song is playing, we should stop it
if ( CurrentMusic == Music )
{
- printf("-- unloading the currently playing music! --\n");
+ //printf("-- unloading the currently playing music! --\n");
Mix_HaltMusic();
}
Mix_FreeMusic((Mix_Music *) Music->Handle);
@@ -377,15 +369,6 @@
if( Sound->Handle )
{
//debugf( NAME_DevSound, TEXT("Unregister sound: %s"), Sound->GetFullName() );
-
- // Stop this sound.
- //for( INT i=0; i<Channels; i++ )
- // if ( PlayingSounds[i].Sound == Sound )
- // StopSound( i );
-
- // Unload this sound.
- //safecall( UnloadSample( (Sample*) Sound->Handle ) );
-
Mix_FreeChunk((Mix_Chunk *) Sound->Handle);
}
unguard;
@@ -429,9 +412,6 @@
if( !Viewport || !Sound )
return 0;
- if (!Sound->Handle)
- RegisterSound(Sound);
-
//printf(" PlaySound: playing %s (handle==%p) ", Sound->GetFullName(), Sound->Handle);
// Allocate a new slot if requested.
@@ -439,42 +419,45 @@
Id = 16 * --FreeSlot;
// Compute priority.
- FLOAT Priority = 0; //SoundPriority( Viewport, Location, Volume, Radius );
+ FLOAT Priority = SoundPriority( Viewport, Location, Volume, Radius );
// If already playing, stop it.
INT Index = -1;
FLOAT BestPriority = Priority;
- //for( INT i=0; i<Channels; i++ )
- //{
- //FPlayingSound& Playing = PlayingSounds[i];
- //if( (Playing.Id&~1)==(Id&~1) )
- //{
+ for( INT i=0; i<Channels; i++ )
+ {
+ FPlayingSound& Playing = PlayingSounds[i];
+ if( (Playing.Id&~1)==(Id&~1) )
+ {
// Skip if not interruptable.
- //if( Id&1 )
- //return 0;
+ if( Id&1 )
+ return 0;
// Stop the sound.
- //Index = i;
- //break;
- //}
- //else if( Playing.Priority<=BestPriority )
- //{
- //Index = i;
- //BestPriority = Playing.Priority;
- //}
- //}
+ Index = i;
+ break;
+ }
+ else if( Playing.Priority<=BestPriority )
+ {
+ Index = i;
+ BestPriority = Playing.Priority;
+ }
+ }
// If no sound, or its priority is overruled, stop it.
- //if( Index==-1 )
- //return 0;
+ if( Index==-1 )
+ return 0;
// Put the sound on the play-list.
- //StopSound( Index );
- //if( Sound!=(USound*)-1 )
- //PlayingSounds[Index] = FPlayingSound( Actor, Id, Sound, Location, Volume, Radius, Pitch, Priority );
+ StopSound( Index );
+ if( Sound!=(USound*)-1 )
+ PlayingSounds[Index] = FPlayingSound( Actor, Id, Sound, Location, Volume, Radius, Pitch, Priority );
- int chan = Mix_PlayChannel(-1, (Mix_Chunk *) Sound->Handle, 0);
- //printf(" on channel %d\n", chan);
+ /*
+ GetSound( Sound );
+ int chan = Mix_PlayChannel(Index, (Mix_Chunk *) Sound->Handle, 0);
+ printf("playing %s on channel %d (wanted %d)\n", Sound->GetPathName(), chan, Index);
+ */
return 1;
@@ -490,21 +473,19 @@
// Stop referencing actor.
for( INT i=0; i<Channels; i++ )
{
- /*
- if( PlayingSounds[i].Actor==Actor )
- {
- if( (PlayingSounds[i].Id&14)==SLOT_Ambient*2 )
+ if( PlayingSounds[i].Actor==Actor )
{
+ if( (PlayingSounds[i].Id&14)==SLOT_Ambient*2 )
+ {
// Stop ambient sound when actor dies.
- StopSound( i );
- }
- else
- {
+ StopSound( i );
+ }
+ else
+ {
// Unbind regular sounds from actors.
- PlayingSounds[i].Actor = NULL;
+ PlayingSounds[i].Actor = NULL;
+ }
}
- }
- */
}
unguard;
@@ -551,7 +532,7 @@
if ( 1 /* Transition is complete */ )
{
// Load and start the new track
- printf("-- loading new track %s --\n", Viewport->Actor->Song->GetPathName());
+ //printf("-- loading new track %s --\n", Viewport->Actor->Song->GetPathName());
RegisterMusic(Viewport->Actor->Song);
// only play this music if it's not already playing
@@ -581,11 +562,11 @@
&& FDistSquared(ViewActor->Location,Actor->Location)<=Square(Actor->WorldSoundRadius()) )
{
INT Id = Actor->GetIndex()*16+SLOT_Ambient*2;
- //for( INT j=0; j<Channels; j++ )
- //if( PlayingSounds[j].Id==Id )
- //break;
- //if( j==Channels )
- // PlaySound( Actor, Id, Actor->AmbientSound, Actor->Location, AmbientFactor*Actor->SoundVolume/255.0, Actor->WorldSoundRadius(), Actor->SoundPitch/64.0 );
+ for( INT j=0; j<Channels; j++ )
+ if( PlayingSounds[j].Id==Id )
+ break;
+ if( j==Channels )
+ PlaySound( Actor, Id, Actor->AmbientSound, Actor->Location, AmbientFactor*Actor->SoundVolume/255.0, Actor->WorldSoundRadius(), Actor->SoundPitch/64.0 );
}
}
unguard;
@@ -593,10 +574,10 @@
// Update all playing ambient sounds.
guard(UpdateAmbience);
- /*
+
for( INT i=0; i<Channels; i++ )
{
- FPlayingSound& Playing = PlayingSounds[i];
+ FPlayingSound& Playing = PlayingSounds[i];
if( (Playing.Id&14)==SLOT_Ambient*2 )
{
check(Playing.Actor);
@@ -624,12 +605,11 @@
}
}
}
- */
unguard;
// Update all active sounds.
guard(UpdateSounds);
- /*
+
for( INT Index=0; Index<Channels; Index++ )
{
FPlayingSound& Playing = PlayingSounds[Index];
@@ -638,18 +618,27 @@
if( PlayingSounds[Index].Id==0 )
{
// Sound is not playing.
+ //printf("-- sound not playing --\n");
continue;
}
- else if( Playing.Channel && SampleFinished(Playing.Channel) )
+ else if( !Mix_Playing(Index) && Playing.PhysChannel != -1 )
{
// Sound is finished.
+ // (not playing, and has been allocated a channel already;
+ // second condition avoids stopping a sample before it starts)
+ //printf("-- sound finished; stopping --\n");
StopSound( Index );
}
else
{
+ //printf("-- sound playing; updating --\n");
+
// Update positioning from actor, if available.
if( Playing.Actor )
- Playing.Location = Playing.Actor->Location;void UpdateSample( Voice* InVoice, INT Freq, INT Volume, INT Panning );
+ Playing.Location = Playing.Actor->Location;
+
+ /*void UpdateSample( Voice* InVoice, INT Freq, INT Volume, INT Panning );*/
+
// Update the priority.
Playing.Priority = SoundPriority( Viewport, Playing.Location, Playing.Volume, Playing.Radius );
@@ -666,7 +655,7 @@
// Compute panning and volume.
INT SoundPan = Clamp( (INT)(AUDIO_MAXPAN/2 + PanAngle*AUDIO_MAXPAN*7/8/PI), 0, AUDIO_MAXPAN );
FLOAT Attenuation = Clamp(1.0-Size/Playing.Radius,0.0,1.0);
- INT SoundVolume = Clamp( (INT)(AUDIO_MAXVOLUME * Playing.Volume * Attenuation * EFFECT_FACTOR), 0, AUDIO_MAXVOLUME );
+ INT SoundVolume = Clamp( (INT)(AUDIO_MAXVOLUME * Playing.Volume * Attenuation * EFFECT_FACTOR), 0, (INT) (AUDIO_MAXVOLUME*EFFECT_FACTOR) );
if( ReverseStereo )
SoundPan = AUDIO_MAXPAN - SoundPan;
if( Location.Z<0.0 && UseSurround )
@@ -677,20 +666,24 @@
if( Playing.Actor )
{
FLOAT V = (Playing.Actor->Velocity
- //-ViewActor->Velocity
+ /*-ViewActor->Velocity*/
) | (Playing.Actor->Location - ViewActor->Location).SafeNormal();
Doppler = Clamp( 1.0 - V/DopplerSpeed, 0.5, 2.0 );
}
// Update the sound.
- Sample* Sample = GetSound(Playing.Sound);
+ GetSound( Playing.Sound );
FVector Z(0,0,0);
FVector L(Location.X/400.0,Location.Y/400.0,Location.Z/400.0);
- if( Playing.Channel )
+ if( Mix_Playing( Index ) )
{
+ //printf("-- sound actually being played -- \n");
// Update an existing sound.
+ //printf("soundvol = %5d, scaled = %5d\n", SoundVolume, (int) (SoundVolume * CurSampleVolume));
guard(UpdateSample);
+ Mix_Volume(Index, (int) (SoundVolume * CurSampleVolume));
+ /*
UpdateSample
(
Playing.Channel,
@@ -699,23 +692,32 @@
SoundPan
);
Playing.Channel->BasePanning = SoundPan;
+ */
unguard;
}
else
{
+ //printf("-- sound not yet started; starting --\n");
// Start this new sound.
guard(StartSample);
- if( !Playing.Channel )
+ //if( !Mix_Playing( Index ) ) {
+ Playing.PhysChannel = Mix_PlayChannel(Index, (Mix_Chunk *) Playing.Sound->Handle, 0);
+ //printf("playing %s on channel %d (wanted %d)\n",
+ // Playing.Sound->GetPathName(), Playing.PhysChannel, Index);
+ //}
+
+ /*
Playing.Channel = StartSample
( Index+1, Sample,
(INT) (Sample->SamplesPerSec * Playing.Pitch * Doppler),
SoundVolume, SoundPan );
- check(Playing.Channel);
+ */
+
+ /*check(Playing.Channel);*/
unguard;
}
}
}
-*/
unguard;
// Unlock.
@@ -813,9 +815,9 @@
// Set music and effects volumes.
- verify( SetSampleVolume( 128*NormSoundVolume ) );
+ verify( SetSampleVolume( NormSoundVolume ) );
if( UseDigitalMusic )
- verify( SetMusicVolume( 128*NormMusicVolume*Max(MusicFade,0.f) ) );
+ verify( SetMusicVolume( NormMusicVolume*Max(MusicFade,0.f) ) );
/* REF
verify( SetSampleVolume( 127*NormSoundVolume ) );
@@ -828,6 +830,17 @@
unguard;
}
+void USDLAudioSubsystem::StopSound( INT Index )
+{
+ guard(UGenericAudioSubsystem::StopSound);
+
+ Mix_HaltChannel( Index );
+ PlayingSounds[Index] = FPlayingSound();
+
+ unguard;
+}
+
/*-----------------------------------------------------------------------------
The End.
-----------------------------------------------------------------------------*/
+
|