Skip to content

Commit e8859aa

Browse files
committed
SoundStream Abstractions
1 parent fbc7aef commit e8859aa

7 files changed

Lines changed: 230 additions & 119 deletions

File tree

platforms/sound/openal/SoundStreamAL.cpp

Lines changed: 52 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -3,49 +3,19 @@
33
#include "common/Logger.hpp"
44

55
SoundStreamAL::SoundStreamAL()
6+
: SoundStream()
67
{
7-
_decoder = nullptr;
8-
_info = stb_vorbis_info();
98
_createSource();
109
_createBuffers();
11-
_tempPcmBufferSize = 4096 * 8;
12-
_tempPcmBuffer = new int16_t[_tempPcmBufferSize];
1310
_alFormat = AL_NONE;
14-
_totalSamplesLeft = 0;
15-
_isStreaming = false;
16-
_isPaused = false;
17-
_shouldLoop = false;
1811

19-
setVolume(1.0f);
12+
_setVolume(getVolume());
2013
}
2114

2215
SoundStreamAL::~SoundStreamAL()
2316
{
2417
_deleteSource();
2518
_deleteBuffers();
26-
_deleteDecoder();
27-
delete[] _tempPcmBuffer;
28-
}
29-
30-
bool SoundStreamAL::_stream(uint32_t buffer)
31-
{
32-
int size = 0;
33-
int result = 0;
34-
35-
while (size < _tempPcmBufferSize)
36-
{
37-
result = stb_vorbis_get_samples_short_interleaved(_decoder, _info.channels, _tempPcmBuffer + size, _tempPcmBufferSize - size);
38-
if (result > 0) size += result * _info.channels;
39-
else break;
40-
}
41-
42-
if (size == 0) return false;
43-
44-
alBufferData(buffer, _alFormat, _tempPcmBuffer, size * sizeof(int16_t), _info.sample_rate);
45-
AL_ERROR_CHECK();
46-
_totalSamplesLeft -= size;
47-
48-
return true;
4919
}
5020

5121
void SoundStreamAL::_deleteSource()
@@ -72,13 +42,25 @@ void SoundStreamAL::_resetSource()
7242

7343
void SoundStreamAL::_deleteBuffers()
7444
{
75-
alDeleteBuffers(2, _buffers);
45+
alDeleteBuffers(_buffers.size(), _buffers.data());
7646
AL_ERROR_CHECK();
47+
48+
_buffers.clear();
49+
_bufferIdMap.clear();
7750
}
7851

7952
void SoundStreamAL::_createBuffers()
8053
{
81-
alGenBuffers(2, _buffers);
54+
// Should not be called while buffers are already present
55+
assert(_buffers.size() == 0);
56+
57+
ALuint buffers[2];
58+
alGenBuffers(2, buffers);
59+
for (int i = 0; i < sizeof(buffers) / sizeof(ALuint); i++)
60+
{
61+
_buffers.push_back(buffers[i]);
62+
_bufferIdMap.emplace(buffers[i], i);
63+
}
8264
}
8365

8466
void SoundStreamAL::_resetBuffers()
@@ -87,77 +69,73 @@ void SoundStreamAL::_resetBuffers()
8769
_createBuffers();
8870
}
8971

90-
void SoundStreamAL::_deleteDecoder()
72+
void SoundStreamAL::_setVolume(float vol)
9173
{
92-
if (_decoder != nullptr)
93-
stb_vorbis_close(_decoder);
94-
_decoder = nullptr;
74+
alSourcef(_source, AL_GAIN, vol);
75+
AL_ERROR_CHECK();
9576
}
9677

97-
bool SoundStreamAL::open(const std::string& fileName)
78+
void SoundStreamAL::_play()
9879
{
99-
if (isStreaming())
100-
{
101-
close();
102-
}
80+
alSourcePlay(_source);
81+
AL_ERROR_CHECK();
82+
}
10383

104-
_isPaused = false;
84+
void SoundStreamAL::_pause()
85+
{
86+
alSourcePause(_source);
87+
AL_ERROR_CHECK();
88+
}
10589

106-
_decoder = stb_vorbis_open_filename(fileName.c_str(), NULL, NULL);
107-
if (!_decoder) return false;
108-
// Get file info
109-
_info = stb_vorbis_get_info(_decoder);
110-
if (_info.channels == 2) _alFormat = AL_FORMAT_STEREO16;
90+
bool SoundStreamAL::_open(const std::string& fileName)
91+
{
92+
if (m_info.channels == 2) _alFormat = AL_FORMAT_STEREO16;
11193
else _alFormat = AL_FORMAT_MONO16;
11294

113-
if (!_stream(_buffers[0])) return false;
114-
if (!_stream(_buffers[1])) return false;
115-
alSourceQueueBuffers(_source, 2, _buffers);
116-
AL_ERROR_CHECK();
117-
alSourcePlay(_source);
95+
size_t size = _buffers.size();
96+
for (int i = 0; i < size; i++)
97+
{
98+
if (!_stream(i)) return false;
99+
}
100+
alSourceQueueBuffers(_source, size, _buffers.data());
118101
AL_ERROR_CHECK();
119-
120-
_totalSamplesLeft = stb_vorbis_stream_length_in_samples(_decoder) * _info.channels;
121-
_isStreaming = true;
102+
_play();
122103

123104
return true;
124105
}
125106

