Skip to content

Commit

Permalink
Broken up OpenALSoundProvider.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
captainurist committed Nov 9, 2023
1 parent 31c774a commit 0178506
Show file tree
Hide file tree
Showing 12 changed files with 687 additions and 646 deletions.
3 changes: 3 additions & 0 deletions src/Media/Audio/AudioPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
#include "Utility/DataPath.h"

#include "SoundList.h"
#include "OpenALTrack16.h"
#include "OpenALSample16.h"
#include "OpenALAudioDataSource.h"

std::unique_ptr<AudioPlayer> pAudioPlayer;

Expand Down
7 changes: 7 additions & 0 deletions src/Media/Audio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@ cmake_minimum_required(VERSION 3.24 FATAL_ERROR)
set(MEDIA_AUDIO_SOURCES
AudioPlayer.cpp
AudioSamplePool.cpp
OpenALAudioDataSource.cpp
OpenALSoundProvider.cpp
OpenALTrack16.cpp
OpenALSample16.cpp
SoundList.cpp)

set(MEDIA_AUDIO_HEADERS
AudioPlayer.h
AudioSamplePool.h
OpenALAudioDataSource.h
OpenALSoundProvider.h
OpenALTrack16.h
OpenALSample16.h
OpenALUpdateThread.h
SoundEnums.h
SoundInfo.h
SoundList.h)
Expand Down
94 changes: 94 additions & 0 deletions src/Media/Audio/OpenALAudioDataSource.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#include "OpenALAudioDataSource.h"

#include "Library/Logger/Logger.h"

#include "OpenALSoundProvider.h"

OpenALAudioDataSource::~OpenALAudioDataSource() {
_baseDataSource->Close();
if (_buffers.size()) {
alDeleteBuffers(_buffers.size(), &_buffers.front());
}
}

bool OpenALAudioDataSource::Open() {
if (_buffers.size()) {
return true;
}

_baseDataSource->Open();

bool result = true;
ALsizei al_sample_rate = GetSampleRate();
ALenum al_format = AL_FORMAT_STEREO16;
unsigned int num_channels = GetChannelCount();

switch (num_channels) {
case 1:
al_format = AL_FORMAT_MONO16;
break;
case 2:
al_format = AL_FORMAT_STEREO16;
break;
default:
if (alIsExtensionPresent("AL_EXT_MCFORMATS")) {
switch (num_channels) {
case 4:
al_format = alGetEnumValue("AL_FORMAT_QUAD16");
break;
case 6:
al_format = alGetEnumValue("AL_FORMAT_51CHN16");
break;
case 7:
al_format = alGetEnumValue("AL_FORMAT_61CHN16");
break;
case 8:
al_format = alGetEnumValue("AL_FORMAT_71CHN16");
break;
}
}
logger->error("Unsupported number of audio channels: {}", num_channels);
}

while (true) {
std::shared_ptr<Blob> buffer = _baseDataSource->GetNextBuffer();
if (!buffer) {
break;
}

ALuint al_buffer = -1;
alGenBuffers(1, &al_buffer);
if (checkOpenALError()) {
result = false;
break;
}

alBufferData(al_buffer, al_format, buffer->data(), buffer->size(), al_sample_rate);
if (checkOpenALError()) {
result = false;
break;
}

_buffers.push_back(al_buffer);
}

_baseDataSource->Close();

return result;
}

void OpenALAudioDataSource::Close() {
_baseDataSource->Close();
}

bool OpenALAudioDataSource::linkSource(ALuint al_source) {
alSourceQueueBuffers(al_source, _buffers.size(), &_buffers.front());
if (checkOpenALError()) {
return false;
}
return true;
}

PAudioDataSource PlatformDataSourceInitialize(PAudioDataSource baseDataSource) {
return std::make_shared<OpenALAudioDataSource>(baseDataSource);
}
31 changes: 31 additions & 0 deletions src/Media/Audio/OpenALAudioDataSource.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include <memory>
#include <vector>

#include <AL/al.h> // NOLINT: not a system C header.

#include "Media/Media.h"

// TODO(Nik-RE-dev): this middleware class is temporary because Media API is not fully
// ready to properly support current use cases
class OpenALAudioDataSource : public IAudioDataSource {
public:
explicit OpenALAudioDataSource(PAudioDataSource baseDataSource):_baseDataSource(baseDataSource) {}
virtual ~OpenALAudioDataSource() override;

virtual bool Open() override;
virtual void Close() override;

virtual size_t GetSampleRate() override { return _baseDataSource->GetSampleRate(); }
virtual size_t GetChannelCount() override { return _baseDataSource->GetChannelCount(); }
virtual std::shared_ptr<Blob> GetNextBuffer() override { return _baseDataSource->GetNextBuffer(); }

bool linkSource(ALuint al_source);

protected:
PAudioDataSource _baseDataSource;
std::vector<ALuint> _buffers;
};

PAudioDataSource PlatformDataSourceInitialize(PAudioDataSource baseDataSource);
183 changes: 183 additions & 0 deletions src/Media/Audio/OpenALSample16.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
#include "OpenALSample16.h"

#include <memory>

#include "OpenALSoundProvider.h"
#include "OpenALAudioDataSource.h"

AudioSample16::~AudioSample16() { Close(); }

