Skip to content

Commit

Permalink
Refactor audio events
Browse files Browse the repository at this point in the history
  • Loading branch information
jurihock committed Jun 6, 2024
1 parent 0e4527c commit 7faab68
Show file tree
Hide file tree
Showing 23 changed files with 213 additions and 267 deletions.
2 changes: 2 additions & 0 deletions voicesmith/src/main/cpp/de/jurihock/voicesmith/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Werror)

include("${CMAKE_CURRENT_LIST_DIR}/libs/cpm.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/libs/easyloggingpp.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/libs/eventpp.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/libs/fmt.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/libs/oboe.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/libs/pffft.cmake")
Expand All @@ -25,6 +26,7 @@ include("${CMAKE_CURRENT_LIST_DIR}/libs/stftpitchshift.cmake")
target_link_libraries(${PROJECT_NAME} PRIVATE
android
easyloggingpp
eventpp
fmt
log
oboe
Expand Down
45 changes: 0 additions & 45 deletions voicesmith/src/main/cpp/de/jurihock/voicesmith/etc/Event.h

This file was deleted.

24 changes: 24 additions & 0 deletions voicesmith/src/main/cpp/de/jurihock/voicesmith/io/AudioEvent.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include <voicesmith/Header.h>

#include <voicesmith/io/AudioEventCode.h>
#include <voicesmith/io/AudioEventCodeExtensions.h>

#include <eventpp/callbacklist.h>

class AudioEvent final : public eventpp::CallbackList<void(const AudioEventCode code, const std::string& text)> {

public:

class Emitter {

public:

virtual ~Emitter() = default;

virtual void subscribe(const Callback& callback) = 0;

};

};
11 changes: 11 additions & 0 deletions voicesmith/src/main/cpp/de/jurihock/voicesmith/io/AudioEventCode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once

enum class AudioEventCode {
Info,
Warning,
SourceOverrun,
SinkUnderrun,
Error,
SourceError,
SinkError,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

#include <voicesmith/Header.h>

#include <voicesmith/io/AudioEventCode.h>

constexpr int operator!(AudioEventCode code) noexcept {
return static_cast<int>(code);
}
59 changes: 14 additions & 45 deletions voicesmith/src/main/cpp/de/jurihock/voicesmith/io/AudioPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,8 @@ AudioPipeline::~AudioPipeline() {
close();
}

void AudioPipeline::onerror() {
events.error.reset();
}

void AudioPipeline::onerror(std::function<void()> callback) {
events.error.set(callback);
void AudioPipeline::subscribe(const AudioEvent::Callback& callback) {
event.append(callback);
}

void AudioPipeline::open() {
Expand Down Expand Up @@ -64,32 +60,18 @@ void AudioPipeline::open() {
source->fifo()->resize(fifosize, source->blocksize());
sink->fifo()->resize(fifosize, sink->blocksize());

source->onxrun([&](const int32_t count) {
onxrun(oboe::Direction::Input, count);
});

sink->onxrun([&](const int32_t count) {
onxrun(oboe::Direction::Output, count);
});

source->onerror([&](const oboe::Result error) {
return onerror(oboe::Direction::Input, error);
source->subscribe([&](const AudioEventCode code, const std::string& text) {
onevent(code, text);
});

sink->onerror([&](const oboe::Result error) {
return onerror(oboe::Direction::Output, error);
source->subscribe([&](const AudioEventCode code, const std::string& text) {
onevent(code, text);
});
}

void AudioPipeline::close() {
stop();

source->onxrun();
sink->onxrun();

source->onerror();
sink->onerror();

source->close();
sink->close();
}
Expand All @@ -101,7 +83,7 @@ void AudioPipeline::start() {
sink->start();

state.loopthread = std::make_shared<std::thread>(
[&]() { loop(); });
[&]() { onloop(); });
}

void AudioPipeline::stop() {
Expand All @@ -121,7 +103,7 @@ void AudioPipeline::stop() {
source->fifo()->flush();
}

void AudioPipeline::loop() {
void AudioPipeline::onloop() {
struct timers_t {
Timer<std::chrono::milliseconds> outer;
Timer<std::chrono::milliseconds> inner;
Expand Down Expand Up @@ -190,25 +172,12 @@ void AudioPipeline::loop() {
}
}

void AudioPipeline::onxrun(const oboe::Direction direction, const int32_t count) {
switch (direction) {
case oboe::Direction::Input:
LOG(WARNING) << $("Audio source {0} overruns occured!", count);
break;
case oboe::Direction::Output:
LOG(WARNING) << $("Audio sink {0} underruns occured!", count);
break;
void AudioPipeline::onevent(const AudioEventCode code, const std::string& text) {
if (code >= AudioEventCode::Error) {
LOG(WARNING) << $("Aborting audio pipeline due to error: {0}!", text);
std::unique_lock lock(eventmutex);
close();
}
}

bool AudioPipeline::onerror(const oboe::Direction direction, const oboe::Result error) {
std::unique_lock lock(onerrormutex);

LOG(WARNING) << $("Aborting audio pipeline due to {0} error {1}!",
oboe::convertToText(direction),
oboe::convertToText(error));

close();
events.error();
return true;
event(code, text);
}
21 changes: 7 additions & 14 deletions voicesmith/src/main/cpp/de/jurihock/voicesmith/io/AudioPipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

#include <voicesmith/Header.h>

#include <voicesmith/etc/Event.h>
#include <voicesmith/fx/AudioEffect.h>
#include <voicesmith/io/AudioEvent.h>
#include <voicesmith/io/AudioSink.h>
#include <voicesmith/io/AudioSource.h>

class AudioPipeline final {
class AudioPipeline final : public AudioEvent::Emitter {

public:

Expand All @@ -17,8 +17,7 @@ class AudioPipeline final {

~AudioPipeline();

void onerror();
void onerror(std::function<void()> callback);
void subscribe(const AudioEvent::Callback& callback) override;

void open();
void close();
Expand All @@ -32,23 +31,17 @@ class AudioPipeline final {
const std::shared_ptr<AudioSink> sink;
const std::shared_ptr<AudioEffect> effect;

struct {

Event<void()> error = []() {};

} events;

struct {

std::shared_ptr<std::thread> loopthread;
bool doloop;

} state;

void loop();
void onxrun(const oboe::Direction direction, const int32_t count);
AudioEvent event;
std::mutex eventmutex;

std::mutex onerrormutex;
bool onerror(const oboe::Direction direction, const oboe::Result error);
void onloop();
void onevent(const AudioEventCode code, const std::string& text);

};
25 changes: 12 additions & 13 deletions voicesmith/src/main/cpp/de/jurihock/voicesmith/io/AudioSink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,7 @@ AudioSink::AudioSink(const std::optional<int> device,
const std::shared_ptr<AudioBlockQueue> queue) :
AudioStream(oboe::Direction::Output, device, samplerate, blocksize),
effect(effect),
queue((queue != nullptr) ? queue : std::make_shared<AudioBlockQueue>()) {

if (effect) {
onopen([this]() {
this->effect->reset(this->samplerate(), this->blocksize());
});
}

onstart([this]() {
this->index = {0, 0};
this->underflows = {false, 0};
});
}
queue((queue != nullptr) ? queue : std::make_shared<AudioBlockQueue>()) {}

std::shared_ptr<AudioEffect> AudioSink::fx() const {
return effect;
Expand Down Expand Up @@ -58,3 +46,14 @@ void AudioSink::callback(const std::span<float> samples) {

++index.outer;
}

void AudioSink::onopen() {
if (effect) {
effect->reset(samplerate(), blocksize());
}
}

void AudioSink::onstart() {
index = {0, 0};
underflows = {false, 0};
}
3 changes: 3 additions & 0 deletions voicesmith/src/main/cpp/de/jurihock/voicesmith/io/AudioSink.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ class AudioSink final : public AudioStream {

void callback(const std::span<float> samples) override;

void onopen() override;
void onstart() override;

private:

const std::shared_ptr<AudioEffect> effect;
Expand Down
23 changes: 11 additions & 12 deletions voicesmith/src/main/cpp/de/jurihock/voicesmith/io/AudioSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,7 @@ AudioSource::AudioSource(const std::optional<int> device,
const std::shared_ptr<AudioBlockQueue> queue) :
AudioStream(oboe::Direction::Input, device, samplerate, blocksize),
effect(effect),
queue((queue != nullptr) ? queue : std::make_shared<AudioBlockQueue>()) {

if (effect) {
onopen([this]() {
this->effect->reset(this->samplerate(), this->blocksize());
});
}

onstart([this]() {
this->index = {0, 0};
});
}
queue((queue != nullptr) ? queue : std::make_shared<AudioBlockQueue>()) {}

std::shared_ptr<AudioEffect> AudioSource::fx() const {
return effect;
Expand All @@ -46,3 +35,13 @@ void AudioSource::callback(const std::span<float> samples) {

++index.outer;
}

void AudioSource::onopen() {
if (effect) {
effect->reset(samplerate(), blocksize());
}
}

void AudioSource::onstart() {
index = {0, 0};
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ class AudioSource final : public AudioStream {

void callback(const std::span<float> samples) override;

void onopen() override;
void onstart() override;

private:

const std::shared_ptr<AudioEffect> effect;
Expand Down
Loading

0 comments on commit 7faab68

Please sign in to comment.