126-
void SoundStreamAL::close()
107+
void SoundStreamAL::_close()
127108
{
128109
_resetSource();
129110
//_resetBuffers();
130-
_deleteDecoder();
131111
_alFormat = AL_NONE;
132-
_totalSamplesLeft = 0;
133-
_isStreaming = false;
134112
}
135113

136-
void SoundStreamAL::update()
114+
void SoundStreamAL::_update()
137115
{
138-
if (!isPlaying()) return;
139-
140-
int32_t processed = 0;
116+
ALint processed = 0;
141117

142118
alGetSourcei(_source, AL_BUFFERS_PROCESSED, &processed);
143119
AL_ERROR_CHECK();
144120

145121
while (processed--)
146122
{
147-
uint32_t buffer = 0;
123+
ALuint buffer = 0;
148124

149125
alSourceUnqueueBuffers(_source, 1, &buffer);
150126
AL_ERROR_CHECK();
151127

152-
if (!_stream(buffer))
128+
int bufferId = _bufferIdMap[buffer];
129+
130+
if (!_stream(bufferId))
153131
{
154132
bool shouldExit = true;
155133

156-
if (_shouldLoop)
134+
if (shouldLoop())
157135
{
158-
stb_vorbis_seek_start(_decoder);
159-
_totalSamplesLeft = stb_vorbis_stream_length_in_samples(_decoder) * _info.channels;
160-
shouldExit = !_stream(buffer);
136+
stb_vorbis_seek_start(m_decoder);
137+
m_totalSamplesLeft = stb_vorbis_stream_length_in_samples(m_decoder) * m_info.channels;
138+
shouldExit = !_stream(bufferId);
161139
}
162140

163141
if (shouldExit)
@@ -171,8 +149,8 @@ void SoundStreamAL::update()
171149
}
172150
}
173151

174-
void SoundStreamAL::setVolume(float vol)
152+
void SoundStreamAL::_publishBuffer(unsigned int destBufferId, const SoundBuffer& sourceBuffer)
175153
{
176-
alSourcef(_source, AL_GAIN, vol);
154+
alBufferData(_buffers[destBufferId], _alFormat, sourceBuffer.m_pData, sourceBuffer.m_dataSize * sizeof(int16_t), m_info.sample_rate);
177155
AL_ERROR_CHECK();
178-
}
156+
}
Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,31 @@
11
#pragma once
22

33
#include <stdint.h>
4+
#include <vector>
5+
#include <map>
46

5-
#define STB_VORBIS_HEADER_ONLY
6-
#include "thirdparty/stb_image/include/stb_vorbis.c"
77
#include "thirdparty/OpenAL.h"
88

99
#include "client/sound/SoundStream.hpp"
1010

1111
class SoundStreamAL : public SoundStream
1212
{
1313
private:
14-
stb_vorbis* _decoder;
15-
stb_vorbis_info _info;
14+
typedef std::map<ALuint, unsigned int> BufferIdMap;
1615

17-
uint32_t _buffers[2];
18-
uint32_t _source;
16+
private:
17+
std::vector<ALuint> _buffers;
18+
BufferIdMap _bufferIdMap;
1919

20-
size_t _tempPcmBufferSize;
21-
int16_t* _tempPcmBuffer;
20+
ALuint _source;
2221

2322
ALenum _alFormat;
24-
size_t _totalSamplesLeft;
25-
bool _isStreaming;
26-
bool _isPaused;
27-
bool _shouldLoop;
2823

2924
public:
3025
SoundStreamAL();
3126
~SoundStreamAL();
3227

3328
private:
34-
bool _stream(uint32_t buffer);
35-
3629
void _deleteSource();
3730
void _createSource();
3831
void _resetSource();
@@ -41,16 +34,12 @@ class SoundStreamAL : public SoundStream
4134
void _createBuffers();
4235
void _resetBuffers();
4336

44-
void _deleteDecoder();
45-
46-
public:
47-
bool isStreaming() const override { return _isStreaming; }
48-
bool isPaused() const override { return _isPaused; }
49-
50-
bool open(const std::string& flieName) override;
51-
void close() override;
52-
void update() override;
53-
54-
void setPausedState(bool state) override { _isPaused = state; };
55-
void setVolume(float vol) override;
37+
protected:
38+
void _setVolume(float vol) override;
39+
void _play() override;
40+
void _pause() override;
41+
bool _open(const std::string& fileName) override;
42+
void _close() override;
43+
void _update() override;
44+
void _publishBuffer(unsigned int destBufferId, const SoundBuffer& sourceBuffer);
5645
};

