1 /******************************************************************************************
2  *
3  * HighNoon - Duell im All
4  * Copyright (c) 2005, 2006 Patrick Gerdsmeier <patrick@gerdsmeier.net>
5  *
6  * "sound.hpp"
7  *
8  *
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2, or (at your option)
13  * any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  ******************************************************************************************/
25 
26 #include <iostream>
27 
28 #include "sound.hpp"
29 
30 #ifdef __clang__
31 #pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare"
32 #endif
33 
34 Soundset::Sample Soundset::sounds[ NUMBEROFCHANNELS ];
35 bool Soundset::soundOn = true;
36 
Soundset()37 Soundset::Soundset()
38 {
39 	verbose( "Initializing Soundset" );
40 
41 	char* SOUNDSETNAMES[] = {
42 		(char*)"/usr/local/share/highmoon/snd/explosion.wav",	// 0
43 		(char*)"/usr/local/share/highmoon/snd/laser.wav",    	// 1
44 		(char*)"/usr/local/share/highmoon/snd/applause.wav",	// 2
45 		(char*)"/usr/local/share/highmoon/snd/curve.wav", 	// 3
46 		(char*)"/usr/local/share/highmoon/snd/kling.wav", 	// 4
47 		(char*)"/usr/local/share/highmoon/snd/pluck.wav", 	// 5
48 		(char*)"/usr/local/share/highmoon/snd/strom.wav",	// 6
49 		(char*)"/usr/local/share/highmoon/snd/click.wav" };	// 7
50 
51 	for ( int i=0; i < _SOUNDSETNAMES; i++ ) {
52 		loadAudio( SOUNDSETNAMES[i], i );
53 	}
54 
55 	soundOn = true;
56 
57 	start();
58 }
59 
~Soundset()60 Soundset::~Soundset()
61 {
62 	verbose( "Deleting Soundset" );
63 
64 	SDL_CloseAudio();
65 
66 	for ( int i=0; i < _SOUNDSETNAMES; i++ )
67 		free( cvt[i].buf );
68 }
69 
toggle()70 void Soundset::toggle()
71 {
72 	verbose( "Toggling Sound" );
73 
74 	soundOn = !soundOn;
75 }
76 
play(SoundId id)77 void Soundset::play(SoundId id)
78 {
79 	if ( id >= 0 && id <= _SOUNDSETNAMES ) {
80 		int index;
81 
82 		// einen leeren Audio-Slot suchen
83 		for ( index=0; index < NUMBEROFCHANNELS; ++index )
84 			if ( sounds[index].dpos == sounds[index].dlen )
85 				break;
86 
87 		if ( index < NUMBEROFCHANNELS ) {
88 
89 			SDL_LockAudio();
90 			sounds[index].data = cvt[id].buf;
91 			sounds[index].dlen = cvt[id].len_cvt;
92 			sounds[index].dpos = 0;
93 			SDL_UnlockAudio();
94 		}
95 	}
96 }
97 
start()98 void Soundset::start()
99 {
100 	format.freq = 22050;
101 	format.format = AUDIO_S16;
102 	format.channels = 2;
103 	format.samples = 512;
104 	format.callback = &(Soundset::mixAudio);
105 	format.userdata = NULL;
106 
107 	if ( SDL_OpenAudio(&format, NULL) < 0 ) {
108 		std::cout << "Error in Sound: " << SDL_GetError() << std::endl;
109 		exit(1);
110 	}
111 
112 	SDL_PauseAudio(0);
113 }
114 
loadAudio(char * filename,int id)115 void Soundset::loadAudio( char *filename, int id )
116 {
117 	SDL_AudioSpec wave;
118 	Uint8 *data;
119 	Uint32 dlen;
120 
121 	// Audio-Datei laden und nach 16 Bit und 22KHz wandeln
122 	if ( SDL_LoadWAV(filename, &wave, &data, &dlen) == NULL ) {
123 		std::cout << "Error in Sound: " << SDL_GetError() << std::endl;
124 		exit(1);
125 	}
126 
127 	SDL_BuildAudioCVT( &cvt[id], wave.format, wave.channels, wave.freq, AUDIO_S16, 2, 22050 );
128 	cvt[id].buf = (Uint8*)malloc( dlen*cvt[id].len_mult );
129 	memcpy( cvt[id].buf, data, dlen );
130 
131 	cvt[id].len = dlen;
132 	SDL_ConvertAudio(&cvt[id]);
133 	SDL_FreeWAV(data);
134 }
135 
mixAudio(void *,Uint8 * stream,int length)136 void Soundset::mixAudio( void *, Uint8 *stream, int length )
137 {
138 	for ( int i=0; i < NUMBEROFCHANNELS; ++i ) {
139 		Uint32 size = (sounds[i].dlen-sounds[i].dpos);
140 
141 		if ( size > (Uint32)length ) size = length;
142 
143 		SDL_MixAudio( stream, &sounds[i].data[ sounds[i].dpos ], size,
144 			(soundOn) ? SDL_MIX_MAXVOLUME : 0 );
145 		sounds[i].dpos += size;
146 	}
147 }
148 
149