diff --git a/stella/src/build/makefile b/stella/src/build/makefile index 46732868b..0559074e5 100644 --- a/stella/src/build/makefile +++ b/stella/src/build/makefile @@ -13,7 +13,7 @@ ## See the file "license" for information on usage and redistribution of ## this file, and for a DISCLAIMER OF ALL WARRANTIES. ## -## $Id: makefile,v 1.22 2002-10-09 04:38:11 bwmott Exp $ +## $Id: makefile,v 1.23 2002-10-11 13:06:59 stephena Exp $ ##============================================================================ ##============================================================================ @@ -179,7 +179,7 @@ linux-x: linux-sdl: make stella.sdl \ - INCLUDES="$(INCLUDES) -I$(UI)/sdl -I$(UI)/sound" \ + INCLUDES="$(INCLUDES) -I$(UI)/sdl" \ SYS_INCLUDES="" \ OPTIONS="-DBSPF_UNIX=1" \ OPTIONS+="$(OPTS.SDL)" \ @@ -187,7 +187,7 @@ linux-sdl: LDFLAGS+="$(CFLAGS.SDL)" \ LDLIBS="-lX11 -lXext" \ LDLIBS+="$(LIBS.SDL)" \ - OBJS="mainSDL.o SndSDL.o RectList.o" \ + OBJS="mainSDL.o SoundSDL.o RectList.o" \ OBJS+="$(OBJS.SDL)" bsdi-x: @@ -408,8 +408,8 @@ SoundX11.o: $(UI)/x11/SoundX11.cxx mainSDL.o: $(UI)/sdl/mainSDL.cxx $(CXX) -c $(CXXFLAGS) $(OPTIONS) $(LDFLAGS) $(UI)/sdl/mainSDL.cxx -SndSDL.o: $(UI)/sdl/SndSDL.cxx $(UI)/sdl/SndSDL.hxx - $(CXX) -c $(CXXFLAGS) $(OPTIONS) $(LDFLAGS) $(UI)/sdl/SndSDL.cxx +SoundSDL.o: $(UI)/sdl/SoundSDL.cxx $(UI)/sdl/SoundSDL.hxx + $(CXX) -c $(CXXFLAGS) $(OPTIONS) $(LDFLAGS) $(UI)/sdl/SoundSDL.cxx RectList.o: $(UI)/sdl/RectList.cxx $(UI)/sdl/RectList.hxx $(CXX) -c $(CXXFLAGS) $(OPTIONS) $(LDFLAGS) $(UI)/sdl/RectList.cxx diff --git a/stella/src/ui/sdl/SndSDL.hxx b/stella/src/ui/sdl/SndSDL.hxx deleted file mode 100644 index 6b1e893eb..000000000 --- a/stella/src/ui/sdl/SndSDL.hxx +++ /dev/null @@ -1,77 +0,0 @@ -//============================================================================ -// -// SSSS tt lll lll -// SS SS tt ll ll -// SS tttttt eeee ll ll aaaa -// SSSS tt ee ee ll ll aa -// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" -// SS SS tt ee ll ll aa aa -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-1998 by Bradford W. Mott -// -// See the file "license" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -// -// $Id: SndSDL.hxx,v 1.1 2002-08-15 00:29:40 stephena Exp $ -//============================================================================ - -#ifndef SOUNDSDL_HXX -#define SOUNDSDL_HXX - -#include - -#include "bspf.hxx" -#include "Sound.hxx" - -/** - This class implements the sound API for SDL. - - @author Stephen Anthony - @version $Id: SndSDL.hxx,v 1.1 2002-08-15 00:29:40 stephena Exp $ -*/ -class SoundSDL : public Sound -{ - public: - /** - Create a new sound object - */ - SoundSDL(int volume, bool activate = true); - - /** - Destructor - */ - virtual ~SoundSDL(); - - public: - /** - Set the value of the specified sound register - - @param reg The sound register to set - @param val The new value for the sound registers - */ - virtual void set(Sound::Register reg, uInt8 val); - - /** - Set the mute state of the sound object - - @param state Mutes sound iff true - */ - virtual void mute(bool state); - - /** - Set the current volume according to the given percentage - - @param percent Scaled value (0-100) indicating the desired volume - */ - void setVolume(int percent); - - - private: - // Indicates if the sound system was initialized - bool myEnabled; - - // Indicates if the sound is currently muted - bool isMuted; -}; -#endif diff --git a/stella/src/ui/sdl/SndSDL.cxx b/stella/src/ui/sdl/SoundSDL.cxx similarity index 52% rename from stella/src/ui/sdl/SndSDL.cxx rename to stella/src/ui/sdl/SoundSDL.cxx index c954d06e5..bca856363 100644 --- a/stella/src/ui/sdl/SndSDL.cxx +++ b/stella/src/ui/sdl/SoundSDL.cxx @@ -13,66 +13,59 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: SndSDL.cxx,v 1.1 2002-08-15 00:29:40 stephena Exp $ +// $Id: SoundSDL.cxx,v 1.1 2002-10-11 13:07:00 stephena Exp $ //============================================================================ #include -#include "TIASound.h" -#include "SndSDL.hxx" +#include "SoundSDL.hxx" -#define FRAGSIZE 1 << 10 - -static int currentVolume = 0; +static uInt8 currentVolume; +static MediaSource* _mediaSource; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -static void fill_audio(void* udata, Uint8* stream, int len) -{ - Uint8 buffer[FRAGSIZE]; - - if(len > FRAGSIZE) - len = FRAGSIZE; - - Tia_process(buffer, len); - SDL_MixAudio(stream, buffer, len, currentVolume); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -SoundSDL::SoundSDL(int volume, bool activate) +SoundSDL::SoundSDL(bool activate) + : myIsInitializedFlag(false), + mySampleRate(31400), + myFragSize(512), + myIsMuted(true) { - myEnabled = activate; + myIsInitializedFlag = activate; - if(!myEnabled) + if(!myIsInitializedFlag) return; if(SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { cerr << "Couldn't init SDL audio system: " << SDL_GetError() << endl; - myEnabled = false; + myIsInitializedFlag = false; + mySampleRate = 0; return; } SDL_AudioSpec desired, obtained; - desired.freq = 31400; - desired.samples = FRAGSIZE; + desired.freq = mySampleRate; + desired.samples = myFragSize; desired.format = AUDIO_U8; - desired.callback = fill_audio; + desired.callback = fillAudio; desired.userdata = NULL; desired.channels = 1; if(SDL_OpenAudio(&desired, &obtained) < 0) { cerr << "Couldn't open SDL audio: " << SDL_GetError() << endl; - myEnabled = false; + myIsInitializedFlag = false; + mySampleRate = 0; return; } - - /* Initialize the TIA Sound Library */ - Tia_sound_init(31400, obtained.freq); - isMuted = false; - setVolume(volume); + myIsMuted = false; + mySampleRate = obtained.freq; + + // Take care of the static stuff ... + currentVolume = 0; + _mediaSource = (MediaSource*) NULL; SDL_PauseAudio(0); } @@ -80,69 +73,75 @@ SoundSDL::SoundSDL(int volume, bool activate) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SoundSDL::~SoundSDL() { - if(myEnabled) - SDL_CloseAudio(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void SoundSDL::set(Sound::Register reg, uInt8 value) +uInt32 SoundSDL::getSampleRate() const { - if(!myEnabled) - return; + return myIsInitializedFlag ? mySampleRate : 0; +} - switch(reg) - { - case AUDC0: - Update_tia_sound(0x15, value); - break; - - case AUDC1: - Update_tia_sound(0x16, value); - break; - - case AUDF0: - Update_tia_sound(0x17, value); - break; - - case AUDF1: - Update_tia_sound(0x18, value); - break; - - case AUDV0: - Update_tia_sound(0x19, value); - break; - - case AUDV1: - Update_tia_sound(0x1A, value); - break; - - default: - return; - break; - } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool SoundSDL::isSuccessfullyInitialized() const +{ + return myIsInitializedFlag; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void SoundSDL::mute(bool state) { - if(!myEnabled) + if(!myIsInitializedFlag) return; // Ignore multiple calls to do the same thing - if(isMuted == state) + if(myIsMuted == state) return; - isMuted = state; + myIsMuted = state; - SDL_PauseAudio(isMuted ? 1 : 0); + SDL_PauseAudio(myIsMuted ? 1 : 0); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void SoundSDL::setVolume(int percent) +void SoundSDL::close() { - if(!myEnabled) + SDL_PauseAudio(0); + + if(myIsInitializedFlag) + SDL_CloseAudio(); + + myIsInitializedFlag = false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void SoundSDL::setSoundVolume(uInt32 percent) +{ + if(!myIsInitializedFlag) return; if((percent >= 0) && (percent <= 100)) currentVolume = (int) (((float) percent / 100.0) * (float) SDL_MIX_MAXVOLUME); } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void SoundSDL::updateSound(MediaSource& mediaSource) +{ + // this is a HUGE HACK and will disappear soon + _mediaSource = &mediaSource; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void SoundSDL::fillAudio(void* udata, uInt8* stream, Int32 len) +{ + if(!_mediaSource) + return; + + uInt32 samples = _mediaSource->numberOfAudioSamples(); + if(samples == 0) + return; + + uInt8 buffer[len]; + _mediaSource->dequeueAudioSamples(buffer, len); + + SDL_MixAudio(stream, buffer, len, currentVolume); +} diff --git a/stella/src/ui/sdl/SoundSDL.hxx b/stella/src/ui/sdl/SoundSDL.hxx new file mode 100644 index 000000000..3cbf15009 --- /dev/null +++ b/stella/src/ui/sdl/SoundSDL.hxx @@ -0,0 +1,111 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-1998 by Bradford W. Mott +// +// See the file "license" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +// +// $Id: SoundSDL.hxx,v 1.1 2002-10-11 13:07:01 stephena Exp $ +//============================================================================ + +#ifndef SOUNDSDL_HXX +#define SOUNDSDL_HXX + +#include + +#include "bspf.hxx" +#include "MediaSrc.hxx" + +/** + This class implements the sound API for SDL. + + @author Stephen Anthony + @version $Id: SoundSDL.hxx,v 1.1 2002-10-11 13:07:01 stephena Exp $ +*/ +class SoundSDL +{ + public: + /** + Create a new sound object + */ + SoundSDL(bool activate = true); + + /** + Destructor + */ + virtual ~SoundSDL(); + + public: + /** + Return the playback sample rate for the sound device. + + @return The playback sample rate + */ + uInt32 getSampleRate() const; + + /** + Return true iff the sound device was successfully initlaized. + + @return true iff the sound device was successfully initlaized. + */ + bool isSuccessfullyInitialized() const; + + /** + Sets the volume of the sound device to the specified level. The + volume is given as a precentage from 0 to 100. + + @param volume The new volume for the sound device + */ + void setSoundVolume(uInt32 volume); + + /** + Update the sound device using the audio sample from the specified + media source. + + @param mediaSource The media source to get audio samples from. + */ + void updateSound(MediaSource& mediaSource); + + /** + Closes the soudn device + */ + void close(); + + /** + Set the mute state of the sound object + + @param state Mutes sound iff true + */ + void mute(bool state); + + private: + // Indicates if the sound device was successfully initialized + bool myIsInitializedFlag; + + // DSP sample rate + uInt32 mySampleRate; + + // SDL fragment size + uInt32 myFragSize; + + // Indicates if the sound is currently muted + bool myIsMuted; + + /** + Some stuff which is required to be static since the SDL audio + callback is a C-style function. + */ + private: + + static void fillAudio(void* udata, uInt8* stream, Int32 len); + +}; +#endif diff --git a/stella/src/ui/sdl/mainSDL.cxx b/stella/src/ui/sdl/mainSDL.cxx index 8bc42415a..4d306ce1f 100644 --- a/stella/src/ui/sdl/mainSDL.cxx +++ b/stella/src/ui/sdl/mainSDL.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: mainSDL.cxx,v 1.29 2002-10-05 12:49:49 stephena Exp $ +// $Id: mainSDL.cxx,v 1.30 2002-10-11 13:07:01 stephena Exp $ //============================================================================ #include @@ -36,10 +36,9 @@ #include "MediaSrc.hxx" #include "PropsSet.hxx" #include "System.hxx" -#include "SndUnix.hxx" #include "RectList.hxx" #include "Settings.hxx" -#include "SndSDL.hxx" +#include "SoundSDL.hxx" #ifdef HAVE_PNG #include "Snapshot.hxx" @@ -1563,15 +1562,16 @@ int main(int argc, char* argv[]) return 0; } - // Create a sound object for use with the console - SoundSDL sound(settings->theDesiredVolume); + // Create a sound object for playing audio + SoundSDL sound; + sound.setSoundVolume(settings->theDesiredVolume); // Get just the filename of the file containing the ROM image const char* filename = (!strrchr(file, '/')) ? file : strrchr(file, '/') + 1; // Create the 2600 game console theConsole = new Console(image, size, filename, - theEvent, propertiesSet, sound); + theEvent, propertiesSet, sound.getSampleRate()); // Free the image since we don't need it any longer delete[] image; @@ -1580,12 +1580,14 @@ int main(int argc, char* argv[]) if(!setupDisplay()) { cerr << "ERROR: Couldn't set up display.\n"; + sound.close(); cleanup(); return 0; } if(!setupJoystick()) { cerr << "ERROR: Couldn't set up joysticks.\n"; + sound.close(); cleanup(); return 0; } @@ -1623,6 +1625,7 @@ int main(int argc, char* argv[]) startTime = getTicks(); theConsole->mediaSource().update(); + sound.updateSound(theConsole->mediaSource()); updateDisplay(theConsole->mediaSource()); handleEvents(); @@ -1662,6 +1665,7 @@ int main(int argc, char* argv[]) if(!thePauseIndicator) { theConsole->mediaSource().update(); + sound.updateSound(theConsole->mediaSource()); } updateDisplay(theConsole->mediaSource()); handleEvents(); @@ -1695,6 +1699,7 @@ int main(int argc, char* argv[]) } // Cleanup time ... + sound.close(); cleanup(); return 0; }