platforms/sound/openal/SoundSystemAL.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,20 +156,20 @@ void SoundSystemAL::_cleanSources()
156156
ALuint SoundSystemAL::_getBuffer(const SoundDesc& sound)
157157
{
158158
// Fetch pre-existing buffer
159-
if (_buffers.count(sound.m_pData) > 0)
159+
if (_buffers.count(sound.m_buffer.m_pData) > 0)
160160
{
161-
return _buffers[sound.m_pData];
161+
return _buffers[sound.m_buffer.m_pData];
162162
}
163163

164164
// Create Buffer
165165
ALuint buffer;
166166
alGenBuffers(1, &buffer);
167167
AL_ERROR_CHECK();
168-
alBufferData(buffer, _getSoundFormat(sound.m_header), sound.m_pData, sound.m_dataSize, sound.m_header.m_sample_rate);
168+
alBufferData(buffer, _getSoundFormat(sound.m_header), sound.m_buffer.m_pData, sound.m_buffer.m_dataSize, sound.m_header.m_sample_rate);
169169
AL_ERROR_CHECK();
170170

171171
// Store
172-
_buffers[sound.m_pData] = buffer;
172+
_buffers[sound.m_buffer.m_pData] = buffer;
173173
return buffer;
174174
}
175175

source/client/sound/SoundData.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ bool SoundDesc::_loadPcm(const AppPlatform* platform, const char *name)
4545
m_codecType = AudioCodec::PCM;
4646
m_fileData = m_file.data;
4747
m_header = *(PCMSoundHeader *) m_fileData;
48-
m_pData = (uint16_t *) (m_fileData + sizeof(PCMSoundHeader));
49-
m_dataSize = m_header.m_channels * m_header.m_length * m_header.m_bytes_per_sample;
48+
m_buffer.m_pData = (void *) (m_fileData + sizeof(PCMSoundHeader));
49+
m_buffer.m_dataSize = m_header.m_channels * m_header.m_length * m_header.m_bytes_per_sample;
5050

5151
// Success!
5252
return true;
@@ -66,13 +66,13 @@ bool SoundDesc::_loadOgg(const AppPlatform* platform, const char* category, cons
6666
m_header.m_bytes_per_sample = 2; // Always 2 (16-bit)
6767
// Casting to a short** here might cause problems. Let's find out...
6868
// Seems like it doesn't. Cool.
69-
m_header.m_length = stb_vorbis_decode_memory(m_file.data, (int) m_file.size, &m_header.m_channels, &m_header.m_sample_rate, (short **) &m_pData);
69+
m_header.m_length = stb_vorbis_decode_memory(m_file.data, (int) m_file.size, &m_header.m_channels, &m_header.m_sample_rate, (short **) &m_buffer.m_pData);
7070
if (m_header.m_length == -1)
7171
{
7272
LOG_E("An error occurred while trying to decode a sound!");
7373
return false;
7474
}
75-
m_dataSize = m_header.m_channels * m_header.m_length * m_header.m_bytes_per_sample;
75+
m_buffer.m_dataSize = m_header.m_channels * m_header.m_length * m_header.m_bytes_per_sample;
7676

7777
// Success!
7878
return true;
@@ -90,7 +90,7 @@ void SoundDesc::_unload()
9090
}
9191
// Free OGG Data
9292
if (m_codecType == AudioCodec::OGG) {
93-
free(m_pData);
93+
free(m_buffer.m_pData);
9494
}
9595
// Free File Data
9696
delete m_file.data;

source/client/sound/SoundData.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ struct PCMSoundHeader
3333
int m_length;
3434
};
3535

36+
struct SoundBuffer
37+
{
38+
void* m_pData;
39+
int m_dataSize;
40+
};
41+
3642
struct AudioDescriptor
3743
{
3844
bool m_isLoaded;
@@ -43,8 +49,7 @@ struct AudioDescriptor
4349
struct SoundDesc : AudioDescriptor
4450
{
4551
AssetFile m_file;
46-
uint16_t* m_pData;
47-
int m_dataSize;
52+
SoundBuffer m_buffer;
4853
unsigned char* m_fileData;
4954

5055
bool _load(const AppPlatform* platform, const char* category, const char *name);

0 commit comments

Comments
 (0)