mirror of https://github.com/auygun/kaliber.git
Rename AudioSink to AudioDevice
This commit is contained in:
parent
e08f6e2022
commit
02418aa42a
|
@ -2,9 +2,9 @@ source_set("audio") {
|
|||
sources = [
|
||||
"audio_bus.cc",
|
||||
"audio_bus.h",
|
||||
"audio_device.h",
|
||||
"audio_mixer.cc",
|
||||
"audio_mixer.h",
|
||||
"audio_sink.h",
|
||||
"mixer_input.cc",
|
||||
"mixer_input.h",
|
||||
"sinc_resampler.cc",
|
||||
|
@ -16,16 +16,16 @@ source_set("audio") {
|
|||
|
||||
if (target_os == "linux") {
|
||||
sources += [
|
||||
"audio_sink_alsa.cc",
|
||||
"audio_sink_alsa.h",
|
||||
"audio_device_alsa.cc",
|
||||
"audio_device_alsa.h",
|
||||
]
|
||||
libs += [ "asound" ]
|
||||
} else if (target_os == "win") {
|
||||
sources += [ "audio_sink_null.h" ]
|
||||
sources += [ "audio_device_null.h" ]
|
||||
} else if (target_os == "android") {
|
||||
sources += [
|
||||
"audio_sink_oboe.cc",
|
||||
"audio_sink_oboe.h",
|
||||
"audio_device_oboe.cc",
|
||||
"audio_device_oboe.h",
|
||||
]
|
||||
deps += [ "//src/third_party/oboe" ]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef ENGINE_AUDIO_AUDIO_DEVICE_H
|
||||
#define ENGINE_AUDIO_AUDIO_DEVICE_H
|
||||
|
||||
namespace eng {
|
||||
|
||||
// Models an audio device sending mixed audio to the audio driver. Audio data
|
||||
// from the mixer source is delivered on a pull model using Delegate.
|
||||
class AudioDevice {
|
||||
public:
|
||||
class Delegate {
|
||||
public:
|
||||
Delegate() = default;
|
||||
virtual ~Delegate() = default;
|
||||
|
||||
virtual int GetChannelCount() = 0;
|
||||
|
||||
virtual void RenderAudio(float* output_buffer, size_t num_frames) = 0;
|
||||
};
|
||||
|
||||
AudioDevice() = default;
|
||||
virtual ~AudioDevice() = default;
|
||||
|
||||
virtual bool Initialize() = 0;
|
||||
|
||||
virtual void Suspend() = 0;
|
||||
virtual void Resume() = 0;
|
||||
|
||||
virtual size_t GetHardwareSampleRate() = 0;
|
||||
|
||||
private:
|
||||
AudioDevice(const AudioDevice&) = delete;
|
||||
AudioDevice& operator=(const AudioDevice&) = delete;
|
||||
};
|
||||
|
||||
} // namespace eng
|
||||
|
||||
#endif // ENGINE_AUDIO_AUDIO_DEVICE_H
|
|
@ -1,4 +1,4 @@
|
|||
#include "engine/audio/audio_sink_alsa.h"
|
||||
#include "engine/audio/audio_device_alsa.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
@ -11,10 +11,10 @@ using namespace base;
|
|||
|
||||
namespace eng {
|
||||
|
||||
AudioSinkAlsa::AudioSinkAlsa(AudioSink::Delegate* delegate)
|
||||
AudioDeviceAlsa::AudioDeviceAlsa(AudioDevice::Delegate* delegate)
|
||||
: delegate_(delegate) {}
|
||||
|
||||
AudioSinkAlsa::~AudioSinkAlsa() {
|
||||
AudioDeviceAlsa::~AudioDeviceAlsa() {
|
||||
LOG(0) << "Shutting down audio.";
|
||||
|
||||
TerminateAudioThread();
|
||||
|
@ -22,7 +22,7 @@ AudioSinkAlsa::~AudioSinkAlsa() {
|
|||
snd_pcm_close(device_);
|
||||
}
|
||||
|
||||
bool AudioSinkAlsa::Initialize() {
|
||||
bool AudioDeviceAlsa::Initialize() {
|
||||
LOG(0) << "Initializing audio.";
|
||||
|
||||
int err;
|
||||
|
@ -145,28 +145,28 @@ bool AudioSinkAlsa::Initialize() {
|
|||
return false;
|
||||
}
|
||||
|
||||
void AudioSinkAlsa::Suspend() {
|
||||
void AudioDeviceAlsa::Suspend() {
|
||||
suspend_audio_thread_.store(true, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
void AudioSinkAlsa::Resume() {
|
||||
void AudioDeviceAlsa::Resume() {
|
||||
suspend_audio_thread_.store(false, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
size_t AudioSinkAlsa::GetHardwareSampleRate() {
|
||||
size_t AudioDeviceAlsa::GetHardwareSampleRate() {
|
||||
return sample_rate_;
|
||||
}
|
||||
|
||||
void AudioSinkAlsa::StartAudioThread() {
|
||||
void AudioDeviceAlsa::StartAudioThread() {
|
||||
DCHECK(!audio_thread_.joinable());
|
||||
|
||||
LOG(0) << "Starting audio thread.";
|
||||
terminate_audio_thread_.store(false, std::memory_order_relaxed);
|
||||
suspend_audio_thread_.store(false, std::memory_order_relaxed);
|
||||
audio_thread_ = std::thread(&AudioSinkAlsa::AudioThreadMain, this);
|
||||
audio_thread_ = std::thread(&AudioDeviceAlsa::AudioThreadMain, this);
|
||||
}
|
||||
|
||||
void AudioSinkAlsa::TerminateAudioThread() {
|
||||
void AudioDeviceAlsa::TerminateAudioThread() {
|
||||
if (!audio_thread_.joinable())
|
||||
return;
|
||||
|
||||
|
@ -176,7 +176,7 @@ void AudioSinkAlsa::TerminateAudioThread() {
|
|||
audio_thread_.join();
|
||||
}
|
||||
|
||||
void AudioSinkAlsa::AudioThreadMain() {
|
||||
void AudioDeviceAlsa::AudioThreadMain() {
|
||||
DCHECK(delegate_);
|
||||
|
||||
size_t num_frames = period_size_ / (num_channels_ * sizeof(float));
|
|
@ -1,19 +1,19 @@
|
|||
#ifndef ENGINE_AUDIO_AUDIO_SINK_ALSA_H
|
||||
#define ENGINE_AUDIO_AUDIO_SINK_ALSA_H
|
||||
#ifndef ENGINE_AUDIO_AUDIO_DEVICE_ALSA_H
|
||||
#define ENGINE_AUDIO_AUDIO_DEVICE_ALSA_H
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
#include "engine/audio/audio_sink.h"
|
||||
#include "engine/audio/audio_device.h"
|
||||
|
||||
typedef struct _snd_pcm snd_pcm_t;
|
||||
|
||||
namespace eng {
|
||||
|
||||
class AudioSinkAlsa final : public AudioSink {
|
||||
class AudioDeviceAlsa final : public AudioDevice {
|
||||
public:
|
||||
AudioSinkAlsa(AudioSink::Delegate* delegate);
|
||||
~AudioSinkAlsa() final;
|
||||
AudioDeviceAlsa(AudioDevice::Delegate* delegate);
|
||||
~AudioDeviceAlsa() final;
|
||||
|
||||
bool Initialize() final;
|
||||
|
||||
|
@ -34,7 +34,7 @@ class AudioSinkAlsa final : public AudioSink {
|
|||
size_t sample_rate_ = 0;
|
||||
size_t period_size_ = 0;
|
||||
|
||||
AudioSink::Delegate* delegate_ = nullptr;
|
||||
AudioDevice::Delegate* delegate_ = nullptr;
|
||||
|
||||
void StartAudioThread();
|
||||
void TerminateAudioThread();
|
||||
|
@ -44,4 +44,4 @@ class AudioSinkAlsa final : public AudioSink {
|
|||
|
||||
} // namespace eng
|
||||
|
||||
#endif // ENGINE_AUDIO_AUDIO_SINK_ALSA_H
|
||||
#endif // ENGINE_AUDIO_AUDIO_DEVICE_ALSA_H
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef ENGINE_AUDIO_AUDIO_DEVICE_NULL_H
|
||||
#define ENGINE_AUDIO_AUDIO_DEVICE_NULL_H
|
||||
|
||||
#include "engine/audio/audio_device.h"
|
||||
|
||||
namespace eng {
|
||||
|
||||
class AudioDeviceNull final : public AudioDevice {
|
||||
public:
|
||||
AudioDeviceNull() = default;
|
||||
~AudioDeviceNull() final = default;
|
||||
|
||||
bool Initialize() final { return true; }
|
||||
|
||||
void Suspend() final {}
|
||||
void Resume() final {}
|
||||
|
||||
size_t GetHardwareSampleRate() final { return 0; }
|
||||
};
|
||||
|
||||
} // namespace eng
|
||||
|
||||
#endif // ENGINE_AUDIO_AUDIO_DEVICE_NULL_H
|
|
@ -1,4 +1,4 @@
|
|||
#include "engine/audio/audio_sink_oboe.h"
|
||||
#include "engine/audio/audio_device_oboe.h"
|
||||
|
||||
#include "base/log.h"
|
||||
#include "third_party/oboe/include/oboe/Oboe.h"
|
||||
|
@ -7,54 +7,54 @@ using namespace base;
|
|||
|
||||
namespace eng {
|
||||
|
||||
AudioSinkOboe::AudioSinkOboe(AudioSink::Delegate* delegate)
|
||||
AudioDeviceOboe::AudioDeviceOboe(AudioDevice::Delegate* delegate)
|
||||
: callback_(std::make_unique<StreamCallback>(this)), delegate_(delegate) {}
|
||||
|
||||
AudioSinkOboe::~AudioSinkOboe() {
|
||||
AudioDeviceOboe::~AudioDeviceOboe() {
|
||||
LOG(0) << "Shutting down audio.";
|
||||
stream_->stop();
|
||||
}
|
||||
|
||||
bool AudioSinkOboe::Initialize() {
|
||||
bool AudioDeviceOboe::Initialize() {
|
||||
LOG(0) << "Initializing audio.";
|
||||
return RestartStream();
|
||||
}
|
||||
|
||||
void AudioSinkOboe::Suspend() {
|
||||
void AudioDeviceOboe::Suspend() {
|
||||
stream_->pause();
|
||||
}
|
||||
|
||||
void AudioSinkOboe::Resume() {
|
||||
void AudioDeviceOboe::Resume() {
|
||||
stream_->start();
|
||||
}
|
||||
|
||||
size_t AudioSinkOboe::GetHardwareSampleRate() {
|
||||
size_t AudioDeviceOboe::GetHardwareSampleRate() {
|
||||
return stream_->getSampleRate();
|
||||
}
|
||||
|
||||
AudioSinkOboe::StreamCallback::StreamCallback(AudioSinkOboe* audio_sink)
|
||||
: audio_sink_(audio_sink) {}
|
||||
AudioDeviceOboe::StreamCallback::StreamCallback(AudioDeviceOboe* audio_device)
|
||||
: audio_device_(audio_device) {}
|
||||
|
||||
AudioSinkOboe::StreamCallback::~StreamCallback() = default;
|
||||
AudioDeviceOboe::StreamCallback::~StreamCallback() = default;
|
||||
|
||||
oboe::DataCallbackResult AudioSinkOboe::StreamCallback::onAudioReady(
|
||||
oboe::DataCallbackResult AudioDeviceOboe::StreamCallback::onAudioReady(
|
||||
oboe::AudioStream* oboe_stream,
|
||||
void* audio_data,
|
||||
int32_t num_frames) {
|
||||
float* output_buffer = static_cast<float*>(audio_data);
|
||||
audio_sink_->delegate_->RenderAudio(output_buffer, num_frames);
|
||||
audio_device_->delegate_->RenderAudio(output_buffer, num_frames);
|
||||
return oboe::DataCallbackResult::Continue;
|
||||
}
|
||||
|
||||
void AudioSinkOboe::StreamCallback::onErrorAfterClose(
|
||||
void AudioDeviceOboe::StreamCallback::onErrorAfterClose(
|
||||
oboe::AudioStream* oboe_stream,
|
||||
oboe::Result error) {
|
||||
LOG(0) << "Error after close. Error: " << oboe::convertToText(error);
|
||||
|
||||
audio_sink_->RestartStream();
|
||||
audio_device_->RestartStream();
|
||||
}
|
||||
|
||||
bool AudioSinkOboe::RestartStream() {
|
||||
bool AudioDeviceOboe::RestartStream() {
|
||||
oboe::AudioStreamBuilder builder;
|
||||
oboe::Result result =
|
||||
builder.setSharingMode(oboe::SharingMode::Exclusive)
|
|
@ -1,19 +1,19 @@
|
|||
#ifndef ENGINE_AUDIO_AUDIO_SINK_OBOE_H
|
||||
#define ENGINE_AUDIO_AUDIO_SINK_OBOE_H
|
||||
#ifndef ENGINE_AUDIO_AUDIO_DEVICE_OBOE_H
|
||||
#define ENGINE_AUDIO_AUDIO_DEVICE_OBOE_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "third_party/oboe/include/oboe/AudioStream.h"
|
||||
#include "third_party/oboe/include/oboe/AudioStreamCallback.h"
|
||||
|
||||
#include "engine/audio/audio_sink.h"
|
||||
#include "engine/audio/audio_device.h"
|
||||
|
||||
namespace eng {
|
||||
|
||||
class AudioSinkOboe final : public AudioSink {
|
||||
class AudioDeviceOboe final : public AudioDevice {
|
||||
public:
|
||||
AudioSinkOboe(AudioSink::Delegate* delegate);
|
||||
~AudioSinkOboe() final;
|
||||
AudioDeviceOboe(AudioDevice::Delegate* delegate);
|
||||
~AudioDeviceOboe() final;
|
||||
|
||||
bool Initialize() final;
|
||||
|
||||
|
@ -25,7 +25,7 @@ class AudioSinkOboe final : public AudioSink {
|
|||
private:
|
||||
class StreamCallback final : public oboe::AudioStreamCallback {
|
||||
public:
|
||||
StreamCallback(AudioSinkOboe* audio);
|
||||
StreamCallback(AudioDeviceOboe* audio);
|
||||
~StreamCallback() final;
|
||||
|
||||
oboe::DataCallbackResult onAudioReady(oboe::AudioStream* oboe_stream,
|
||||
|
@ -36,17 +36,17 @@ class AudioSinkOboe final : public AudioSink {
|
|||
oboe::Result error) final;
|
||||
|
||||
private:
|
||||
AudioSinkOboe* audio_sink_;
|
||||
AudioDeviceOboe* audio_device_;
|
||||
};
|
||||
|
||||
oboe::ManagedStream stream_;
|
||||
std::unique_ptr<StreamCallback> callback_;
|
||||
|
||||
AudioSink::Delegate* delegate_ = nullptr;
|
||||
AudioDevice::Delegate* delegate_ = nullptr;
|
||||
|
||||
bool RestartStream();
|
||||
};
|
||||
|
||||
} // namespace eng
|
||||
|
||||
#endif // ENGINE_AUDIO_AUDIO_SINK_OBOE_H
|
||||
#endif // ENGINE_AUDIO_AUDIO_DEVICE_OBOE_H
|
|
@ -8,11 +8,11 @@
|
|||
#include "engine/audio/mixer_input.h"
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#include "engine/audio/audio_sink_oboe.h"
|
||||
#include "engine/audio/audio_device_oboe.h"
|
||||
#elif defined(__linux__)
|
||||
#include "engine/audio/audio_sink_alsa.h"
|
||||
#include "engine/audio/audio_device_alsa.h"
|
||||
#elif defined(_WIN32)
|
||||
#include "engine/audio/audio_sink_null.h"
|
||||
#include "engine/audio/audio_device_null.h"
|
||||
#endif
|
||||
|
||||
using namespace base;
|
||||
|
@ -22,19 +22,19 @@ namespace eng {
|
|||
AudioMixer::AudioMixer()
|
||||
: main_thread_task_runner_(TaskRunner::GetThreadLocalTaskRunner()),
|
||||
#if defined(__ANDROID__)
|
||||
audio_sink_{std::make_unique<AudioSinkOboe>(this)} {
|
||||
audio_device_{std::make_unique<AudioDeviceOboe>(this)} {
|
||||
#elif defined(__linux__)
|
||||
audio_sink_{std::make_unique<AudioSinkAlsa>(this)} {
|
||||
audio_device_{std::make_unique<AudioDeviceAlsa>(this)} {
|
||||
#elif defined(_WIN32)
|
||||
// TODO: Implement AudioSinkWindows
|
||||
audio_sink_{std::make_unique<AudioSinkNull>()} {
|
||||
// TODO: Implement AudioDeviceWindows
|
||||
audio_device_{std::make_unique<AudioDeviceNull>()} {
|
||||
#endif
|
||||
bool res = audio_sink_->Initialize();
|
||||
CHECK(res) << "Failed to initialize audio sink.";
|
||||
bool res = audio_device_->Initialize();
|
||||
CHECK(res) << "Failed to initialize audio device.";
|
||||
}
|
||||
|
||||
AudioMixer::~AudioMixer() {
|
||||
audio_sink_.reset();
|
||||
audio_device_.reset();
|
||||
}
|
||||
|
||||
void AudioMixer::AddInput(std::shared_ptr<MixerInput> mixer_input) {
|
||||
|
@ -45,15 +45,15 @@ void AudioMixer::AddInput(std::shared_ptr<MixerInput> mixer_input) {
|
|||
}
|
||||
|
||||
void AudioMixer::Suspend() {
|
||||
audio_sink_->Suspend();
|
||||
audio_device_->Suspend();
|
||||
}
|
||||
|
||||
void AudioMixer::Resume() {
|
||||
audio_sink_->Resume();
|
||||
audio_device_->Resume();
|
||||
}
|
||||
|
||||
size_t AudioMixer::GetHardwareSampleRate() {
|
||||
return audio_sink_->GetHardwareSampleRate();
|
||||
return audio_device_->GetHardwareSampleRate();
|
||||
}
|
||||
|
||||
void AudioMixer::RenderAudio(float* output_buffer, size_t num_frames) {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <mutex>
|
||||
|
||||
#include "base/closure.h"
|
||||
#include "engine/audio/audio_sink.h"
|
||||
#include "engine/audio/audio_device.h"
|
||||
|
||||
namespace base {
|
||||
class TaskRunner;
|
||||
|
@ -21,9 +21,9 @@ class MixerInput;
|
|||
// when it needs more data. Input source will be removed once end-of-stream is
|
||||
// reached. Any unfilled frames will be filled with silence. The mixer always
|
||||
// outputs audio when active, even if input sources underflow. A platform
|
||||
// specific AudioSink implementation is expected to periodically call
|
||||
// specific AudioDevice implementation is expected to periodically call
|
||||
// RenderAudio() in a background thread.
|
||||
class AudioMixer : public AudioSink::Delegate {
|
||||
class AudioMixer : public AudioDevice::Delegate {
|
||||
public:
|
||||
AudioMixer();
|
||||
~AudioMixer();
|
||||
|
@ -48,11 +48,11 @@ class AudioMixer : public AudioSink::Delegate {
|
|||
|
||||
std::shared_ptr<base::TaskRunner> main_thread_task_runner_;
|
||||
|
||||
std::unique_ptr<AudioSink> audio_sink_;
|
||||
std::unique_ptr<AudioDevice> audio_device_;
|
||||
|
||||
bool audio_enabled_ = true;
|
||||
|
||||
// AudioSink::Delegate interface
|
||||
// AudioDevice::Delegate interface
|
||||
int GetChannelCount() final { return kChannelCount; }
|
||||
void RenderAudio(float* output_buffer, size_t num_frames) final;
|
||||
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
#ifndef ENGINE_AUDIO_AUDIO_SINK_H
|
||||
#define ENGINE_AUDIO_AUDIO_SINK_H
|
||||
|
||||
namespace eng {
|
||||
|
||||
// Models an audio sink sending mixed audio to the audio driver. Audio data from
|
||||
// the mixer source is delivered on a pull model using Delegate.
|
||||
class AudioSink {
|
||||
public:
|
||||
class Delegate {
|
||||
public:
|
||||
Delegate() = default;
|
||||
virtual ~Delegate() = default;
|
||||
|
||||
virtual int GetChannelCount() = 0;
|
||||
|
||||
virtual void RenderAudio(float* output_buffer, size_t num_frames) = 0;
|
||||
};
|
||||
|
||||
AudioSink() = default;
|
||||
virtual ~AudioSink() = default;
|
||||
|
||||
virtual bool Initialize() = 0;
|
||||
|
||||
virtual void Suspend() = 0;
|
||||
virtual void Resume() = 0;
|
||||
|
||||
virtual size_t GetHardwareSampleRate() = 0;
|
||||
|
||||
private:
|
||||
AudioSink(const AudioSink&) = delete;
|
||||
AudioSink& operator=(const AudioSink&) = delete;
|
||||
};
|
||||
|
||||
} // namespace eng
|
||||
|
||||
#endif // ENGINE_AUDIO_AUDIO_SINK_H
|
|
@ -1,23 +0,0 @@
|
|||
#ifndef ENGINE_AUDIO_AUDIO_SINK_NULL_H
|
||||
#define ENGINE_AUDIO_AUDIO_SINK_NULL_H
|
||||
|
||||
#include "engine/audio/audio_sink.h"
|
||||
|
||||
namespace eng {
|
||||
|
||||
class AudioSinkNull final : public AudioSink {
|
||||
public:
|
||||
AudioSinkNull() = default;
|
||||
~AudioSinkNull() final = default;
|
||||
|
||||
bool Initialize() final { return true; }
|
||||
|
||||
void Suspend() final {}
|
||||
void Resume() final {}
|
||||
|
||||
size_t GetHardwareSampleRate() final { return 0; }
|
||||
};
|
||||
|
||||
} // namespace eng
|
||||
|
||||
#endif // ENGINE_AUDIO_AUDIO_SINK_NULL_H
|
|
@ -11,8 +11,8 @@ namespace eng {
|
|||
class AudioBus;
|
||||
class AudioMixer;
|
||||
|
||||
// An audio input stream that gets mixed and rendered to the audio sink. Handles
|
||||
// playback and volume control.
|
||||
// An audio input stream that gets mixed and rendered to the audio device.
|
||||
// Handles playback and volume control.
|
||||
class MixerInput : public std::enable_shared_from_this<MixerInput> {
|
||||
public:
|
||||
enum Flags { kLoop = 1, kStopped = 2, kSimulateStereo = 4 };
|
||||
|
|
Loading…
Reference in New Issue