Line data Source code
1 : #include <cstdio>
2 : #include <cstring>
3 :
4 : #include "SoundFX.h"
5 :
6 : // SoundFX()
7 : //
8 : // Class constructor.
9 28 : SoundFX::SoundFX() {
10 14 : Buffers = NULL;
11 14 : Sources = NULL;
12 14 : Num_of_SFX = 0;
13 28 : }
14 :
15 : // ~SoundFX()
16 : //
17 : // Class destructor.
18 26 : SoundFX::~SoundFX() {
19 13 : unload();
20 26 : }
21 :
22 : // load()
23 : //
24 : // Sets up OpenAL and loads all sound effect files into
25 : // memory from the sounds directory.
26 0 : void SoundFX::load() {
27 0 : if (Buffers != NULL || Sources != NULL) {
28 0 : PRINT_ERROR("Sounds already loaded; no sounds will be loaded.\n");
29 0 : return;
30 : }
31 :
32 0 : Buffers = NULL;
33 0 : Sources = NULL;
34 :
35 0 : DIR *SFXDir = opendir( "./sounds/" );
36 :
37 0 : if (SFXDir == NULL) {
38 : PRINT_DEBUG_LVL(2, "'sounds' directory not present; no sounds will be loaded.\n");
39 0 : return;
40 : }
41 :
42 : dirent *de;
43 0 : std::string files[256];
44 :
45 0 : if (SFXDir != NULL) {
46 0 : Num_of_SFX = 0;
47 0 : while ((de = readdir(SFXDir)) != NULL) {
48 0 : if ( std::strstr( de->d_name, ".ogg" ) ) {
49 0 : files[Num_of_SFX] = std::string( de->d_name );
50 0 : Num_of_SFX++;
51 0 : }
52 : }
53 0 : closedir( SFXDir );
54 0 : }
55 :
56 0 : if (Num_of_SFX < 1) {
57 : PRINT_DEBUG_LVL(2, "No sound files in the ogg format present in 'sounds' directory; no sounds will be loaded.\n");
58 0 : return;
59 : }
60 :
61 : // Init buffers and sources.
62 0 : Buffers = new ALuint[Num_of_SFX];
63 0 : Sources = new ALuint[Num_of_SFX];
64 0 : alGenBuffers( Num_of_SFX, Buffers );
65 0 : alGenSources( Num_of_SFX, Sources );
66 : char Sound_Buffer[BUFFER_SIZE];
67 :
68 : // Load sound files.
69 : char filePath[MAX_PATH_LEN];
70 :
71 0 : for ( int i = 0; i < Num_of_SFX; i++ ) {
72 : // build full path to load //
73 0 : strcpy(filePath, "./sounds/");
74 0 : strcat(filePath, files[i].c_str());
75 : PRINT_DEBUG("Loading sound file '%s'...\n", filePath);
76 :
77 0 : FILE *Music_File = fopen( filePath, "rb" );
78 :
79 0 : if (Music_File == NULL) {
80 0 : PRINT_ERROR("Could not open sound file: '%s'...\n", filePath);
81 0 : continue;
82 : }
83 :
84 : OggVorbis_File Ogg_File;
85 0 : ov_open( Music_File, &Ogg_File, NULL, 0 );
86 :
87 : // Get format infomation from the info struct.
88 : ALenum Format;
89 0 : vorbis_info *Ogg_Info = ov_info( &Ogg_File, -1 );
90 :
91 0 : if ( Ogg_Info->channels == 1 )
92 0 : Format = AL_FORMAT_MONO16;
93 : else
94 0 : Format = AL_FORMAT_STEREO16;
95 :
96 : // Fill sound buffers.
97 0 : int Size = 0;
98 0 : int Section = 0;
99 0 : while ( Size < BUFFER_SIZE ) {
100 0 : int Bytes = ov_read(
101 : &Ogg_File,
102 0 : Sound_Buffer + Size,
103 0 : BUFFER_SIZE - Size,
104 : 0, 2, 1, &Section
105 : );
106 :
107 0 : if (Bytes == 0)
108 0 : break;
109 :
110 0 : Size += Bytes;
111 : }
112 0 : alBufferData( Buffers[i], Format, Sound_Buffer, Size, Ogg_Info->rate );
113 :
114 0 : ALenum errorCode = alGetError();
115 0 : if (errorCode != AL_NO_ERROR)
116 0 : PRINT_ERROR("Could not load sound buffer data; AL error code: '%d'.\n", errorCode);
117 :
118 0 : File_Hash[ files[i] ] = i; // Create name to index map.
119 0 : SetSFX( files[i], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, AL_FALSE );
120 :
121 0 : ov_clear(&Ogg_File);
122 0 : }
123 :
124 0 : SetSFXListener( 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f );
125 0 : }
126 :
127 : // unload()
128 : //
129 : // Cleans up OpenAL buffer information.
130 26 : void SoundFX::unload() {
131 : PRINT_DEBUG("Cleaning-up sounds...\n");
132 26 : if (Buffers != NULL) {
133 0 : alDeleteBuffers( Num_of_SFX, Buffers );
134 0 : delete[] Buffers;
135 0 : Buffers = NULL;
136 0 : }
137 :
138 26 : if (Sources != NULL) {
139 0 : alDeleteSources( Num_of_SFX, Sources );
140 0 : delete[] Sources;
141 0 : Sources = NULL;
142 0 : }
143 :
144 : PRINT_DEBUG("Clean-up complete.\n");
145 26 : }
146 :
147 : // PlaySFX()
148 : //
149 : // Plays a specified sound file. Accepts a file name (not the complete path).
150 0 : void SoundFX::PlaySFX( const std::string &sfx ) {
151 0 : if (Sources == NULL)
152 0 : return;
153 :
154 : PRINT_DEBUG_LVL(1, "Playing sound (%s)\n", sfx.c_str());
155 0 : alSourcePlay( Sources[ File_Hash[sfx] ] );
156 :
157 0 : ALenum errorCode = alGetError();
158 0 : if (errorCode != AL_NO_ERROR)
159 0 : PRINT_ERROR("Could not play sound; AL error code: '%d'.\n", errorCode);
160 0 : }
161 :
162 : // SetSFX
163 : //
164 : // Sets the location, velocity, and repeat bit for a given file name. Takes
165 : // eight parameters: The name of the wav file; X, Y, and Z locational
166 : // coordinates; X, Y, and Z velocity values; and a boolean representing whether
167 : // or not the sound should be looped.
168 0 : void SoundFX::SetSFX(
169 : const std::string &sfx,
170 : const ALfloat &PosX, const ALfloat &PosY, const ALfloat &PosZ,
171 : const ALfloat &VelX, const ALfloat &VelY, const ALfloat &VelZ,
172 : const ALboolean &repeat
173 : ) {
174 0 : if (Buffers == NULL || Sources == NULL)
175 0 : return;
176 :
177 0 : ALfloat SourcePos[3] = { PosX, PosY, PosZ };
178 0 : ALfloat SourceVel[3] = { VelX, VelY, VelZ };
179 0 : int index = File_Hash[sfx];
180 :
181 0 : alSourcei ( Sources[index], AL_BUFFER, Buffers[index] );
182 0 : alSourcef ( Sources[index], AL_PITCH, 1.0f );
183 0 : alSourcef ( Sources[index], AL_GAIN, 1.0f );
184 0 : alSourcefv( Sources[index], AL_POSITION, SourcePos );
185 0 : alSourcefv( Sources[index], AL_VELOCITY, SourceVel );
186 0 : alSourcei ( Sources[index], AL_LOOPING, repeat );
187 0 : }
188 :
189 : // SetSFXListener()
190 : //
191 : // Sets the position and velocity of the listener. Takes six parameters. The
192 : // first three represent the listener's X, Y, and Z position, and the second
193 : // three represent the relative X, Y, and Z velocity.
194 0 : void SoundFX::SetSFXListener(
195 : const ALfloat &PosX, const ALfloat &PosY, const ALfloat &PosZ,
196 : const ALfloat &VelX, const ALfloat &VelY, const ALfloat &VelZ
197 : ) {
198 0 : ALfloat ListenerPos[3] = { PosX, PosY, PosZ };
199 0 : ALfloat ListenerVel[3] = { VelX, VelY, VelZ };
200 0 : ALfloat ListenerOri[6] = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f };
201 :
202 0 : alListenerfv( AL_POSITION, ListenerPos );
203 0 : alListenerfv( AL_VELOCITY, ListenerVel );
204 0 : alListenerfv( AL_ORIENTATION, ListenerOri );
205 0 : }
|