1 /// Part of my old D1 game library along with [arsd.screen] and [arsd.engine]. Do not use in new projects.
2 module arsd.audio;
3 
4 import sdl.SDL;
5 import sdl.SDL_mixer;
6 
7 import std..string;
8 
9 import arsd.engine;
10 
11 bool audioIsLoaded; // potential hack material
12 
13 class Sound {
14   public:
15 	this(char[] filename){
16 		if(!audioIsLoaded)
17 			return;
18 		sfx = Mix_LoadWAV(std..string.toStringz(filename));
19 		if(sfx is null)
20 			throw new Exception(immutableString("Sound load " ~ filename));
21 	}
22 
23 	/*
24 	this(Wav wav){
25 		auto w = wav.toMemory;
26 		SDL_RWops* a = SDL_RWFromMem(w, w.length)
27 		if(a is null) throw new Exception("sdl rw ops");
28 		scope(exit) SDL_FreeRW(a);
29 		sfx = Mix_LoadWAV_RW(a, 0);
30 		if(sfx is null) throw new Exception("loadwav rw");
31 	}
32 	*/
33 
34 	~this(){
35 		if(sfx !is null)
36 			Mix_FreeChunk(sfx);
37 	}
38 
39   private:
40 	Mix_Chunk* sfx;
41 }
42 
43 class Music {
44   public:
45 	this(char[] filename){
46 		if(!audioIsLoaded)
47 			return;
48 		mus = Mix_LoadMUS(std..string.toStringz(filename));
49 		if(mus is null)
50 			throw new Exception(immutableString("Music load " ~ filename));
51 	}
52 
53 	~this(){
54 		if(mus !is null)
55 			Mix_FreeMusic(mus);
56 	}
57   private:
58 	Mix_Music* mus;
59 }
60 
61 class Audio{
62   public:
63 	this(bool act = true){
64 		if(audioIsLoaded)
65 			throw new Exception("Cannot load audio twice");
66 
67 		if(!act){
68 			audioIsLoaded = false;
69 			active = false;
70 			return;
71 		}
72 		if(Mix_OpenAudio(22050, AUDIO_S16SYS, 2, 4096/2 /* the /2 is new */) != 0){
73 			active = false; //throw new Error;
74 			error = true;
75 			audioIsLoaded = false;
76 		} else {
77 			active = true;
78 			error = false;
79 			audioIsLoaded = true;
80 		}
81 
82 		sfxChannel = 1;
83 
84 		careAboutErrors = false;
85 	}
86 
87 	void activate(){
88 		if(!audioIsLoaded) return;
89 		if(!error)
90 			active = true;
91 	}
92 
93 	void deactivate(){
94 		if(!audioIsLoaded) return;
95 		active = false;
96 	}
97 
98 	void toggleActivation(){
99 		if(!audioIsLoaded) return;
100 		if(error)
101 			return;
102 		active = !active;
103 	}
104 
105 	~this(){
106 		if(audioIsLoaded){
107 			Mix_HaltMusic();
108 			Mix_HaltChannel(-1);
109 			Mix_CloseAudio();
110 		}
111 	}
112 
113 	void playEffect(Sound snd, bool loop = false){
114 		if(!active || snd is null)
115 			return;
116 
117 		//if(Mix_Playing(sfxChannel))
118 		//	return;
119 
120 		sfxChannel = Mix_PlayChannel(-1, snd.sfx, loop == true ? -1 : 0);
121 
122 	}
123 	void stopEffect(){
124 		if(!active)
125 			return;
126 
127 		Mix_HaltChannel(sfxChannel);
128 	}
129 
130 	void playMusic(Music mus, bool loop = true){
131 		if(!active || mus is null)
132 			return;
133 
134 		if(Mix_PlayMusic(mus.mus, loop == true ? -1 : 0) == -1)
135 			throw new Exception("play music");
136 		//	musicIsPlaying = false;
137 		else
138 			musicIsPlaying = true;
139 	}
140 
141 	void pauseMusic(){
142 		if(!active)
143 			return;
144 
145 		if(musicIsPlaying){
146 			Mix_PauseMusic();
147 			musicIsPaused = true;
148 		}
149 	}
150 
151 	void unpauseMusic(){
152 		if(!active)
153 			return;
154 
155 		if(musicIsPaused){
156 			Mix_ResumeMusic();
157 			musicIsPaused = false;
158 		}
159 	}
160 
161 	void stopMusic(){
162 		if(!active)
163 			return;
164 
165 		Mix_HaltMusic();
166 	}
167 
168 
169 	void stopAll(){
170 		if(!active)
171 			return;
172 
173 		Mix_HaltMusic();
174 		Mix_HaltChannel(-1);
175 	}
176 
177   private:
178   	int sfxChannel;
179 	bool active;
180 	bool error;
181 
182 	bool musicIsPaused;
183 	bool musicIsPlaying;
184 
185 	bool careAboutErrors;
186 }
187 
188 	int Mix_PlayChannel(int channel, Mix_Chunk* chunk, int loops) {
189 		return Mix_PlayChannelTimed(channel,chunk,loops,-1);
190 	}
191 	Mix_Chunk * Mix_LoadWAV(in char *file) {
192 		return Mix_LoadWAV_RW(SDL_RWFromFile(file, "rb"), 1);
193 	}
Suggestion Box / Bug Report