Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/rhiannon / apps/rhiannon_demo/main.cpp |
| Date | Not specified in source |
| Repository | Janady13/rhiannon |
| Revision | df358362a21fdde4372dc6239573622aafe4835f |
| Branch | main |
| Path or archive member | apps/rhiannon_demo/main.cpp |
| Original SHA-256 | b8f7cf64709b5f32028e09c61ab9881c64c6ea1fff0926ca052ce3d03d924cfb |
| Git blob SHA | ab6139114498e54b15db5e2c284b55da5fefa56f |
| Reading-copy SHA-256 | b8f7cf64709b5f32028e09c61ab9881c64c6ea1fff0926ca052ce3d03d924cfb |
Recovered source transcript
Download complete source text ↓133 lines · 3.5 KB
// Rhiannon demo — CLI + simple loop (optional WS/MIDI compiled out by default)
#include "agents/rhiannon.hpp"
#include <chrono>
#include <cmath>
#include <thread>
#include <vector>
#include <iostream>
#include <getopt.h>
#ifdef RHIANNON_WITH_WS
#include <nlohmann/json.hpp>
#include <uwebsockets/App.h>
#endif
#ifdef __has_include
# if __has_include(<spdlog/spdlog.h>)
# include <spdlog/spdlog.h>
using ::spdlog::info;
using ::spdlog::warn;
# else
static inline void info(const char* fmt) { (void)fmt; }
static inline void warn(const char* fmt) { (void)fmt; }
# endif
#endif
using namespace std::chrono_literals;
struct Options {
std::size_t dim = 8;
int iters = 100;
bool headless = false;
bool live_midi = false;
bool ws = false;
bool gpu = false;
int ws_port = 8080;
};
static void print_usage(const char* argv0) {
std::cout
<< "Usage: " << argv0 << " [--dim N] [--iters N] [--headless] [--live-midi] [--ws PORT] [--gpu]\n";
}
int main(int argc, char** argv) {
Options opt{};
static option long_opts[] = {
{"dim", required_argument, nullptr, 'd'},
{"iters", required_argument, nullptr, 'i'},
{"headless", no_argument, nullptr, 'H'},
{"live-midi", no_argument, nullptr, 'M'},
{"ws", required_argument, nullptr, 'W'},
{"gpu", no_argument, nullptr, 'G'},
{"help", no_argument, nullptr, 'h'},
{nullptr, 0, nullptr, 0}
};
int c;
while ((c = ::getopt_long(argc, argv, "d:i:HMW:Gh", long_opts, nullptr)) != -1) {
switch (c) {
case 'd': opt.dim = static_cast<std::size_t>(std::stoul(optarg)); break;
case 'i': opt.iters = std::stoi(optarg); break;
case 'H': opt.headless = true; break;
case 'M': opt.live_midi = true; break;
case 'W': opt.ws = true; opt.ws_port = std::stoi(optarg); break;
case 'G': opt.gpu = true; break;
case 'h': default: print_usage(argv[0]); return c == 'h' ? 0 : 1;
}
}
agents::TwoWayEngine::Cfg cfg;
cfg.dim = opt.dim;
cfg.iters = opt.iters;
cfg.epsilon = 1e-6;
cfg.use_gpu = opt.gpu;
agents::Rhiannon rhiannon(cfg);
std::vector<float> input(opt.dim, 0.5f);
auto gen_target = [&]() {
const auto now = std::chrono::steady_clock::now().time_since_epoch();
const double t = std::chrono::duration<double>(now).count();
for (std::size_t i = 0; i < opt.dim; ++i) {
input[i] = static_cast<float>(0.5 + 0.5 * std::sin(0.2 * i + t));
}
rhiannon.set_input(input);
};
#ifdef RHIANNON_WITH_WS
std::unique_ptr<std::thread> ws_thread;
std::unique_ptr<uWS::App> app;
if (opt.ws) {
app = std::make_unique<uWS::App>();
app->ws<false>("/*", {
.message = [&](auto *ws, std::string_view, uWS::OpCode) {
nlohmann::json j;
j["e"] = rhiannon.state_e();
j["z"] = rhiannon.state_z();
ws->send(j.dump(), uWS::OpCode::TEXT);
}
}).listen(opt.ws_port, [&](auto *token) {
if (token) info("WebSocket listening");
});
ws_thread = std::make_unique<std::thread>([app_ptr = app.get()]() { app_ptr->run(); });
}
#else
if (opt.ws) {
warn("WebSocket disabled at build time; rebuild with -DRHIANNON_WITH_WS=ON");
}
#endif
for (int tick = 0; tick < 1000; ++tick) {
gen_target();
rhiannon.tick();
const double e = rhiannon.state_e();
if (!opt.headless) {
std::cout << "Tick " << tick << " e=" << e << " dim=" << opt.dim << "\n";
}
if (e < 1e-4) break;
std::this_thread::sleep_for(16ms);
}
#ifdef RHIANNON_WITH_WS
if (opt.ws && app) {
app->close();
if (ws_thread && ws_thread->joinable()) ws_thread->join();
}
#endif
return 0;
}