secondvoice/src/utils/Config.cpp
StillHammer ddf34db2a0 feat: Add GLAD OpenGL loader and NVIDIA GPU forcing
Changes:
- Add GLAD dependency via vcpkg for proper OpenGL function loading
- Force NVIDIA GPU usage with game-style exports (NvOptimusEnablement)
- Create working console version (SecondVoice_Console.exe)
- Add dual executable build (UI + Console versions)
- Update to OpenGL 4.6 Core Profile with GLSL 460
- Add GPU detection and logging
- Fix GLFW header conflicts with GLFW_INCLUDE_NONE

Note: OpenGL shaders still failing to compile despite GLAD integration.
Console version is fully functional for audio capture and translation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 15:18:54 +08:00

117 lines
4.2 KiB
C++

#include "Config.h"
#include <nlohmann/json.hpp>
#include <fstream>
#include <iostream>
#include <cstdlib>
using json = nlohmann::json;
namespace secondvoice {
Config& Config::getInstance() {
static Config instance;
return instance;
}
bool Config::load(const std::string& config_path, const std::string& env_path) {
// Load .env file
std::ifstream env_file(env_path);
if (env_file.is_open()) {
std::string line;
while (std::getline(env_file, line)) {
if (line.empty() || line[0] == '#') continue;
auto pos = line.find('=');
if (pos != std::string::npos) {
std::string key = line.substr(0, pos);
std::string value = line.substr(pos + 1);
// Remove quotes if present
if (!value.empty() && value.front() == '"' && value.back() == '"') {
value = value.substr(1, value.length() - 2);
}
if (key == "OPENAI_API_KEY") {
openai_key_ = value;
} else if (key == "ANTHROPIC_API_KEY") {
anthropic_key_ = value;
}
}
}
env_file.close();
} else {
std::cerr << "Warning: Could not open .env file: " << env_path << std::endl;
}
// Load config.json
std::cerr << "[Config] Opening config file: " << config_path << std::endl;
std::ifstream config_file(config_path);
if (!config_file.is_open()) {
std::cerr << "Error: Could not open config file: " << config_path << std::endl;
return false;
}
std::cerr << "[Config] File opened successfully" << std::endl;
json config_json;
try {
std::cerr << "[Config] About to parse JSON..." << std::endl;
config_file >> config_json;
std::cerr << "[Config] JSON parsed successfully" << std::endl;
} catch (const json::parse_error& e) {
std::cerr << "Error parsing config.json: " << e.what() << std::endl;
return false;
} catch (...) {
std::cerr << "Unknown error parsing config.json" << std::endl;
return false;
}
// Parse audio config
if (config_json.contains("audio")) {
auto& audio = config_json["audio"];
audio_config_.sample_rate = audio.value("sample_rate", 16000);
audio_config_.channels = audio.value("channels", 1);
audio_config_.chunk_duration_seconds = audio.value("chunk_duration_seconds", 10);
audio_config_.format = audio.value("format", "wav");
}
// Parse whisper config
if (config_json.contains("whisper")) {
auto& whisper = config_json["whisper"];
whisper_config_.model = whisper.value("model", "whisper-1");
whisper_config_.language = whisper.value("language", "zh");
whisper_config_.temperature = whisper.value("temperature", 0.0f);
whisper_config_.prompt = whisper.value("prompt", "");
whisper_config_.stream = whisper.value("stream", false);
whisper_config_.response_format = whisper.value("response_format", "text");
}
// Parse claude config
if (config_json.contains("claude")) {
auto& claude = config_json["claude"];
claude_config_.model = claude.value("model", "claude-haiku-4-20250514");
claude_config_.max_tokens = claude.value("max_tokens", 1024);
claude_config_.temperature = claude.value("temperature", 0.3f);
claude_config_.system_prompt = claude.value("system_prompt", "");
}
// Parse UI config
if (config_json.contains("ui")) {
auto& ui = config_json["ui"];
ui_config_.window_width = ui.value("window_width", 800);
ui_config_.window_height = ui.value("window_height", 600);
ui_config_.font_size = ui.value("font_size", 16);
ui_config_.max_display_lines = ui.value("max_display_lines", 50);
}
// Parse recording config
if (config_json.contains("recording")) {
auto& recording = config_json["recording"];
recording_config_.save_audio = recording.value("save_audio", true);
recording_config_.output_directory = recording.value("output_directory", "./recordings");
}
return true;
}
} // namespace secondvoice