Browse Source

Added Sound without many changes made.

Now using std::vector instead of fixed size arrays.
Thomas Buck 10 years ago
parent
commit
420e8b75af
3 changed files with 339 additions and 0 deletions
  1. 104
    0
      include/Sound.h
  2. 1
    0
      src/CMakeLists.txt
  3. 234
    0
      src/Sound.cpp

+ 104
- 0
include/Sound.h View File

@@ -0,0 +1,104 @@
1
+/*!
2
+ * \file include/Sound.h
3
+ * \brief This is the audio manager Header
4
+ *
5
+ * \author xythobuz
6
+ * \author Mongoose
7
+ */
8
+
9
+#ifndef _SOUND_H_
10
+#define _SOUND_H_
11
+
12
+#include <vector>
13
+
14
+/*!
15
+ * \brief This is the audio manager for OpenRaider
16
+ */
17
+class Sound {
18
+public:
19
+
20
+    typedef enum {
21
+        SoundFlagsNone = 0,       //!< No effect
22
+        SoundFlagsLoop = (1 << 0) //!< Enable looping during playback
23
+    } SoundFlags;
24
+
25
+    /*!
26
+     * \brief Constructs an object of Sound
27
+     */
28
+    Sound();
29
+
30
+    /*!
31
+     * \brief Deconstructs an object of Sound
32
+     */
33
+    ~Sound();
34
+
35
+    /*!
36
+     * \brief Initialize sound system
37
+     * \returns 0 on success or < 0 error flags
38
+     */
39
+    int init();
40
+
41
+    /*!
42
+     * \brief Get number of registered sources
43
+     * \returns number of registered sources
44
+     */
45
+    int registeredSources();
46
+
47
+    /*!
48
+     * \brief Move listener and repositions them
49
+     * \param pos New position for listener
50
+     * \param angle New orientation for listener
51
+     */
52
+    void listenAt(float pos[3], float angle[3]);
53
+
54
+    /*!
55
+     * \brief Move sound source to position
56
+     * \param source valid source id
57
+     * \param pos new position for source
58
+     */
59
+    void sourceAt(int source, float pos[3]);
60
+
61
+    /*!
62
+     * \brief Load wav file from disk
63
+     * \param filename not NULL!
64
+     * \param source not NULL! Returns new source ID or -1 on error.
65
+     * \param flags set options. Use SoundFlags enum bitwise OR-ed
66
+     * \returns 0 for no error or < 0 error flag
67
+     */
68
+    int addFile(const char *filename, int *source, unsigned int flags);
69
+
70
+    /*!
71
+     * \brief Load wav file from buffer
72
+     * \param wav not NULL! Is a valid waveform buffer!
73
+     * \param length length of wav buffer
74
+     * \param source not NULL! Returns new source ID or -1 on error.
75
+     * \param flags set options. Use SoundFlags enum bitwise OR-ed
76
+     * \returns 0 for no error or < 0 error flag
77
+     */
78
+    int addWave(unsigned char *wav, unsigned int length, int *source, unsigned int flags);
79
+
80
+    /*!
81
+     * \brief Remove all loaded sounds
82
+     */
83
+    void clear();
84
+
85
+    /*!
86
+     * \brief Play sound source
87
+     * \param source sound source to play
88
+     */
89
+    void play(int source);
90
+
91
+    /*!
92
+     * \brief Stop playing sound source
93
+     * \param source sound source to stop
94
+     */
95
+    void stop(int source);
96
+
97
+private:
98
+
99
+    bool mInit;                        //!< Guard to ensure ausio system is active
100
+    std::vector<unsigned int> mBuffer; //!< Audio buffer id list
101
+    std::vector<unsigned int> mSource; //!< Audio source id list
102
+};
103
+
104
+#endif

+ 1
- 0
src/CMakeLists.txt View File

@@ -1,5 +1,6 @@
1 1
 # Set Source files
2 2
 set (SRCS ${SRCS} "main.cpp")
3
+set (SRCS ${SRCS} "Sound.cpp")
3 4
 
4 5
 #################################################################
5 6
 

+ 234
- 0
src/Sound.cpp View File

