Hi.
As I was recently sucked into the Eurorack world,
I have begun to work on a small C++ project to create tools
for working with control voltages. My ultimate plan
is to write a small software CV sequencer.
But until then, I am going for low hanging fruits, esp. so that I can
warm up to writing JACK code. One of these is cv2midiclock.
It takes a CV signal (actually works with Line-In as well, but
my ultimate plan is to use an Expert Sleepers ES-8 to get
DC-coupled AD/DAC) from an audio port and outputs a synced
MIDI Clock on a MIDI port. Very simple, very basic, but might
be useful, actually.
https://github.com/mlang/brlcv
Disclaimer: This repository will never implement any sort of GUI.
In fact, it is likely that the only user interface the control
voltage sequencer will ever have is going to be based on a Braille display.
You are welcome to fork the code to port it (once it works) to other
user interfaces. Patches to implement visual UIs will be rejected, as
was the case with my patches to improve GTK Accessibility.
However, if you are fine with CLIs or OSC and have an interest
in CV tools on Linux, you are very welcome to join forces.
P.S.: This repo contains my version of a C++ wrapper for JACK clients.
While it is definitely not complete, it can be used to
implement simple JACK clients in very few lines of code.
If you are into modern C++ (C++14 and beyond), take a look.
If you like/dislike it, send feedback please.
Below is (totally useless) example client:
#include <jack.hpp>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
template<typename... Features>
using AudioAccumulatorSet = boost::accumulators::accumulator_set<
float, boost::accumulators::features<Features...>
;
using Count = boost::accumulators::tag::count;
using Max = boost::accumulators::tag::max;
using Min = boost::accumulators::tag::min;
using Mean = boost::accumulators::tag::mean;
using Variance = boost::accumulators::tag::variance;
class Statistics final : public JACK::Client {
JACK::AudioIn In;
AudioAccumulatorSet<Count, Max, Mean, Min, Variance> Accumulator;
public:
Statistics() : JACK::Client("Statistics"), In(createAudioIn("In"))
{}
int process(std::uint32_t FrameCount) override {
for (auto &Value: In.buffer(FrameCount)) Accumulator(Value);
return 0;
}
auto max() const { return boost::accumulators::max(Accumulator); }
auto mean() const { return boost::accumulators::mean(Accumulator); }
auto min() const { return boost::accumulators::min(Accumulator); }
auto sampleCount() const { return boost::accumulators::count(Accumulator); }
auto variance() const { return boost::accumulators::variance(Accumulator); }
};
#include <chrono>
#include <iostream>
#include <thread>
using namespace std::literals::chrono_literals;
int main() {
Statistics Client;
std::cout << "Rate: " << Client.sampleRate() << std::endl;
Client.activate();
std::this_thread::sleep_for(5s);
Client.deactivate();
std::cout << Client.sampleCount() << ": "
<< "mean=" << Client.mean()
<< ", variance=" << Client.variance()
<< ", min=" << Client.min()
<< ", max=" << Client.max()
<< std::endl;
}
--
Happy patching (pun intended),
⡍⠁⠗⠊⠕ | Blog: <https://blind.guru/> GitHub: <https://github.com/mlang/>
.''`. | Twitter: @blindbird23 FaceBook: disyled
: :' : | SoundCloud: <soundcloud.com/mario-lang>
`. `' | YouTube: <youtube.com/user/mlang23>
`-