From 100e2d3bd46f64df730c8a375559680c577036ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Gl=C3=B6ckner?= Date: Mon, 25 Jan 2016 14:14:22 +0100 Subject: applied clang-format --- drumgizmo/drumgizmoc.cc | 2 +- drumgizmo/enginefactory.cc | 61 +++++++++------ drumgizmo/enginefactory.h | 51 ++++++------ drumgizmo/input/inputdummy.cc | 29 +++---- drumgizmo/input/inputdummy.h | 28 +++---- drumgizmo/input/jackmidi.cc | 99 ++++++++++++------------ drumgizmo/input/jackmidi.h | 59 +++++++------- drumgizmo/input/midifile.cc | 166 +++++++++++++++++++++++----------------- drumgizmo/input/midifile.h | 54 ++++++------- drumgizmo/jackclient.cc | 62 ++++++++------- drumgizmo/jackclient.h | 56 +++++++------- drumgizmo/output/alsa.cc | 130 ++++++++++++++++--------------- drumgizmo/output/alsa.h | 50 ++++++------ drumgizmo/output/jackaudio.cc | 79 ++++++++++--------- drumgizmo/output/jackaudio.h | 65 ++++++++-------- drumgizmo/output/outputdummy.cc | 29 +++---- drumgizmo/output/outputdummy.h | 28 +++---- drumgizmo/output/wavfile.cc | 88 +++++++++++---------- drumgizmo/output/wavfile.h | 44 +++++------ 19 files changed, 610 insertions(+), 570 deletions(-) diff --git a/drumgizmo/drumgizmoc.cc b/drumgizmo/drumgizmoc.cc index 25012f8..6f21d14 100644 --- a/drumgizmo/drumgizmoc.cc +++ b/drumgizmo/drumgizmoc.cc @@ -1,6 +1,6 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** - * cli.cc + * drumgizmoc.cc * * Thu Sep 16 10:23:22 CEST 2010 * Copyright 2010 Bent Bisballe Nyeng diff --git a/drumgizmo/enginefactory.cc b/drumgizmo/enginefactory.cc index 06f8141..b5368ac 100644 --- a/drumgizmo/enginefactory.cc +++ b/drumgizmo/enginefactory.cc @@ -29,14 +29,12 @@ #include "cpp11fix.h" // required for c++11 #include "enginefactory.h" -EngineFactory::EngineFactory() - : input{} - , output{} +EngineFactory::EngineFactory() : input{}, output {} #ifdef USE_JACK - , jack{nullptr} +, jack { nullptr } #endif { - // list available input engines +// list available input engines #ifdef HAVE_INPUT_DUMMY input.push_back("inputdummy"); #endif @@ -46,8 +44,8 @@ EngineFactory::EngineFactory() #ifdef HAVE_INPUT_JACKMIDI input.push_back("jackmidi"); #endif - - // list available output engines + +// list available output engines #ifdef HAVE_OUTPUT_DUMMY output.push_back("outputdummy"); #endif @@ -63,70 +61,85 @@ EngineFactory::EngineFactory() } #ifdef USE_JACK -void EngineFactory::prepareJack() { - if (jack == nullptr) { +void EngineFactory::prepareJack() +{ + if (jack == nullptr) + { jack = std::make_unique(); } } #endif -std::list const & EngineFactory::getInputEngines() const { +std::list const &EngineFactory::getInputEngines() const +{ return input; } -std::list const & EngineFactory::getOutputEngines() const { +std::list const &EngineFactory::getOutputEngines() const +{ return output; } -std::unique_ptr EngineFactory::createInput(std::string const & name) { +std::unique_ptr +EngineFactory::createInput(std::string const &name) +{ #ifdef HAVE_INPUT_DUMMY - if (name == "dummy") { + if (name == "dummy") + { return std::make_unique(); } #endif #ifdef HAVE_INPUT_MIDIFILE - if (name == "midifile") { + if (name == "midifile") + { return std::make_unique(); } #endif #ifdef HAVE_INPUT_JACKMIDI - if (name == "jackmidi") { + if (name == "jackmidi") + { prepareJack(); return std::make_unique(*jack); } #endif - + // todo: add more engines - + std::cerr << "[EngineFactory] Unsupported input engine '" << name << "'\n"; return nullptr; } -std::unique_ptr EngineFactory::createOutput(std::string const & name) { +std::unique_ptr +EngineFactory::createOutput(std::string const &name) +{ #ifdef HAVE_OUTPUT_DUMMY - if (name == "dummy") { + if (name == "dummy") + { return std::make_unique(); } #endif #ifdef HAVE_OUTPUT_WAVFILE - if (name == "wavfile") { + if (name == "wavfile") + { return std::make_unique(); } #endif #ifdef HAVE_OUTPUT_ALSA - if (name == "alsa") { + if (name == "alsa") + { return std::make_unique(); } #endif #ifdef HAVE_OUTPUT_JACKAUDIO - if (name == "jackaudio") { + if (name == "jackaudio") + { prepareJack(); return std::make_unique(*jack); } #endif - + // todo: add more engines - + std::cerr << "[EngineFactory] Unsupported output engine '" << name << "'\n"; return nullptr; } diff --git a/drumgizmo/enginefactory.h b/drumgizmo/enginefactory.h index f00df99..2d8da80 100644 --- a/drumgizmo/enginefactory.h +++ b/drumgizmo/enginefactory.h @@ -33,54 +33,55 @@ #include "audiooutputengine.h" #if defined(HAVE_INPUT_JACKMIDI) || defined(HAVE_OUTPUT_JACKAUDIO) - #define USE_JACK - #include "jackclient.h" +#define USE_JACK +#include "jackclient.h" #endif #ifdef HAVE_INPUT_DUMMY - #include "input/inputdummy.h" +#include "input/inputdummy.h" #endif #ifdef HAVE_INPUT_MIDIFILE - #include "input/midifile.h" +#include "input/midifile.h" #endif #ifdef HAVE_INPUT_JACKMIDI - #include "input/jackmidi.h" +#include "input/jackmidi.h" #endif #ifdef HAVE_OUTPUT_DUMMY - #include "output/outputdummy.h" +#include "output/outputdummy.h" #endif #ifdef HAVE_OUTPUT_WAVFILE - #include "output/wavfile.h" +#include "output/wavfile.h" #endif #ifdef HAVE_OUTPUT_ALSA - #include "output/alsa.h" +#include "output/alsa.h" #endif #ifdef HAVE_OUTPUT_JACKAUDIO - #include "output/jackaudio.h" +#include "output/jackaudio.h" #endif -class EngineFactory { - private: - std::list input, output; // available engines - +class EngineFactory +{ +private: + std::list input, output; // available engines + #ifdef USE_JACK - std::unique_ptr jack; - - void prepareJack(); + std::unique_ptr jack; + + void prepareJack(); #endif - - public: - EngineFactory(); - - std::list const & getInputEngines() const; - std::list const & getOutputEngines() const; - - std::unique_ptr createInput(std::string const & name); - std::unique_ptr createOutput(std::string const & name); + +public: + EngineFactory(); + + std::list const &getInputEngines() const; + std::list const &getOutputEngines() const; + + std::unique_ptr createInput(std::string const &name); + std::unique_ptr createOutput(std::string const &name); }; diff --git a/drumgizmo/input/inputdummy.cc b/drumgizmo/input/inputdummy.cc index f078cd5..f2d33b7 100644 --- a/drumgizmo/input/inputdummy.cc +++ b/drumgizmo/input/inputdummy.cc @@ -26,33 +26,24 @@ */ #include "inputdummy.h" -DummyInputEngine::DummyInputEngine() { -} +DummyInputEngine::DummyInputEngine() {} -DummyInputEngine::~DummyInputEngine() { -} +DummyInputEngine::~DummyInputEngine() {} -bool DummyInputEngine::init(Instruments& instruments) { - return true; -} +bool DummyInputEngine::init(Instruments &instruments) { return true; } -void DummyInputEngine::setParm(std::string parm, std::string value) { -} +void DummyInputEngine::setParm(std::string parm, std::string value) {} -bool DummyInputEngine::start() { - return true; -} +bool DummyInputEngine::start() { return true; } -void DummyInputEngine::stop() { -} +void DummyInputEngine::stop() {} -void DummyInputEngine::pre() { -} +void DummyInputEngine::pre() {} -event_t* DummyInputEngine::run(size_t pos, size_t len, size_t *nevents) { +event_t *DummyInputEngine::run(size_t pos, size_t len, size_t *nevents) +{ nevents = 0u; return nullptr; } -void DummyInputEngine::post() { -} +void DummyInputEngine::post() {} diff --git a/drumgizmo/input/inputdummy.h b/drumgizmo/input/inputdummy.h index b047ba7..fb84443 100644 --- a/drumgizmo/input/inputdummy.h +++ b/drumgizmo/input/inputdummy.h @@ -27,18 +27,18 @@ #pragma once #include -class DummyInputEngine - : public AudioInputEngine { - public: - DummyInputEngine(); - ~DummyInputEngine(); - - // based on AudioInputEngine - bool init(Instruments &instruments) override; - void setParm(std::string parm, std::string value) override; - bool start() override; - void stop() override; - void pre() override; - event_t* run(size_t pos, size_t len, size_t* nevents) override; - void post() override; +class DummyInputEngine : public AudioInputEngine +{ +public: + DummyInputEngine(); + ~DummyInputEngine(); + + // based on AudioInputEngine + bool init(Instruments &instruments) override; + void setParm(std::string parm, std::string value) override; + bool start() override; + void stop() override; + void pre() override; + event_t *run(size_t pos, size_t len, size_t *nevents) override; + void post() override; }; diff --git a/drumgizmo/input/jackmidi.cc b/drumgizmo/input/jackmidi.cc index ba4e8b3..5ae6add 100644 --- a/drumgizmo/input/jackmidi.cc +++ b/drumgizmo/input/jackmidi.cc @@ -32,101 +32,103 @@ int const NOTE_ON = 0x90; -JackMidiInputEngine::JackMidiInputEngine(JackClient& client) - : AudioInputEngine{} - , JackProcess{} - , client(client) - , port{nullptr} - , midimap{} - , midi_mapper{} - , pos{0u} - , list{nullptr} - , listsize{0u} { +JackMidiInputEngine::JackMidiInputEngine(JackClient &client) + : AudioInputEngine{}, JackProcess{}, client(client), port{nullptr}, + midimap{}, midi_mapper{}, pos{0u}, list{nullptr}, listsize{0u} +{ client.add(*this); } -JackMidiInputEngine::~JackMidiInputEngine() { - client.remove(*this); -} +JackMidiInputEngine::~JackMidiInputEngine() { client.remove(*this); } -bool JackMidiInputEngine::isMidiEngine() { - return true; -} +bool JackMidiInputEngine::isMidiEngine() { return true; } -bool JackMidiInputEngine::init(Instruments& instruments) { - if (midimap == "") { +bool JackMidiInputEngine::init(Instruments &instruments) +{ + if (midimap == "") + { std::cerr << "[JackMidiInputEngine] Missing midimap filename\n"; return false; } MidiMapParser p{midimap}; - if (p.parse()) { - std::cerr << "[JackmidiInputEngine] Failed to parse midimap '" - << midimap << "'\n"; + if (p.parse()) + { + std::cerr << "[JackmidiInputEngine] Failed to parse midimap '" << midimap + << "'\n"; return false; } midi_mapper.midimap = p.midimap; - for (auto i = 0u; i < instruments.size(); ++i) { + for (auto i = 0u; i < instruments.size(); ++i) + { auto name = instruments[i]->name(); midi_mapper.instrmap[name] = i; } port = std::make_unique(client, "drumgizmo_midiin", - JACK_DEFAULT_MIDI_TYPE, JackPortIsInput); + JACK_DEFAULT_MIDI_TYPE, JackPortIsInput); return true; } -void JackMidiInputEngine::setParm(std::string parm, std::string value) { - if (parm == "midimap") { +void JackMidiInputEngine::setParm(std::string parm, std::string value) +{ + if (parm == "midimap") + { // apply midimap filename midimap = value; - - } else { - std::cerr << "[JackMidiInputEngine] Unsupported parameter '" - << parm << "'\n"; + } + else + { + std::cerr << "[JackMidiInputEngine] Unsupported parameter '" << parm + << "'\n"; } } -bool JackMidiInputEngine::start() { +bool JackMidiInputEngine::start() +{ client.activate(); return true; } -void JackMidiInputEngine::stop() { -} +void JackMidiInputEngine::stop() {} -void JackMidiInputEngine::pre() { -} +void JackMidiInputEngine::pre() {} -event_t* JackMidiInputEngine::run(size_t pos, size_t len, size_t* nevents) { +event_t *JackMidiInputEngine::run(size_t pos, size_t len, size_t *nevents) +{ *nevents = listsize; - event_t* l = list; - printf("Owning raw pointer at drumgizmo/input/jackmidiinput.cc - GET RID OF THEM!\n"); + event_t *l = list; + printf("Owning raw pointer at drumgizmo/input/jackmidi.cc - GET RID OF " + "THEM!\n"); list = (event_t *)malloc(sizeof(event_t) * 1000); listsize = 0; return l; } -void JackMidiInputEngine::post() { -} +void JackMidiInputEngine::post() {} -void JackMidiInputEngine::process(jack_nframes_t num_frames) { +void JackMidiInputEngine::process(jack_nframes_t num_frames) +{ assert(port != nullptr); - void* buffer = jack_port_get_buffer(port->port, num_frames); + void *buffer = jack_port_get_buffer(port->port, num_frames); jack_nframes_t num_events = jack_midi_get_event_count(buffer); - for(jack_nframes_t i = 0; i < num_events; ++i) { + for (jack_nframes_t i = 0; i < num_events; ++i) + { jack_midi_event_t event; jack_midi_event_get(&event, buffer, i); - if(event.size != 3) { + if (event.size != 3) + { continue; } - if((event.buffer[0] & NOTE_ON) != NOTE_ON) { + if ((event.buffer[0] & NOTE_ON) != NOTE_ON) + { continue; } int key = event.buffer[1]; int velocity = event.buffer[2]; printf("Event key:%d vel:%d\n", key, velocity); int k = midi_mapper.lookup(key); - if(k != -1 && velocity) { + if (k != -1 && velocity) + { list[listsize].type = TYPE_ONSET; list[listsize].instrument = k; list[listsize].velocity = velocity / 127.0; @@ -139,8 +141,7 @@ void JackMidiInputEngine::process(jack_nframes_t num_frames) { } /* - DrumKit* kit; - size_t pos; - EventQueue *eventqueue; + DrumKit* kit; + size_t pos; + EventQueue *eventqueue; */ - diff --git a/drumgizmo/input/jackmidi.h b/drumgizmo/input/jackmidi.h index 3c64f2d..41a3e55 100644 --- a/drumgizmo/input/jackmidi.h +++ b/drumgizmo/input/jackmidi.h @@ -34,34 +34,33 @@ #include "midimapparser.h" #include "../jackclient.h" -class JackMidiInputEngine - : public AudioInputEngine - , public JackProcess { - public: - JackMidiInputEngine(JackClient& client); - ~JackMidiInputEngine(); - - // based on AudioInputEngine - bool isMidiEngine() override; - bool init(Instruments& instruments) override; - void setParm(std::string parm, std::string value) override; - bool start() override; - void stop() override; - void pre() override; - event_t* run(size_t pos, size_t len, size_t* nevents) override; - void post() override; - - // based on JackProcess - void process(jack_nframes_t num_frames) override; - - private: - JackClient& client; - std::unique_ptr port; - - std::string midimap; - MidiMapper midi_mapper; - std::size_t pos; - - event_t* list; - size_t listsize; +class JackMidiInputEngine : public AudioInputEngine, public JackProcess +{ +public: + JackMidiInputEngine(JackClient &client); + ~JackMidiInputEngine(); + + // based on AudioInputEngine + bool isMidiEngine() override; + bool init(Instruments &instruments) override; + void setParm(std::string parm, std::string value) override; + bool start() override; + void stop() override; + void pre() override; + event_t *run(size_t pos, size_t len, size_t *nevents) override; + void post() override; + + // based on JackProcess + void process(jack_nframes_t num_frames) override; + +private: + JackClient &client; + std::unique_ptr port; + + std::string midimap; + MidiMapper midi_mapper; + std::size_t pos; + + event_t *list; + size_t listsize; }; diff --git a/drumgizmo/input/midifile.cc b/drumgizmo/input/midifile.cc index c9aeaf8..0cc9dea 100644 --- a/drumgizmo/input/midifile.cc +++ b/drumgizmo/input/midifile.cc @@ -31,116 +31,131 @@ int const NOTE_ON = 0x90; MidifileInputEngine::MidifileInputEngine() - : smf{nullptr} - , current_event{nullptr} - , file{} - , midimap{} - , speed{1.f} - , track{-1} // all tracks - , loop{false} - , offset{0.0} { + : smf{nullptr}, current_event{nullptr}, file{}, midimap{}, speed{1.f}, + track{-1} // all tracks + , + loop{false}, offset{0.0} +{ } -MidifileInputEngine::~MidifileInputEngine() { - if (smf != nullptr) { +MidifileInputEngine::~MidifileInputEngine() +{ + if (smf != nullptr) + { smf_delete(smf); } } -bool MidifileInputEngine::isMidiEngine() { - return true; -} +bool MidifileInputEngine::isMidiEngine() { return true; } -bool MidifileInputEngine::init(Instruments& instruments) { - if (file == "") { +bool MidifileInputEngine::init(Instruments &instruments) +{ + if (file == "") + { std::cerr << "[MidifileInputEngine] Missing midi filename\n"; return false; } - if (midimap == "") { + if (midimap == "") + { std::cerr << "[MidifileInputEngine] Missing midimap filename\n"; return false; } smf = smf_load(file.c_str()); - if (smf == nullptr) { - std::cerr << "[MidifileInputEngine] Failed to load midifile '" - << file << "'\n"; + if (smf == nullptr) + { + std::cerr << "[MidifileInputEngine] Failed to load midifile '" << file + << "'\n"; return false; } MidiMapParser p{midimap}; - if (p.parse()) { - std::cerr << "[MidifileInputEngine] Failed to parse midimap '" - << midimap << "'\n"; + if (p.parse()) + { + std::cerr << "[MidifileInputEngine] Failed to parse midimap '" << midimap + << "'\n"; return false; } midi_mapper.midimap = p.midimap; - for (auto i = 0u; i < instruments.size(); ++i) { + for (auto i = 0u; i < instruments.size(); ++i) + { auto name = instruments[i]->name(); midi_mapper.instrmap[name] = i; } return true; } -void MidifileInputEngine::setParm(std::string parm, std::string value) { - if(parm == "file") { +void MidifileInputEngine::setParm(std::string parm, std::string value) +{ + if (parm == "file") + { // apply midi input filename file = value; - - } else if(parm == "speed") { + } + else if (parm == "speed") + { // try to apply speed - try { + try + { speed = std::stof(value); - } catch (...) { - std::cerr << "[MidifileInputEngine] Invalid speed " - << value << "\n"; } - } else if (parm == "midimap") { + catch (...) + { + std::cerr << "[MidifileInputEngine] Invalid speed " << value << "\n"; + } + } + else if (parm == "midimap") + { // apply midimap filename midimap = value; - - } else if (parm == "loop") { + } + else if (parm == "loop") + { // apply looping loop = true; - - } else { - std::cerr << "[MidifileInputEngine] Unsupported parameter '" - << parm << "'\n"; + } + else + { + std::cerr << "[MidifileInputEngine] Unsupported parameter '" << parm + << "'\n"; } } -bool MidifileInputEngine::start() { - return true; -} +bool MidifileInputEngine::start() { return true; } -void MidifileInputEngine::stop() { -} +void MidifileInputEngine::stop() {} -void MidifileInputEngine::pre() { -} +void MidifileInputEngine::pre() {} -event_t* MidifileInputEngine::run(size_t pos, size_t len, size_t *nevents) { - event_t* evs{nullptr}; +event_t *MidifileInputEngine::run(size_t pos, size_t len, size_t *nevents) +{ + event_t *evs{nullptr}; size_t num_events{0u}; - + double current_max_time = (1.0 + pos + len) / (44100.0 / speed); current_max_time -= offset; // double cur_min_time = (double)(pos) / (44100.0 / speed); - - if(!current_event) { + + if (!current_event) + { current_event = smf_get_next_event(smf); } - - while(current_event && current_event->time_seconds < current_max_time) { - if(!smf_event_is_metadata(current_event)) { - if( (current_event->midi_buffer_length == 3) && - ((current_event->midi_buffer[0] & NOTE_ON) == NOTE_ON) && - (track == -1 || current_event->track_number == track) && - current_event->midi_buffer[2] > 0) { - - if(evs == nullptr) { - printf("Owning raw pointer at drumgizmo/input/midifile.cc - GET RID OF THEM!\n"); + + while (current_event && current_event->time_seconds < current_max_time) + { + if (!smf_event_is_metadata(current_event)) + { + if ((current_event->midi_buffer_length == 3) && + ((current_event->midi_buffer[0] & NOTE_ON) == NOTE_ON) && + (track == -1 || current_event->track_number == track) && + current_event->midi_buffer[2] > 0) + { + + if (evs == nullptr) + { + printf("Owning raw pointer at drumgizmo/input/midifile.cc - GET RID " + "OF THEM!\n"); evs = (event_t *)malloc(sizeof(event_t) * 1000); } - + int key = current_event->midi_buffer[1]; int velocity = current_event->midi_buffer[2]; @@ -149,29 +164,37 @@ event_t* MidifileInputEngine::run(size_t pos, size_t len, size_t *nevents) { evs[num_events].offset = evpos - pos; int i = midi_mapper.lookup(key); - if(i != -1) { + if (i != -1) + { evs[num_events].instrument = i; evs[num_events].velocity = velocity / 127.0; - + ++num_events; - if(num_events > 999) { + if (num_events > 999) + { fprintf(stderr, "PANIC!\n"); break; } } } } - + current_event = smf_get_next_event(smf); } - if(!current_event) { - if(loop) { + if (!current_event) + { + if (loop) + { smf_rewind(smf); offset += current_max_time; - } else { - if(evs == nullptr) { - printf("Owning raw pointer at drumgizmo/input/midifile.cc - GET RID OF THEM!\n"); + } + else + { + if (evs == nullptr) + { + printf("Owning raw pointer at drumgizmo/input/midifile.cc - GET RID OF " + "THEM!\n"); evs = (event_t *)malloc(sizeof(event_t) * 1000); } evs[num_events].type = TYPE_STOP; @@ -183,5 +206,4 @@ event_t* MidifileInputEngine::run(size_t pos, size_t len, size_t *nevents) { return evs; } -void MidifileInputEngine::post() { -} +void MidifileInputEngine::post() {} diff --git a/drumgizmo/input/midifile.h b/drumgizmo/input/midifile.h index 6749339..5efcc72 100644 --- a/drumgizmo/input/midifile.h +++ b/drumgizmo/input/midifile.h @@ -34,31 +34,31 @@ #include "midimapper.h" #include "midimapparser.h" -class MidifileInputEngine - : public AudioInputEngine { - public: - MidifileInputEngine(); - ~MidifileInputEngine(); - - // based on AudioInputEngine - bool isMidiEngine() override; - bool init(Instruments &instruments) override; - void setParm(std::string parm, std::string value) override; - bool start() override; - void stop() override; - void pre() override; - event_t* run(size_t pos, size_t len, size_t* nevents) override; - void post() override; - - private: - smf_t* smf; - smf_event_t* current_event; - - MidiMapper midi_mapper; - - std::string file, midimap; - float speed; - int track; - bool loop; - double offset; +class MidifileInputEngine : public AudioInputEngine +{ +public: + MidifileInputEngine(); + ~MidifileInputEngine(); + + // based on AudioInputEngine + bool isMidiEngine() override; + bool init(Instruments &instruments) override; + void setParm(std::string parm, std::string value) override; + bool start() override; + void stop() override; + void pre() override; + event_t *run(size_t pos, size_t len, size_t *nevents) override; + void post() override; + +private: + smf_t *smf; + smf_event_t *current_event; + + MidiMapper midi_mapper; + + std::string file, midimap; + float speed; + int track; + bool loop; + double offset; }; diff --git a/drumgizmo/jackclient.cc b/drumgizmo/jackclient.cc index 3d1a836..eb35bf6 100644 --- a/drumgizmo/jackclient.cc +++ b/drumgizmo/jackclient.cc @@ -28,19 +28,22 @@ #include "jackclient.h" -JackProcess::~JackProcess() { -} +JackProcess::~JackProcess() {} // -------------------------------------------------------------------- -JackPort::JackPort(JackClient& client, std::string const & name, const char * type, JackPortFlags flags) - : client{client.client} - // register jack port for given client - , port{jack_port_register(this->client, name.c_str(), type, flags, 0)} { +JackPort::JackPort(JackClient &client, std::string const &name, + const char *type, JackPortFlags flags) + : client{client.client} // register jack port for given client + , + port{jack_port_register(this->client, name.c_str(), type, flags, 0)} +{ } -JackPort::~JackPort() { - if (port != nullptr) { +JackPort::~JackPort() +{ + if (port != nullptr) + { assert(client != nullptr); jack_port_unregister(client, port); } @@ -48,51 +51,54 @@ JackPort::~JackPort() { // -------------------------------------------------------------------- -int _wrap_jack_process(jack_nframes_t nframes, void* arg){ - return static_cast(arg)->process(nframes); +int _wrap_jack_process(jack_nframes_t nframes, void *arg) +{ + return static_cast(arg)->process(nframes); } -JackClient::JackClient() - : client{nullptr} - , processes{} - , is_active{false} { +JackClient::JackClient() : client{nullptr}, processes{}, is_active{false} +{ jack_status_t status; client = jack_client_open("DrumGizmo", JackNullOption, &status); jack_set_process_callback(client, _wrap_jack_process, this); } -JackClient::~JackClient() { - if (client != nullptr) { +JackClient::~JackClient() +{ + if (client != nullptr) + { jack_client_close(client); } } -void JackClient::add(JackProcess& process) { - processes.insert(&process); -} +void JackClient::add(JackProcess &process) { processes.insert(&process); } -void JackClient::remove(JackProcess& process) { - processes.erase(&process); -} +void JackClient::remove(JackProcess &process) { processes.erase(&process); } -void JackClient::activate() { - if (!is_active) { +void JackClient::activate() +{ + if (!is_active) + { jack_activate(client); } is_active = true; } -int JackClient::process(jack_nframes_t num_frames) { - for (auto& ptr: processes) { +int JackClient::process(jack_nframes_t num_frames) +{ + for (auto &ptr : processes) + { ptr->process(num_frames); } return 0; } -std::size_t JackClient::getBufferSize() const { +std::size_t JackClient::getBufferSize() const +{ return jack_get_buffer_size(client); } -std::size_t JackClient::getSampleRate() const { +std::size_t JackClient::getSampleRate() const +{ return jack_get_sample_rate(client); } diff --git a/drumgizmo/jackclient.h b/drumgizmo/jackclient.h index ede6d9e..ebfc28d 100644 --- a/drumgizmo/jackclient.h +++ b/drumgizmo/jackclient.h @@ -35,41 +35,45 @@ class JackClient; -class JackProcess { - public: - virtual ~JackProcess(); - virtual void process(jack_nframes_t num_frames) = 0; +class JackProcess +{ +public: + virtual ~JackProcess(); + virtual void process(jack_nframes_t num_frames) = 0; }; // -------------------------------------------------------------------- // RAII-wrapper for jack_port_t -struct JackPort { - JackPort(JackClient& client, std::string const & name, const char * type, JackPortFlags flags); +struct JackPort +{ + JackPort(JackClient &client, std::string const &name, const char *type, + JackPortFlags flags); ~JackPort(); - - jack_client_t* const client; - jack_port_t* const port; + + jack_client_t *const client; + jack_port_t *const port; }; // -------------------------------------------------------------------- -class JackClient { +class JackClient +{ friend struct JackPort; - - public: - JackClient(); - ~JackClient(); - - void add(JackProcess& process); - void remove(JackProcess& process); - void activate(); - int process(jack_nframes_t num_frames); - std::size_t getBufferSize() const; - std::size_t getSampleRate() const; - - private: - jack_client_t* client; - std::set processes; - bool is_active; + +public: + JackClient(); + ~JackClient(); + + void add(JackProcess &process); + void remove(JackProcess &process); + void activate(); + int process(jack_nframes_t num_frames); + std::size_t getBufferSize() const; + std::size_t getSampleRate() const; + +private: + jack_client_t *client; + std::set processes; + bool is_active; }; 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 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 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_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_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 samples; - - Channel(JackClient& client, std::string const & name, std::size_t buffer_size); - }; - - JackClient& client; - std::vector 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 samples; + + Channel(JackClient &client, std::string const &name, + std::size_t buffer_size); + }; + + JackClient &client; + std::vector 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(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(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 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 channels; + size_t num_channels; + + std::string file; }; -- cgit v1.2.3