/
reds
/
OpenDAW
Обзор
Документация
Войти
/
reds
/
OpenDAW
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop
src/ui/CLI.cpp
383 строки
11 KB
OpenDAW Developer
feat(v1.0.0-phase2): Add CLI Interface with track listing
21 фев 2026, 13:39
21 фев 2026, 13:39
73ad560
Код
Авторство
О чём код?
#include <opendaw/ui/CLI.h> #include <opendaw/core/AudioGraph.h> #include <opendaw/core/Globals.h> #include <opendaw/plugin/PluginHost.h> #include <iostream> #include <fstream> #include <sstream> #include <iterator> #include <algorithm> namespace opendaw { CLI::CLI() { // Register built-in commands addCommand({"help", "Show help information", "help [command]", [this](const auto& args) { handleHelp(args); }}); addCommand({"quit", "Exit the application", "quit", [this](const auto& args) { handleQuit(args); }}); addCommand({"exit", "Exit the application", "exit", [this](const auto& args) { handleQuit(args); }}); addCommand({"tracks", "List all tracks", "tracks", [this](const auto& args) { handleTracks(args); }}); addCommand({"create", "Create a new track", "create track <audio|midi> [name]", [this](const auto& args) { handleCreateTrack(args); }}); addCommand({"remove", "Remove a track", "remove track <index>", [this](const auto& args) { handleRemoveTrack(args); }}); addCommand({"vol", "Set track volume", "vol <track> <volume>", [this](const auto& args) { handleSetVolume(args); }}); addCommand({"pan", "Set track pan", "pan <track> <pan>", [this](const auto& args) { handleSetPan(args); }}); addCommand({"mute", "Mute/unmute track", "mute <track>", [this](const auto& args) { handleMute(args); }}); addCommand({"solo", "Solo/unsolo track", "solo <track>", [this](const auto& args) { handleSolo(args); }}); addCommand({"plugins", "List loaded plugins", "plugins", [this](const auto& args) { handlePlugins(args); }}); addCommand({"load", "Load plugin or project", "load plugin <file> <track> | load project <file>", [this](const auto& args) { handleLoad(args); }}); addCommand({"scan", "Scan for plugins", "scan [path]", [this](const auto& args) { handleScanPlugins(args); }}); addCommand({"status", "Show graph status", "status", [this](const auto& args) { handleStatus(args); }}); addCommand({"play", "Start playback", "play", [this](const auto& args) { handlePlay(args); }}); addCommand({"stop", "Stop playback", "stop", [this](const auto& args) { handleStop(args); }}); addCommand({"rec", "Toggle recording", "rec", [this](const auto& args) { handleRecord(args); }}); addCommand({"save", "Save project", "save <file>", [this](const auto& args) { handleSave(args); }}); addCommand({"script", "Run script file", "script <file>", [this](const auto& args) { handleScript(args); }}); addCommand({"verbose", "Toggle verbose output", "verbose [on|off]", [this](const auto& args) { handleVerbose(args); }}); } void CLI::run() { running_ = true; print("OpenDAW CLI v1.0.0"); print("Type 'help' for commands"); print(""); std::string line; while (running_) { std::cout << "> "; std::getline(std::cin, line); if (!line.empty()) { executeCommand(line); } } } void CLI::stop() { running_ = false; } bool CLI::executeCommand(const std::string& line) { std::istringstream iss(line); std::vector<std::string> args{ std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>{} }; if (args.empty()) { return true; } std::string cmdName = args[0]; // Find command for (const auto& cmd : commands_) { if (cmd.name == cmdName) { try { cmd.handler(args); return true; } catch (const std::exception& e) { printError(std::string("Error: ") + e.what()); return false; } } } printError("Unknown command: " + cmdName); print("Type 'help' for available commands"); return false; } bool CLI::runScript(const std::string& filename) { std::ifstream file(filename); if (!file.is_open()) { printError("Cannot open script file: " + filename); return false; } print("Running script: " + filename); std::string line; int lineNum = 0; while (std::getline(file, line)) { lineNum++; // Skip comments and empty lines if (line.empty() || line[0] == '#') { continue; } std::cout << " " << line << std::endl; if (!executeCommand(line)) { printError("Script error at line " + std::to_string(lineNum)); return false; } } print("Script completed"); return true; } void CLI::showHelp() { print("OpenDAW CLI Help"); print("==============="); print(""); print("Track commands:"); print(" tracks - List all tracks"); print(" create track <type> - Create track (audio|midi)"); print(" remove track <idx> - Remove track by index"); print(" vol <trk> <vol> - Set volume (0-1)"); print(" pan <trk> <pan> - Set pan (-1 to 1)"); print(" mute <track> - Toggle mute"); print(" solo <track> - Toggle solo"); print(""); print("Plugin commands:"); print(" plugins - List loaded plugins"); print(" load plugin <f> <t> - Load plugin to track"); print(" scan [path] - Scan for plugins"); print(""); print("Transport:"); print(" play - Start playback"); print(" stop - Stop playback"); print(" rec - Toggle recording"); print(""); print("Project:"); print(" save <file> - Save project"); print(" load project <file> - Load project"); print(" script <file> - Run script"); print(""); print("Other:"); print(" status - Show status"); print(" verbose [on|off] - Toggle verbose"); print(" help - Show this help"); print(" quit - Exit"); } void CLI::showCommands() { print("Available commands:"); for (const auto& cmd : commands_) { print(" " + cmd.name + " - " + cmd.description); } } void CLI::addCommand(const CLICommand& cmd) { commands_.push_back(cmd); } void CLI::print(const std::string& message) { std::cout << message << std::endl; } void CLI::printError(const std::string& message) { std::cerr << "❌ " << message << std::endl; } void CLI::printSuccess(const std::string& message) { std::cout << "✅ " << message << std::endl; } // Command Handlers void CLI::handleHelp(const std::vector<std::string>& args) { showHelp(); } void CLI::handleQuit(const std::vector<std::string>& args) { print("Goodbye!"); stop(); } void CLI::handleTracks(const std::vector<std::string>& args) { auto* graph = getGlobalGraph(); if (!graph) { printError("No audio graph available"); return; } print("Tracks:"); for (int i = 0; i < graph->getNumTracks(); ++i) { auto* track = graph->getTrack(i); if (track) { std::string type = (track->getType() == TrackType::Audio) ? "Audio" : (track->getType() == TrackType::Midi) ? "MIDI" : "Bus"; print(" " + std::to_string(i) + ": " + track->getName() + " (" + type + ")" + " vol=" + std::to_string(static_cast<int>(track->getVolume() * 100)) + "%" + (track->isMuted() ? " [MUTED]" : "") + (track->isSolo() ? " [SOLO]" : "")); } } } void CLI::handleCreateTrack(const std::vector<std::string>& args) { if (args.size() < 3) { printError("Usage: create track <audio|midi> [name]"); return; } std::string type = args[2]; std::string name = args.size() > 3 ? args[3] : "Track " + std::to_string(args.size()); printSuccess("Would create " + type + " track: " + name); } void CLI::handleRemoveTrack(const std::vector<std::string>& args) { if (args.size() < 3) { printError("Usage: remove track <index>"); return; } printSuccess("Would remove track " + args[2]); } void CLI::handleSetVolume(const std::vector<std::string>& args) { if (args.size() < 3) { printError("Usage: vol <track> <volume>"); return; } printSuccess("Would set volume"); } void CLI::handleSetPan(const std::vector<std::string>& args) { if (args.size() < 3) { printError("Usage: pan <track> <pan>"); return; } printSuccess("Would set pan"); } void CLI::handleMute(const std::vector<std::string>& args) { if (args.size() < 2) { printError("Usage: mute <track>"); return; } printSuccess("Would toggle mute"); } void CLI::handleSolo(const std::vector<std::string>& args) { if (args.size() < 2) { printError("Usage: solo <track>"); return; } printSuccess("Would toggle solo"); } void CLI::handlePlugins(const std::vector<std::string>& args) { print("No plugins loaded"); } void CLI::handleLoad(const std::vector<std::string>& args) { if (args.size() < 4) { printError("Usage: load plugin <file> <track> | load project <file>"); return; } std::string type = args[1]; if (type == "plugin") { printSuccess("Would load plugin: " + args[2]); } else if (type == "project") { printSuccess("Would load project: " + args[2]); } else { printError("Unknown load type: " + type); } } void CLI::handleScanPlugins(const std::vector<std::string>& args) { print("Scanning for plugins..."); print("Plugin scanning not yet implemented"); } void CLI::handleStatus(const std::vector<std::string>& args) { print("OpenDAW Status:"); print(" Sample rate: 48000 Hz"); print(" Block size: 512 samples"); print(" Tracks: 0"); print(" Plugins: 0"); print(" Playing: No"); print(" Recording: No"); } void CLI::handlePlay(const std::vector<std::string>& args) { printSuccess("Playback started"); } void CLI::handleStop(const std::vector<std::string>& args) { printSuccess("Playback stopped"); } void CLI::handleRecord(const std::vector<std::string>& args) { printSuccess("Recording toggled"); } void CLI::handleSave(const std::vector<std::string>& args) { if (args.size() < 2) { printError("Usage: save <file>"); return; } printSuccess("Would save project to: " + args[1]); } void CLI::handleScript(const std::vector<std::string>& args) { if (args.size() < 2) { printError("Usage: script <file>"); return; } runScript(args[1]); } void CLI::handleVerbose(const std::vector<std::string>& args) { if (args.size() > 1) { verbose_ = (args[1] == "on" || args[1] == "1"); } else { verbose_ = !verbose_; } print("Verbose: " + std::string(verbose_ ? "ON" : "OFF")); } } // namespace opendaw