void AudioSample16::Close() {
pDataSource = nullptr;

if (alIsSource(al_source) != 0) {
alSourceStop(al_source);
checkOpenALError();
alSourcei(al_source, AL_BUFFER, 0);
checkOpenALError();
alDeleteSources(1, &al_source);
checkOpenALError();
}

al_source = -1;
}

void AudioSample16::defaultSource() {
assert((al_source != -1) && "Cannot default invalid source!");
setSourceDefaults(al_source);
alSourcef(al_source, AL_REFERENCE_DISTANCE, REFERENCE_DIST);
alSourcef(al_source, AL_MAX_DISTANCE, MAX_SOUND_DIST);
alSourcef(al_source, AL_ROLLOFF_FACTOR, ROLLOFF_FACTOR);
}

bool AudioSample16::Open(PAudioDataSource data_source) {
pDataSource = data_source;
if (!pDataSource) {
return false;
}

std::shared_ptr<OpenALAudioDataSource> openalDataSource = std::dynamic_pointer_cast<OpenALAudioDataSource, IAudioDataSource>(pDataSource);

if (!openalDataSource->Open()) {
return false;
}

alGenSources((ALuint)1, &al_source);
if (checkOpenALError()) {
return false;
}

defaultSource();

if (!openalDataSource->linkSource(al_source)) {
Close();
return false;
}

return true;
}

bool AudioSample16::SetPosition(float x, float y, float z, float max_dist) {
_position = Vec3f(x, y, z);
_maxDistance = max_dist;

if (IsValid()) {
alSource3f(al_source, AL_POSITION, x, y, z);
alSourcef(al_source, AL_MAX_DISTANCE, max_dist);
if (checkOpenALError()) {
return false;
}
}

return true;
}

bool AudioSample16::IsValid() {
return (alIsSource(al_source) != 0);
}

bool AudioSample16::IsStopped() {
ALint status;

alGetSourcei(al_source, AL_SOURCE_STATE, &status);
return status == AL_STOPPED;
}

bool AudioSample16::Play(bool loop, bool positioned) {
if (!IsValid()) {
return false;
}

alSourcei(al_source, AL_SOURCE_RELATIVE, positioned ? AL_FALSE : AL_TRUE);
if (!positioned) {
alSource3f(al_source, AL_POSITION, 0.f, 0.f, 0.f);
alSourcef(al_source, AL_MAX_DISTANCE, 2000.f);
} else {
alSource3f(al_source, AL_POSITION, _position.x, _position.y, _position.z);
alSourcef(al_source, AL_MAX_DISTANCE, _maxDistance);
}
alSource3f(al_source, AL_VELOCITY, 0.f, 0.f, 0.f);
alSourcef(al_source, AL_GAIN, _volume);
alSourcei(al_source, AL_LOOPING, loop ? AL_TRUE : AL_FALSE);

ALint status;
alGetSourcei(al_source, AL_SOURCE_STATE, &status);
if (status == AL_PLAYING) {
return true;
}

alSourcePlay(al_source);
if (checkOpenALError()) {
return false;
}

return true;
}

bool AudioSample16::Stop() {
if (!IsValid()) {
return false;
}

alSourceStop(al_source);
if (checkOpenALError()) {
return false;
}

return true;
}

bool AudioSample16::Pause() {
if (!IsValid()) {
return false;
}

ALint status;
alGetSourcei(al_source, AL_SOURCE_STATE, &status);
if (status != AL_PLAYING) {
return false;
}

alSourcePause(al_source);
if (checkOpenALError()) {
return false;
}

return true;
}

bool AudioSample16::Resume() {
if (!IsValid()) {
return false;
}

ALint status;
alGetSourcei(al_source, AL_SOURCE_STATE, &status);
if (status != AL_PAUSED) {
return false;
}

alSourcePlay(al_source);
if (checkOpenALError()) {
return false;
}

return true;
}

bool AudioSample16::SetVolume(float volume) {
_volume = volume;

if (IsValid()) {
alSourcef(al_source, AL_GAIN, volume);
if (checkOpenALError()) {
return false;
}
}

return true;
}

PAudioSample CreateAudioSample() {
return std::make_shared<AudioSample16>();
}
36 changes: 36 additions & 0 deletions src/Media/Audio/OpenALSample16.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#pragma once

#include <AL/al.h>

#include "Library/Geometry/Vec.h"

#include "Media/Media.h"

class AudioSample16 : public IAudioSample {
public:
AudioSample16() {}
virtual ~AudioSample16() override;

virtual bool Open(PAudioDataSource data_source) override;
virtual bool IsValid() override;
virtual bool IsStopped() override;

virtual bool Play(bool loop = false, bool positioned = false) override;
virtual bool Stop() override;
virtual bool Pause() override;
virtual bool Resume() override;
virtual bool SetVolume(float volume) override;
virtual bool SetPosition(float x, float y, float z, float max_dist) override;

protected:
void Close();
void defaultSource();

PAudioDataSource pDataSource = nullptr;
ALuint al_source = -1;
Vec3f _position = Vec3f(0.0, 0.0, 0.0);
float _maxDistance = 0.0;
float _volume = 0.0;
};

PAudioSample CreateAudioSample();
Loading

0 comments on commit 0178506

Please sign in to comment.