diff --git a/bugs b/bugs index b3d0e8b..e69de29 100644 --- a/bugs +++ b/bugs @@ -1,27 +0,0 @@ -Linux: - Updater: - After updater has extracted the file set the executable flag again for the TeaClient binary - - -Windows: - Updater: - Updater popups console which says that there are invalid arguments! Fix this! - Improve access to the update-install.exe (May request admin permissions) - - -General: - Audio replay with TS3 is a bit buggy! - - -Tasks designer: - TeaCup steam animated - Client redesign dark [+ Chat system] - Redesign loading animation (Web) - - - -Notice: -electron-package-manager must be at 8.7.2 (Node 6 support)! - - -FIXME: Test the new voice resampler! \ No newline at end of file diff --git a/modules/renderer/connection/VoiceConnection.ts b/modules/renderer/connection/VoiceConnection.ts index 598be06..5586b4a 100644 --- a/modules/renderer/connection/VoiceConnection.ts +++ b/modules/renderer/connection/VoiceConnection.ts @@ -115,7 +115,32 @@ export namespace _audio { } available_clients(): connection.voice.VoiceClient[] { - return this.handle.available_clients(); + return this.handle.available_clients().map(e => Object.assign(e, { + support_latency_settings() { return true; }, + reset_latency_settings: function() { + const stream = this.get_stream(); + stream.set_buffer_latency(0.02); + stream.set_buffer_max_latency(0.2); + return this.latency_settings(); + }, + latency_settings: function (settings?: connection.voice.LatencySettings) : connection.voice.LatencySettings { + const stream = this.get_stream(); + if(typeof settings !== "undefined") { + stream.set_buffer_latency(settings.min_buffer / 1000); + stream.set_buffer_max_latency(settings.max_buffer / 100); + } + return { + max_buffer: Math.floor(stream.get_buffer_max_latency() * 1000), + min_buffer: Math.floor(stream.get_buffer_latency() * 1000) + }; + }, + + support_flush() { return true; }, + flush: function () { + const stream = this.get_stream(); + stream.flush_buffer(); + } + })); } find_client(client_id: number) : connection.voice.VoiceClient | undefined { @@ -132,13 +157,9 @@ export namespace _audio { register_client(client_id: number): connection.voice.VoiceClient { const client = this.handle.register_client(client_id); - if(!client) - return client; - - const stream = client.get_stream(); - stream.set_buffer_latency(0.02); - stream.set_buffer_max_latency(0.2); - return client; + const c = this.find_client(client_id); + c.reset_latency_settings(); + return c; } decoding_supported(codec: number): boolean { diff --git a/native/serverconnection/src/audio/AudioInput.cpp b/native/serverconnection/src/audio/AudioInput.cpp index d593011..f3159c8 100644 --- a/native/serverconnection/src/audio/AudioInput.cpp +++ b/native/serverconnection/src/audio/AudioInput.cpp @@ -68,7 +68,6 @@ bool AudioInput::open_device(std::string& error, PaDeviceIndex index) { parameters.device = this->_current_device_index; parameters.sampleFormat = paFloat32; parameters.suggestedLatency = this->_current_device->defaultLowOutputLatency; - auto err = Pa_OpenStream( &this->input_stream, ¶meters, @@ -78,8 +77,10 @@ bool AudioInput::open_device(std::string& error, PaDeviceIndex index) { paClipOff, &AudioInput::_audio_callback, this); + if(err != paNoError) { - error = "Pa_OpenStream returned " + to_string(err); + this->input_stream = nullptr; + error = to_string(err) + "/" + Pa_GetErrorText(err); return false; } @@ -111,18 +112,22 @@ bool AudioInput::recording() { void AudioInput::stop() { lock_guard lock(this->input_stream_lock); if(this->input_stream) { - Pa_AbortStream(this->input_stream); + if(Pa_IsStreamActive(this->input_stream)) + Pa_StopStream(this->input_stream); } } void AudioInput::close_device() { lock_guard lock(this->input_stream_lock); if(this->input_stream) { - /* TODO: Test for errors */ - Pa_AbortStream(this->input_stream); - Pa_CloseStream(this->input_stream); + if(Pa_IsStreamActive(this->input_stream)) + Pa_StopStream(this->input_stream); + auto error = Pa_CloseStream(this->input_stream); + if(error != paNoError) + log_error(category::audio, tr("Failed to close PA stream: {}"), error); this->input_stream = nullptr; + this_thread::sleep_for(chrono::seconds{1}); } } diff --git a/native/serverconnection/src/audio/AudioOutput.cpp b/native/serverconnection/src/audio/AudioOutput.cpp index 9123ac2..05d2012 100644 --- a/native/serverconnection/src/audio/AudioOutput.cpp +++ b/native/serverconnection/src/audio/AudioOutput.cpp @@ -254,7 +254,7 @@ bool AudioOutput::open_device(std::string& error, PaDeviceIndex index) { auto err = Pa_OpenStream(&output_stream, nullptr, &output_parameters, (double) this->_sample_rate, paFramesPerBufferUnspecified, paClipOff, &AudioOutput::_audio_callback, this); if(err != paNoError) { - error = "Pa_OpenStream returned " + to_string(err); + error = to_string(err) + "/" + Pa_GetErrorText(err); return false; } diff --git a/native/serverconnection/test/js/main.ts b/native/serverconnection/test/js/main.ts index 77b263b..9078eff 100644 --- a/native/serverconnection/test/js/main.ts +++ b/native/serverconnection/test/js/main.ts @@ -29,6 +29,24 @@ const stream = handle.audio.playback.create_stream(); console.log("Own stream: %o", stream); +for(let i = 0; i < 12; i++) { + const recorder = handle.audio.record.create_recorder(); + for(const device of handle.audio.available_devices()) { + if(!device.input_supported) + continue; + + if(device.name != "pulse") + continue; + + console.log("Found pulse at %o", device.device_index); + recorder.set_device(device.device_index, () => {}); + break; + } + recorder.start(flag => console.log("X: " + flag)); + const consumer = recorder.create_consumer(); + consumer.create_filter_threshold(2); +} + /* -1 => default device */ const recorder = handle.audio.record.create_recorder(); console.log("Have device: %o", recorder); @@ -38,8 +56,10 @@ if(recorder.get_device() == -1) { for(const device of handle.audio.available_devices()) { if(!device.input_supported) continue; + if(device.name != "pulse") continue; + console.log("Found pulse at %o", device.device_index); recorder.set_device(device.device_index, () => {}); }