Commits

Ivan Vučica committed 88f3a4e

Added audio manager from Y.

  • Participants
  • Parent commits c82f83b

Comments (0)

Files changed (3)

Pucaljka.xcodeproj/project.pbxproj

 		7F2FD0991750F44B00643CB5 /* asteroid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7F2FD0971750F44B00643CB5 /* asteroid.cpp */; };
 		7F2FD09B1750FBF500643CB5 /* credits.png in Resources */ = {isa = PBXBuildFile; fileRef = 7F2FD09A1750FBF500643CB5 /* credits.png */; };
 		7F2FD09D1750FF6200643CB5 /* Mad_Mav_-_Torture.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 7F2FD09C1750FF6200643CB5 /* Mad_Mav_-_Torture.mp3 */; };
+		7F2FD0A01750FFB500643CB5 /* audiomgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7F2FD09E1750FFB500643CB5 /* audiomgr.cpp */; };
 		7F74A6DF1747BDCF00CE1680 /* bullet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7F74A6DD1747BDCF00CE1680 /* bullet.cpp */; };
 		7F74A6E31747BDEC00CE1680 /* backbutton.png in Resources */ = {isa = PBXBuildFile; fileRef = 7F74A6E01747BDEC00CE1680 /* backbutton.png */; };
 		7F74A6E41747BDEC00CE1680 /* bullet.png in Resources */ = {isa = PBXBuildFile; fileRef = 7F74A6E11747BDEC00CE1680 /* bullet.png */; };
 		7F2FD0981750F44B00643CB5 /* asteroid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = asteroid.h; sourceTree = SOURCE_ROOT; };
 		7F2FD09A1750FBF500643CB5 /* credits.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = credits.png; sourceTree = "<group>"; };
 		7F2FD09C1750FF6200643CB5 /* Mad_Mav_-_Torture.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = "Mad_Mav_-_Torture.mp3"; sourceTree = "<group>"; };
+		7F2FD09E1750FFB500643CB5 /* audiomgr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audiomgr.cpp; sourceTree = SOURCE_ROOT; };
+		7F2FD09F1750FFB500643CB5 /* audiomgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audiomgr.h; sourceTree = SOURCE_ROOT; };
 		7F74A6DD1747BDCF00CE1680 /* bullet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bullet.cpp; sourceTree = SOURCE_ROOT; };
 		7F74A6DE1747BDCF00CE1680 /* bullet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bullet.h; sourceTree = SOURCE_ROOT; };
 		7F74A6E01747BDEC00CE1680 /* backbutton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = backbutton.png; sourceTree = "<group>"; };
 		AF1D1E941477E6D400C95550 /* Pucaljka */ = {
 			isa = PBXGroup;
 			children = (
+				7F2FD09E1750FFB500643CB5 /* audiomgr.cpp */,
+				7F2FD09F1750FFB500643CB5 /* audiomgr.h */,
 				7F2FD0971750F44B00643CB5 /* asteroid.cpp */,
 				7F1510BB172C2A19001DEF50 /* blueenemyship.cpp */,
 				7F74A6DD1747BDCF00CE1680 /* bullet.cpp */,
 				7F1510C4172C2F69001DEF50 /* redenemyship.cpp in Sources */,
 				7F74A6DF1747BDCF00CE1680 /* bullet.cpp in Sources */,
 				7F2FD0991750F44B00643CB5 /* asteroid.cpp in Sources */,
+				7F2FD0A01750FFB500643CB5 /* audiomgr.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
+#ifndef WIN32
+    #include <err.h>
+#else
+    #define warnx
+#endif
+
+#include "audiomgr.h"
+
+#if 1
+#ifdef HAVE_SDL_MIXER
+
+#if !defined(__APPLE__)
+#include <SDL/SDL_mixer.h>
+#else
+#include <SDL_mixer/SDL_mixer.h>
+#endif
+#include "util.h"
+
+
+
+AudioMgr::AudioMgr() {
+
+	m_music = NULL;
+	initAudio();
+	m_allowSound = true;
+}
+
+AudioMgr::~AudioMgr()
+{
+	haltMusic();
+	Mix_CloseAudio();
+}
+
+
+void AudioMgr::initAudio()
+{
+	m_audioRate = 22050;
+	m_audioFormat = AUDIO_S16;
+	m_audioChannels = 2;
+	m_audioBuffers = 4096;
+
+	if(Mix_OpenAudio(m_audioRate, m_audioFormat, m_audioChannels, m_audioBuffers)) {
+		warnx("unable to open audio!");
+	}
+	Mix_ChannelFinished(AudioMgr::channelFinished);
+
+}
+
+void AudioMgr::startMusic(std::string fn)
+{
+    std::string s = y_findfile(fn.c_str(), "r");
+    if (m_musicfn == s) {
+        return;
+    }
+
+
+	if (m_music) {
+		haltMusic();
+	}
+
+
+    m_musicfn = s;
+	m_music = Mix_LoadMUS(s.c_str());
+	Mix_PlayMusic(m_music, 0);
+	if (!m_allowSound)
+        Mix_PauseMusic();
+	Mix_HookMusicFinished(musicDone);
+}
+
+void AudioMgr::haltMusic() {
+	Mix_HaltMusic();
+	Mix_FreeMusic(m_music);
+	m_musicfn = "";
+	m_music = NULL;
+}
+
+
+void AudioMgr::musicDone()
+{
+	Mix_PlayMusic(getInstance()->m_music, 0);
+}
+
+
+uint32_t AudioMgr::loadSound(std::string fn)
+{
+	int id = rand();
+	printf("Loading sound %s\n", fn.c_str());
+    std::string s = y_findfile(fn.c_str(), "r");
+
+	m_chunks[id] = Mix_LoadWAV(s.c_str());
+	return id;
+}
+
+uint32_t AudioMgr::playSound(uint32_t id, int repeat)
+{
+    if (!m_allowSound) return -1;
+	std::map<uint32_t, Mix_Chunk*>::iterator it = m_chunks.find(id);
+	if (it == m_chunks.end()) return -1;
+	int channel = Mix_PlayChannel(-1, it->second, repeat);
+	m_channels[channel] = AM_Channel(id);
+	return channel;
+}
+
+void AudioMgr::unloadSound(uint32_t id)
+{
+    if (id == -1) return;
+	std::map<uint32_t, Mix_Chunk*>::iterator it = m_chunks.find(id);
+	if (it != m_chunks.end()) {
+        Mix_FreeChunk(it->second);
+        m_chunks.erase(it);
+	}
+
+}
+
+void AudioMgr::haltSound(uint32_t channel)
+{
+	Mix_HaltChannel(channel);
+}
+
+
+void AudioMgr::unloadSounds()
+{
+	for (std::map<uint32_t, Mix_Chunk*>::iterator it = m_chunks.begin(); it != m_chunks.end(); it++) {
+		Mix_FreeChunk(it->second);
+	}
+	m_chunks.clear();
+}
+
+void AudioMgr::channelFinished(int channel)
+{
+    std::map<uint32_t, AM_Channel>::iterator chit = getInstance()->m_channels.find(channel);
+    if (chit == getInstance()->m_channels.end())
+        printf("AudioMgr::channelFinished(): channel %d not found playing\n", channel);
+    else {
+        if (chit->second.nextchunkid != -1)
+            getInstance()->m_channels[channel] = AudioMgr::getInstance()->playSound(chit->second.nextchunkid);
+        else
+            getInstance()->m_channels.erase(chit);
+    }
+    printf("AudioMgr::channelFinished(): Removed.\n");
+}
+
+void AudioMgr::attachNextSound(int channel, int nextsound)
+{
+    std::map<uint32_t, AM_Channel>::iterator chit = m_channels.find(channel);
+    if (chit == m_channels.end())
+        printf("AudioMgr::attachNextSound(): channel %d not found playing\n", channel);
+    else
+        chit->second.nextchunkid = nextsound;
+
+}
+void AudioMgr::enableSound(bool enabled)
+{
+    m_allowSound = enabled;
+    if (!m_allowSound) {
+        Mix_PauseMusic();
+    } else {
+        Mix_ResumeMusic();
+    }
+}
+#endif
+
+
+#else
+
+AudioMgr::AudioMgr()
+{
+}
+
+AudioMgr::~AudioMgr()
+{
+}
+
+void AudioMgr::initAudio()
+{
+}
+
+void AudioMgr::startMusic(std::string fn)
+{
+}
+
+void AudioMgr::haltMusic()
+{
+}
+
+void AudioMgr::musicDone()
+{
+}
+
+uint32_t AudioMgr::loadSound(std::string fn)
+{
+}
+
+uint32_t AudioMgr::playSound(uint32_t id, int repeat)
+{
+}
+
+void AudioMgr::unloadSound(uint32_t id)
+{
+}
+
+void AudioMgr::haltSound(uint32_t channel)
+{
+}
+
+void AudioMgr::unloadSounds()
+{
+}
+
+void AudioMgr::channelFinished(int channel)
+{
+}
+
+void AudioMgr::attachNextSound(int,int)
+{
+}
+
+void AudioMgr::enableSound(bool enabled)
+{
+}
+
+#endif
+#ifndef __Y_AUDIOMGR_H
+#define __Y_AUDIOMGR_H
+
+#include <string>
+
+#ifdef HAVE_SDL_MIXER
+
+
+#if !defined(__APPLE__)
+#include <SDL/SDL_mixer.h>
+#else
+#include <SDL_mixer/SDL_mixer.h>
+#endif
+#include <stdint.h>
+#include <map>
+
+struct AM_Channel {
+    AM_Channel () : chunkid(-1), nextchunkid(-1) {
+
+    }
+    AM_Channel (int _chunkid, int _nextchunkid=-1) : chunkid(_chunkid), nextchunkid(_nextchunkid) {
+
+    }
+
+    int chunkid;
+    int nextchunkid;
+};
+
+class AudioMgr {
+	public:
+		~AudioMgr();
+
+		static AudioMgr* getInstance() { static AudioMgr* am=0; if (!am) am = new AudioMgr; return am; }
+		void initAudio();
+		void startMusic(std::string fn);
+		void haltMusic();
+
+		uint32_t loadSound(std::string fn);
+		uint32_t playSound(uint32_t id, int repeat=0);
+		void unloadSound(uint32_t id);
+		void haltSound(uint32_t channel);
+		void unloadSounds();
+
+        static void channelFinished(int channel);
+
+        void attachNextSound(int channel, int nextsound);
+
+        void toggleSound() { enableSound(!m_allowSound); }
+        void enableSound(bool enabled);
+        bool isEnabledSound() { return m_allowSound; }
+	private:
+		AudioMgr();
+
+		static void musicDone();
+
+		int m_audioRate;
+		uint16_t m_audioFormat;
+		int m_audioChannels;
+		int m_audioBuffers;
+
+        std::string m_musicfn;
+		Mix_Music *m_music;
+		std::map<uint32_t, Mix_Chunk*> m_chunks;
+		std::map<uint32_t, AM_Channel> m_channels;
+		bool m_allowSound;
+
+};
+
+#else
+class AudioMgr {
+	public:
+		~AudioMgr() {}
+
+		static AudioMgr* getInstance() { static AudioMgr* am=0; if (!am) am = new AudioMgr; return am; }
+		void initAudio() {}
+		void startMusic(std::string fn) {}
+		void haltMusic() {}
+
+		uint32_t loadSound(std::string fn) {return 0;}
+		uint32_t playSound(uint32_t id, int repeat=0) {return 0;}
+		void unloadSound(uint32_t id) {}
+		void haltSound(uint32_t channel) {}
+		void unloadSounds() {}
+
+		void attachNextSound(int channel, int nextsound) {}
+        void toggleSound() {  }
+        void enableSound(bool enabled) {}
+        bool isEnabledSound() { return false; }
+
+	private:
+		AudioMgr() {}
+
+};
+
+
+#endif
+
+#endif