]>
Dogcows Code - chaz/yoink/blob - src/Moof/Sound.cc
2 /*******************************************************************************
4 Copyright (c) 2009, Charles McGarvey
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
10 * Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *******************************************************************************/
32 #include <SDL/SDL_sound.h>
36 #include "Mippleton.hh"
39 #define BUFFER_SIZE (8 * 4096)
47 static ALenum
getAudioFormat(const Sound_AudioInfo
& audioInfo
)
49 if (audioInfo
.format
== AUDIO_U8
|| audioInfo
.format
== AUDIO_S8
)
51 if (audioInfo
.channels
== 1) return AL_FORMAT_MONO8
;
52 else return AL_FORMAT_STEREO8
;
56 if (audioInfo
.channels
== 1) return AL_FORMAT_MONO16
;
57 else return AL_FORMAT_STEREO16
;
61 struct Buffer
: public Mippleton
<Buffer
>
63 Buffer(const std::string
& name
) :
64 Mippleton
<Buffer
>(name
)
73 alDeleteBuffers(2, objects
);
75 if (sound
) Sound_FreeSample(sound
);
79 void loadFromFile(const std::string
& filePath
, bool stream
)
81 if (objects
[0] != 0) return;
83 sound
= Sound_NewSampleFromFile(filePath
.c_str(),
88 logWarning("error while loading sound %s: %s", getName().c_str(), Sound_GetError());
89 throw Exception(Exception::FILE_NOT_FOUND
);
94 unsigned decoded
= Sound_DecodeAll(sound
);
97 logWarning("decoded no bytes from %s", getName().c_str());
98 //throw Exception(Exception::FILE_NOT_FOUND);
102 alGenBuffers(2, objects
);
103 alBufferData(objects
[0], getAudioFormat(sound
->actual
), sound
->buffer
,
104 sound
->buffer_size
, sound
->actual
.rate
);
105 logDebug("buffer size: %d", sound
->buffer_size
);
106 logDebug(" channels: %d", sound
->actual
.channels
);
107 logDebug(" format: %d", sound
->actual
.format
);
108 logDebug(" frequency: %d", sound
->actual
.rate
);
110 Sound_FreeSample(sound
);
115 logDebug("buffer size: %d", sound
->buffer_size
);
116 logDebug(" channels: %d", sound
->actual
.channels
);
117 logDebug(" format: %d", sound
->actual
.format
);
118 logDebug(" frequency: %d", sound
->actual
.rate
);
119 alGenBuffers(2, objects
);
123 bool stream(ALuint buffer
)
125 int bytes
= Sound_Decode(sound
);
127 if (bytes
< BUFFER_SIZE
) return false;
129 alBufferData(buffer
, getAudioFormat(sound
->actual
), sound
->buffer
,
130 sound
->buffer_size
, sound
->actual
.rate
);
137 //ALfloat location[] = {0.0f, 0.0f, 0.0f};
138 //ALfloat location2[] = {0.0f, 0.0f, 0.0f};
139 //ALfloat orient[] = {0.0f, 0.0f, -1.0f, 0.0, 1.0, 0.0};
142 //alListenerfv(AL_POSITION, location);
143 //alListenerfv(AL_VELOCITY, location);
144 //alListenerfv(AL_VELOCITY, orient);
147 Impl(const std::string
& name
, bool stream
= false) :
148 buffer_(Buffer::getInstance(name
))
150 if (!stream
) buffer_
->loadFromFile(Sound::getPath(name
), stream
);
151 else buffer_
->loadFromFile(SoundStream::getPath(name
), stream
);
153 ALfloat location
[] = {0.0f
, 0.0f
, 0.0f
};
155 alGenSources(1, &source_
);
157 alSourcef(source_
, AL_PITCH
, 1.0f
);
158 alSourcef(source_
, AL_GAIN
, 1.0f
);
159 alSourcefv(source_
, AL_POSITION
, location
);
160 alSourcefv(source_
, AL_VELOCITY
, location
);
161 alSourcei(source_
, AL_LOOPING
, AL_FALSE
);
165 alSourcei(source_
, AL_BUFFER
, buffer_
->objects
[0]);
169 buffer_
->stream(buffer_
->objects
[0]);
170 buffer_
->stream(buffer_
->objects
[1]);
172 alSourceQueueBuffers(source_
, 2, buffer_
->objects
);
178 alDeleteSources(1, &source_
);
186 alGetSourcei(source_
, AL_BUFFERS_PROCESSED
, &finished
);
188 while (finished
-- > 0)
192 alSourceUnqueueBuffers(source_
, 1, &buffer
);
193 buffer_
->stream(buffer
);
194 alSourceQueueBuffers(source_
, 1, &buffer
);
199 boost::shared_ptr
<Buffer
> buffer_
;
205 Sound::Sound(const std::string
& name
) :
207 impl_(new Sound::Impl(name
)) {}
212 if (!impl_
->buffer_
->sound
) return;
214 //alSourceRewind(impl_->source_);
215 alSourcePlay(impl_
->source_
);
216 impl_
->playing
= true;
221 alSourcePause(impl_
->source_
);
222 impl_
->playing
= false;
225 void Sound::togglePlayPause()
227 if (impl_
->playing
) pause();
231 void Sound::setGain(Scalar gain
)
233 alSourcef(impl_
->source_
, AL_GAIN
, gain
);
237 std::string
Sound::getPath(const std::string
& name
)
239 std::string path
= Resource::getPath("sounds/" + name
+ ".ogg");
244 //##############################################################################
247 SoundStream::SoundStream(const std::string
& name
)
249 //impl_(name, true) {}
251 impl_
= boost::shared_ptr
<Sound::Impl
>(new Sound::Impl(name
, true));
255 void SoundStream::update(Scalar t
, Scalar dt
)
262 std::string
SoundStream::getPath(const std::string
& name
)
264 std::string path
= Resource::getPath("sounds/" + name
+ ".xm");
271 /** vim: set ts=4 sw=4 tw=80: *************************************************/
This page took 0.045374 seconds and 4 git commands to generate.