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