@@ -0,0 +1,234 @@
1
+/*!
2
+ * \file src/Sound.cpp
3
+ * \brief This is the audio manager Implementation
4
+ *
5
+ * \author xythobuz
6
+ * \author Mongoose
7
+ */
8
+
9
+#ifdef __APPLE__
10
+#include <OpenAL/al.h>
11
+#else
12
+#include <AL/al.h>
13
+#endif
14
+
15
+#include <AL/alut.h>
16
+
17
+#include <time.h>
18
+#include <stdio.h>
19
+#include <stdlib.h>
20
+#include <sys/time.h>
21
+#include <sys/types.h>
22
+#include <sys/stat.h>
23
+#include <fcntl.h>
24
+#include <unistd.h>
25
+#include <assert.h>
26
+
27
+#include "Sound.h"
28
+
29
+Sound::Sound() {
30
+    mInit = false;
31
+}
32
+
33
+Sound::~Sound() {
34
+    if (mInit)
35
+        alutExit();
36
+}
37
+
38
+int Sound::init() {
39
+#ifndef __APPLE__
40
+    int fd;
41
+
42
+    fd = open("/dev/dsp", O_RDWR);
43
+
44
+    if (fd < 0) {
45
+        perror("Sound::Init> Could not open /dev/dsp : ");
46
+        return -1;
47
+    }
48
+
49
+    close(fd);
50
+#endif
51
+
52
+    ALCdevice *Device = alcOpenDevice("OSS");
53
+    ALCcontext *Context = alcCreateContext(Device, NULL);
54
+    alcMakeContextCurrent(Context);
55
+
56
+    if (alutInitWithoutContext(NULL, NULL) == AL_FALSE) {
57
+        printf("Sound::Init> Could not initialize alut (%s)\n", alutGetErrorString(alutGetError()));
58
+        return -2;
59
+    }
60
+
61
+    mInit = true;
62
+    printf("Created OpenAL Context\n");
63
+
64
+    return 0;
65
+}
66
+
67
+int Sound::registeredSources() {
68
+    assert(mInit == true);
69
+    assert(mSource.size() == mBuffer.size());
70
+
71
+    return mSource.size();
72
+}
73
+
74
+void Sound::listenAt(float pos[3], float angle[3]) {
75
+    assert(mInit == true);
76
+    assert(mSource.size() == mBuffer.size());
77
+    assert(pos != NULL);
78
+    assert(angle != NULL);
79
+
80
+    alListenerfv(AL_POSITION, pos);
81
+    alListenerfv(AL_ORIENTATION, angle);
82
+}
83
+
84
+void Sound::sourceAt(int source, float pos[3]) {
85
+    assert(mInit == true);
86
+    assert(mSource.size() == mBuffer.size());
87
+    assert(source >= 0);
88
+    assert(source < (int)mSource.size());
89
+    assert(pos != NULL);
90
+
91
+    alSourcefv(mSource[source], AL_POSITION, pos);
92
+}
93
+
94
+//! \fixme Seperate sourcing and buffering, Mongoose 2002.01.04
95
+int Sound::addFile(const char *filename, int *source, unsigned int flags)
96
+{
97
+    ALsizei size;
98
+    ALfloat freq;
99
+    ALenum format;
100
+    ALvoid *data;
101
+    int id;
102
+
103
+    assert(mInit == true);
104
+    assert(mSource.size() == mBuffer.size());
105
+    assert(filename != NULL);
106
+    assert(filename[0] != '\0');
107
+    assert(source != NULL);
108
+
109
+    *source = -1;
110
+    id = mSource.size();
111
+
112
+    alGetError();
113
+    alGenBuffers(1, &mBuffer[id]);
114
+    if (alGetError() != AL_NO_ERROR) {
115
+        fprintf(stderr, "Sound::AddFile> alGenBuffers call failed\n");
116
+        return -1;
117
+    }
118
+
119
+    alGetError();
120
+    alGenSources(1, &mSource[id]);
121
+    if (alGetError() != AL_NO_ERROR) {
122
+        fprintf(stderr, "Sound::AddFile> alGenSources call failed\n");
123
+        return -2;
124
+    }
125
+
126
+    // err = alutLoadWAV(filename, &data, &format, &size, &bits, &freq);
127
+    // is deprecated!
128
+    data = alutLoadMemoryFromFile(filename, &format, &size, &freq);
129
+    if (alutGetError() != ALUT_ERROR_NO_ERROR) {
130
+        fprintf(stderr, "Could not load %s\n", filename);
131
+        return -3;
132
+    }
133
+
134
+    alBufferData(mBuffer[id], format, data, size, static_cast<ALsizei>(freq));
135
+    alSourcei(mSource[id], AL_BUFFER, mBuffer[id]);
136
+
137
+    if (flags & SoundFlagsLoop) {
138
+        alSourcei(mSource[id], AL_LOOPING, 1);
139
+    }
140
+
141
+    *source = id;
142
+
143
+    return 0;
144
+}
145
+
146
+int Sound::addWave(unsigned char *wav, unsigned int length, int *source, unsigned int flags) {
147
+    ALsizei size;
148
+    ALfloat freq;
149
+    ALenum format;
150
+    ALvoid *data;
151
+    int error = 0;
152
+    int id;
153
+
154
+    assert(mInit == true);
155
+    assert(mSource.size() == mBuffer.size());
156
+    assert(wav != NULL);
157
+    assert(source != NULL);
158
+
159
+    *source = -1;
160
+    id = mSource.size();
161
+
162
+    data = wav;
163
+
164
+    alGetError();
165
+    alGenBuffers(1, &mBuffer[id]);
166
+    if (alGetError() != AL_NO_ERROR) {
167
+        fprintf(stderr, "Sound::AddWave> alGenBuffers call failed\n");
168
+        return -1;
169
+    }
170
+
171
+    alGetError();
172
+    alGenSources(1, &mSource[id]);
173
+    if (alGetError() != AL_NO_ERROR) {
174
+        fprintf(stderr, "Sound::AddWave> alGenSources call failed\n");
175
+        return -2;
176
+    }
177
+
178
+    //AL_FORMAT_WAVE_EXT does not exist on Mac!"
179
+    // alBufferData(mBuffer[id], AL_FORMAT_WAVE_EXT, data, size, freq);
180
+    // Idea: Fill Buffer with
181
+    // alutLoadMemoryFromFileImage
182
+    //     (const ALvoid *data, ALsizei length, ALenum *format, ALsizei *size, ALfloat *frequency)
183
+
184
+    data = alutLoadMemoryFromFileImage(wav, length, &format, &size, &freq);
185
+    if (((error = alutGetError()) != ALUT_ERROR_NO_ERROR) || (data == NULL)) {
186
+        fprintf(stderr, "Could not load wav buffer (%s)\n", alutGetErrorString(error));
187
+        return -3;
188
+    }
189
+
190
+    alBufferData(mBuffer[id], format, data, size, static_cast<ALsizei>(freq));
191
+    alSourcei(mSource[id], AL_BUFFER, mBuffer[id]);
192
+
193
+    if (flags & SoundFlagsLoop) {
194
+        alSourcei(mSource[id], AL_LOOPING, 1);
195
+    }
196
+
197
+    *source = id;
198
+
199
+    //! \fixme Should free alut buffer?
200
+
201
+    return 0;
202
+}
203
+
204
+void Sound::clear() {
205
+    assert(mInit == true);
206
+    assert(mSource.size() == mBuffer.size());
207
+
208
+    for (size_t i = 0; i < mSource.size(); i++) {
209
+        alDeleteSources(1, &mSource[i]);
210
+        alDeleteBuffers(1, &mBuffer[i]);
211
+    }
212
+
213
+    mSource.clear();
214
+    mBuffer.clear();
215
+}
216
+
217
+void Sound::play(int source) {
218
+    assert(mInit == true);
219
+    assert(mSource.size() == mBuffer.size());
220
+    assert(source >= 0);
221
+    assert(source < (int)mSource.size());
222
+
223
+    alSourcePlay(mSource[source]);
224
+}
225
+
226
+void Sound::stop(int source) {
227
+    assert(mInit == true);
228
+    assert(mSource.size() == mBuffer.size());
229
+    assert(source >= 0);
230
+    assert(source < (int)mSource.size());
231
+
232
+    alSourceStop(mSource[source]);
233
+}
234
+

Loading…
Cancel
Save