diff options
Diffstat (limited to 'drumgizmo/output')
-rw-r--r-- | drumgizmo/output/alsa.cc | 130 | ||||
-rw-r--r-- | drumgizmo/output/alsa.h | 50 | ||||
-rw-r--r-- | drumgizmo/output/jackaudio.cc | 79 | ||||
-rw-r--r-- | drumgizmo/output/jackaudio.h | 65 | ||||
-rw-r--r-- | drumgizmo/output/outputdummy.cc | 29 | ||||
-rw-r--r-- | drumgizmo/output/outputdummy.h | 28 | ||||
-rw-r--r-- | drumgizmo/output/wavfile.cc | 88 | ||||
-rw-r--r-- | drumgizmo/output/wavfile.h | 44 |
8 files changed, 258 insertions, 255 deletions
diff --git a/drumgizmo/output/alsa.cc b/drumgizmo/output/alsa.cc index 14a9c6d..26cb0cf 100644 --- a/drumgizmo/output/alsa.cc +++ b/drumgizmo/output/alsa.cc @@ -30,57 +30,59 @@ int const BUFFER_SIZE = 40960; -struct AlsaInitError { +struct AlsaInitError +{ int const code; std::string const msg; - - AlsaInitError(int op_code, std::string const & msg) - : code{code} - , msg{msg} { - } - - static inline void test(int code, std::string const & msg) { - if (code < 0) { + + AlsaInitError(int op_code, std::string const &msg) : code{code}, msg{msg} {} + + static inline void test(int code, std::string const &msg) + { + if (code < 0) + { throw AlsaInitError(code, msg); } } }; AlsaOutputEngine::AlsaOutputEngine() - : handle{nullptr} - , params{nullptr} - , data{} - , num_channels{0u} - , dev{"default"} - , srate{44100} - , frames{32} { + : handle{nullptr}, params{nullptr}, data{}, num_channels{0u}, + dev{"default"}, srate{44100}, frames{32} +{ } -AlsaOutputEngine::~AlsaOutputEngine() { +AlsaOutputEngine::~AlsaOutputEngine() +{ // note: do NOT release `params`, it was allocated by `alloca()` - - if (handle != nullptr) { + + if (handle != nullptr) + { snd_pcm_close(handle); } } -bool AlsaOutputEngine::init(Channels channels) { +bool AlsaOutputEngine::init(Channels channels) +{ // try to initialize alsa - try { + try + { int value = snd_pcm_open(&handle, dev.c_str(), SND_PCM_STREAM_PLAYBACK, 0); AlsaInitError::test(value, "snd_pcm_open"); num_channels = channels.size(); - if (handle == nullptr) { + if (handle == nullptr) + { std::cerr << "[AlsaOutputEngine] Failed to acquire " - << "hardware handle\n"; + << "hardware handle\n"; return false; } // Allocate and init a hardware parameters object snd_pcm_hw_params_alloca(¶ms); value = snd_pcm_hw_params_any(handle, params); AlsaInitError::test(value, "snd_pcm_hw_params_any"); - - value = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); + + value = snd_pcm_hw_params_set_access(handle, params, + SND_PCM_ACCESS_RW_INTERLEAVED); AlsaInitError::test(value, "snd_pcm_hw_params_set_access"); value = snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_FLOAT); AlsaInitError::test(value, "snd_pcm_hw_params_set_format"); @@ -92,67 +94,75 @@ bool AlsaOutputEngine::init(Channels channels) { AlsaInitError::test(value, "snd_pcm_hw_params_set_period_size_near"); value = snd_pcm_hw_params(handle, params); AlsaInitError::test(value, "snd_pcm_hw_params"); - - } catch (AlsaInitError const & error) { - std::cerr << "[AlsaOutputEngine] " << error.msg << " failed: " - << snd_strerror(error.code) << std::endl; + } + catch (AlsaInitError const &error) + { + std::cerr << "[AlsaOutputEngine] " << error.msg + << " failed: " << snd_strerror(error.code) << std::endl; return false; } - + data.clear(); data.resize(BUFFER_SIZE * num_channels); - + return true; } -void AlsaOutputEngine::setParm(std::string parm, std::string value) { - if (parm == "dev") { +void AlsaOutputEngine::setParm(std::string parm, std::string value) +{ + if (parm == "dev") + { // apply hardware device name dev = value; - - } else if (parm == "frames") { + } + else if (parm == "frames") + { // try to apply hardware buffer size - try { + try + { frames = std::stoi(value); - } catch (...) { - std::cerr << "[AlsaOutputEngine] Invalid buffer size " - << value << "\n"; } - } else if (parm == "srate") { - try { + catch (...) + { + std::cerr << "[AlsaOutputEngine] Invalid buffer size " << value << "\n"; + } + } + else if (parm == "srate") + { + try + { srate = std::stoi(value); - } catch (...) { - std::cerr << "[AlsaOutputEngine] Invalid samplerate " - << value << "\n"; } - } else { - std::cerr << "[AlsaOutputEngine] Unsupported parameter '" - << parm << "'\n"; + catch (...) + { + std::cerr << "[AlsaOutputEngine] Invalid samplerate " << value << "\n"; + } + } + else + { + std::cerr << "[AlsaOutputEngine] Unsupported parameter '" << parm << "'\n"; } } -bool AlsaOutputEngine::start() { - return true; -} +bool AlsaOutputEngine::start() { return true; } -void AlsaOutputEngine::stop() { -} +void AlsaOutputEngine::stop() {} -void AlsaOutputEngine::pre(size_t nsamples) { -} +void AlsaOutputEngine::pre(size_t nsamples) {} -void AlsaOutputEngine::run(int ch, sample_t* samples, size_t nsamples) { +void AlsaOutputEngine::run(int ch, sample_t *samples, size_t nsamples) +{ // Write channel data in interleaved buffer - for (auto i = 0u; i < nsamples; ++i) { + for (auto i = 0u; i < nsamples; ++i) + { data[i * num_channels + ch] = samples[i]; } } -void AlsaOutputEngine::post(size_t nsamples) { +void AlsaOutputEngine::post(size_t nsamples) +{ // Write the interleaved buffer to the soundcard snd_pcm_writei(handle, data.data(), nsamples); } -size_t AlsaOutputEngine::samplerate() { - return srate; -} +size_t AlsaOutputEngine::samplerate() { return srate; } diff --git a/drumgizmo/output/alsa.h b/drumgizmo/output/alsa.h index c7585e0..81d83cc 100644 --- a/drumgizmo/output/alsa.h +++ b/drumgizmo/output/alsa.h @@ -34,29 +34,29 @@ #include "audiooutputengine.h" -class AlsaOutputEngine - : public AudioOutputEngine { - public: - AlsaOutputEngine(); - ~AlsaOutputEngine(); - - // based on AudioOutputEngine - bool init(Channels chan) override; - void setParm(std::string parm, std::string value) override; - bool start() override; - void stop() override; - void pre(size_t nsamples) override; - void run(int ch, sample_t* samples, size_t nsamples) override; - void post(size_t nsamples) override; - size_t samplerate() override; - - private: - snd_pcm_t* handle; - snd_pcm_hw_params_t* params; - std::vector<sample_t> data; - size_t num_channels; - - std::string dev; - unsigned int srate; // samplerate - snd_pcm_uframes_t frames; +class AlsaOutputEngine : public AudioOutputEngine +{ +public: + AlsaOutputEngine(); + ~AlsaOutputEngine(); + + // based on AudioOutputEngine + bool init(Channels chan) override; + void setParm(std::string parm, std::string value) override; + bool start() override; + void stop() override; + void pre(size_t nsamples) override; + void run(int ch, sample_t *samples, size_t nsamples) override; + void post(size_t nsamples) override; + size_t samplerate() override; + +private: + snd_pcm_t *handle; + snd_pcm_hw_params_t *params; + std::vector<sample_t> data; + size_t num_channels; + + std::string dev; + unsigned int srate; // samplerate + snd_pcm_uframes_t frames; }; diff --git a/drumgizmo/output/jackaudio.cc b/drumgizmo/output/jackaudio.cc index 240037a..2c80080 100644 --- a/drumgizmo/output/jackaudio.cc +++ b/drumgizmo/output/jackaudio.cc @@ -29,31 +29,31 @@ #include "jackaudio.h" -JackAudioOutputEngine::JackAudioOutputEngine(JackClient& client) - : client(client) // wanna use initializer braces here but jenkins fails - , channels{} - , sema{"jackaudio"} { +JackAudioOutputEngine::JackAudioOutputEngine(JackClient &client) + : client(client), channels{}, sema{"jackaudio"} +{ client.add(*this); } -JackAudioOutputEngine::~JackAudioOutputEngine() { - client.remove(*this); -} +JackAudioOutputEngine::~JackAudioOutputEngine() { client.remove(*this); } -bool JackAudioOutputEngine::init(Channels data) { +bool JackAudioOutputEngine::init(Channels data) +{ channels.clear(); channels.reserve(data.size()); auto i = 0u; auto const buffer_size = getBufferSize(); - - for (auto const & elem: data) { + + for (auto const &elem : data) + { auto name = std::to_string(i) + "-" + elem.name; // initialize new channel channels.emplace_back(client, name, buffer_size); - - if (channels.back().port.port == nullptr) { + + if (channels.back().port.port == nullptr) + { std::cerr << "[JackAudioOutputEngine] Cannot create jack " - << "port for channel #" << i << "\n"; + << "port for channel #" << i << "\n"; return false; } ++i; @@ -61,53 +61,52 @@ bool JackAudioOutputEngine::init(Channels data) { return true; } -void JackAudioOutputEngine::setParm(std::string parm, std::string value) { -} +void JackAudioOutputEngine::setParm(std::string parm, std::string value) {} -bool JackAudioOutputEngine::start() { +bool JackAudioOutputEngine::start() +{ client.activate(); return true; } -void JackAudioOutputEngine::stop() { -} +void JackAudioOutputEngine::stop() {} -void JackAudioOutputEngine::pre(size_t nsamples) { -} +void JackAudioOutputEngine::pre(size_t nsamples) {} -void JackAudioOutputEngine::run(int ch, sample_t* samples, size_t nsamples) { - for (auto i = 0u; i < nsamples; ++i) { +void JackAudioOutputEngine::run(int ch, sample_t *samples, size_t nsamples) +{ + for (auto i = 0u; i < nsamples; ++i) + { channels[ch].samples[i] = samples[i]; } } -void JackAudioOutputEngine::post(size_t nsamples) { - sema.wait(); -} +void JackAudioOutputEngine::post(size_t nsamples) { sema.wait(); } -void JackAudioOutputEngine::process(jack_nframes_t num_frames) { +void JackAudioOutputEngine::process(jack_nframes_t num_frames) +{ assert(num_frames == getBufferSize()); - - for (auto& channel: channels) { - auto ptr = static_cast<jack_default_audio_sample_t*>( - jack_port_get_buffer(channel.port.port, num_frames)); - for (auto i = 0u; i < num_frames; ++i) { + + for (auto &channel : channels) + { + auto ptr = static_cast<jack_default_audio_sample_t *>( + jack_port_get_buffer(channel.port.port, num_frames)); + for (auto i = 0u; i < num_frames; ++i) + { ptr[i] = channel.samples[i]; } } sema.post(); } -size_t JackAudioOutputEngine::getBufferSize() { - return client.getBufferSize(); -} +size_t JackAudioOutputEngine::getBufferSize() { return client.getBufferSize(); } -size_t JackAudioOutputEngine::samplerate() { - return client.getSampleRate(); -} +size_t JackAudioOutputEngine::samplerate() { return client.getSampleRate(); } -JackAudioOutputEngine::Channel::Channel(JackClient& client, std::string const & name, std::size_t buffer_size) - : port{client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput} - , samples{} { +JackAudioOutputEngine::Channel::Channel(JackClient &client, + std::string const &name, + std::size_t buffer_size) + : port{client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput}, samples{} +{ samples.resize(buffer_size); } diff --git a/drumgizmo/output/jackaudio.h b/drumgizmo/output/jackaudio.h index 12539c5..dc66978 100644 --- a/drumgizmo/output/jackaudio.h +++ b/drumgizmo/output/jackaudio.h @@ -31,36 +31,37 @@ #include "audiooutputengine.h" #include "../jackclient.h" -class JackAudioOutputEngine - : public AudioOutputEngine - , public JackProcess { - public: - JackAudioOutputEngine(JackClient& client); - ~JackAudioOutputEngine(); - - // based on AudioOutputEngine - bool init(Channels chan) override; - void setParm(std::string parm, std::string value) override; - bool start() override; - void stop() override; - void pre(size_t nsamples) override; - void run(int ch, sample_t* samples, size_t nsamples) override; - void post(size_t nsamples) override; - size_t getBufferSize() override; - size_t samplerate() override; - - // based on JackProcess - void process(jack_nframes_t num_frames) override; - - private: - struct Channel { - JackPort port; - std::vector<sample_t> samples; - - Channel(JackClient& client, std::string const & name, std::size_t buffer_size); - }; - - JackClient& client; - std::vector<Channel> channels; - Semaphore sema; +class JackAudioOutputEngine : public AudioOutputEngine, public JackProcess +{ +public: + JackAudioOutputEngine(JackClient &client); + ~JackAudioOutputEngine(); + + // based on AudioOutputEngine + bool init(Channels chan) override; + void setParm(std::string parm, std::string value) override; + bool start() override; + void stop() override; + void pre(size_t nsamples) override; + void run(int ch, sample_t *samples, size_t nsamples) override; + void post(size_t nsamples) override; + size_t getBufferSize() override; + size_t samplerate() override; + + // based on JackProcess + void process(jack_nframes_t num_frames) override; + +private: + struct Channel + { + JackPort port; + std::vector<sample_t> samples; + + Channel(JackClient &client, std::string const &name, + std::size_t buffer_size); + }; + + JackClient &client; + std::vector<Channel> channels; + Semaphore sema; }; diff --git a/drumgizmo/output/outputdummy.cc b/drumgizmo/output/outputdummy.cc index 3c390a5..3a3d6a0 100644 --- a/drumgizmo/output/outputdummy.cc +++ b/drumgizmo/output/outputdummy.cc @@ -26,31 +26,20 @@ */ #include "outputdummy.h" -DummyOutputEngine::DummyOutputEngine() { -} +DummyOutputEngine::DummyOutputEngine() {} -DummyOutputEngine::~DummyOutputEngine() { -} +DummyOutputEngine::~DummyOutputEngine() {} -bool DummyOutputEngine::init(Channels data) { - return true; -} +bool DummyOutputEngine::init(Channels data) { return true; } -void DummyOutputEngine::setParm(std::string parm, std::string value) { -} +void DummyOutputEngine::setParm(std::string parm, std::string value) {} -bool DummyOutputEngine::start() { - return true; -} +bool DummyOutputEngine::start() { return true; } -void DummyOutputEngine::stop() { -} +void DummyOutputEngine::stop() {} -void DummyOutputEngine::pre(size_t nsamples) { -} +void DummyOutputEngine::pre(size_t nsamples) {} -void DummyOutputEngine::run(int ch, sample_t* samples, size_t nsamples) { -} +void DummyOutputEngine::run(int ch, sample_t *samples, size_t nsamples) {} -void DummyOutputEngine::post(size_t nsamples) { -} +void DummyOutputEngine::post(size_t nsamples) {} diff --git a/drumgizmo/output/outputdummy.h b/drumgizmo/output/outputdummy.h index e1e18c7..cfb3754 100644 --- a/drumgizmo/output/outputdummy.h +++ b/drumgizmo/output/outputdummy.h @@ -27,18 +27,18 @@ #pragma once #include "audiooutputengine.h" -class DummyOutputEngine - : public AudioOutputEngine { - public: - DummyOutputEngine(); - ~DummyOutputEngine(); - - // based on AudioOutputEngine - bool init(Channels chan) override; - void setParm(std::string parm, std::string value) override; - bool start() override; - void stop() override; - void pre(size_t nsamples) override; - void run(int ch, sample_t* samples, size_t nsamples) override; - void post(size_t nsamples) override; +class DummyOutputEngine : public AudioOutputEngine +{ +public: + DummyOutputEngine(); + ~DummyOutputEngine(); + + // based on AudioOutputEngine + bool init(Channels chan) override; + void setParm(std::string parm, std::string value) override; + bool start() override; + void stop() override; + void pre(size_t nsamples) override; + void run(int ch, sample_t *samples, size_t nsamples) override; + void post(size_t nsamples) override; }; diff --git a/drumgizmo/output/wavfile.cc b/drumgizmo/output/wavfile.cc index d8b8d99..9d4deb1 100644 --- a/drumgizmo/output/wavfile.cc +++ b/drumgizmo/output/wavfile.cc @@ -28,10 +28,8 @@ #include "wavfile.h" -WavfileOutputEngine::WavfileOutputEngine() - : info{} - , channels{} - , file{"output"} { +WavfileOutputEngine::WavfileOutputEngine() : info{}, channels{}, file{"output"} +{ info.frames = 0; info.samplerate = 44100; info.channels = 1; @@ -40,73 +38,79 @@ WavfileOutputEngine::WavfileOutputEngine() info.seekable = 0; } -WavfileOutputEngine::~WavfileOutputEngine() { - for (auto& ptr: channels) { - if (ptr != nullptr) { +WavfileOutputEngine::~WavfileOutputEngine() +{ + for (auto &ptr : channels) + { + if (ptr != nullptr) + { sf_close(ptr); } } } -bool WavfileOutputEngine::init(Channels data) { - channels.clear(), - channels.resize(data.size()); // value-initialized with null - for (auto i = 0u; i < data.size(); ++i) { +bool WavfileOutputEngine::init(Channels data) +{ + channels.clear(), channels.resize(data.size()); // value-initialized with null + for (auto i = 0u; i < data.size(); ++i) + { // write channel to file auto fname = file + data[i].name + "-" + std::to_string(i) + ".wav"; channels[i] = sf_open(fname.c_str(), SFM_WRITE, &info); - if (channels[i] == nullptr) { + if (channels[i] == nullptr) + { std::cerr << "[WaffileOutputEngine] Failed to initialize " - << "channel #" << i << "\n"; + << "channel #" << i << "\n"; return false; } } return true; } -void WavfileOutputEngine::setParm(std::string parm, std::string value) { - if (parm == "file") { +void WavfileOutputEngine::setParm(std::string parm, std::string value) +{ + if (parm == "file") + { // apply output filename prefix file = value; - - } else if (parm == "srate") { + } + else if (parm == "srate") + { // try to apply samplerate - try { + try + { info.samplerate = std::stoi(value); - } catch (...) { - std::cerr << "[WavfileOutputEngine] Invalid samplerate " - << value << "\n"; } - - } else { - std::cerr << "[WavfileOutputEngine] Unsupported parameter '" - << parm << "'\n"; + catch (...) + { + std::cerr << "[WavfileOutputEngine] Invalid samplerate " << value << "\n"; + } + } + else + { + std::cerr << "[WavfileOutputEngine] Unsupported parameter '" << parm + << "'\n"; } } -bool WavfileOutputEngine::start() { - return true; -} +bool WavfileOutputEngine::start() { return true; } -void WavfileOutputEngine::stop() { -} +void WavfileOutputEngine::stop() {} -void WavfileOutputEngine::pre(size_t nsamples) { -} +void WavfileOutputEngine::pre(size_t nsamples) {} -void WavfileOutputEngine::run(int ch, sample_t* samples, size_t nsamples) { - if (static_cast<unsigned int>(ch) >= channels.size()) { - std::cerr << "[WavfileOutputEngine] cannot access channel #" - << ch << " (" << channels.size() << " channels available)\n"; +void WavfileOutputEngine::run(int ch, sample_t *samples, size_t nsamples) +{ + if (static_cast<unsigned int>(ch) >= channels.size()) + { + std::cerr << "[WavfileOutputEngine] cannot access channel #" << ch << " (" + << channels.size() << " channels available)\n"; return; } - + sf_writef_float(channels[ch], samples, nsamples); } -void WavfileOutputEngine::post(size_t nsamples) { -} +void WavfileOutputEngine::post(size_t nsamples) {} -size_t WavfileOutputEngine::samplerate() { - return info.samplerate; -} +size_t WavfileOutputEngine::samplerate() { return info.samplerate; } diff --git a/drumgizmo/output/wavfile.h b/drumgizmo/output/wavfile.h index 5aa9306..7bc7666 100644 --- a/drumgizmo/output/wavfile.h +++ b/drumgizmo/output/wavfile.h @@ -32,26 +32,26 @@ #include "audiooutputengine.h" -class WavfileOutputEngine - : public AudioOutputEngine { - public: - WavfileOutputEngine(); - ~WavfileOutputEngine(); - - // based on AudioOutputEngine - bool init(Channels data) override; - void setParm(std::string parm, std::string value) override; - bool start() override; - void stop() override; - void pre(size_t nsamples) override; - void run(int ch, sample_t* samples, size_t nsamples) override; - void post(size_t nsamples) override; - size_t samplerate() override; - - private: - SF_INFO info; - std::vector<SNDFILE*> channels; - size_t num_channels; - - std::string file; +class WavfileOutputEngine : public AudioOutputEngine +{ +public: + WavfileOutputEngine(); + ~WavfileOutputEngine(); + + // based on AudioOutputEngine + bool init(Channels data) override; + void setParm(std::string parm, std::string value) override; + bool start() override; + void stop() override; + void pre(size_t nsamples) override; + void run(int ch, sample_t *samples, size_t nsamples) override; + void post(size_t nsamples) override; + size_t samplerate() override; + +private: + SF_INFO info; + std::vector<SNDFILE *> channels; + size_t num_channels; + + std::string file; }; |