1 /***************************************************************************
2   alienBlaster
3   Copyright (C) 2004
4   Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
5 
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10 
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15 
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 ***************************************************************************/
20 using namespace std;
21 
22 #include "mixer.h"
23 #include "SDL_mixer.h"
24 #include <string>
25 #include <fstream>
26 #include <iostream>
27 
28 Mixer mixer;
29 
Mixer()30 Mixer::Mixer() {
31     if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
32       printf("Couldn't initialize SDL audio subsystem: %s\n", SDL_GetError());
33       exit(1);
34     }
35 	mixChunks = MixChunks(0);
36 	musics = Musics(0);
37 	enabled = false;
38 	initMixer();
39 	lastUsedReservedChannel = 0;
40 	reservedChannels = 0;
41 	musicPlaying = MUSIC_NONE;
42 }
43 
~Mixer()44 Mixer::~Mixer() {
45 	if (enabled) {
46 		freeMixer();
47 	}
48 }
49 
initMixer()50 void Mixer::initMixer() {
51 	enabled = (Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 1, 1024) >= 0);
52 	if (enabled) {
53 		Mix_AllocateChannels(MIXER_NUMBER_CHANNELS);
54 		reservedChannels = Mix_ReserveChannels( MIXER_RESERVED_CHANNELS );
55 		if ( MIXER_RESERVED_CHANNELS != reservedChannels )
56 			cout << "reserve channels not successfull: reserved: " << reservedChannels << endl;
57 		lastUsedReservedChannel = 0;
58 		fn2snd.clear();
59 		fn2mus.clear();
60 		playsOn.clear();
61 	}
62 }
63 
freeMixer()64 void Mixer::freeMixer() {
65 	if (enabled) {
66 		Mix_ExpireChannel(-1, 0);
67 		for (unsigned int index = 0; index < mixChunks.size(); index++) {
68 			Mix_FreeChunk(mixChunks[index]);
69 		}
70 		for (unsigned int index = 0; index < musics.size(); index++) {
71 			Mix_FreeMusic(musics[index]);
72 		}
73 	}
74 }
75 
loadSample(string fileName,int volume)76 int Mixer::loadSample(string fileName, int volume) {
77 	if (enabled) {
78 		if (fn2snd.find(fileName) == fn2snd.end()) {
79 			// open the file for reading
80 			ifstream inputFile ( fileName.c_str(), ios::in);
81 			if (!inputFile.good()) {
82 				cout << "ERROR: file " << fileName << " does not exist!" << endl;
83 				exit(1);
84 			}
85 			mixChunks.push_back(Mix_LoadWAV(fileName.c_str()));
86 			fn2snd[ fileName ] = mixChunks.size() - 1;
87 			if ( 0 <= volume && volume < 128 ) {
88 				Mix_VolumeChunk( mixChunks[ mixChunks.size() - 1 ], volume );
89 			}
90 			return mixChunks.size() - 1;
91 		}
92 		return fn2snd[ fileName ];
93 	}
94 	return 0;
95 }
96 
97 
playSample(int sampleId,int loop,bool withPriority)98 bool Mixer::playSample( int sampleId, int loop, bool withPriority ) {
99 	int ret = -1;
100 	if (enabled) {
101 		if ( !withPriority || reservedChannels == 0 ) {
102 			ret = Mix_PlayChannel(-1, mixChunks[sampleId], loop);
103 			playsOn[ sampleId ] = ret;
104 		} else {
105 			lastUsedReservedChannel = (lastUsedReservedChannel+1) % reservedChannels;
106 			ret = Mix_PlayChannel( lastUsedReservedChannel, mixChunks[sampleId], loop );
107 			playsOn[ sampleId ] = ret;
108 		}
109 		//if ( ret == -1 ) cout << "playSample: error: " << Mix_GetError() << endl;
110 		return ret != -1;
111 	}
112 	return true;
113 }
114 
stopSample(int sampleId)115 bool Mixer::stopSample(int sampleId) {
116 	if (enabled) {
117 		return Mix_HaltChannel( playsOn[sampleId] ) != -1;
118 	}
119 	return true;
120 }
121 
reset()122 void Mixer::reset() {
123 	freeMixer();
124 	if (enabled) {
125 		initMixer();
126 	}
127 }
128 
fadeOut(int mSecs)129 void Mixer::fadeOut(int mSecs) {
130 	if (enabled) {
131 		Mix_FadeOutChannel(-1, mSecs);
132 	}
133 }
134 
135 
loadMusic(string fn)136 int Mixer::loadMusic( string fn ) {
137 	if (enabled) {
138 		if (fn2mus.find(fn) == fn2mus.end()) {
139 			// open the file for reading
140 			ifstream inputFile ( fn.c_str(), ios::in);
141 			if (!inputFile.good()) {
142 				cout << "ERROR: file " << fn << " does not exist!" << endl;
143 				exit(1);
144 			}
145 
146 			musics.push_back(Mix_LoadMUS(fn.c_str()));
147 			fn2mus[ fn ] = musics.size() - 1;
148 			return musics.size() - 1;
149 		}
150 		return fn2mus[ fn ];
151 	}
152 	return 0;
153 }
154 
playMusic(MusicTracks musNum,int loop,int fadeInTime)155 void Mixer::playMusic( MusicTracks musNum, int loop, int fadeInTime ) {
156 	if (enabled) {
157 		if ( musNum < NR_MUSIC_TRACKS ) {
158 			Mix_FadeInMusic( musics[ loadMusic( FN_MUSIC[ (int)musNum ] ) ], loop, fadeInTime );
159 			musicPlaying = musNum;
160 		}
161 	}
162 }
163 
stopMusic(int fadeOutTime)164 void Mixer::stopMusic( int fadeOutTime ) {
165 	if (enabled) {
166 		Mix_FadeOutMusic( fadeOutTime );
167 	}
168 }
169 
whichMusicPlaying()170 MusicTracks Mixer::whichMusicPlaying() {
171 	return musicPlaying;
172 }
173