Merge branch 'main' into devtools
This commit is contained in:
@@ -167,12 +167,12 @@ assetload::postfunc assetload::sound(
|
|||||||
// looking for 'sound_name' as base sound
|
// looking for 'sound_name' as base sound
|
||||||
auto soundFile = paths->find(file+extension);
|
auto soundFile = paths->find(file+extension);
|
||||||
if (fs::exists(soundFile)) {
|
if (fs::exists(soundFile)) {
|
||||||
baseSound.reset(audio::load_sound(soundFile, keepPCM));
|
baseSound = audio::load_sound(soundFile, keepPCM);
|
||||||
}
|
}
|
||||||
// looking for 'sound_name_0' as base sound
|
// looking for 'sound_name_0' as base sound
|
||||||
auto variantFile = paths->find(file+"_0"+extension);
|
auto variantFile = paths->find(file+"_0"+extension);
|
||||||
if (fs::exists(variantFile)) {
|
if (fs::exists(variantFile)) {
|
||||||
baseSound.reset(audio::load_sound(variantFile, keepPCM));
|
baseSound = audio::load_sound(variantFile, keepPCM);
|
||||||
}
|
}
|
||||||
|
|
||||||
// loading sound variants
|
// loading sound variants
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include "../../debug/Logger.hpp"
|
#include "../../debug/Logger.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
static debug::Logger logger("al-audio");
|
static debug::Logger logger("al-audio");
|
||||||
|
|
||||||
@@ -24,14 +23,14 @@ ALSound::~ALSound() {
|
|||||||
buffer = 0;
|
buffer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Speaker* ALSound::newInstance(int priority, int channel) const {
|
std::unique_ptr<Speaker> ALSound::newInstance(int priority, int channel) const {
|
||||||
uint source = al->getFreeSource();
|
uint source = al->getFreeSource();
|
||||||
if (source == 0) {
|
if (source == 0) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
AL_CHECK(alSourcei(source, AL_BUFFER, buffer));
|
AL_CHECK(alSourcei(source, AL_BUFFER, buffer));
|
||||||
|
|
||||||
auto speaker = new ALSpeaker(al, source, priority, channel);
|
auto speaker = std::make_unique<ALSpeaker>(al, source, priority, channel);
|
||||||
speaker->duration = duration;
|
speaker->duration = duration;
|
||||||
return speaker;
|
return speaker;
|
||||||
}
|
}
|
||||||
@@ -67,7 +66,7 @@ bool ALStream::preloadBuffer(uint buffer, bool loop) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Speaker* ALStream::createSpeaker(bool loop, int channel) {
|
std::unique_ptr<Speaker> ALStream::createSpeaker(bool loop, int channel) {
|
||||||
this->loop = loop;
|
this->loop = loop;
|
||||||
uint source = al->getFreeSource();
|
uint source = al->getFreeSource();
|
||||||
if (source == 0) {
|
if (source == 0) {
|
||||||
@@ -80,7 +79,7 @@ Speaker* ALStream::createSpeaker(bool loop, int channel) {
|
|||||||
}
|
}
|
||||||
AL_CHECK(alSourceQueueBuffers(source, 1, &buffer));
|
AL_CHECK(alSourceQueueBuffers(source, 1, &buffer));
|
||||||
}
|
}
|
||||||
return new ALSpeaker(al, source, PRIORITY_HIGH, channel);
|
return std::make_unique<ALSpeaker>(al, source, PRIORITY_HIGH, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -379,15 +378,15 @@ ALAudio::~ALAudio() {
|
|||||||
context = nullptr;
|
context = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sound* ALAudio::createSound(std::shared_ptr<PCM> pcm, bool keepPCM) {
|
std::unique_ptr<Sound> ALAudio::createSound(std::shared_ptr<PCM> pcm, bool keepPCM) {
|
||||||
auto format = AL::to_al_format(pcm->channels, pcm->bitsPerSample);
|
auto format = AL::to_al_format(pcm->channels, pcm->bitsPerSample);
|
||||||
uint buffer = getFreeBuffer();
|
uint buffer = getFreeBuffer();
|
||||||
AL_CHECK(alBufferData(buffer, format, pcm->data.data(), pcm->data.size(), pcm->sampleRate));
|
AL_CHECK(alBufferData(buffer, format, pcm->data.data(), pcm->data.size(), pcm->sampleRate));
|
||||||
return new ALSound(this, buffer, pcm, keepPCM);
|
return std::make_unique<ALSound>(this, buffer, pcm, keepPCM);
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream* ALAudio::openStream(std::shared_ptr<PCMStream> stream, bool keepSource) {
|
std::unique_ptr<Stream> ALAudio::openStream(std::shared_ptr<PCMStream> stream, bool keepSource) {
|
||||||
return new ALStream(this, stream, keepSource);
|
return std::make_unique<ALStream>(this, stream, keepSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALAudio* ALAudio::create() {
|
ALAudio* ALAudio::create() {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace audio {
|
|||||||
return pcm;
|
return pcm;
|
||||||
}
|
}
|
||||||
|
|
||||||
Speaker* newInstance(int priority, int channel) const override;
|
std::unique_ptr<Speaker> newInstance(int priority, int channel) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ALStream : public Stream {
|
class ALStream : public Stream {
|
||||||
@@ -65,7 +65,7 @@ namespace audio {
|
|||||||
|
|
||||||
std::shared_ptr<PCMStream> getSource() const override;
|
std::shared_ptr<PCMStream> getSource() const override;
|
||||||
void bindSpeaker(speakerid_t speaker) override;
|
void bindSpeaker(speakerid_t speaker) override;
|
||||||
Speaker* createSpeaker(bool loop, int channel) override;
|
std::unique_ptr<Speaker> createSpeaker(bool loop, int channel) override;
|
||||||
speakerid_t getSpeaker() const override;
|
speakerid_t getSpeaker() const override;
|
||||||
void update(double delta) override;
|
void update(double delta) override;
|
||||||
|
|
||||||
@@ -148,8 +148,8 @@ namespace audio {
|
|||||||
|
|
||||||
std::vector<std::string> getAvailableDevices() const;
|
std::vector<std::string> getAvailableDevices() const;
|
||||||
|
|
||||||
Sound* createSound(std::shared_ptr<PCM> pcm, bool keepPCM) override;
|
std::unique_ptr<Sound> createSound(std::shared_ptr<PCM> pcm, bool keepPCM) override;
|
||||||
Stream* openStream(std::shared_ptr<PCMStream> stream, bool keepSource) override;
|
std::unique_ptr<Stream> openStream(std::shared_ptr<PCMStream> stream, bool keepSource) override;
|
||||||
|
|
||||||
void setListener(
|
void setListener(
|
||||||
glm::vec3 position,
|
glm::vec3 position,
|
||||||
|
|||||||
+11
-9
@@ -1,6 +1,7 @@
|
|||||||
#include "alutil.hpp"
|
#include "alutil.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include "../../debug/Logger.hpp"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -14,30 +15,31 @@
|
|||||||
#include <AL/alc.h>
|
#include <AL/alc.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static debug::Logger logger("open-al");
|
||||||
|
|
||||||
bool AL::check_errors(const std::string& filename, const std::uint_fast32_t line){
|
bool AL::check_errors(const std::string& filename, const std::uint_fast32_t line){
|
||||||
ALenum error = alGetError();
|
ALenum error = alGetError();
|
||||||
if(error != AL_NO_ERROR){
|
if(error != AL_NO_ERROR){
|
||||||
std::cerr << "OpenAL ERROR (" << filename << ": " << line << ")\n" ;
|
logger.error() << filename << ": " << line;
|
||||||
switch(error){
|
switch(error){
|
||||||
case AL_INVALID_NAME:
|
case AL_INVALID_NAME:
|
||||||
std::cerr << "AL_INVALID_NAME: a bad name (ID) was passed to an OpenAL function";
|
logger.error() << "a bad name (ID) was passed to an OpenAL function";
|
||||||
break;
|
break;
|
||||||
case AL_INVALID_ENUM:
|
case AL_INVALID_ENUM:
|
||||||
std::cerr << "AL_INVALID_ENUM: an invalid enum value was passed to an OpenAL function";
|
logger.error() << "an invalid enum value was passed to an OpenAL function";
|
||||||
break;
|
break;
|
||||||
case AL_INVALID_VALUE:
|
case AL_INVALID_VALUE:
|
||||||
std::cerr << "AL_INVALID_VALUE: an invalid value was passed to an OpenAL function";
|
logger.error() << "an invalid value was passed to an OpenAL function";
|
||||||
break;
|
break;
|
||||||
case AL_INVALID_OPERATION:
|
case AL_INVALID_OPERATION:
|
||||||
std::cerr << "AL_INVALID_OPERATION: the requested operation is not valid";
|
logger.error() << "the requested operation is not valid";
|
||||||
break;
|
break;
|
||||||
case AL_OUT_OF_MEMORY:
|
case AL_OUT_OF_MEMORY:
|
||||||
std::cerr << "AL_OUT_OF_MEMORY: the requested operation resulted in OpenAL running out of memory";
|
logger.error() << "the requested operation resulted in OpenAL running out of memory";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
std::cerr << "UNKNOWN AL ERROR: " << error;
|
logger.error() << "UNKNOWN AL ERROR: " << error;
|
||||||
}
|
}
|
||||||
std::cerr << std::endl;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ NoSound::NoSound(std::shared_ptr<PCM> pcm, bool keepPCM) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Sound* NoAudio::createSound(std::shared_ptr<PCM> pcm, bool keepPCM) {
|
std::unique_ptr<Sound> NoAudio::createSound(std::shared_ptr<PCM> pcm, bool keepPCM) {
|
||||||
return new NoSound(pcm, keepPCM);
|
return std::make_unique<NoSound>(pcm, keepPCM);
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream* NoAudio::openStream(std::shared_ptr<PCMStream> stream, bool keepSource) {
|
std::unique_ptr<Stream> NoAudio::openStream(std::shared_ptr<PCMStream> stream, bool keepSource) {
|
||||||
return new NoStream(stream, keepSource);
|
return std::make_unique<NoStream>(stream, keepSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
NoAudio* NoAudio::create() {
|
NoAudio* NoAudio::create() {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace audio {
|
|||||||
return pcm;
|
return pcm;
|
||||||
}
|
}
|
||||||
|
|
||||||
Speaker* newInstance(int priority, int channel) const override {
|
std::unique_ptr<Speaker> newInstance(int priority, int channel) const override {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -42,7 +42,7 @@ namespace audio {
|
|||||||
void bindSpeaker(speakerid_t speaker) override {
|
void bindSpeaker(speakerid_t speaker) override {
|
||||||
}
|
}
|
||||||
|
|
||||||
Speaker* createSpeaker(bool loop, int channel) override{
|
std::unique_ptr<Speaker> createSpeaker(bool loop, int channel) override {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,8 +65,8 @@ namespace audio {
|
|||||||
public:
|
public:
|
||||||
~NoAudio() {}
|
~NoAudio() {}
|
||||||
|
|
||||||
Sound* createSound(std::shared_ptr<PCM> pcm, bool keepPCM) override;
|
std::unique_ptr<Sound> createSound(std::shared_ptr<PCM> pcm, bool keepPCM) override;
|
||||||
Stream* openStream(std::shared_ptr<PCMStream> stream, bool keepSource) override;
|
std::unique_ptr<Stream> openStream(std::shared_ptr<PCMStream> stream, bool keepSource) override;
|
||||||
|
|
||||||
void setListener(
|
void setListener(
|
||||||
glm::vec3 position,
|
glm::vec3 position,
|
||||||
|
|||||||
+15
-14
@@ -156,7 +156,7 @@ void audio::initialize(bool enabled) {
|
|||||||
create_channel("master");
|
create_channel("master");
|
||||||
}
|
}
|
||||||
|
|
||||||
PCM* audio::load_PCM(const fs::path& file, bool headerOnly) {
|
std::unique_ptr<PCM> audio::load_PCM(const fs::path& file, bool headerOnly) {
|
||||||
if (!fs::exists(file)) {
|
if (!fs::exists(file)) {
|
||||||
throw std::runtime_error("file not found '"+file.u8string()+"'");
|
throw std::runtime_error("file not found '"+file.u8string()+"'");
|
||||||
}
|
}
|
||||||
@@ -169,16 +169,16 @@ PCM* audio::load_PCM(const fs::path& file, bool headerOnly) {
|
|||||||
throw std::runtime_error("unsupported audio format");
|
throw std::runtime_error("unsupported audio format");
|
||||||
}
|
}
|
||||||
|
|
||||||
Sound* audio::load_sound(const fs::path& file, bool keepPCM) {
|
std::unique_ptr<Sound> audio::load_sound(const fs::path& file, bool keepPCM) {
|
||||||
std::shared_ptr<PCM> pcm(load_PCM(file, !keepPCM && backend->isDummy()));
|
std::shared_ptr<PCM> pcm(load_PCM(file, !keepPCM && backend->isDummy()).release());
|
||||||
return create_sound(pcm, keepPCM);
|
return create_sound(pcm, keepPCM);
|
||||||
}
|
}
|
||||||
|
|
||||||
Sound* audio::create_sound(std::shared_ptr<PCM> pcm, bool keepPCM) {
|
std::unique_ptr<Sound> audio::create_sound(std::shared_ptr<PCM> pcm, bool keepPCM) {
|
||||||
return backend->createSound(pcm, keepPCM);
|
return backend->createSound(pcm, keepPCM);
|
||||||
}
|
}
|
||||||
|
|
||||||
PCMStream* audio::open_PCM_stream(const fs::path& file) {
|
std::unique_ptr<PCMStream> audio::open_PCM_stream(const fs::path& file) {
|
||||||
std::string ext = file.extension().u8string();
|
std::string ext = file.extension().u8string();
|
||||||
if (ext == ".wav" || ext == ".WAV") {
|
if (ext == ".wav" || ext == ".WAV") {
|
||||||
return wav::create_stream(file);
|
return wav::create_stream(file);
|
||||||
@@ -188,7 +188,7 @@ PCMStream* audio::open_PCM_stream(const fs::path& file) {
|
|||||||
throw std::runtime_error("unsupported audio stream format");
|
throw std::runtime_error("unsupported audio stream format");
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream* audio::open_stream(const fs::path& file, bool keepSource) {
|
std::unique_ptr<Stream> audio::open_stream(const fs::path& file, bool keepSource) {
|
||||||
if (!keepSource && backend->isDummy()) {
|
if (!keepSource && backend->isDummy()) {
|
||||||
auto header = load_PCM(file, true);
|
auto header = load_PCM(file, true);
|
||||||
// using void source sized as audio instead of actual audio file
|
// using void source sized as audio instead of actual audio file
|
||||||
@@ -203,7 +203,7 @@ Stream* audio::open_stream(const fs::path& file, bool keepSource) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream* audio::open_stream(std::shared_ptr<PCMStream> stream, bool keepSource) {
|
std::unique_ptr<Stream> audio::open_stream(std::shared_ptr<PCMStream> stream, bool keepSource) {
|
||||||
return backend->openStream(stream, keepSource);
|
return backend->openStream(stream, keepSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,7 +255,7 @@ speakerid_t audio::play(
|
|||||||
sound = sound->variants.at(index).get();
|
sound = sound->variants.at(index).get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Speaker* speaker = sound->newInstance(priority, channel);
|
auto speaker = sound->newInstance(priority, channel);
|
||||||
if (speaker == nullptr) {
|
if (speaker == nullptr) {
|
||||||
remove_lower_priority_speaker(priority);
|
remove_lower_priority_speaker(priority);
|
||||||
speaker = sound->newInstance(priority, channel);
|
speaker = sound->newInstance(priority, channel);
|
||||||
@@ -264,7 +264,7 @@ speakerid_t audio::play(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
speakerid_t id = nextId++;
|
speakerid_t id = nextId++;
|
||||||
speakers.emplace(id, speaker);
|
speakers.emplace(id, std::move(speaker));
|
||||||
speaker->setPosition(position);
|
speaker->setPosition(position);
|
||||||
speaker->setVolume(volume);
|
speaker->setVolume(volume);
|
||||||
speaker->setPitch(pitch);
|
speaker->setPitch(pitch);
|
||||||
@@ -283,17 +283,18 @@ speakerid_t audio::play(
|
|||||||
bool loop,
|
bool loop,
|
||||||
int channel
|
int channel
|
||||||
) {
|
) {
|
||||||
Speaker* speaker = stream->createSpeaker(loop, channel);
|
auto speaker_ptr = stream->createSpeaker(loop, channel);
|
||||||
if (speaker == nullptr) {
|
if (speaker_ptr == nullptr) {
|
||||||
remove_lower_priority_speaker(PRIORITY_HIGH);
|
remove_lower_priority_speaker(PRIORITY_HIGH);
|
||||||
speaker = stream->createSpeaker(loop, channel);
|
speaker_ptr = stream->createSpeaker(loop, channel);
|
||||||
}
|
}
|
||||||
if (speaker == nullptr) {
|
if (speaker_ptr == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
auto speaker = speaker_ptr.get();
|
||||||
speakerid_t id = nextId++;
|
speakerid_t id = nextId++;
|
||||||
streams.emplace(id, stream);
|
streams.emplace(id, stream);
|
||||||
speakers.emplace(id, speaker);
|
speakers.emplace(id, std::move(speaker_ptr));
|
||||||
stream->bindSpeaker(id);
|
stream->bindSpeaker(id);
|
||||||
|
|
||||||
speaker->setPosition(position);
|
speaker->setPosition(position);
|
||||||
|
|||||||
+10
-10
@@ -179,7 +179,7 @@ namespace audio {
|
|||||||
/// @param loop is stream looped (required for correct buffers preload)
|
/// @param loop is stream looped (required for correct buffers preload)
|
||||||
/// @param channel channel index
|
/// @param channel channel index
|
||||||
/// @return speaker id or 0
|
/// @return speaker id or 0
|
||||||
virtual Speaker* createSpeaker(bool loop, int channel) = 0;
|
virtual std::unique_ptr<Speaker> createSpeaker(bool loop, int channel) = 0;
|
||||||
|
|
||||||
/// @brief Unbind previous speaker and bind new speaker to the stream
|
/// @brief Unbind previous speaker and bind new speaker to the stream
|
||||||
/// @param speaker speaker id or 0 if all you need is unbind speaker
|
/// @param speaker speaker id or 0 if all you need is unbind speaker
|
||||||
@@ -225,7 +225,7 @@ namespace audio {
|
|||||||
/// @param channel channel index
|
/// @param channel channel index
|
||||||
/// @return new speaker with sound bound or nullptr
|
/// @return new speaker with sound bound or nullptr
|
||||||
/// if all speakers are in use
|
/// if all speakers are in use
|
||||||
virtual Speaker* newInstance(int priority, int channel) const = 0;
|
virtual std::unique_ptr<Speaker> newInstance(int priority, int channel) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief Audio source controller interface.
|
/// @brief Audio source controller interface.
|
||||||
@@ -336,8 +336,8 @@ namespace audio {
|
|||||||
public:
|
public:
|
||||||
virtual ~Backend() {};
|
virtual ~Backend() {};
|
||||||
|
|
||||||
virtual Sound* createSound(std::shared_ptr<PCM> pcm, bool keepPCM) = 0;
|
virtual std::unique_ptr<Sound> createSound(std::shared_ptr<PCM> pcm, bool keepPCM) = 0;
|
||||||
virtual Stream* openStream(std::shared_ptr<PCMStream> stream, bool keepSource) = 0;
|
virtual std::unique_ptr<Stream> openStream(std::shared_ptr<PCMStream> stream, bool keepSource) = 0;
|
||||||
virtual void setListener(
|
virtual void setListener(
|
||||||
glm::vec3 position,
|
glm::vec3 position,
|
||||||
glm::vec3 velocity,
|
glm::vec3 velocity,
|
||||||
@@ -360,38 +360,38 @@ namespace audio {
|
|||||||
/// @param headerOnly read header only
|
/// @param headerOnly read header only
|
||||||
/// @throws std::runtime_error if I/O error ocurred or format is unknown
|
/// @throws std::runtime_error if I/O error ocurred or format is unknown
|
||||||
/// @return PCM audio data
|
/// @return PCM audio data
|
||||||
PCM* load_PCM(const fs::path& file, bool headerOnly);
|
std::unique_ptr<PCM> load_PCM(const fs::path& file, bool headerOnly);
|
||||||
|
|
||||||
/// @brief Load sound from file
|
/// @brief Load sound from file
|
||||||
/// @param file audio file path
|
/// @param file audio file path
|
||||||
/// @param keepPCM store PCM data in sound to make it accessible with Sound::getPCM
|
/// @param keepPCM store PCM data in sound to make it accessible with Sound::getPCM
|
||||||
/// @throws std::runtime_error if I/O error ocurred or format is unknown
|
/// @throws std::runtime_error if I/O error ocurred or format is unknown
|
||||||
/// @return new Sound instance
|
/// @return new Sound instance
|
||||||
Sound* load_sound(const fs::path& file, bool keepPCM);
|
std::unique_ptr<Sound> load_sound(const fs::path& file, bool keepPCM);
|
||||||
|
|
||||||
/// @brief Create new sound from PCM data
|
/// @brief Create new sound from PCM data
|
||||||
/// @param pcm PCM data
|
/// @param pcm PCM data
|
||||||
/// @param keepPCM store PCM data in sound to make it accessible with Sound::getPCM
|
/// @param keepPCM store PCM data in sound to make it accessible with Sound::getPCM
|
||||||
/// @return new Sound instance
|
/// @return new Sound instance
|
||||||
Sound* create_sound(std::shared_ptr<PCM> pcm, bool keepPCM);
|
std::unique_ptr<Sound> create_sound(std::shared_ptr<PCM> pcm, bool keepPCM);
|
||||||
|
|
||||||
/// @brief Open new PCM stream from file
|
/// @brief Open new PCM stream from file
|
||||||
/// @param file audio file path
|
/// @param file audio file path
|
||||||
/// @throws std::runtime_error if I/O error ocurred or format is unknown
|
/// @throws std::runtime_error if I/O error ocurred or format is unknown
|
||||||
/// @return new PCMStream instance
|
/// @return new PCMStream instance
|
||||||
PCMStream* open_PCM_stream(const fs::path& file);
|
std::unique_ptr<PCMStream> open_PCM_stream(const fs::path& file);
|
||||||
|
|
||||||
/// @brief Open new audio stream from file
|
/// @brief Open new audio stream from file
|
||||||
/// @param file audio file path
|
/// @param file audio file path
|
||||||
/// @param keepSource store PCMStream in stream to make it accessible with Stream::getSource
|
/// @param keepSource store PCMStream in stream to make it accessible with Stream::getSource
|
||||||
/// @return new Stream instance
|
/// @return new Stream instance
|
||||||
Stream* open_stream(const fs::path& file, bool keepSource);
|
std::unique_ptr<Stream> open_stream(const fs::path& file, bool keepSource);
|
||||||
|
|
||||||
/// @brief Open new audio stream from source
|
/// @brief Open new audio stream from source
|
||||||
/// @param stream PCM data source
|
/// @param stream PCM data source
|
||||||
/// @param keepSource store PCMStream in stream to make it accessible with Stream::getSource
|
/// @param keepSource store PCMStream in stream to make it accessible with Stream::getSource
|
||||||
/// @return new Stream instance
|
/// @return new Stream instance
|
||||||
Stream* open_stream(std::shared_ptr<PCMStream> stream, bool keepSource);
|
std::unique_ptr<Stream> open_stream(std::shared_ptr<PCMStream> stream, bool keepSource);
|
||||||
|
|
||||||
/// @brief Configure 3D listener
|
/// @brief Configure 3D listener
|
||||||
/// @param position listener position
|
/// @param position listener position
|
||||||
|
|||||||
+7
-4
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
static debug::Logger logger("ogg");
|
static debug::Logger logger("ogg");
|
||||||
|
|
||||||
|
namespace fs = std::filesystem;
|
||||||
using namespace audio;
|
using namespace audio;
|
||||||
|
|
||||||
static inline std::string vorbis_error_message(int code) {
|
static inline std::string vorbis_error_message(int code) {
|
||||||
@@ -33,7 +34,7 @@ static inline std::string vorbis_error_message(int code) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
audio::PCM* ogg::load_pcm(const std::filesystem::path& file, bool headerOnly) {
|
std::unique_ptr<audio::PCM> ogg::load_pcm(const fs::path& file, bool headerOnly) {
|
||||||
OggVorbis_File vf;
|
OggVorbis_File vf;
|
||||||
int code;
|
int code;
|
||||||
if ((code = ov_fopen(file.u8string().c_str(), &vf))) {
|
if ((code = ov_fopen(file.u8string().c_str(), &vf))) {
|
||||||
@@ -66,7 +67,9 @@ audio::PCM* ogg::load_pcm(const std::filesystem::path& file, bool headerOnly) {
|
|||||||
totalSamples = data.size() / channels / 2;
|
totalSamples = data.size() / channels / 2;
|
||||||
}
|
}
|
||||||
ov_clear(&vf);
|
ov_clear(&vf);
|
||||||
return new PCM(std::move(data), totalSamples, channels, 16, sampleRate, seekable);
|
return std::make_unique<PCM>(
|
||||||
|
std::move(data), totalSamples, channels, 16, sampleRate, seekable
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class OggStream : public PCMStream {
|
class OggStream : public PCMStream {
|
||||||
@@ -149,11 +152,11 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
PCMStream* ogg::create_stream(const std::filesystem::path& file) {
|
std::unique_ptr<PCMStream> ogg::create_stream(const fs::path& file) {
|
||||||
OggVorbis_File vf;
|
OggVorbis_File vf;
|
||||||
int code;
|
int code;
|
||||||
if ((code = ov_fopen(file.u8string().c_str(), &vf))) {
|
if ((code = ov_fopen(file.u8string().c_str(), &vf))) {
|
||||||
throw std::runtime_error("vorbis: "+vorbis_error_message(code));
|
throw std::runtime_error("vorbis: "+vorbis_error_message(code));
|
||||||
}
|
}
|
||||||
return new OggStream(std::move(vf));
|
return std::make_unique<OggStream>(std::move(vf));
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -9,8 +9,8 @@ namespace audio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace ogg {
|
namespace ogg {
|
||||||
extern audio::PCM* load_pcm(const std::filesystem::path& file, bool headerOnly);
|
std::unique_ptr<audio::PCM> load_pcm(const std::filesystem::path& file, bool headerOnly);
|
||||||
extern audio::PCMStream* create_stream(const std::filesystem::path& file);
|
std::unique_ptr<audio::PCMStream> create_stream(const std::filesystem::path& file);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // CODERS_OGG_HPP_
|
#endif // CODERS_OGG_HPP_
|
||||||
|
|||||||
+15
-8
@@ -1,14 +1,18 @@
|
|||||||
#include "wav.hpp"
|
#include "wav.hpp"
|
||||||
|
|
||||||
#include "../audio/audio.hpp"
|
#include "../audio/audio.hpp"
|
||||||
|
#include "../debug/Logger.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
static debug::Logger logger("wav-coder");
|
||||||
|
|
||||||
bool is_big_endian() {
|
bool is_big_endian() {
|
||||||
uint32_t ui32_v = 0x01020304;
|
uint32_t ui32_v = 0x01020304;
|
||||||
char bytes[sizeof(uint32_t)];
|
char bytes[sizeof(uint32_t)];
|
||||||
@@ -65,7 +69,7 @@ public:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (in.fail()) {
|
if (in.fail()) {
|
||||||
std::cerr << "Wav::load_pcm: I/O error ocurred" << std::endl;
|
logger.error() << "Wav::load_pcm: I/O error ocurred";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return in.gcount();
|
return in.gcount();
|
||||||
@@ -114,7 +118,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
audio::PCMStream* wav::create_stream(const std::filesystem::path& file) {
|
std::unique_ptr<audio::PCMStream> wav::create_stream(const fs::path& file) {
|
||||||
std::ifstream in(file, std::ios::binary);
|
std::ifstream in(file, std::ios::binary);
|
||||||
if(!in.is_open()){
|
if(!in.is_open()){
|
||||||
throw std::runtime_error("could not to open file '"+file.u8string()+"'");
|
throw std::runtime_error("could not to open file '"+file.u8string()+"'");
|
||||||
@@ -197,7 +201,6 @@ audio::PCMStream* wav::create_stream(const std::filesystem::path& file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(std::strncmp(buffer, "data", 4) != 0){
|
if(std::strncmp(buffer, "data", 4) != 0){
|
||||||
std::cerr << buffer << std::endl;
|
|
||||||
throw std::runtime_error("file is not a valid WAVE file (doesn't have 'data' tag)");
|
throw std::runtime_error("file is not a valid WAVE file (doesn't have 'data' tag)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,11 +217,13 @@ audio::PCMStream* wav::create_stream(const std::filesystem::path& file) {
|
|||||||
if(in.fail()){
|
if(in.fail()){
|
||||||
throw std::runtime_error("fail state set on the file");
|
throw std::runtime_error("fail state set on the file");
|
||||||
}
|
}
|
||||||
return new WavStream(std::move(in), channels, bitsPerSample, sampleRate, size, initialOffset);
|
return std::make_unique<WavStream>(
|
||||||
|
std::move(in), channels, bitsPerSample, sampleRate, size, initialOffset
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
audio::PCM* wav::load_pcm(const std::filesystem::path& file, bool headerOnly) {
|
std::unique_ptr<audio::PCM> wav::load_pcm(const fs::path& file, bool headerOnly) {
|
||||||
std::unique_ptr<audio::PCMStream> stream(wav::create_stream(file));
|
auto stream = wav::create_stream(file);
|
||||||
|
|
||||||
size_t totalSamples = stream->getTotalSamples();
|
size_t totalSamples = stream->getTotalSamples();
|
||||||
uint channels = stream->getChannels();
|
uint channels = stream->getChannels();
|
||||||
@@ -233,5 +238,7 @@ audio::PCM* wav::load_pcm(const std::filesystem::path& file, bool headerOnly) {
|
|||||||
data.resize(size);
|
data.resize(size);
|
||||||
stream->readFully(data.data(), size, false);
|
stream->readFully(data.data(), size, false);
|
||||||
}
|
}
|
||||||
return new audio::PCM(std::move(data), totalSamples, channels, bitsPerSample, sampleRate, true);
|
return std::make_unique<audio::PCM>(
|
||||||
|
std::move(data), totalSamples, channels, bitsPerSample, sampleRate, true
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -9,8 +9,8 @@ namespace audio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace wav {
|
namespace wav {
|
||||||
extern audio::PCM* load_pcm(const std::filesystem::path& file, bool headerOnly);
|
std::unique_ptr<audio::PCM> load_pcm(const std::filesystem::path& file, bool headerOnly);
|
||||||
extern audio::PCMStream* create_stream(const std::filesystem::path& file);
|
std::unique_ptr<audio::PCMStream> create_stream(const std::filesystem::path& file);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // CODERS_WAV_HPP_
|
#endif // CODERS_WAV_HPP_
|
||||||
|
|||||||
@@ -1,9 +1,44 @@
|
|||||||
#include "command_line.hpp"
|
#include "command_line.hpp"
|
||||||
|
|
||||||
|
#include "../files/engine_paths.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <string>
|
||||||
|
#include <cstring>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
class ArgsReader {
|
||||||
|
int argc;
|
||||||
|
char** argv;
|
||||||
|
int pos = 0;
|
||||||
|
const char* last = "";
|
||||||
|
public:
|
||||||
|
ArgsReader(int argc, char** argv) : argc(argc), argv(argv) {}
|
||||||
|
|
||||||
|
void skip() {
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasNext() const {
|
||||||
|
return pos < argc && strlen(argv[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isKeywordArg() const {
|
||||||
|
return last[0] == '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string next() {
|
||||||
|
if (pos >= argc) {
|
||||||
|
throw std::runtime_error("unexpected end");
|
||||||
|
}
|
||||||
|
last = argv[pos];
|
||||||
|
return argv[pos++];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
bool perform_keyword(ArgsReader& reader, const std::string& keyword, EnginePaths& paths) {
|
bool perform_keyword(ArgsReader& reader, const std::string& keyword, EnginePaths& paths) {
|
||||||
if (keyword == "--res") {
|
if (keyword == "--res") {
|
||||||
auto token = reader.next();
|
auto token = reader.next();
|
||||||
|
|||||||
@@ -1,40 +1,7 @@
|
|||||||
#ifndef UTIL_COMMAND_LINE_HPP_
|
#ifndef UTIL_COMMAND_LINE_HPP_
|
||||||
#define UTIL_COMMAND_LINE_HPP_
|
#define UTIL_COMMAND_LINE_HPP_
|
||||||
|
|
||||||
#include <string>
|
class EnginePaths;
|
||||||
#include <cstring>
|
|
||||||
#include <iostream>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include "../files/engine_paths.hpp"
|
|
||||||
|
|
||||||
class ArgsReader {
|
|
||||||
int argc;
|
|
||||||
char** argv;
|
|
||||||
int pos = 0;
|
|
||||||
const char* last = "";
|
|
||||||
public:
|
|
||||||
ArgsReader(int argc, char** argv) : argc(argc), argv(argv) {}
|
|
||||||
|
|
||||||
void skip() {
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hasNext() const {
|
|
||||||
return pos < argc && strlen(argv[pos]);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isKeywordArg() const {
|
|
||||||
return last[0] == '-';
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string next() {
|
|
||||||
if (pos >= argc) {
|
|
||||||
throw std::runtime_error("unexpected end");
|
|
||||||
}
|
|
||||||
last = argv[pos];
|
|
||||||
return argv[pos++];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// @return false if engine start can
|
/// @return false if engine start can
|
||||||
bool parse_cmdline(int argc, char** argv, EnginePaths& paths);
|
bool parse_cmdline(int argc, char** argv, EnginePaths& paths);
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
namespace util {
|
namespace util {
|
||||||
/// @brief Function used for string serialization in text formats
|
/// @brief Function used for string serialization in text formats
|
||||||
|
|||||||
Reference in New Issue
Block a user