feat(windows): UI overhaul -- toolbar, unified log, PM windows, channel counts, output volume
- Voice actions (Join Voice, Share Screen Audio) moved to a ToolStrip toolbar and a new Voice menu in the menu bar; removed from the bottom voice panel - Activity log and chat log collapsed into a single RichTextBox (rtbLog); activity events appear in gray, chat messages in default color - Private messaging reworked: each conversation opens in its own modeless PrivateMessageForm instead of sharing the main chat log via a scope dropdown; cboScope removed; main compose bar always sends to the current channel - New "Messages -> New Private Message..." menu item (Ctrl+P) opens a UserPickerDialog listing all connected server users (not just the current channel) so you can PM anyone on the server - Channel tree now shows live user counts, e.g. "General (3)" -- counts sourced from the existing _users dictionary which already tracks all server users with channel IDs - Global output volume slider (TrackBar, 0-100, default 80) added to the right panel; wired to new vc_set_output_volume C ABI function that applies a master gain multiplier in the audio engine playback callback after mixing all streams - vc_set_output_volume added end-to-end: voicecat.h, audio_engine.h/.cpp, client.h/.cpp, voicecat.cpp, NativeMethods.cs, VoiceCatClient.cs - Documented Windows PowerShell ctest requirement in AGENTS.md and CLAUDE.md: MinGW binaries exit 0xc0000139 in Git Bash; always run ctest/.exe via PowerShell 22/22 ctest green (PowerShell); dotnet build 0 warnings. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -659,8 +659,11 @@ void AudioEngine::on_playback(int16_t* out, ma_uint32 frames) {
|
||||
}
|
||||
}
|
||||
|
||||
for (ma_uint32 i = 0; i < frames * pb_channels; ++i)
|
||||
out[i] = static_cast<int16_t>(std::clamp(mix[i], -32768, 32767));
|
||||
const float ovol = output_volume_.load(std::memory_order_relaxed);
|
||||
for (ma_uint32 i = 0; i < frames * pb_channels; ++i) {
|
||||
int32_t s = static_cast<int32_t>(static_cast<float>(mix[i]) * ovol);
|
||||
out[i] = static_cast<int16_t>(std::clamp(s, -32768, 32767));
|
||||
}
|
||||
#else
|
||||
(void)out;
|
||||
(void)frames;
|
||||
|
||||
@@ -163,6 +163,9 @@ class AudioEngine {
|
||||
// Called by the net thread when a decoded voice frame arrives for a remote stream.
|
||||
void push_recv_frame(uint32_t ssrc, JitterBuffer::Frame f);
|
||||
|
||||
// Global output volume applied after mixing all streams (default 1.0). Thread-safe.
|
||||
void set_output_volume(float gain) { output_volume_.store(gain, std::memory_order_relaxed); }
|
||||
|
||||
// Per-stream receive-side controls (safe from any thread).
|
||||
void set_stream_gain(uint32_t ssrc, float gain); // 0.0–2.0, default 1.0
|
||||
void set_stream_mute(uint32_t ssrc, bool mute);
|
||||
@@ -337,7 +340,8 @@ class AudioEngine {
|
||||
|
||||
AudioParams params_{};
|
||||
CaptureCallback capture_cb_;
|
||||
std::atomic<bool> running_{false};
|
||||
std::atomic<bool> running_{false};
|
||||
std::atomic<float> output_volume_{1.0f};
|
||||
|
||||
// Capture-side frame accumulators: miniaudio fires the capture (and loopback) callback at
|
||||
// whatever period the hardware/driver chooses — commonly 480 samples (10 ms) on WASAPI
|
||||
|
||||
Reference in New Issue
Block a user