Skip to content

Commit

Permalink
SOUND: Use ScopedPtr/ScopedArray in the SoundManager
Browse files Browse the repository at this point in the history
  • Loading branch information
DrMcCoy committed Oct 29, 2016
1 parent 8bca0a7 commit 8692d1f
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 61 deletions.
111 changes: 52 additions & 59 deletions src/sound/sound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
#include <cassert>
#include <cstring>

#include "src/common/readstream.h"
#include <boost/scope_exit.hpp>

#include "src/common/util.h"
#include "src/common/readstream.h"
#include "src/common/strutil.h"
#include "src/common/error.h"

Expand Down Expand Up @@ -61,9 +63,6 @@ SoundManager::~SoundManager() {
}

void SoundManager::init() {
for (size_t i = 0; i < kChannelCount; i++)
_channels[i] = 0;

for (size_t i = 0; i < kSoundTypeMAX; i++)
_types[i].gain = 1.0f;

Expand Down Expand Up @@ -181,21 +180,21 @@ bool SoundManager::isPlaying(size_t channel) const {
alGetSourcei(_channels[channel]->source, AL_SOURCE_STATE, &val);
if ((error = alGetError()) != AL_NO_ERROR)
throw Common::Exception("OpenAL error while getting source state in %s: 0x%X",
formatChannel(_channels[channel]).c_str(), error);
formatChannel(_channels[channel].get()).c_str(), error);

if (val != AL_PLAYING) {
if (!_channels[channel]->stream || _channels[channel]->stream->endOfStream()) {
ALint buffersQueued;
alGetSourcei(_channels[channel]->source, AL_BUFFERS_QUEUED, &buffersQueued);
if ((error = alGetError()) != AL_NO_ERROR)
throw Common::Exception("OpenAL error while getting queued buffers in %s: 0x%X",
formatChannel(_channels[channel]).c_str(), error);
formatChannel(_channels[channel].get()).c_str(), error);

ALint buffersProcessed;
alGetSourcei(_channels[channel]->source, AL_BUFFERS_PROCESSED, &buffersProcessed);
if ((error = alGetError()) != AL_NO_ERROR)
throw Common::Exception("OpenAL error while getting processed buffers in %s: 0x%X",
formatChannel(_channels[channel]).c_str(), error);
formatChannel(_channels[channel].get()).c_str(), error);

if (buffersQueued == buffersProcessed)
return false;
Expand Down Expand Up @@ -312,7 +311,13 @@ ChannelHandle SoundManager::playAudioStream(AudioStream *audStream, SoundType ty

ChannelHandle handle = newChannel();

_channels[handle.channel] = new Channel;
bool success = false;
BOOST_SCOPE_EXIT ( (&success) (&handle) (this_) ) {
if (!success)
this_->freeChannel(handle);
} BOOST_SCOPE_EXIT_END

_channels[handle.channel].reset(new Channel);
Channel &channel = *_channels[handle.channel];

channel.id = handle.id;
Expand All @@ -326,54 +331,48 @@ ChannelHandle SoundManager::playAudioStream(AudioStream *audStream, SoundType ty
channel.finishedBuffers = 0;
channel.gain = 1.0f;

try {
if (!channel.stream)
throw Common::Exception("Could not detect stream type");

ALenum error = AL_NO_ERROR;

if (!channel.stream)
throw Common::Exception("Could not detect stream type");
if (_hasSound) {
// Create the source
alGenSources(1, &channel.source);
if ((error = alGetError()) != AL_NO_ERROR)
throw Common::Exception("OpenAL error while generating sources: 0x%X", error);

ALenum error = AL_NO_ERROR;
// Create all needed buffers
for (size_t i = 0; i < kOpenALBufferCount; i++) {
ALuint buffer;

if (_hasSound) {
// Create the source
alGenSources(1, &channel.source);
alGenBuffers(1, &buffer);
if ((error = alGetError()) != AL_NO_ERROR)
throw Common::Exception("OpenAL error while generating sources: 0x%X", error);
throw Common::Exception("OpenAL error while generating buffers: 0x%X", error);

// Create all needed buffers
for (size_t i = 0; i < kOpenALBufferCount; i++) {
ALuint buffer;
if (fillBuffer(channel, buffer, channel.stream, channel.bufferSize[buffer])) {
// If we could fill the buffer with data, queue it

alGenBuffers(1, &buffer);
alSourceQueueBuffers(channel.source, 1, &buffer);
if ((error = alGetError()) != AL_NO_ERROR)
throw Common::Exception("OpenAL error while generating buffers: 0x%X", error);

if (fillBuffer(channel, buffer, channel.stream, channel.bufferSize[buffer])) {
// If we could fill the buffer with data, queue it

alSourceQueueBuffers(channel.source, 1, &buffer);
if ((error = alGetError()) != AL_NO_ERROR)
throw Common::Exception("OpenAL error while queueing buffers: 0x%X", error);
throw Common::Exception("OpenAL error while queueing buffers: 0x%X", error);

} else
// If not, put it into our free list
channel.freeBuffers.push_back(buffer);
} else
// If not, put it into our free list
channel.freeBuffers.push_back(buffer);

channel.buffers.push_back(buffer);
}

// Set the gain to the current sound type gain
alSourcef(channel.source, AL_GAIN, _types[channel.type].gain);
channel.buffers.push_back(buffer);
}

// Add the channel to the correct type list
_types[channel.type].list.push_back(&channel);
channel.typeIt = --_types[channel.type].list.end();

} catch (...) {
freeChannel(handle);
throw;
// Set the gain to the current sound type gain
alSourcef(channel.source, AL_GAIN, _types[channel.type].gain);
}

// Add the channel to the correct type list
_types[channel.type].list.push_back(&channel);
channel.typeIt = --_types[channel.type].list.end();

success = true;
return handle;
}

Expand Down Expand Up @@ -406,7 +405,7 @@ const SoundManager::Channel *SoundManager::getChannel(const ChannelHandle &handl
if (_channels[handle.channel]->id != handle.id)
return 0;

return _channels[handle.channel];
return _channels[handle.channel].get();
}

SoundManager::Channel *SoundManager::getChannel(const ChannelHandle &handle) {
Expand All @@ -419,7 +418,7 @@ SoundManager::Channel *SoundManager::getChannel(const ChannelHandle &handle) {
if (_channels[handle.channel]->id != handle.id)
return 0;

return _channels[handle.channel];
return _channels[handle.channel].get();
}

void SoundManager::startChannel(ChannelHandle &handle) {
Expand Down Expand Up @@ -464,7 +463,7 @@ void SoundManager::pauseAll(bool pause) {
Common::StackLock lock(_mutex);

for (size_t i = 0; i < kChannelCount; i++)
pauseChannel(_channels[i], pause);
pauseChannel(_channels[i].get(), pause);
}

void SoundManager::stopAll() {
Expand Down Expand Up @@ -624,26 +623,21 @@ bool SoundManager::fillBuffer(const Channel &channel, ALuint alBuffer,
// Read in the required amount of samples
size_t numSamples = kOpenALBufferSize / 2;

byte *buffer = new byte[kOpenALBufferSize];
std::memset(buffer, 0, kOpenALBufferSize);
Common::ScopedArray<byte> buffer(new byte[kOpenALBufferSize]);
std::memset(buffer.get(), 0, kOpenALBufferSize);

numSamples = stream->readBuffer(reinterpret_cast<int16 *>(buffer), numSamples);
numSamples = stream->readBuffer(reinterpret_cast<int16 *>(buffer.get()), numSamples);
if (numSamples == AudioStream::kSizeInvalid) {
delete[] buffer;

warning("Failed reading from stream while filling buffer in %s", formatChannel(&channel).c_str());
return false;
}

bufferedSize = numSamples * 2;
alBufferData(alBuffer, format, buffer, bufferedSize, stream->getRate());

delete[] buffer;
alBufferData(alBuffer, format, buffer.get(), bufferedSize, stream->getRate());

ALenum error = alGetError();
if (error != AL_NO_ERROR) {
warning("OpenAL error while filling buffer in %s: 0x%X",
formatChannel(&channel).c_str(), error);
warning("OpenAL error while filling buffer in %s: 0x%X", formatChannel(&channel).c_str(), error);
return false;
}

Expand Down Expand Up @@ -798,7 +792,7 @@ void SoundManager::freeChannel(size_t channel) {
if (channel >= kChannelCount)
return;

Channel *c = _channels[channel];
Channel *c = _channels[channel].get();
if (!c)
// Nothing to do
return;
Expand All @@ -822,8 +816,7 @@ void SoundManager::freeChannel(size_t channel) {
_types[c->type].list.erase(c->typeIt);

// And finally delete the channel itself
delete c;
_channels[channel] = 0;
_channels[channel].reset();
}

void SoundManager::threadMethod() {
Expand Down
5 changes: 3 additions & 2 deletions src/sound/sound.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <map>

#include "src/common/types.h"
#include "src/common/scopedptr.h"
#include "src/common/singleton.h"
#include "src/common/thread.h"
#include "src/common/mutex.h"
Expand Down Expand Up @@ -219,8 +220,8 @@ class SoundManager : public Common::Singleton<SoundManager>, public Common::Thre
bool _hasMultiChannel; ///< Do we have the multi-channel extension?
ALenum _format51; ///< The value for the 5.1 multi-channel format.

Channel *_channels[kChannelCount]; ///< The sound channels.
Type _types [kSoundTypeMAX]; ///< The sound types.
Common::ScopedPtr<Channel> _channels[kChannelCount]; ///< The sound channels.
Type _types[kSoundTypeMAX]; ///< The sound types.

uint32 _curID; ///< The ID the next sound will get.

Expand Down

0 comments on commit 8692d1f

Please sign in to comment.