From 52125a3d3479e7a4ac8b64b987a982d9c391747c Mon Sep 17 00:00:00 2001 From: Christof Ruch Date: Fri, 18 Oct 2024 23:49:42 +0200 Subject: [PATCH 01/31] Stop putting the session info (all channels of all participants) into each audio block, because that increases the block size of the audio stream a lot when more participants join the session. It might even increase the block size beyond the maximum frame size, which makes the audio go kaputt. Instead, send a separate package with a reduced frame rate to the other clients. This makes the peak meteres be less real time, but it saves a lot in terms of audio package size and allows us to turn on FEC again! --- Client/Source/DataReceiveThread.cpp | 8 +++- Server/Source/MixerThread.cpp | 6 +-- Server/Source/SendThread.cpp | 16 +++++++ Server/Source/SendThread.h | 3 +- Server/Source/SharedServerTypes.h | 12 +++-- common/CMakeLists.txt | 11 +++-- common/JammerNetzAudioData.fbs | 11 +---- common/JammerNetzChannelSetup.fbs | 14 ++++++ common/JammerNetzClientInfoMessage.h | 2 + common/JammerNetzPackage.cpp | 50 ++++---------------- common/JammerNetzPackage.h | 71 +++++++++++++++++++++++++--- common/JammerNetzSessionInfo.fbs | 15 ++++++ 12 files changed, 151 insertions(+), 68 deletions(-) create mode 100644 common/JammerNetzChannelSetup.fbs create mode 100644 common/JammerNetzSessionInfo.fbs diff --git a/Client/Source/DataReceiveThread.cpp b/Client/Source/DataReceiveThread.cpp index 641ccae..6a20032 100644 --- a/Client/Source/DataReceiveThread.cpp +++ b/Client/Source/DataReceiveThread.cpp @@ -99,7 +99,6 @@ void DataReceiveThread::run() ScopedLock sessionLock(sessionDataLock_); // Hand off to player currentRTT_ = Time::getMillisecondCounterHiRes() - audioData->timestamp(); - currentSession_ = audioData->sessionSetup(); //TODO - this is not thread safe, I trust newDataHandler_(audioData); } break; @@ -112,6 +111,13 @@ void DataReceiveThread::run() } break; } + case JammerNetzMessage::SESSIONSETUP: { + auto sessionInfo = std::dynamic_pointer_cast(message); + if (sessionInfo) { + currentSession_ = sessionInfo->channels_; //TODO - this is not thread safe, I trust + } + break; + } default: // What's this? jassert(false); diff --git a/Server/Source/MixerThread.cpp b/Server/Source/MixerThread.cpp index 87f2622..d0f1102 100644 --- a/Server/Source/MixerThread.cpp +++ b/Server/Source/MixerThread.cpp @@ -132,9 +132,9 @@ void MixerThread::run() { midiSignal, 48000, mixdownSetup_, - outBuffer, - sessionSetup - )); + outBuffer), + sessionSetup + ); if (!outgoing_.try_push(package)) { // That's a bad sign - I would assume the sender thread died and that's possibly because the network is down. // Abort diff --git a/Server/Source/SendThread.cpp b/Server/Source/SendThread.cpp index 4b44539..c4337f2 100644 --- a/Server/Source/SendThread.cpp +++ b/Server/Source/SendThread.cpp @@ -77,6 +77,21 @@ void SendThread::sendClientInfoPackage(std::string const &targetAddress) sendWriteBuffer(ipAddress, port, bytesWritten); } +void SendThread::sendSessionInfoPackage(std::string const &targetAddress, JammerNetzChannelSetup &sessionSetup) +{ + // Loop over the incoming data streams and add them to our statistics package we are going to send to the client + JammerNetzSessionInfoMessage sessionInfoMessage; + sessionInfoMessage.channels_.channels = sessionSetup.channels; + + size_t bytesWritten = 0; + sessionInfoMessage.serialize(writebuffer_, bytesWritten); + + String ipAddress; + int port; + determineTargetIP(targetAddress, ipAddress, port); + sendWriteBuffer(ipAddress, port, bytesWritten); +} + void SendThread::sendWriteBuffer(String ipAddress, int port, size_t size) { if (sizet_is_safe_as_int(size)) { int cipherLength = static_cast(size); @@ -118,6 +133,7 @@ void SendThread::run() } if (packageCounters_[nextBlock.targetAddress] % 100 == 0) { sendClientInfoPackage(nextBlock.targetAddress); + sendSessionInfoPackage(nextBlock.targetAddress, nextBlock.sessionSetup); } packageCounters_[nextBlock.targetAddress]++; } diff --git a/Server/Source/SendThread.h b/Server/Source/SendThread.h index 69ddd8a..d0cb2e9 100644 --- a/Server/Source/SendThread.h +++ b/Server/Source/SendThread.h @@ -21,7 +21,8 @@ class SendThread : public Thread { private: void determineTargetIP(std::string const &targetAddress, String &ipAddress, int &portNumber); void sendWriteBuffer(String ipAddress, int port, size_t size); - void sendClientInfoPackage(std::string const &targetAddress); + void sendSessionInfoPackage(std::string const &targetAddress, JammerNetzChannelSetup &sessionSetup); + void sendClientInfoPackage(std::string const &targetAddress); void sendAudioBlock(std::string const &targetAddress, AudioBlock &audioBlock); TOutgoingQueue& sendQueue_; diff --git a/Server/Source/SharedServerTypes.h b/Server/Source/SharedServerTypes.h index 2ed30d5..fa83a25 100644 --- a/Server/Source/SharedServerTypes.h +++ b/Server/Source/SharedServerTypes.h @@ -14,16 +14,20 @@ #include "tbb/concurrent_queue.h" #include "tbb/concurrent_unordered_map.h" +#include #include -struct OutgoingPackage { - OutgoingPackage() = default; - OutgoingPackage(std::string const &targetAddress, AudioBlock const &audioBlock) : - targetAddress(targetAddress), audioBlock(audioBlock) { +class OutgoingPackage { +public: + OutgoingPackage() : targetAddress(""), audioBlock(), sessionSetup(false) {} + + OutgoingPackage(std::string const &targetAddress_, AudioBlock const &audioBlock_, JammerNetzChannelSetup sessionSetup_) : + targetAddress(targetAddress_), audioBlock(audioBlock_), sessionSetup(sessionSetup_) { } std::string targetAddress; AudioBlock audioBlock; + JammerNetzChannelSetup sessionSetup; }; #if WIN32 diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 2ed6679..4cd185f 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -19,7 +19,13 @@ IF (WIN32) ELSE() set(FLATBUFFERS_FLATC_EXECUTABLE "${CMAKE_CURRENT_LIST_DIR}/../third_party/flatbuffers/LinuxBuilds/flatc") ENDIF() -FLATBUFFERS_GENERATE_C_HEADERS(FlatJammer JammerNetzPackages.fbs JammerNetzAudioData.fbs) +set(FLATBUFFER_INPUT + JammerNetzPackages.fbs + JammerNetzAudioData.fbs + JammerNetzChannelSetup.fbs + JammerNetzSessionInfo.fbs + ) +FLATBUFFERS_GENERATE_C_HEADERS(FlatJammer ${FLATBUFFER_INPUT}) # Define the sources for the static library set(Sources @@ -28,9 +34,8 @@ set(Sources Encryption.cpp Encryption.h JammerNetzClientInfoMessage.cpp JammerNetzClientInfoMessage.h JammerNetzPackage.cpp JammerNetzPackage.h - JammerNetzPackages.fbs - JammerNetzAudioData.fbs JuceHeader.h + ${FLATBUFFER_INPUT} ${FlatJammer_OUTPUTS} PacketStreamQueue.cpp PacketStreamQueue.h Pool.h diff --git a/common/JammerNetzAudioData.fbs b/common/JammerNetzAudioData.fbs index db9d1a5..fa58c32 100644 --- a/common/JammerNetzAudioData.fbs +++ b/common/JammerNetzAudioData.fbs @@ -4,14 +4,7 @@ // Dual licensed: Distributed under Affero GPL license by default, an MIT license is available for purchase // -table JammerNetzPNPChannelSetup { - target :uint8; - volume :float; - mag: float; - rms: float; - pitch: float; - name: string; -} +include "JammerNetzChannelSetup.fbs"; table JammerNetzPNPAudioSamples { audioSamples :[uint16]; @@ -27,7 +20,7 @@ table JammerNetzPNPAudioBlock { sampleRate :uint16; channelSetup :[JammerNetzPNPChannelSetup]; channels :[JammerNetzPNPAudioSamples]; - allChannels :[JammerNetzPNPChannelSetup]; + allChannels :[JammerNetzPNPChannelSetup] (deprecated); // This was deprecated to reduce the size of the return package wantEcho: bool = true; // True is the old behavior where the client did not have any local monitoring! serverTime :uint64 = 0; bpm :float = 0.0; diff --git a/common/JammerNetzChannelSetup.fbs b/common/JammerNetzChannelSetup.fbs new file mode 100644 index 0000000..ff834e5 --- /dev/null +++ b/common/JammerNetzChannelSetup.fbs @@ -0,0 +1,14 @@ +// +// Copyright (c) 2024 Christof Ruch. All rights reserved. +// +// Dual licensed: Distributed under Affero GPL license by default, an MIT license is available for purchase +// + +table JammerNetzPNPChannelSetup { + target :uint8; + volume :float; + mag: float; + rms: float; + pitch: float; + name: string; +} diff --git a/common/JammerNetzClientInfoMessage.h b/common/JammerNetzClientInfoMessage.h index 9c2d4c1..c96bcd2 100644 --- a/common/JammerNetzClientInfoMessage.h +++ b/common/JammerNetzClientInfoMessage.h @@ -8,6 +8,8 @@ #include "JammerNetzPackage.h" +#include + /* | CLIENTINFO type message - these are sent only by the server to the clients | JammerNetzClientInfoMessage diff --git a/common/JammerNetzPackage.cpp b/common/JammerNetzPackage.cpp index 9ce2944..e9c5d4c 100644 --- a/common/JammerNetzPackage.cpp +++ b/common/JammerNetzPackage.cpp @@ -15,8 +15,8 @@ JammerNetzSingleChannelSetup::JammerNetzSingleChannelSetup() : { } -JammerNetzSingleChannelSetup::JammerNetzSingleChannelSetup(uint8 target) : - target(target), volume(1.0f), mag(0.0f), rms(0.0f), pitch(0.0f) +JammerNetzSingleChannelSetup::JammerNetzSingleChannelSetup(uint8 target_) : + target(target_), volume(1.0f), mag(0.0f), rms(0.0f), pitch(0.0f) { } @@ -44,24 +44,15 @@ bool JammerNetzChannelSetup::isEqualEnough(const JammerNetzChannelSetup &other) { if (isLocalMonitoringDontSendEcho != other.isLocalMonitoringDontSendEcho) return false; if (channels.size() != other.channels.size()) return false; - for (int i = 0; i < channels.size(); i++) { + for (size_t i = 0; i < channels.size(); i++) { if (!(channels[i].isEqualEnough(other.channels[i]))) return false; } return true; } -/*bool JammerNetzChannelSetup::operator==(const JammerNetzChannelSetup &other) const -{ - if (channels.size() != other.channels.size()) return false; - for (int i = 0; i < channels.size(); i++) { - if (!(channels[i] == other.channels[i])) return false; - } - return true; -}*/ - -AudioBlock::AudioBlock(double timestamp, uint64 messageCounter, uint64 serverTime, float bpm, MidiSignal midiSignal, uint16 sampleRate, JammerNetzChannelSetup const &channelSetup, - std::shared_ptr> audioBuffer, JammerNetzChannelSetup const &sessionSetup) : - timestamp(timestamp), messageCounter(messageCounter), serverTime(serverTime), bpm(bpm), midiSignal(midiSignal), sampleRate(sampleRate), channelSetup(channelSetup), audioBuffer(audioBuffer), sessionSetup(sessionSetup) +AudioBlock::AudioBlock(double timestamp_, uint64 messageCounter_, uint64 serverTime_, float bpm_, MidiSignal midiSignal_, uint16 sampleRate_, JammerNetzChannelSetup const &channelSetup_, + std::shared_ptr> audioBuffer_) : + timestamp(timestamp_), messageCounter(messageCounter_), serverTime(serverTime_), bpm(bpm_), midiSignal(midiSignal_), sampleRate(sampleRate_), channelSetup(channelSetup_), audioBuffer(audioBuffer_) { } @@ -78,6 +69,8 @@ std::shared_ptr JammerNetzMessage::deserialize(uint8 *data, s return std::make_shared(data, bytes); case CLIENTINFO: return std::make_shared(data, bytes); + case SESSIONSETUP: + return std::make_shared(data, bytes); default: std::cerr << "Unknown message type received, ignoring it" << std::endl; } @@ -91,7 +84,7 @@ std::shared_ptr JammerNetzMessage::deserialize(uint8 *data, s return nullptr;; } -int JammerNetzMessage::writeHeader(uint8 *output, uint8 messageType) const +size_t JammerNetzMessage::writeHeader(uint8 *output, uint8 messageType) const { JammerNetzHeader *header = reinterpret_cast(output); header->magic0 = '1'; @@ -212,13 +205,7 @@ flatbuffers::Offset JammerNetzAudioData::serializeAudio auto fb_name = fbb.CreateString(channel.name); channelSetup.push_back(CreateJammerNetzPNPChannelSetup(fbb, channel.target, channel.volume, channel.mag, channel.rms, channel.pitch, fb_name)); } - std::vector> sessionChannels; - for (const auto& channel : src->sessionSetup.channels) { - auto fb_name = fbb.CreateString(channel.name); - sessionChannels.push_back(CreateJammerNetzPNPChannelSetup(fbb, channel.target, channel.volume, channel.mag, channel.rms, channel.pitch, fb_name)); - } auto channelSetupVector = fbb.CreateVector(channelSetup); - auto sessionSetupVector = fbb.CreateVector(sessionChannels); auto audioSamples = appendAudioBuffer(fbb, *src->audioBuffer, reductionFactor); JammerNetzPNPAudioBlockBuilder audioBlock(fbb); @@ -232,7 +219,6 @@ flatbuffers::Offset JammerNetzAudioData::serializeAudio audioBlock.add_sampleRate(sampleRate / reductionFactor); audioBlock.add_channelSetup(channelSetupVector); audioBlock.add_channels(audioSamples); - audioBlock.add_allChannels(sessionSetupVector); audioBlock.add_wantEcho(!src->channelSetup.isLocalMonitoringDontSendEcho); return audioBlock.Finish(); @@ -304,11 +290,6 @@ JammerNetzChannelSetup JammerNetzAudioData::channelSetup() const return activeBlock_->channelSetup; } -JammerNetzChannelSetup JammerNetzAudioData::sessionSetup() const -{ - return activeBlock_->sessionSetup; -} - std::shared_ptr JammerNetzAudioData::readAudioHeaderAndBytes(JammerNetzPNPAudioBlock const *block) { auto result = std::make_shared(); @@ -325,18 +306,7 @@ std::shared_ptr JammerNetzAudioData::readAudioHeaderAndBytes(JammerN setup.pitch = channel->pitch(); setup.name = channel->name()->str(); result->channelSetup.channels.push_back(setup); - }; - - result->sessionSetup.isLocalMonitoringDontSendEcho = !block->wantEcho(); - for (auto channel = block->allChannels()->cbegin(); channel != block->allChannels()->cend(); channel++) { - JammerNetzSingleChannelSetup setup(channel->target()); - setup.volume = channel->volume(); - setup.mag = channel->mag(); - setup.rms = channel->rms(); - setup.pitch = channel->pitch(); - setup.name = channel->name()->str(); - result->sessionSetup.channels.push_back(setup); - }; + } result->sampleRate = 48000; int upsampleRate = block->sampleRate() != 0 ? 48000 / block->sampleRate() : 48000; diff --git a/common/JammerNetzPackage.h b/common/JammerNetzPackage.h index cb31524..a6ebee9 100644 --- a/common/JammerNetzPackage.h +++ b/common/JammerNetzPackage.h @@ -10,6 +10,7 @@ #include "flatbuffers/flatbuffers.h" #include "JammerNetzAudioData_generated.h" +#include "JammerNetzSessionInfo_generated.h" const size_t MAXFRAMESIZE = 65536; @@ -82,11 +83,11 @@ struct JammerNetzAudioHeader { }; struct AudioBlock { - AudioBlock() : channelSetup(false), sessionSetup(false) { + AudioBlock() : channelSetup(false) { } - AudioBlock(AudioBlock const &other) = default; - AudioBlock(double timestamp, uint64 messageCounter, uint64 serverTime, float bpm, MidiSignal midiSignal, uint16 sampleRate, JammerNetzChannelSetup const &channelSetup, std::shared_ptr> audioBuffer, JammerNetzChannelSetup const &sessionSetup); + //AudioBlock(AudioBlock const &other) = default; + AudioBlock(double timestamp, uint64 messageCounter, uint64 serverTime, float bpm, MidiSignal midiSignal, uint16 sampleRate, JammerNetzChannelSetup const &channelSetup, std::shared_ptr> audioBuffer); double timestamp; // Using JUCE's high resolution timer juce::uint64 messageCounter; juce::uint64 serverTime; @@ -96,11 +97,10 @@ struct AudioBlock { uint16 sampleRate; JammerNetzChannelSetup channelSetup; std::shared_ptr> audioBuffer; - JammerNetzChannelSetup sessionSetup; }; struct JammerNetzMessageParseException : public std::exception { - const char *what() const throw () + const char *what() const noexcept { return "JammerNetz Message Parse Error"; } @@ -111,6 +111,7 @@ class JammerNetzMessage { enum MessageType { AUDIODATA = 1, CLIENTINFO = 8, + SESSIONSETUP = 16, }; virtual MessageType getType() const = 0; @@ -119,9 +120,66 @@ class JammerNetzMessage { static std::shared_ptr deserialize(uint8 *data, size_t bytes); protected: - int writeHeader(uint8 *output, uint8 messageType) const; + size_t writeHeader(uint8 *output, uint8 messageType) const; }; +template +class JammerNetzFlatbufferMessage : public JammerNetzMessage { +public: + JammerNetzFlatbufferMessage() : channels_(false) { + } + + // Generic deserialization constructor + JammerNetzFlatbufferMessage(uint8 *data, size_t size) : channels_(false) { + if (size < sizeof(JammerNetzAudioHeader)) { + throw JammerNetzMessageParseException(); + } + + uint8* dataStart = data + sizeof(JammerNetzHeader); + flatbuffers::Verifier verifier(dataStart, size - sizeof(JammerNetzHeader)); + if (VerifyJammerNetzSessionInfoBuffer(verifier)) { + auto package = GetJammerNetzSessionInfo(dataStart); + channels_.channels.clear(); + for (auto channel = package->allChannels()->cbegin(); channel != package->allChannels()->cend(); channel++) { + JammerNetzSingleChannelSetup setup(channel->target()); + setup.volume = channel->volume(); + setup.mag = channel->mag(); + setup.rms = channel->rms(); + setup.pitch = channel->pitch(); + setup.name = channel->name()->str(); + channels_.channels.push_back(setup); + } + } + } + + void serialize(uint8 *output, size_t &byteswritten) const override + { + byteswritten = writeHeader(output, getType()); + + flatbuffers::FlatBufferBuilder fbb; + + std::vector> allChannels; + for (const auto& channel : channels_.channels) { + auto fb_name = fbb.CreateString(channel.name); + allChannels.push_back(CreateJammerNetzPNPChannelSetup(fbb, channel.target, channel.volume, channel.mag, channel.rms, channel.pitch, fb_name)); + } + auto channelSetupVector = fbb.CreateVector(allChannels); + fbb.Finish(CreateJammerNetzSessionInfo(fbb, channelSetupVector)); + memcpy(output + byteswritten, fbb.GetBufferPointer(), fbb.GetSize()); + byteswritten += fbb.GetSize(); + } + + [[nodiscard]] MessageType getType() const override + { + return ID; + } + + JammerNetzChannelSetup channels_; +}; + +using JammerNetzSessionInfoMessage = JammerNetzFlatbufferMessage; + class JammerNetzAudioData : public JammerNetzMessage { public: JammerNetzAudioData(uint8 *data, size_t bytes); @@ -143,7 +201,6 @@ class JammerNetzAudioData : public JammerNetzMessage { float bpm() const; MidiSignal midiSignal() const; JammerNetzChannelSetup channelSetup() const; - JammerNetzChannelSetup sessionSetup() const; private: flatbuffers::Offset serializeAudioBlock(flatbuffers::FlatBufferBuilder &fbb, std::shared_ptr src, uint16 sampleRate, uint16 reductionFactor) const; diff --git a/common/JammerNetzSessionInfo.fbs b/common/JammerNetzSessionInfo.fbs new file mode 100644 index 0000000..b017f10 --- /dev/null +++ b/common/JammerNetzSessionInfo.fbs @@ -0,0 +1,15 @@ +// +// Copyright (c) 2024 Christof Ruch. All rights reserved. +// +// Dual licensed: Distributed under Affero GPL license by default, an MIT license is available for purchase +// + +include "JammerNetzChannelSetup.fbs"; + +table JammerNetzSessionInfo { + allChannels :[JammerNetzPNPChannelSetup]; +} + +root_type JammerNetzSessionInfo; + + From 455379e91ac6031b2fb82f5a8a7224067ed47d25 Mon Sep 17 00:00:00 2001 From: Christof Ruch Date: Sat, 19 Oct 2024 19:32:35 +0200 Subject: [PATCH 02/31] Fix? CMake including the generated header files the correct way --- common/CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 4cd185f..87c80aa 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -36,7 +36,6 @@ set(Sources JammerNetzPackage.cpp JammerNetzPackage.h JuceHeader.h ${FLATBUFFER_INPUT} - ${FlatJammer_OUTPUTS} PacketStreamQueue.cpp PacketStreamQueue.h Pool.h Recorder.cpp Recorder.h @@ -46,9 +45,13 @@ set(Sources ServerInfo.cpp ServerInfo.h XPlatformUtils.h ) - # Setup library add_library(JammerCommon ${Sources}) +foreach(OPT ${FlatJammer_OUTPUTS}) + message("Adding source file ${OPT}") +target_sources(JammerCommon PRIVATE ${OPT}) +endforeach() + target_include_directories(JammerCommon PUBLIC "${INTEL_TBB_DIRECTORY}/include/" "${CMAKE_CURRENT_LIST_DIR}/../third_party/flatbuffers/include" "${CMAKE_CURRENT_BINARY_DIR}" INTERFACE ${CMAKE_CURRENT_LIST_DIR} From a13d7891f559f1ec07f377c462e4ae509eb8c60f Mon Sep 17 00:00:00 2001 From: Christof Ruch Date: Sat, 19 Oct 2024 19:32:54 +0200 Subject: [PATCH 03/31] A little lint --- common/RingOfAudioBuffers.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/common/RingOfAudioBuffers.h b/common/RingOfAudioBuffers.h index 7470941..d2786f4 100644 --- a/common/RingOfAudioBuffers.h +++ b/common/RingOfAudioBuffers.h @@ -24,7 +24,11 @@ class RingOfAudioBuffers { void push(std::shared_ptr audioBuffer) { // The write pointer always points to the next element to write to - data_[endIndex_] = audioBuffer; + if (endIndex_ < 0) { + jassertfalse; + return; + } + data_[(size_t) endIndex_] = audioBuffer; incIndex(endIndex_); if (endIndex_ == headIndex_) { incIndex(headIndex_); @@ -39,7 +43,7 @@ class RingOfAudioBuffers { int readIndex = endIndex_ - 1; if (readIndex < 0) readIndex += (int) data_.size(); - return data_[readIndex]; + return data_[(size_t) readIndex]; } std::shared_ptr getNthLast(int n) const @@ -62,13 +66,13 @@ class RingOfAudioBuffers { if (readIndex < 0) readIndex += (int) data_.size(); count++; } - return data_[readIndex]; + return data_[(size_t) readIndex]; } private: void incIndex(int &index) { - index = (index + 1) % data_.size(); + index = (index + 1) % (int) data_.size(); } std::vector> data_; From e0c20629bde4f99886738b2195764f2af77a6f29 Mon Sep 17 00:00:00 2001 From: Christof Ruch Date: Sat, 19 Oct 2024 19:34:22 +0200 Subject: [PATCH 04/31] Prepare for a generic control message that will be used to send parameter changes to the server. Not enjoying flatbuffers enough to put all the parameters into individual flatbuffer messages, we'll be just using a string with JSON here. This is low frequency data, therefore that overhead won't matter. --- common/CMakeLists.txt | 1 + common/JammerNetzControlMessage.fbs | 11 ++++++ common/JammerNetzPackage.h | 54 +++++++++++++++++++---------- 3 files changed, 47 insertions(+), 19 deletions(-) create mode 100644 common/JammerNetzControlMessage.fbs diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 87c80aa..0a03643 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -24,6 +24,7 @@ set(FLATBUFFER_INPUT JammerNetzAudioData.fbs JammerNetzChannelSetup.fbs JammerNetzSessionInfo.fbs + JammerNetzControlMessage.fbs ) FLATBUFFERS_GENERATE_C_HEADERS(FlatJammer ${FLATBUFFER_INPUT}) diff --git a/common/JammerNetzControlMessage.fbs b/common/JammerNetzControlMessage.fbs new file mode 100644 index 0000000..12e5a83 --- /dev/null +++ b/common/JammerNetzControlMessage.fbs @@ -0,0 +1,11 @@ +// +// Copyright (c) 2024 Christof Ruch. All rights reserved. +// +// Dual licensed: Distributed under Affero GPL license by default, an MIT license is available for purchase +// + +table JammerNetzControlInfo { + control_message_json: string; +} + +root_type JammerNetzControlInfo; diff --git a/common/JammerNetzPackage.h b/common/JammerNetzPackage.h index a6ebee9..e7f7b3a 100644 --- a/common/JammerNetzPackage.h +++ b/common/JammerNetzPackage.h @@ -11,6 +11,7 @@ #include "flatbuffers/flatbuffers.h" #include "JammerNetzAudioData_generated.h" #include "JammerNetzSessionInfo_generated.h" +#include "JammerNetzControlMessage_generated.h" const size_t MAXFRAMESIZE = 65536; @@ -114,6 +115,10 @@ class JammerNetzMessage { SESSIONSETUP = 16, }; + JammerNetzMessage() = default; + JammerNetzMessage(JammerNetzMessage const&) = default; + virtual ~JammerNetzMessage() = default; + virtual MessageType getType() const = 0; virtual void serialize(uint8 *output, size_t &byteswritten) const = 0; @@ -123,18 +128,43 @@ class JammerNetzMessage { size_t writeHeader(uint8 *output, uint8 messageType) const; }; -template +template class JammerNetzFlatbufferMessage : public JammerNetzMessage { public: - JammerNetzFlatbufferMessage() : channels_(false) { - } + JammerNetzFlatbufferMessage() = default; // Generic deserialization constructor - JammerNetzFlatbufferMessage(uint8 *data, size_t size) : channels_(false) { + JammerNetzFlatbufferMessage(size_t size) { if (size < sizeof(JammerNetzAudioHeader)) { throw JammerNetzMessageParseException(); } + } + + void serialize(uint8 *output, size_t &byteswritten) const override + { + byteswritten = writeHeader(output, getType()); + flatbuffers::FlatBufferBuilder fbb; + serializeToFlatbuffer(fbb); + memcpy(output + byteswritten, fbb.GetBufferPointer(), fbb.GetSize()); + byteswritten += fbb.GetSize(); + } + + virtual void serializeToFlatbuffer(flatbuffers::FlatBufferBuilder &fbb) const = 0; + + [[nodiscard]] MessageType getType() const override + { + return ID; + } +}; +class JammerNetzSessionInfoMessage : public JammerNetzFlatbufferMessage +{ +public: + JammerNetzSessionInfoMessage() : channels_(false) + { + } + + JammerNetzSessionInfoMessage(uint8 *data, size_t size) : JammerNetzFlatbufferMessage(size), channels_(false) { uint8* dataStart = data + sizeof(JammerNetzHeader); flatbuffers::Verifier verifier(dataStart, size - sizeof(JammerNetzHeader)); if (VerifyJammerNetzSessionInfoBuffer(verifier)) { @@ -152,12 +182,8 @@ class JammerNetzFlatbufferMessage : public JammerNetzMessage { } } - void serialize(uint8 *output, size_t &byteswritten) const override + void serializeToFlatbuffer(flatbuffers::FlatBufferBuilder &fbb) const override { - byteswritten = writeHeader(output, getType()); - - flatbuffers::FlatBufferBuilder fbb; - std::vector> allChannels; for (const auto& channel : channels_.channels) { auto fb_name = fbb.CreateString(channel.name); @@ -165,21 +191,11 @@ class JammerNetzFlatbufferMessage : public JammerNetzMessage { } auto channelSetupVector = fbb.CreateVector(allChannels); fbb.Finish(CreateJammerNetzSessionInfo(fbb, channelSetupVector)); - memcpy(output + byteswritten, fbb.GetBufferPointer(), fbb.GetSize()); - byteswritten += fbb.GetSize(); - } - - [[nodiscard]] MessageType getType() const override - { - return ID; } JammerNetzChannelSetup channels_; }; -using JammerNetzSessionInfoMessage = JammerNetzFlatbufferMessage; - class JammerNetzAudioData : public JammerNetzMessage { public: JammerNetzAudioData(uint8 *data, size_t bytes); From dc0ae8f26d92e192d1a5f448746c8ec727d6ddc5 Mon Sep 17 00:00:00 2001 From: Christof Ruch Date: Sat, 19 Oct 2024 19:43:20 +0200 Subject: [PATCH 05/31] A bit more lint --- Client/Source/AudioCallback.cpp | 2 +- Server/Source/Main.cpp | 2 +- common/JammerNetzPackage.h | 22 +++++++++++----------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Client/Source/AudioCallback.cpp b/Client/Source/AudioCallback.cpp index 0d083bd..1b556a2 100644 --- a/Client/Source/AudioCallback.cpp +++ b/Client/Source/AudioCallback.cpp @@ -26,7 +26,7 @@ AudioCallback::AudioCallback() : jammerService_([this](std::shared_ptr < JammerN // Where to record to? uploadRecorder_ = std::make_shared(Settings::instance().getSessionStorageDir(), "LocalRecording", RecordingType::WAV); masterRecorder_ = std::make_shared(Settings::instance().getSessionStorageDir(), "MasterRecording", RecordingType::FLAC); - masterRecorder_->setChannelInfo(SAMPLE_RATE, JammerNetzChannelSetup(false, { JammerNetzChannelTarget::Left, JammerNetzChannelTarget::Right })); + masterRecorder_->setChannelInfo(SAMPLE_RATE, JammerNetzChannelSetup(false, { JammerNetzSingleChannelSetup(JammerNetzChannelTarget::Left), JammerNetzSingleChannelSetup(JammerNetzChannelTarget::Right) })); //midiRecorder_ = std::make_unique(deviceManager); // We might want to share a score sheet or similar diff --git a/Server/Source/Main.cpp b/Server/Source/Main.cpp index 7f804ee..8a9a035 100644 --- a/Server/Source/Main.cpp +++ b/Server/Source/Main.cpp @@ -36,7 +36,7 @@ class Server { public: Server(std::shared_ptr cryptoKey, ServerBufferConfig bufferConfig, int serverPort, bool useFEC) : mixdownRecorder_(File::getCurrentWorkingDirectory(), "mixdown", RecordingType::FLAC), clientRecorder_(File(), "input", RecordingType::AIFF), - mixdownSetup_(false, { JammerNetzChannelTarget::Left, JammerNetzChannelTarget::Right }) // Setup standard mix down setup - two channels only in stereo + mixdownSetup_(false, { JammerNetzSingleChannelSetup(JammerNetzChannelTarget::Left), JammerNetzSingleChannelSetup(JammerNetzChannelTarget::Right) }) // Setup standard mix down setup - two channels only in stereo { // Start the recorder of the mix down //mixdownRecorder_.updateChannelInfo(48000, mixdownSetup_); diff --git a/common/JammerNetzPackage.h b/common/JammerNetzPackage.h index e7f7b3a..f397bf6 100644 --- a/common/JammerNetzPackage.h +++ b/common/JammerNetzPackage.h @@ -13,6 +13,8 @@ #include "JammerNetzSessionInfo_generated.h" #include "JammerNetzControlMessage_generated.h" +#include +#include const size_t MAXFRAMESIZE = 65536; @@ -47,7 +49,7 @@ enum JammerNetzChannelTarget { struct JammerNetzSingleChannelSetup { JammerNetzSingleChannelSetup(); - JammerNetzSingleChannelSetup(uint8 target); + explicit JammerNetzSingleChannelSetup(uint8 target); uint8 target; float volume; float mag; @@ -55,27 +57,25 @@ struct JammerNetzSingleChannelSetup { float pitch; std::string name; - bool isEqualEnough(const JammerNetzSingleChannelSetup &other) const; - //bool operator ==(const JammerNetzSingleChannelSetup &other) const; + [[nodiscard]] bool isEqualEnough(const JammerNetzSingleChannelSetup &other) const; }; struct JammerNetzChannelSetup { - JammerNetzChannelSetup(bool localMonitoring); + explicit JammerNetzChannelSetup(bool localMonitoring); JammerNetzChannelSetup(bool localMonitoring, std::vector const &channelInfo); bool isLocalMonitoringDontSendEcho; std::vector channels; - bool isEqualEnough(const JammerNetzChannelSetup &other) const; - //bool operator ==(const JammerNetzChannelSetup &other) const; + [[nodiscard]] bool isEqualEnough(const JammerNetzChannelSetup &other) const; }; struct JammerNetzAudioBlock { - double timestamp; // Using JUCE's high resolution timer - juce::uint64 messageCounter; + double timestamp{}; // Using JUCE's high resolution timer + juce::uint64 messageCounter{}; JammerNetzChannelSetup channelSetup; - uint8 numchannels; - uint16 numberOfSamples; - uint16 sampleRate; + uint8 numchannels{}; + uint16 numberOfSamples{}; + uint16 sampleRate{}; }; struct JammerNetzAudioHeader { From a38e4d18967bf8eadc5f8034c320765800cbbadf Mon Sep 17 00:00:00 2001 From: Christof Ruch Date: Sat, 19 Oct 2024 21:12:14 +0200 Subject: [PATCH 06/31] Lot's of Lint, and get the Server compile on MacOS without warnings. --- Client/CMakeLists.txt | 1 + Client/Source/DataReceiveThread.cpp | 3 + Client/Source/IncludeFFMeters.h | 7 ++ Client/Source/Main.cpp | 4 +- Client/Source/MainComponent.cpp | 5 +- Client/Source/MainComponent.h | 4 +- Client/Source/PlayalongDisplay.h | 2 +- Client/Source/RecordingInfo.h | 2 +- Client/Source/version.cpp.in | 2 +- Server/CMakeLists.txt | 1 + Server/Source/AcceptThread.cpp | 118 +++++++++++++++++----------- Server/Source/AcceptThread.h | 9 ++- Server/Source/Main.cpp | 16 ++-- Server/Source/MixerThread.cpp | 22 ++++-- Server/Source/MixerThread.h | 6 +- Server/Source/SendThread.cpp | 6 +- Server/Source/ServerLogger.cpp | 26 +++--- Server/Source/SharedServerTypes.h | 6 ++ common/JammerNetzPackage.cpp | 8 +- common/JammerNetzPackage.h | 44 ++++++++++- common/PacketStreamQueue.h | 5 ++ 21 files changed, 208 insertions(+), 89 deletions(-) diff --git a/Client/CMakeLists.txt b/Client/CMakeLists.txt index 990796e..72260d7 100644 --- a/Client/CMakeLists.txt +++ b/Client/CMakeLists.txt @@ -159,6 +159,7 @@ if (MSVC) else() # lots of warnings and all warnings as errors #target_compile_options(JammerNetzClient PRIVATE -Wall -Wextra -pedantic -Werror) + target_compile_options(JammerNetzClient PRIVATE -Wno-unknown-pragmas) endif() IF(WIN32) diff --git a/Client/Source/DataReceiveThread.cpp b/Client/Source/DataReceiveThread.cpp index 6a20032..c1c1a56 100644 --- a/Client/Source/DataReceiveThread.cpp +++ b/Client/Source/DataReceiveThread.cpp @@ -118,6 +118,9 @@ void DataReceiveThread::run() } break; } + case JammerNetzMessage::MessageType::GENERIC_JSON: + // Ignore for now + break; default: // What's this? jassert(false); diff --git a/Client/Source/IncludeFFMeters.h b/Client/Source/IncludeFFMeters.h index 8c00e0e..2cdb31f 100644 --- a/Client/Source/IncludeFFMeters.h +++ b/Client/Source/IncludeFFMeters.h @@ -7,7 +7,14 @@ #pragma once +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wimplicit-float-conversion" +#pragma clang diagnostic ignored "-Wsign-compare" +#pragma clang diagnostic ignored "-Wsign-conversion" +#pragma clang diagnostic ignored "-Wshadow" +#pragma clang diagnostic ignored "-Wunknown-pragmas" #pragma warning( push ) #pragma warning( disable: 4244 4100 4456 4702) #include "ff_meters/ff_meters.h" #pragma warning (pop ) +#pragma clang diagnostic pop diff --git a/Client/Source/Main.cpp b/Client/Source/Main.cpp index 5529c89..73e8f46 100644 --- a/Client/Source/Main.cpp +++ b/Client/Source/Main.cpp @@ -72,7 +72,7 @@ class ClientApplication : public JUCEApplication if (clientID.isNotEmpty()) { windowTitle += ": " + clientID; } - mainWindow = std::make_unique(new MainComponent(clientID, audioService_, audioService_->getMasterRecorder(), audioService_->getLocalRecorder()), windowTitle, clientID); + mainWindow = std::make_unique(new MainComponent(audioService_, audioService_->getMasterRecorder(), audioService_->getLocalRecorder()), windowTitle); #ifdef USE_SENTRY // Initialize sentry for error crash reporting @@ -130,7 +130,7 @@ class ClientApplication : public JUCEApplication class MainWindow : public DocumentWindow { public: - MainWindow (Component *mainComponent, String name, String clientID) : DocumentWindow (name, + MainWindow (Component *mainComponent, String name) : DocumentWindow (name, Desktop::getInstance().getDefaultLookAndFeel() .findColour (ResizableWindow::backgroundColourId), DocumentWindow::allButtons) diff --git a/Client/Source/MainComponent.cpp b/Client/Source/MainComponent.cpp index cabda6d..126a047 100644 --- a/Client/Source/MainComponent.cpp +++ b/Client/Source/MainComponent.cpp @@ -20,7 +20,7 @@ #include "BuffersConfig.h" -MainComponent::MainComponent(String clientID, std::shared_ptr audioService, std::shared_ptr masterRecorder, std::shared_ptr localRecorder) : +MainComponent::MainComponent(std::shared_ptr audioService, std::shared_ptr masterRecorder, std::shared_ptr localRecorder) : audioService_(audioService), inputSelector_(VALUE_INPUT_SETUP, false, true), outputSelector_(VALUE_OUTPUT_SETUP, false, false), @@ -210,7 +210,6 @@ void MainComponent::resized() auto outputArea = area.removeFromRight(masterMixerWidth + deviceSelectorWidth /* + playalongArea.getWidth()*/); // Upper middle, other session participants - auto sessionArea = area; sessionGroup_.setBounds(area); allChannels_.setBounds(area.reduced(kNormalInset, kNormalInset)); @@ -332,7 +331,7 @@ void MainComponent::timerCallback() } // and for the session channels if (currentSessionSetup_) { - for (int i = 0; i < currentSessionSetup_->channels.size(); i++) { + for (int i = 0; i < (int) currentSessionSetup_->channels.size(); i++) { allChannels_.setPitchDisplayed(i, MidiNote(audioService_->sessionPitch(i))); } } diff --git a/Client/Source/MainComponent.h b/Client/Source/MainComponent.h index 602a32f..7176210 100644 --- a/Client/Source/MainComponent.h +++ b/Client/Source/MainComponent.h @@ -24,8 +24,8 @@ class MainComponent : public Component, private Timer, public ValueTree::Listener { public: - MainComponent(String clientID, std::shared_ptr audioService, std::shared_ptr masterRecorder, std::shared_ptr localRecorder); - ~MainComponent(); + MainComponent(std::shared_ptr audioService, std::shared_ptr masterRecorder, std::shared_ptr localRecorder); + virtual ~MainComponent() override; void resized() override; diff --git a/Client/Source/PlayalongDisplay.h b/Client/Source/PlayalongDisplay.h index 2ce40b1..3a4c169 100644 --- a/Client/Source/PlayalongDisplay.h +++ b/Client/Source/PlayalongDisplay.h @@ -13,7 +13,7 @@ class PlayalongDisplay : public Component, private Button::Listener, private Timer { public: PlayalongDisplay(MidiPlayAlong *playalong); - virtual ~PlayalongDisplay(); + virtual ~PlayalongDisplay() override; virtual void resized() override; diff --git a/Client/Source/RecordingInfo.h b/Client/Source/RecordingInfo.h index 887207c..cc68379 100644 --- a/Client/Source/RecordingInfo.h +++ b/Client/Source/RecordingInfo.h @@ -13,7 +13,7 @@ class RecordingInfo : public Component, private TextButton::Listener { public: RecordingInfo(std::weak_ptr recorder, String explanation); - ~RecordingInfo(); + virtual ~RecordingInfo() override; virtual void resized() override; diff --git a/Client/Source/version.cpp.in b/Client/Source/version.cpp.in index 88fa398..b59c369 100644 --- a/Client/Source/version.cpp.in +++ b/Client/Source/version.cpp.in @@ -4,7 +4,7 @@ Dual licensed: Distributed under Affero GPL license by default, an MIT license is available for purchase */ -std::string getClientVersion() +static std::string getClientVersion() { return "@JammerNetzClient_VERSION@"; } diff --git a/Server/CMakeLists.txt b/Server/CMakeLists.txt index d963988..6cdf503 100644 --- a/Server/CMakeLists.txt +++ b/Server/CMakeLists.txt @@ -60,4 +60,5 @@ if (MSVC) else() # lots of warnings and all warnings as errors #target_compile_options(JammerNetzServer PRIVATE -Wall -Wextra -pedantic -Werror) + target_compile_options(JammerNetzServer PRIVATE -Werror) endif() diff --git a/Server/Source/AcceptThread.cpp b/Server/Source/AcceptThread.cpp index 138d2ca..2796986 100644 --- a/Server/Source/AcceptThread.cpp +++ b/Server/Source/AcceptThread.cpp @@ -51,6 +51,52 @@ AcceptThread::~AcceptThread() qualityTimer_->stopTimer(); } +void AcceptThread::processControlMessage(std::shared_ptr message) +{ + if (message) + { + + } +} + +void AcceptThread::processAudioMessage(std::shared_ptr audioData, std::string const& clientName) +{ + if (audioData) { + // Insert this package into the right priority audio queue + bool prefill = false; + if (incomingData_.find(clientName) == incomingData_.end()) { + // This is from a new client! + ServerLogger::printClientStatus(4, clientName, + "New client connected, first package received"); + incomingData_[clientName] = std::make_unique(clientName); + prefill = true; + } else if (!incomingData_[clientName]) { + ServerLogger::printClientStatus(4, clientName, + "Reconnected successfully and starts sending again"); + incomingData_[clientName] = std::make_unique(clientName); + prefill = false; + } + if (prefill) { + auto lastInserted = audioData; + std::stack> reverse; + for (int i = 0; i < bufferConfig_.serverBufferPrefillOnConnect; i++) { + lastInserted = lastInserted->createPrePaddingPackage(); + reverse.push(lastInserted); + } + while (!reverse.empty()) { + incomingData_[clientName]->push(reverse.top()); + reverse.pop(); + } + } + + if (incomingData_[clientName]->push(audioData)) { + // Only if this was not a duplicate package do give the mixer thread a tick, else duplicates will cause queue drain + wakeUpQueue_.push( + 1); // The value pushed is irrelevant, we just want to wake up the mixer thread which is in a blocking read on this queue + } + } +} + void AcceptThread::run() { // Start the timer that will frequently output quality data for each of the clients' connections @@ -78,8 +124,8 @@ void AcceptThread::run() continue; } int messageLength = -1; - if (blowFish_) { - messageLength = blowFish_->decrypt(readbuffer, dataRead); + if (blowFish_ && dataRead > 0) { + messageLength = blowFish_->decrypt(readbuffer, (size_t) dataRead); if (messageLength == -1) { ServerLogger::printClientStatus(4, clientName, "Using wrong encryption key, can't connect"); continue; @@ -90,50 +136,34 @@ void AcceptThread::run() messageLength = dataRead; } - auto message = JammerNetzMessage::deserialize(readbuffer, messageLength); - if (message) { - auto audioData = std::dynamic_pointer_cast(message); - if (audioData) { - // Insert this package into the right priority audio queue - bool prefill = false; - if (incomingData_.find(clientName) == incomingData_.end()) { - // This is from a new client! - ServerLogger::printClientStatus(4, clientName, "New client connected, first package received"); - incomingData_[clientName] = std::make_unique(clientName); - prefill = true; - } - else if (!incomingData_[clientName]) { - ServerLogger::printClientStatus(4, clientName, "Reconnected successfully and starts sending again"); - incomingData_[clientName] = std::make_unique(clientName); - prefill = false; - } - if (prefill) { - auto lastInserted = audioData; - std::stack> reverse; - for (int i = 0; i < bufferConfig_.serverBufferPrefillOnConnect; i++) { - lastInserted = lastInserted->createPrePaddingPackage(); - reverse.push(lastInserted); - } - while (!reverse.empty()) { - incomingData_[clientName]->push(reverse.top()); - reverse.pop(); - } - } - - if (incomingData_[clientName]->push(audioData)) { - // Only if this was not a duplicate package do give the mixer thread a tick, else duplicates will cause queue drain - wakeUpQueue_.push(1); // The value pushed is irrelevant, we just want to wake up the mixer thread which is in a blocking read on this queue - } - } - } + if (messageLength > 0) { + auto message = JammerNetzMessage::deserialize(readbuffer, (size_t) messageLength); + if (message) { + switch (message->getType()) { + case JammerNetzMessage::MessageType::AUDIODATA: + processAudioMessage(std::dynamic_pointer_cast(message), clientName); + break; + case JammerNetzMessage::MessageType::GENERIC_JSON: + processControlMessage(std::dynamic_pointer_cast(message)); + break; + case JammerNetzMessage::MessageType::CLIENTINFO: + // fall through + case JammerNetzMessage::MessageType::SESSIONSETUP: + // fall through + default: + // Ignoring Message + break; + } + } #ifdef ALLOW_HELO - // Useful for debugging firewall problems, use ncat and send some bytes to this port to get the message back - else { - // HELO - std::string helo("HELO"); - receiveSocket_.write(senderIPAdress, senderPortNumber, helo.data(), (int)helo.size()); - } + // Useful for debugging firewall problems, use ncat and send some bytes to this port to get the message back + else { + // HELO + std::string helo("HELO"); + receiveSocket_.write(senderIPAdress, senderPortNumber, helo.data(), (int)helo.size()); + } #endif + } break; } case -1: diff --git a/Server/Source/AcceptThread.h b/Server/Source/AcceptThread.h index 33e2cff..b8a4074 100644 --- a/Server/Source/AcceptThread.h +++ b/Server/Source/AcceptThread.h @@ -11,17 +11,22 @@ #include "SharedServerTypes.h" #include "BuffersConfig.h" +#include "JammerNetzPackage.h" + class PrintQualityTimer; class AcceptThread : public Thread { public: AcceptThread(int serverPort, DatagramSocket &socket, TPacketStreamBundle &incomingData, TMessageQueue &wakeUpQueue, ServerBufferConfig bufferConfig, void *keydata, int keysize); - ~AcceptThread(); + virtual ~AcceptThread() override; virtual void run() override; private: - DatagramSocket &receiveSocket_; + void processControlMessage(std::shared_ptr message); + void processAudioMessage(std::shared_ptr message, std::string const& clientName); + + DatagramSocket &receiveSocket_; TPacketStreamBundle &incomingData_; TMessageQueue &wakeUpQueue_; uint8 readbuffer[MAXFRAMESIZE]; diff --git a/Server/Source/Main.cpp b/Server/Source/Main.cpp index 8a9a035..20b2f18 100644 --- a/Server/Source/Main.cpp +++ b/Server/Source/Main.cpp @@ -19,6 +19,8 @@ #include "ServerLogger.h" +std::string getServerVersion(); + #include "version.cpp" #ifdef WIN32 @@ -35,8 +37,10 @@ class Server { public: - Server(std::shared_ptr cryptoKey, ServerBufferConfig bufferConfig, int serverPort, bool useFEC) : mixdownRecorder_(File::getCurrentWorkingDirectory(), "mixdown", RecordingType::FLAC), clientRecorder_(File(), "input", RecordingType::AIFF), - mixdownSetup_(false, { JammerNetzSingleChannelSetup(JammerNetzChannelTarget::Left), JammerNetzSingleChannelSetup(JammerNetzChannelTarget::Right) }) // Setup standard mix down setup - two channels only in stereo + Server(std::shared_ptr cryptoKey, ServerBufferConfig bufferConfig, int serverPort, bool useFEC) : + clientRecorder_(File(), "input", RecordingType::AIFF) + , mixdownRecorder_(File::getCurrentWorkingDirectory(), "mixdown", RecordingType::FLAC) + , mixdownSetup_(false, { JammerNetzSingleChannelSetup(JammerNetzChannelTarget::Left), JammerNetzSingleChannelSetup(JammerNetzChannelTarget::Right) }) // Setup standard mix down setup - two channels only in stereo { // Start the recorder of the mix down //mixdownRecorder_.updateChannelInfo(48000, mixdownSetup_); @@ -51,7 +55,7 @@ class Server { acceptThread_ = std::make_unique(serverPort, socket_, incomingStreams_, wakeUpQueue_, bufferConfig, cryptoData, cipherLength); sendThread_ = std::make_unique (socket_, sendQueue_, incomingStreams_, cryptoData, cipherLength, useFEC); - mixerThread_ = std::make_unique(incomingStreams_, mixdownSetup_, sendQueue_, wakeUpQueue_, mixdownRecorder_, bufferConfig); + mixerThread_ = std::make_unique(incomingStreams_, mixdownSetup_, sendQueue_, wakeUpQueue_, bufferConfig); sendQueue_.set_capacity(128); // This is an arbitrary number only to prevent memory overflow should the sender thread somehow die (i.e. no network or something) } @@ -110,10 +114,10 @@ int main(int argc, char *argv[]) std::shared_ptr cryptoKey; // Parse command line arguments - ArgumentList args(argc, argv); + ArgumentList arguments(argc, argv); // Sweet executable name - File myself(args.executableName); + File myself(arguments.executableName); String shortExeName = myself.getFileName(); // Specify commands @@ -173,7 +177,7 @@ int main(int argc, char *argv[]) sentry_capture_event(sentry_value_new_message_event(SENTRY_LEVEL_INFO, "custom", "Launching JammerNetzServer")); #endif - app.findAndRunCommand(args); + app.findAndRunCommand(arguments); #ifdef USE_SENTRY std::cout << "Shutting down Sentry" << std::endl; diff --git a/Server/Source/MixerThread.cpp b/Server/Source/MixerThread.cpp index d0f1102..4b2eea1 100644 --- a/Server/Source/MixerThread.cpp +++ b/Server/Source/MixerThread.cpp @@ -9,10 +9,16 @@ #include "BuffersConfig.h" #include "ServerLogger.h" -MixerThread::MixerThread(TPacketStreamBundle &incoming, JammerNetzChannelSetup mixdownSetup, TOutgoingQueue &outgoing, TMessageQueue &wakeUpQueue, Recorder &recorder, ServerBufferConfig bufferConfig) : - Thread("MixerThread"), - incoming_(incoming), mixdownSetup_(mixdownSetup), outgoing_(outgoing), wakeUpQueue_(wakeUpQueue), recorder_(recorder), bufferConfig_(bufferConfig), serverTime_(0), - lastBpm_(120.0f) +MixerThread::MixerThread(TPacketStreamBundle &incoming, JammerNetzChannelSetup mixdownSetup, TOutgoingQueue &outgoing, TMessageQueue &wakeUpQueue/*, Recorder &recorder*/, ServerBufferConfig bufferConfig) : + Thread("MixerThread") + , serverTime_(0) + , lastBpm_(120.0f) + , incoming_(incoming) + , outgoing_(outgoing) + , wakeUpQueue_(wakeUpQueue) + , mixdownSetup_(mixdownSetup) + /*, recorder_(recorder) */ + , bufferConfig_(bufferConfig) { } @@ -33,8 +39,8 @@ void MixerThread::run() { for (auto &inqueue : incoming_) { if (inqueue.second) { clientCount++; - if (inqueue.second->size() > bufferConfig_.serverIncomingJitterBuffer) available++; - if (inqueue.second->size() > bufferConfig_.serverIncomingMaximumBuffer) queueOverrun = true; // This is one client much faster than the others + if ((int)inqueue.second->size() > bufferConfig_.serverIncomingJitterBuffer) available++; + if ((int)inqueue.second->size() > bufferConfig_.serverIncomingMaximumBuffer) queueOverrun = true; // This is one client much faster than the others } } if (clientCount == available) allHaveDelivered = true; @@ -87,7 +93,7 @@ void MixerThread::run() { if (incomingData.size() > 0) { //TODO - current assumption: all clients provide buffers of the same size. Therefore, take the length of the first client as the output size int bufferLength = (*incomingData.begin()).second->audioBuffer()->getNumSamples(); - serverTime_ += bufferLength; // Server time counts time of mixing thread in samples mixed since launch + serverTime_ += (size_t) bufferLength; // Server time counts time of mixing thread in samples mixed since launch // For each client that has delivered data, produce a mix down package and send it back //TODO - also the clients that have not provided data should get a package with a note that they are not contained within - they could do a local fill in. @@ -168,7 +174,7 @@ void MixerThread::bufferMixdown(std::shared_ptr> &outBuffer, auto channelSetup = audioData->channelSetup(); bool wantsEcho = !channelSetup.isLocalMonitoringDontSendEcho; for (int channel = 0; channel < audioData->audioBuffer()->getNumChannels(); channel++) { - JammerNetzSingleChannelSetup setup = channelSetup.channels[channel]; + JammerNetzSingleChannelSetup setup = channelSetup.channels[(size_t)channel]; switch (setup.target) { case Mute: // Nothing to be done diff --git a/Server/Source/MixerThread.h b/Server/Source/MixerThread.h index 3c14348..c6eaac5 100644 --- a/Server/Source/MixerThread.h +++ b/Server/Source/MixerThread.h @@ -16,7 +16,9 @@ class MixerThread : public Thread { public: - MixerThread(TPacketStreamBundle &incoming, JammerNetzChannelSetup mixdownSetup, TOutgoingQueue &outgoing, TMessageQueue &wakeUpQueue, Recorder &recorder, ServerBufferConfig bufferConfig); + MixerThread(TPacketStreamBundle &incoming, JammerNetzChannelSetup mixdownSetup, TOutgoingQueue &outgoing, TMessageQueue &wakeUpQueue + /*, Recorder &recorder*/ + , ServerBufferConfig bufferConfig); virtual void run() override; @@ -29,6 +31,6 @@ class MixerThread : public Thread { TOutgoingQueue &outgoing_; TMessageQueue &wakeUpQueue_; JammerNetzChannelSetup mixdownSetup_; - Recorder &recorder_; + //Recorder &recorder_; ServerBufferConfig bufferConfig_; }; diff --git a/Server/Source/SendThread.cpp b/Server/Source/SendThread.cpp index c4337f2..330d38d 100644 --- a/Server/Source/SendThread.cpp +++ b/Server/Source/SendThread.cpp @@ -11,7 +11,11 @@ #include "ServerLogger.h" SendThread::SendThread(DatagramSocket& socket, TOutgoingQueue &sendQueue, TPacketStreamBundle &incomingData, void *keydata, int keysize, bool useFEC) - : Thread("SenderThread"), sendSocket_(socket), sendQueue_(sendQueue), incomingData_(incomingData), useFEC_(useFEC) + : Thread("SenderThread") + , sendQueue_(sendQueue) + , incomingData_(incomingData) + , sendSocket_(socket) + , useFEC_(useFEC) { if (keydata) { blowFish_ = std::make_unique(keydata, keysize); diff --git a/Server/Source/ServerLogger.cpp b/Server/Source/ServerLogger.cpp index 9ccc17e..0124a5f 100644 --- a/Server/Source/ServerLogger.cpp +++ b/Server/Source/ServerLogger.cpp @@ -55,7 +55,7 @@ std::vector> kColumnHeaders = { {0, "Client"}, {20, std::map sClientRows; int kRowsInTable = 0; -int yForClient(std::string const &clientID) { +static int yForClient(std::string const &clientID) { if (sClientRows.find(clientID) == sClientRows.end()) { sClientRows[clientID] = kRowsInTable++; } @@ -88,19 +88,23 @@ void ServerLogger::printStatistics(int row, std::string const &clientID, JammerN char buffer[200]; //snprintf(buffer, 200, "%6d", (int)quality.packagesPushed); mvprintw(y, 20, buffer); //snprintf(buffer, 200, "%6d", (int)quality.packagesPopped); mvprintw(y, 28, buffer); +#ifndef __GNUC__ #pragma warning( push ) #pragma warning( disable : 4996 ) - sprintf(buffer, "%*d", 6, (int)(quality.packagesPushed - quality.packagesPopped)); mvprintw(y, kColumnHeaders[1].first, buffer); - sprintf(buffer, "%*d", 6, (int)quality.outOfOrderPacketCounter); mvprintw(y, kColumnHeaders[2].first, buffer); - sprintf(buffer, "%*d", 6, (int)quality.maxWrongOrderSpan); mvprintw(y, kColumnHeaders[3].first, buffer); - sprintf(buffer, "%*d", 6, (int)quality.duplicatePacketCounter); mvprintw(y, kColumnHeaders[4].first, buffer); - sprintf(buffer, "%*d", 6, (int)quality.dropsHealed); mvprintw(y, kColumnHeaders[5].first, buffer); - sprintf(buffer, "%*d", 6, (int)quality.tooLateOrDuplicate); mvprintw(y, kColumnHeaders[6].first, buffer); - sprintf(buffer, "%*d", 6, (int)quality.droppedPacketCounter); mvprintw(y, kColumnHeaders[7].first, buffer); - sprintf(buffer, "%*d", 6, (int)quality.maxLengthOfGap); mvprintw(y, kColumnHeaders[8].first, buffer); - sprintf(buffer, "%2.1f", quality.jitterMeanMillis); mvprintw(y, kColumnHeaders[9].first, buffer); - sprintf(buffer, "%2.1f", quality.jitterSDMillis); mvprintw(y, kColumnHeaders[10].first, buffer); +#endif + snprintf(buffer, 200, "%*d", 6, (int)(quality.packagesPushed - quality.packagesPopped)); mvprintw(y, kColumnHeaders[1].first, buffer); + snprintf(buffer, 200, "%*d", 6, (int)quality.outOfOrderPacketCounter); mvprintw(y, kColumnHeaders[2].first, buffer); + snprintf(buffer, 200, "%*d", 6, (int)quality.maxWrongOrderSpan); mvprintw(y, kColumnHeaders[3].first, buffer); + snprintf(buffer, 200, "%*d", 6, (int)quality.duplicatePacketCounter); mvprintw(y, kColumnHeaders[4].first, buffer); + snprintf(buffer, 200, "%*d", 6, (int)quality.dropsHealed); mvprintw(y, kColumnHeaders[5].first, buffer); + snprintf(buffer, 200, "%*d", 6, (int)quality.tooLateOrDuplicate); mvprintw(y, kColumnHeaders[6].first, buffer); + snprintf(buffer, 200, "%*d", 6, (int)quality.droppedPacketCounter); mvprintw(y, kColumnHeaders[7].first, buffer); + snprintf(buffer, 200, "%*d", 6, (int)quality.maxLengthOfGap); mvprintw(y, kColumnHeaders[8].first, buffer); + snprintf(buffer, 200, "%2.1f", quality.jitterMeanMillis); mvprintw(y, kColumnHeaders[9].first, buffer); + snprintf(buffer, 200, "%2.1f", quality.jitterSDMillis); mvprintw(y, kColumnHeaders[10].first, buffer); +#ifndef __GNUC__ #pragma warning( pop ) +#endif refresh(); } } diff --git a/Server/Source/SharedServerTypes.h b/Server/Source/SharedServerTypes.h index fa83a25..976bbff 100644 --- a/Server/Source/SharedServerTypes.h +++ b/Server/Source/SharedServerTypes.h @@ -11,9 +11,15 @@ #include "JammerNetzPackage.h" #include "PacketStreamQueue.h" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wextra-semi" +#pragma clang diagnostic ignored "-Wsign-conversion" + #include "tbb/concurrent_queue.h" #include "tbb/concurrent_unordered_map.h" +#pragma clang diagnostic pop + #include #include diff --git a/common/JammerNetzPackage.cpp b/common/JammerNetzPackage.cpp index e9c5d4c..50d1340 100644 --- a/common/JammerNetzPackage.cpp +++ b/common/JammerNetzPackage.cpp @@ -11,12 +11,12 @@ #include "JammerNetzClientInfoMessage.h" JammerNetzSingleChannelSetup::JammerNetzSingleChannelSetup() : - target(JammerNetzChannelTarget::Mono), volume(1.0f), mag(0.0f), rms(0.0f), pitch(0.0f) + target(JammerNetzChannelTarget::Mono), volume(1.0f), mag(0.0f), rms(0.0f), pitch(0.0f), name("") { } JammerNetzSingleChannelSetup::JammerNetzSingleChannelSetup(uint8 target_) : - target(target_), volume(1.0f), mag(0.0f), rms(0.0f), pitch(0.0f) + target(target_), volume(1.0f), mag(0.0f), rms(0.0f), pitch(0.0f), name("") { } @@ -59,7 +59,7 @@ AudioBlock::AudioBlock(double timestamp_, uint64 messageCounter_, uint64 serverT std::shared_ptr JammerNetzMessage::deserialize(uint8 *data, size_t bytes) { if (bytes >= sizeof(JammerNetzHeader)) { - JammerNetzHeader *header = reinterpret_cast(data); + auto header = reinterpret_cast(data); try { // Check the magic @@ -71,6 +71,8 @@ std::shared_ptr JammerNetzMessage::deserialize(uint8 *data, s return std::make_shared(data, bytes); case SESSIONSETUP: return std::make_shared(data, bytes); + case GENERIC_JSON: + return std::make_shared(data, bytes); default: std::cerr << "Unknown message type received, ignoring it" << std::endl; } diff --git a/common/JammerNetzPackage.h b/common/JammerNetzPackage.h index f397bf6..8cb3126 100644 --- a/common/JammerNetzPackage.h +++ b/common/JammerNetzPackage.h @@ -8,13 +8,23 @@ #include "JuceHeader.h" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wfloat-equal" + #include "flatbuffers/flatbuffers.h" + +#pragma clang diagnostic pop + + #include "JammerNetzAudioData_generated.h" #include "JammerNetzSessionInfo_generated.h" #include "JammerNetzControlMessage_generated.h" +#include "nlohmann/json.hpp" + #include #include +#include const size_t MAXFRAMESIZE = 65536; @@ -101,7 +111,7 @@ struct AudioBlock { }; struct JammerNetzMessageParseException : public std::exception { - const char *what() const noexcept + [[nodiscard]] const char *what() const noexcept { return "JammerNetz Message Parse Error"; } @@ -113,13 +123,14 @@ class JammerNetzMessage { AUDIODATA = 1, CLIENTINFO = 8, SESSIONSETUP = 16, + GENERIC_JSON = 32, }; JammerNetzMessage() = default; JammerNetzMessage(JammerNetzMessage const&) = default; virtual ~JammerNetzMessage() = default; - virtual MessageType getType() const = 0; + [[nodiscard]] virtual MessageType getType() const = 0; virtual void serialize(uint8 *output, size_t &byteswritten) const = 0; static std::shared_ptr deserialize(uint8 *data, size_t bytes); @@ -157,6 +168,35 @@ class JammerNetzFlatbufferMessage : public JammerNetzMessage { } }; +class JammerNetzControlMessage : public JammerNetzFlatbufferMessage +{ +public: + JammerNetzControlMessage(nlohmann::json &json) : json_(json) + { + } + + JammerNetzControlMessage(uint8 *data, size_t size) : JammerNetzFlatbufferMessage(size) { + uint8* dataStart = data + sizeof(JammerNetzHeader); + flatbuffers::Verifier verifier(dataStart, size - sizeof(JammerNetzHeader)); + if (VerifyJammerNetzControlInfoBuffer(verifier)) { + auto buffer = GetJammerNetzControlInfo(dataStart); + try { + json_ = nlohmann::json::parse(buffer->control_message_json()->str()); + } + catch (nlohmann::json::parse_error &e) { + throw JammerNetzMessageParseException(); + } + } + } + + void serializeToFlatbuffer(flatbuffers::FlatBufferBuilder &fbb) const override { + auto fb_json = fbb.CreateString(json_.dump()); + fbb.Finish(CreateJammerNetzControlInfo(fbb, fb_json)); + } + + nlohmann::json json_; +}; + class JammerNetzSessionInfoMessage : public JammerNetzFlatbufferMessage { public: diff --git a/common/PacketStreamQueue.h b/common/PacketStreamQueue.h index 5c4b2f5..c357a80 100644 --- a/common/PacketStreamQueue.h +++ b/common/PacketStreamQueue.h @@ -11,9 +11,14 @@ #include "JammerNetzPackage.h" #include "JammerNetzClientInfoMessage.h" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wsign-conversion" + #include "tbb/concurrent_hash_map.h" #include "tbb/concurrent_priority_queue.h" +#pragma clang diagnostic pop + #include "RunningStats.h" From 526da4b9f60c26493692e6f85ce128042b96df21 Mon Sep 17 00:00:00 2001 From: Christof Ruch Date: Sat, 19 Oct 2024 21:22:37 +0200 Subject: [PATCH 07/31] Now get the Common package MacOS warning free --- common/CMakeLists.txt | 1 + common/JammerNetzClientInfoMessage.cpp | 2 +- common/JammerNetzClientInfoMessage.h | 26 +++++++++++++------------- common/JammerNetzPackage.cpp | 14 +++++++------- common/JammerNetzPackage.h | 2 +- common/PacketStreamQueue.cpp | 5 ++++- common/Recorder.cpp | 14 ++++++++++---- 7 files changed, 37 insertions(+), 27 deletions(-) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 0a03643..363cbd5 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -67,6 +67,7 @@ if (MSVC) else() # lots of warnings and all warnings as errors #target_compile_options(JammerCommon PRIVATE -Wall -Wextra -pedantic -Werror) + target_compile_options(JammerCommon PRIVATE -Werror) endif() # Define tests diff --git a/common/JammerNetzClientInfoMessage.cpp b/common/JammerNetzClientInfoMessage.cpp index ffb29c6..3d0108e 100644 --- a/common/JammerNetzClientInfoMessage.cpp +++ b/common/JammerNetzClientInfoMessage.cpp @@ -109,7 +109,7 @@ String JammerNetzClientInfoMessage::getIPAddress(uint8 clientNo) const JammerNetzStreamQualityInfo JammerNetzClientInfoMessage::getStreamQuality(uint8 clientNo) const { - JammerNetzStreamQualityInfo result{ 0 }; + JammerNetzStreamQualityInfo result{}; if (clientNo < getNumClients()) { return clientInfos_[clientNo].qualityInfo; } diff --git a/common/JammerNetzClientInfoMessage.h b/common/JammerNetzClientInfoMessage.h index c96bcd2..3153be7 100644 --- a/common/JammerNetzClientInfoMessage.h +++ b/common/JammerNetzClientInfoMessage.h @@ -19,23 +19,23 @@ struct JammerNetzStreamQualityInfo { // Unhealed problems - uint64_t tooLateOrDuplicate; - int64_t droppedPacketCounter; + uint64_t tooLateOrDuplicate{}; + int64_t droppedPacketCounter{}; // Healed problems - int64_t outOfOrderPacketCounter; - int64_t duplicatePacketCounter; - uint64_t dropsHealed; + int64_t outOfOrderPacketCounter{}; + int64_t duplicatePacketCounter{}; + uint64_t dropsHealed{}; // Pure statistics - uint64_t packagesPushed; - uint64_t packagesPopped; - uint64_t maxLengthOfGap; - uint64_t maxWrongOrderSpan; - - double wallClockDelta; - double jitterMeanMillis; - double jitterSDMillis; + uint64_t packagesPushed{}; + uint64_t packagesPopped{}; + uint64_t maxLengthOfGap{}; + uint64_t maxWrongOrderSpan{}; + + double wallClockDelta{}; + double jitterMeanMillis{}; + double jitterSDMillis{}; }; struct JammerNetzClientInfo { diff --git a/common/JammerNetzPackage.cpp b/common/JammerNetzPackage.cpp index 50d1340..2385ebb 100644 --- a/common/JammerNetzPackage.cpp +++ b/common/JammerNetzPackage.cpp @@ -23,7 +23,7 @@ JammerNetzSingleChannelSetup::JammerNetzSingleChannelSetup(uint8 target_) : bool JammerNetzSingleChannelSetup::isEqualEnough(const JammerNetzSingleChannelSetup &other) const { - return target == other.target && volume == other.volume && name == other.name; + return target == other.target && fabs(volume-other.volume) < 1e-6f && name == other.name; } /*bool JammerNetzSingleChannelSetup::operator==(const JammerNetzSingleChannelSetup &other) const @@ -241,7 +241,7 @@ flatbuffers::Offset JammerNetzAudioData::readAudioHeaderAndBytes(JammerN } result->sampleRate = 48000; - int upsampleRate = block->sampleRate() != 0 ? 48000 / block->sampleRate() : 48000; + size_t upsampleRate = block->sampleRate() != 0 ? 48000 / block->sampleRate() : 48000; jassert(block->numberOfSamples() * upsampleRate == SAMPLE_BUFFER_SIZE); result->audioBuffer = std::make_shared>(block->numChannels(), block->numberOfSamples() * upsampleRate); readAudioBytes(block->channels(), result->audioBuffer, upsampleRate); return result; } -void JammerNetzAudioData::readAudioBytes(flatbuffers::Vector> const *samples, std::shared_ptr> destBuffer, int upsampleRate) { +void JammerNetzAudioData::readAudioBytes(flatbuffers::Vector> const *samples, std::shared_ptr> destBuffer, size_t upsampleRate) { int c = 0; for (auto channel = samples->cbegin(); channel != samples->cend(); channel++) { //TODO we might not have enough bytes in the package for this operation @@ -332,7 +332,7 @@ void JammerNetzAudioData::readAudioBytes(flatbuffers::Vector dst_pointer(destBuffer->getWritePointer(c)); - dst_pointer.convertSamples(src_pointer, channel->audioSamples()->size()); + dst_pointer.convertSamples(src_pointer, (int) channel->audioSamples()->size()); } else { float tempBuffer[MAXFRAMESIZE]; @@ -344,11 +344,11 @@ void JammerNetzAudioData::readAudioBytes(flatbuffers::Vector dst_pointer(tempBuffer); - dst_pointer.convertSamples(src_pointer, channel->audioSamples()->size()); + dst_pointer.convertSamples(src_pointer, (int) channel->audioSamples()->size()); auto write = destBuffer->getWritePointer(c); for (size_t i = 0; i < channel->audioSamples()->size(); i++) { - for (int j = 0; j < upsampleRate; j++) { + for (size_t j = 0; j < upsampleRate; j++) { write[i * upsampleRate + j] = tempBuffer[i]; } } diff --git a/common/JammerNetzPackage.h b/common/JammerNetzPackage.h index 8cb3126..64b744e 100644 --- a/common/JammerNetzPackage.h +++ b/common/JammerNetzPackage.h @@ -262,7 +262,7 @@ class JammerNetzAudioData : public JammerNetzMessage { flatbuffers::Offset serializeAudioBlock(flatbuffers::FlatBufferBuilder &fbb, std::shared_ptr src, uint16 sampleRate, uint16 reductionFactor) const; flatbuffers::Offset>> appendAudioBuffer(flatbuffers::FlatBufferBuilder &fbb, AudioBuffer &buffer, uint16 reductionFactor) const; std::shared_ptr readAudioHeaderAndBytes(JammerNetzPNPAudioBlock const *block); - void readAudioBytes(flatbuffers::Vector> const *samples, std::shared_ptr> destBuffer, int upsampleRate); + void readAudioBytes(flatbuffers::Vector> const *samples, std::shared_ptr> destBuffer, size_t upsampleRate); std::shared_ptr audioBlock_; std::shared_ptr fecBlock_; diff --git a/common/PacketStreamQueue.cpp b/common/PacketStreamQueue.cpp index a6243bf..b90079a 100644 --- a/common/PacketStreamQueue.cpp +++ b/common/PacketStreamQueue.cpp @@ -6,7 +6,10 @@ #include "PacketStreamQueue.h" -PacketStreamQueue::PacketStreamQueue(std::string const &streamName) : lastPoppedMessage_(0), lastPushedMessage_(0), currentGap_(0) +PacketStreamQueue::PacketStreamQueue(std::string const &streamName) : + lastPushedMessage_(0) + , lastPoppedMessage_(0) + , currentGap_(0) { qualityData_.streamName = streamName; } diff --git a/common/Recorder.cpp b/common/Recorder.cpp index 8e4e56d..b5acf2c 100644 --- a/common/Recorder.cpp +++ b/common/Recorder.cpp @@ -7,7 +7,13 @@ #include "Recorder.h" Recorder::Recorder(File directory, std::string const &baseFileName, RecordingType recordingType) - : directory_(directory), baseFileName_(baseFileName), writer_(nullptr), recordingType_(recordingType), samplesWritten_(0), lastChannelSetup_(false) + : + samplesWritten_(0) + , directory_(directory) + , baseFileName_(baseFileName) + , recordingType_(recordingType) + , writer_(nullptr) + , lastChannelSetup_(false) { thread_ = std::make_unique("RecorderDiskWriter"); thread_->startThread(); @@ -95,7 +101,7 @@ void Recorder::updateChannelInfo(int sampleRate, JammerNetzChannelSetup const &c // Setup the channel layout AudioChannelSet channels; - int numChannels = 0; + unsigned numChannels = 0; for (auto channel : channelSetup.channels) { switch (channel.target) { case Mute: @@ -152,12 +158,12 @@ void Recorder::launchWriter() { void Recorder::saveBlock(const float* const* data, int numSamples) { // Don't crash on me when there is surprisingly no data in the package - if (data && data[0]) { + if (data && data[0] && numSamples > 0) { if (!writeThread_->write(data, numSamples)) { //TODO - need a smarter strategy than that std::cerr << "Ups, FIFO full and can't write block to disk, lost it!" << std::endl; } - samplesWritten_ += numSamples; + samplesWritten_ += (size_t) numSamples; } } From e02d5c7eb83080ad5fde4b52a4dbeada32c1417c Mon Sep 17 00:00:00 2001 From: Christof Ruch Date: Sat, 19 Oct 2024 21:52:31 +0200 Subject: [PATCH 08/31] Warnings as errors for Mac, get the Mac build warning free --- Client/CMakeLists.txt | 2 +- Client/Source/AudioCallback.cpp | 45 +++++++++++++++++------------ Client/Source/AudioCallback.h | 8 ++--- Client/Source/AudioService.cpp | 8 ++--- Client/Source/AudioService.h | 6 ++-- Client/Source/BPMDisplay.cpp | 2 +- Client/Source/ChannelController.cpp | 9 ++++-- Client/Source/DeviceSelector.cpp | 13 +++++---- Client/Source/DeviceSelector.h | 2 +- Client/Source/IncludeFFMeters.h | 4 +++ Client/Source/MainComponent.cpp | 10 +++---- Client/Source/MidiSendThread.cpp | 2 -- Client/Source/MidiSendThread.h | 5 +++- Client/Source/RecordingInfo.cpp | 6 ++-- Client/Source/Tuner.cpp | 26 ++++++++++++++--- Client/Source/Tuner.h | 2 +- common/Pool.h | 2 +- 17 files changed, 95 insertions(+), 57 deletions(-) diff --git a/Client/CMakeLists.txt b/Client/CMakeLists.txt index 72260d7..852fc1c 100644 --- a/Client/CMakeLists.txt +++ b/Client/CMakeLists.txt @@ -159,7 +159,7 @@ if (MSVC) else() # lots of warnings and all warnings as errors #target_compile_options(JammerNetzClient PRIVATE -Wall -Wextra -pedantic -Werror) - target_compile_options(JammerNetzClient PRIVATE -Wno-unknown-pragmas) + target_compile_options(JammerNetzClient PRIVATE -Werror -Wno-unknown-pragmas) endif() IF(WIN32) diff --git a/Client/Source/AudioCallback.cpp b/Client/Source/AudioCallback.cpp index 1b556a2..8262afe 100644 --- a/Client/Source/AudioCallback.cpp +++ b/Client/Source/AudioCallback.cpp @@ -15,8 +15,15 @@ #include "Logger.h" -AudioCallback::AudioCallback() : jammerService_([this](std::shared_ptr < JammerNetzAudioData> buffer) { playBuffer_.push(buffer); }), playBuffer_("server"), masterVolume_(1.0), monitorBalance_(0.0), - channelSetup_(false), clientBpm_(0.0f), midiSignalToGenerate_(MidiSignal_None), midiSignalToSend_(MidiSignal_None) +AudioCallback::AudioCallback() : + jammerService_([this](std::shared_ptr < JammerNetzAudioData> buffer) { playBuffer_.push(buffer); }) + , playBuffer_("server") + , masterVolume_(1.0) + , monitorBalance_(0.0) + , clientBpm_(0.0f) + , channelSetup_(false) + , midiSignalToSend_(MidiSignal_None) + , midiSignalToGenerate_(MidiSignal_None) { isPlaying_ = false; minPlayoutBufferLength_ = CLIENT_PLAYOUT_JITTER_BUFFER; @@ -37,10 +44,10 @@ AudioCallback::AudioCallback() : jammerService_([this](std::shared_ptr < JammerN // Setup listeners listeners_.push_back(std::make_unique(Data::instance().get().getPropertyAsValue(VALUE_MIN_PLAYOUT_BUFFER, nullptr), [this](Value& newValue) { - minPlayoutBufferLength_ = (int) newValue.getValue(); + minPlayoutBufferLength_ = (uint64) newValue.getValue().operator long long(); })); listeners_.push_back(std::make_unique(Data::instance().get().getPropertyAsValue(VALUE_MAX_PLAYOUT_BUFFER, nullptr), [this](Value& newValue) { - maxPlayoutBufferLength_ = (int)newValue.getValue(); + maxPlayoutBufferLength_ = (uint64)newValue.getValue().operator long long(); })); auto mixer = Data::instance().get().getOrCreateChildWithName(VALUE_MIXER, nullptr); auto outputController = mixer.getOrCreateChildWithName(VALUE_MASTER_OUTPUT, nullptr); @@ -123,7 +130,7 @@ void AudioCallback::measureSamplesPerTime(PlayoutQualityInfo &qualityInfo, int n } // https://dsp.stackexchange.com/questions/14754/equal-power-crossfade -std::pair calcMonitorGain() { +static std::pair calcMonitorGain() { auto mixer = Data::instance().get().getChildWithName(VALUE_MIXER); double t = mixer.getProperty(VALUE_MONITOR_BALANCE); @@ -140,7 +147,7 @@ void AudioCallback::calcLocalMonitoring(std::shared_ptr> inpu auto [monitorVolume, _] = calcMonitorGain(); // Apply gain to our channels and do a stereo mixdown jassert(inputBuffer->getNumSamples() == outputBuffer.getNumSamples()); - for (int channel = 0; channel < inputBuffer->getNumChannels(); channel++) { + for (size_t channel = 0; channel < (size_t) inputBuffer->getNumChannels(); channel++) { const JammerNetzSingleChannelSetup& setup = channelSetup_.channels[channel]; float input_volume = (float) (setup.volume * monitorVolume * masterVolume_); switch (setup.target) { @@ -150,13 +157,13 @@ void AudioCallback::calcLocalMonitoring(std::shared_ptr> inpu case Left: // This is a left channel, going into the left. if (outputBuffer.getNumChannels() > 0) { - outputBuffer.addFrom(0, 0, *inputBuffer, channel, 0, inputBuffer->getNumSamples(), input_volume); + outputBuffer.addFrom(0, 0, *inputBuffer, (int) channel, 0, inputBuffer->getNumSamples(), input_volume); } break; case Right: // And the same for the right channel if (outputBuffer.getNumChannels() > 1) { - outputBuffer.addFrom(1, 0, *inputBuffer, channel, 0, inputBuffer->getNumSamples(), input_volume); + outputBuffer.addFrom(1, 0, *inputBuffer, (int) channel, 0, inputBuffer->getNumSamples(), input_volume); } break; case SendLeft: @@ -166,10 +173,10 @@ void AudioCallback::calcLocalMonitoring(std::shared_ptr> inpu break; case Mono: if (outputBuffer.getNumChannels() > 0) { - outputBuffer.addFrom(0, 0, *inputBuffer, channel, 0, inputBuffer->getNumSamples(), input_volume); + outputBuffer.addFrom(0, 0, *inputBuffer, (int) channel, 0, inputBuffer->getNumSamples(), input_volume); } if (outputBuffer.getNumChannels() > 1) { - outputBuffer.addFrom(1, 0, *inputBuffer, channel, 0, inputBuffer->getNumSamples(), input_volume); + outputBuffer.addFrom(1, 0, *inputBuffer, (int) channel, 0, inputBuffer->getNumSamples(), input_volume); } break; } @@ -177,17 +184,17 @@ void AudioCallback::calcLocalMonitoring(std::shared_ptr> inpu } } -uint8 sysexMsb(uint16 in) +static uint8 sysexMsb(uint16 in) { return (uint8)(in >> 7); } -uint8 sysexLsb(uint16 in) +static uint8 sysexLsb(uint16 in) { return (uint8)(in & 0x7f); } -MidiMessage createBossRC300ClockMessage(double bpm, MidiSignal additionalSignal) +static MidiMessage createBossRC300ClockMessage(double bpm, MidiSignal additionalSignal) { // Boss RC-300 loop pedal is infamous for not being able to slave to MIDI clock. Let's try with tailored sysex messages then // See https://www.vguitarforums.com/smf/index.php?topic=7678.50 "RC300- Here's how to slave the RC-300's Tempo to (some) external sources" @@ -225,7 +232,7 @@ MidiMessage createBossRC300ClockMessage(double bpm, MidiSignal additionalSignal) return MidiMessage::createSysExMessage(rc300.data(), (int) rc300.size()); } -std::vector createMidiBeatMessage(double bpm, std::optional additionalSignal, bool includeBossRC300) +static std::vector createMidiBeatMessage(double bpm, std::optional additionalSignal, bool includeBossRC300) { // For every Midi "Beat" we create a clock message (0xf8) std::vector result; @@ -292,10 +299,10 @@ void AudioCallback::audioDeviceIOCallbackWithContext(const float* const* inputCh meterSource_.measureBlock(*audioBuffer); // Send the MAG, RMS values and the pitch to the server, which will forward it to the other clients so they can show my levels even if they have only the mixed audio - for (int c = 0; c < numInputChannels; c++) { + for (size_t c = 0; c < (size_t) numInputChannels; c++) { if (c < channelSetup_.channels.size()) { - channelSetup_.channels[c].mag = meterSource_.getMaxLevel(c); - channelSetup_.channels[c].rms = meterSource_.getRMSLevel(c); + channelSetup_.channels[c].mag = meterSource_.getMaxLevel((int) c); + channelSetup_.channels[c].rms = meterSource_.getRMSLevel((int) c); channelSetup_.channels[c].pitch = tuner_->getPitch(c); } else { @@ -535,12 +542,12 @@ double AudioCallback::currentRTT() return jammerService_.receiver()->currentRTT(); } -float AudioCallback::channelPitch(int channel) const +float AudioCallback::channelPitch(size_t channel) const { return tuner_->getPitch(channel); } -float AudioCallback::sessionPitch(int channel) { +float AudioCallback::sessionPitch(size_t channel) { auto setup = getSessionSetup(); if (channel < setup.channels.size()) return setup.channels[channel].pitch; diff --git a/Client/Source/AudioCallback.h b/Client/Source/AudioCallback.h index ab4d014..0e424b2 100644 --- a/Client/Source/AudioCallback.h +++ b/Client/Source/AudioCallback.h @@ -79,7 +79,7 @@ class ReadOnceLatch class AudioCallback : public AudioIODeviceCallback { public: AudioCallback(); - virtual ~AudioCallback(); + virtual ~AudioCallback() override; void shutdown(); @@ -87,7 +87,7 @@ class AudioCallback : public AudioIODeviceCallback { void setMidiSignalToSend(MidiSignal signal); virtual void audioDeviceIOCallbackWithContext(const float* const* inputChannelData, int numInputChannels, float* const* outputChannelData, int numOutputChannels, - int numSamples, const AudioIODeviceCallbackContext& context); + int numSamples, const AudioIODeviceCallbackContext& context) override; virtual void audioDeviceAboutToStart(AudioIODevice* device) override; virtual void audioDeviceStopped() override; @@ -109,8 +109,8 @@ class AudioCallback : public AudioIODeviceCallback { std::string currentReceptionQuality() const; bool isReceivingData(); double currentRTT(); - float channelPitch(int channel) const; - float sessionPitch(int channel); + float channelPitch(size_t channel) const; + float sessionPitch(size_t channel); std::shared_ptr getMasterRecorder() const; std::shared_ptr getLocalRecorder() const; diff --git a/Client/Source/AudioService.cpp b/Client/Source/AudioService.cpp index a0434b0..cdbc21d 100644 --- a/Client/Source/AudioService.cpp +++ b/Client/Source/AudioService.cpp @@ -49,7 +49,7 @@ void AudioService::refreshChannelSetup(std::shared_ptr setup) JammerNetzChannelSetup channelSetup(isLocalMonitoring); if (setup) { - for (int i = 0; i < setup->activeChannelIndices.size(); i++) { + for (size_t i = 0; i < setup->activeChannelIndices.size(); i++) { String inputController = "Input" + String(i); auto controllerData = mixer.getChildWithName(inputController); jassert(controllerData.isValid()); @@ -146,12 +146,12 @@ int AudioService::currentPacketSize() return callback_.currentPacketSize(); } -float AudioService::channelPitch(int channel) const +float AudioService::channelPitch(size_t channel) const { return callback_.channelPitch(channel); } -float AudioService::sessionPitch(int channel) +float AudioService::sessionPitch(size_t channel) { return callback_.sessionPitch(channel); } @@ -225,7 +225,7 @@ std::shared_ptr AudioService::getSetup(ValueTree data) const return channelSetup; } -BigInteger makeChannelMask(std::vector const& indices) { +static BigInteger makeChannelMask(std::vector const& indices) { BigInteger inputChannelMask; for (int activeChannelIndex : indices) { inputChannelMask.setBit(activeChannelIndex); diff --git a/Client/Source/AudioService.h b/Client/Source/AudioService.h index d598b98..50925ae 100644 --- a/Client/Source/AudioService.h +++ b/Client/Source/AudioService.h @@ -23,7 +23,7 @@ struct ChannelSetup { class AudioService : private ValueTree::Listener { public: AudioService(); - ~AudioService(); + virtual ~AudioService() override; void shutdown(); // Controlled stop @@ -48,8 +48,8 @@ class AudioService : private ValueTree::Listener { std::string currentReceptionQuality() const; int currentPacketSize(); - float channelPitch(int channel) const; - float sessionPitch(int channel); + float channelPitch(size_t channel) const; + float sessionPitch(size_t channel); FFAU::LevelMeterSource* getInputMeterSource(); FFAU::LevelMeterSource* getOutputMeterSource(); diff --git a/Client/Source/BPMDisplay.cpp b/Client/Source/BPMDisplay.cpp index 10cbfee..acb1572 100644 --- a/Client/Source/BPMDisplay.cpp +++ b/Client/Source/BPMDisplay.cpp @@ -8,7 +8,7 @@ class BPMTimer : public Timer { public: - BPMTimer(Label &label, std::weak_ptr clocker) : label_(label), clocker_(clocker) {}; + BPMTimer(Label &label, std::weak_ptr clocker) : label_(label), clocker_(clocker) {} virtual void timerCallback() override { diff --git a/Client/Source/ChannelController.cpp b/Client/Source/ChannelController.cpp index 010955c..77fb70d 100644 --- a/Client/Source/ChannelController.cpp +++ b/Client/Source/ChannelController.cpp @@ -13,8 +13,13 @@ ChannelController::ChannelController(String const &name, String const &id, bool hasVolume /*= true*/, bool hasTarget /*= true*/, bool hasPitch /* = false */) : - id_(id), levelMeter_(name == "Master" ? FFAU::LevelMeter::Default : FFAU::LevelMeter::SingleChannel), - hasVolume_(hasVolume), hasTarget_(hasTarget), hasPitch_(hasPitch), meterSource_(nullptr), channelNo_(0) + id_(id) + , hasVolume_(hasVolume) + , hasTarget_(hasTarget) + , hasPitch_(hasPitch) + , levelMeter_(name == "Master" ? FFAU::LevelMeter::Default : FFAU::LevelMeter::SingleChannel) + , meterSource_(nullptr) + , channelNo_(0) { channelName_.setText(name, dontSendNotification); if (hasVolume) { diff --git a/Client/Source/DeviceSelector.cpp b/Client/Source/DeviceSelector.cpp index 7423370..2a67530 100644 --- a/Client/Source/DeviceSelector.cpp +++ b/Client/Source/DeviceSelector.cpp @@ -16,7 +16,10 @@ #include "LayoutConstants.h" DeviceSelector::DeviceSelector(String const& title, bool showTitle, bool inputInsteadOfOutputDevices) - : title_(title), showTitle_(showTitle), inputDevices_(inputInsteadOfOutputDevices) + : + showTitle_(showTitle) + , title_(title) + , inputDevices_(inputInsteadOfOutputDevices) { titleLabel_.setText(title, dontSendNotification); @@ -89,7 +92,7 @@ DeviceSelector::DeviceSelector(String const& title, bool showTitle, bool inputIn // Does it have a control panel? if (selectedDevice->hasControlPanel()) { controlPanelButton_ = std::make_unique("Configure"); - controlPanelButton_->onClick = [this, selectedDevice]() { + controlPanelButton_->onClick = [selectedDevice]() { selectedDevice->showControlPanel(); }; addAndMakeVisible(*controlPanelButton_); @@ -198,7 +201,7 @@ void DeviceSelector::resized() return deviceTypes_[typeDropdown_.getSelectedItemIndex()]; }*/ -bool comboHasText(ComboBox* combo, String text) { +static bool comboHasText(ComboBox* combo, String text) { for (int i = 0; i < combo->getNumItems(); i++) { if (combo->getItemText(i) == text) return true; @@ -241,8 +244,8 @@ void DeviceSelector::bindControls() deviceSelector.setProperty(VALUE_DEVICE_NAME, "", nullptr); } deviceDropdown_.onChange = [this]() { - ValueTree deviceSelector = Data::instance().get().getChildWithName(Identifier(titleLabel_.getText(false))); - deviceSelector.setProperty(VALUE_DEVICE_NAME, deviceDropdown_.getText(), nullptr); + ValueTree dropdownSelector = Data::instance().get().getChildWithName(Identifier(titleLabel_.getText(false))); + dropdownSelector.setProperty(VALUE_DEVICE_NAME, deviceDropdown_.getText(), nullptr); }; listeners_.push_back(std::make_unique(deviceSelector.getPropertyAsValue(VALUE_DEVICE_NAME, nullptr), [this](Value& newValue) { String newType = newValue.getValue(); diff --git a/Client/Source/DeviceSelector.h b/Client/Source/DeviceSelector.h index ac4c090..5641514 100644 --- a/Client/Source/DeviceSelector.h +++ b/Client/Source/DeviceSelector.h @@ -14,7 +14,7 @@ class DeviceSelector : public Component { public: DeviceSelector(String const &title, bool showTitle, bool inputInsteadOfOutputDevices); - virtual ~DeviceSelector(); + virtual ~DeviceSelector() override; virtual void resized() override; diff --git a/Client/Source/IncludeFFMeters.h b/Client/Source/IncludeFFMeters.h index 2cdb31f..32a45b6 100644 --- a/Client/Source/IncludeFFMeters.h +++ b/Client/Source/IncludeFFMeters.h @@ -9,10 +9,14 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wimplicit-float-conversion" +#pragma clang diagnostic ignored "-Wfloat-conversion" +#pragma clang diagnostic ignored "-Wfloat-equal" #pragma clang diagnostic ignored "-Wsign-compare" #pragma clang diagnostic ignored "-Wsign-conversion" #pragma clang diagnostic ignored "-Wshadow" #pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-parameter" +#pragma clang diagnostic ignored "-Winconsistent-missing-destructor-override" #pragma warning( push ) #pragma warning( disable: 4244 4100 4456 4702) #include "ff_meters/ff_meters.h" diff --git a/Client/Source/MainComponent.cpp b/Client/Source/MainComponent.cpp index 126a047..73614f5 100644 --- a/Client/Source/MainComponent.cpp +++ b/Client/Source/MainComponent.cpp @@ -26,9 +26,9 @@ MainComponent::MainComponent(std::shared_ptr audioService, std::sh outputSelector_(VALUE_OUTPUT_SETUP, false, false), outputController_("Master", VALUE_MASTER_OUTPUT, true, false), monitorBalance_("Local", "Remote", 50), - logView_(false), // Turn off line numbers - stageLeftWhenInMillis_(Time::currentTimeMillis()), - bpmSlider_(juce::Slider::SliderStyle::LinearHorizontal, juce::Slider::TextBoxRight) + bpmSlider_(juce::Slider::SliderStyle::LinearHorizontal, juce::Slider::TextBoxRight), + logView_(false), // Turn off line numbers + stageLeftWhenInMillis_(Time::currentTimeMillis()) { // Create an a Logger for the JammerNetz client logViewLogger_ = std::make_unique(logView_); @@ -327,12 +327,12 @@ void MainComponent::timerCallback() // Refresh tuning info for my own channels for (int i = 0; i < ownChannels_.numChannels(); i++) { - ownChannels_.setPitchDisplayed(i, MidiNote(audioService_->channelPitch(i))); + ownChannels_.setPitchDisplayed(i, MidiNote(audioService_->channelPitch((size_t) i))); } // and for the session channels if (currentSessionSetup_) { for (int i = 0; i < (int) currentSessionSetup_->channels.size(); i++) { - allChannels_.setPitchDisplayed(i, MidiNote(audioService_->sessionPitch(i))); + allChannels_.setPitchDisplayed(i, MidiNote(audioService_->sessionPitch((size_t) i))); } } diff --git a/Client/Source/MidiSendThread.cpp b/Client/Source/MidiSendThread.cpp index 09eaec3..d420c84 100644 --- a/Client/Source/MidiSendThread.cpp +++ b/Client/Source/MidiSendThread.cpp @@ -45,9 +45,7 @@ void MidiSendThread::run() MessageQueueItem item; while (midiMessages.try_pop(item) && !threadShouldExit()) { // Wait until the time has come - uint64 waiting = 0; while (std::chrono::high_resolution_clock::now() < item.whenToSend) { - waiting += 1; } // Send the F8 MIDI Clock message to all devices registered for (auto &out : f8_outputs) { diff --git a/Client/Source/MidiSendThread.h b/Client/Source/MidiSendThread.h index c95e67c..28c1ac4 100644 --- a/Client/Source/MidiSendThread.h +++ b/Client/Source/MidiSendThread.h @@ -4,7 +4,10 @@ #include "MidiController.h" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wextra-semi" #include "tbb/concurrent_queue.h" +#pragma clang diagnostic pop #include #include @@ -13,7 +16,7 @@ class MidiSendThread : juce::Thread { public: MidiSendThread(std::vector const outputs); - virtual ~MidiSendThread(); + virtual ~MidiSendThread() override; void enqueue(std::chrono::high_resolution_clock::duration fromNow, std::vector const &messages); diff --git a/Client/Source/RecordingInfo.cpp b/Client/Source/RecordingInfo.cpp index 00cd531..c649bd0 100644 --- a/Client/Source/RecordingInfo.cpp +++ b/Client/Source/RecordingInfo.cpp @@ -13,7 +13,7 @@ // https://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java // -String humanReadableByteCount(size_t bytes, bool si) { +static String humanReadableByteCount(size_t bytes, bool si) { size_t unit = si ? 1000 : 1024; if (bytes < unit) { return String(bytes) + " B"; @@ -31,7 +31,7 @@ String humanReadableByteCount(size_t bytes, bool si) { class RecordingInfo::UpdateTimer : public Timer { public: - UpdateTimer(RecordingInfo *info) : info_(info) {}; + UpdateTimer(RecordingInfo *info) : info_(info) {} virtual void timerCallback() override { @@ -128,7 +128,7 @@ void RecordingInfo::updateData() auto dir = recorder_.lock()->getDirectory(); recordingPath_.setText(dir.getFullPathName(), dontSendNotification); diskSpacePercentage_ = 1.0 - dir.getBytesFreeOnVolume() / (double)dir.getVolumeTotalSize(); - diskSpace_.setTextToDisplay(humanReadableByteCount(dir.getBytesFreeOnVolume(), false)); + diskSpace_.setTextToDisplay(humanReadableByteCount((size_t) dir.getBytesFreeOnVolume(), false)); bool isLive = recorder_.lock()->isRecording(); recording_.setToggleState(!isLive, dontSendNotification); diff --git a/Client/Source/Tuner.cpp b/Client/Source/Tuner.cpp index 3444ca2..5b5a789 100644 --- a/Client/Source/Tuner.cpp +++ b/Client/Source/Tuner.cpp @@ -8,10 +8,28 @@ #include "BuffersConfig.h" +#ifndef __GNUC__ #pragma warning( push ) #pragma warning( disable: 4244 4267 4305 4456) +#endif +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wfloat-conversion" +#pragma clang diagnostic ignored "-Wimplicit-float-conversion" +#pragma clang diagnostic ignored "-Wsign-conversion" +#pragma clang diagnostic ignored "-Wshorten-64-to-32" +#pragma clang diagnostic ignored "-Wc++98-compat-extra-semi" +#pragma clang diagnostic ignored "-Wextra-semi" +#pragma clang diagnostic ignored "-Wshadow" +#pragma clang diagnostic ignored "-Wshadow-field-in-constructor" +#pragma clang diagnostic ignored "-Wimplicit-int-conversion" +#pragma clang diagnostic ignored "-Wfloat-equal" +#pragma clang diagnostic ignored "-Wmissing-field-initializers" #include +#pragma clang diagnostic pop +#ifndef __GNUC__ #pragma warning ( pop ) +#endif + namespace q = cycfi::q; using namespace q::literals; @@ -22,21 +40,21 @@ class Tuner::TunerImpl { if (audioData) { auto readPointers = audioData->getArrayOfReadPointers(); - for (int channel = 0; channel < audioData->getNumChannels(); channel++) { + for (size_t channel = 0; channel < (size_t) audioData->getNumChannels(); channel++) { // Do we already create a detector for this channel? if (detectors.size() <= channel) { detectors.push_back(std::make_unique(50.0_Hz, 2000.0_Hz, (float) SAMPLE_RATE, q::lin_to_db(0.0))); } // Feed the samples of this channel into the pitch detector - for (int s = 0; s < audioData->getNumSamples(); s++) { + for (size_t s = 0; s < (size_t) audioData->getNumSamples(); s++) { (*detectors[channel])(readPointers[channel][s]); } } } } - float getPitch(int channel) const { + float getPitch(size_t channel) const { if (channel < detectors.size()) { return detectors[channel]->predict_frequency(); } @@ -61,7 +79,7 @@ void Tuner::detectPitch(std::shared_ptr> audioBuffer) impl->detectPitch(audioBuffer); } -float Tuner::getPitch(int channel) const +float Tuner::getPitch(size_t channel) const { return impl->getPitch(channel); } diff --git a/Client/Source/Tuner.h b/Client/Source/Tuner.h index 91d994d..62e7ae6 100644 --- a/Client/Source/Tuner.h +++ b/Client/Source/Tuner.h @@ -15,7 +15,7 @@ class Tuner { ~Tuner(); void detectPitch(std::shared_ptr> audioBuffer); - float getPitch(int channel) const; + float getPitch(size_t channel) const; private: // We might want to try different pitch detection libraries, therefore hide the implementation diff --git a/common/Pool.h b/common/Pool.h index 14f2fbe..bffc930 100644 --- a/common/Pool.h +++ b/common/Pool.h @@ -36,7 +36,7 @@ class Pool } } auto it = free_m.begin(); - std::shared_ptr sptr( it->get(), [=](T* ptr){ this->free(ptr); } ); + std::shared_ptr sptr( it->get(), [this](T* ptr){ this->free(ptr); } ); used_m.push_front(std::move(*it)); free_m.erase(it); return sptr; From 8577677950731538d613cb670f6266df6c998b6d Mon Sep 17 00:00:00 2001 From: Christof Ruch Date: Sat, 19 Oct 2024 21:54:27 +0200 Subject: [PATCH 09/31] Get pedantic in Common --- common/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 363cbd5..1271d37 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -66,8 +66,7 @@ if (MSVC) target_compile_options(JammerCommon PRIVATE /W4 /WX) else() # lots of warnings and all warnings as errors - #target_compile_options(JammerCommon PRIVATE -Wall -Wextra -pedantic -Werror) - target_compile_options(JammerCommon PRIVATE -Werror) + target_compile_options(JammerCommon PRIVATE -Wall -Wextra -pedantic -Werror) endif() # Define tests From 5e373a8779606877e18c27fb19ea568806e01ee3 Mon Sep 17 00:00:00 2001 From: Christof Ruch Date: Sat, 19 Oct 2024 21:55:33 +0200 Subject: [PATCH 10/31] Pedantic for the server --- Server/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Server/CMakeLists.txt b/Server/CMakeLists.txt index 6cdf503..f0f9e94 100644 --- a/Server/CMakeLists.txt +++ b/Server/CMakeLists.txt @@ -59,6 +59,5 @@ if (MSVC) target_compile_options(JammerNetzServer PRIVATE /W4 /WX) else() # lots of warnings and all warnings as errors - #target_compile_options(JammerNetzServer PRIVATE -Wall -Wextra -pedantic -Werror) - target_compile_options(JammerNetzServer PRIVATE -Werror) + target_compile_options(JammerNetzServer PRIVATE -Wall -Wextra -pedantic -Werror) endif() From cb211c9847dac397bf26d8e523db28b8586dc37b Mon Sep 17 00:00:00 2001 From: Christof Ruch Date: Sat, 19 Oct 2024 21:57:11 +0200 Subject: [PATCH 11/31] And pedantic for the Client. That did not make a difference for clang. --- Client/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Client/CMakeLists.txt b/Client/CMakeLists.txt index 852fc1c..8872b9c 100644 --- a/Client/CMakeLists.txt +++ b/Client/CMakeLists.txt @@ -158,8 +158,7 @@ if (MSVC) target_compile_options(JammerNetzClient PRIVATE /W4 /WX) else() # lots of warnings and all warnings as errors - #target_compile_options(JammerNetzClient PRIVATE -Wall -Wextra -pedantic -Werror) - target_compile_options(JammerNetzClient PRIVATE -Werror -Wno-unknown-pragmas) + target_compile_options(JammerNetzClient PRIVATE -Wall -Wextra -pedantic -Werror -Wno-unknown-pragmas) endif() IF(WIN32) From 001d44c65a30b6f4be1959e035104fa0a74b4c96 Mon Sep 17 00:00:00 2001 From: Christof Ruch Date: Sat, 19 Oct 2024 22:02:29 +0200 Subject: [PATCH 12/31] Shield clang pragmas from the other compilers --- Client/Source/IncludeFFMeters.h | 4 ++++ Client/Source/MidiSendThread.h | 4 ++++ Client/Source/Tuner.cpp | 4 ++++ Server/Source/SharedServerTypes.h | 7 ++++--- common/JammerNetzPackage.h | 7 ++++--- common/PacketStreamQueue.h | 7 ++++--- 6 files changed, 24 insertions(+), 9 deletions(-) diff --git a/Client/Source/IncludeFFMeters.h b/Client/Source/IncludeFFMeters.h index 32a45b6..3acd30f 100644 --- a/Client/Source/IncludeFFMeters.h +++ b/Client/Source/IncludeFFMeters.h @@ -7,6 +7,7 @@ #pragma once +#ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wimplicit-float-conversion" #pragma clang diagnostic ignored "-Wfloat-conversion" @@ -17,8 +18,11 @@ #pragma clang diagnostic ignored "-Wunknown-pragmas" #pragma clang diagnostic ignored "-Wunused-parameter" #pragma clang diagnostic ignored "-Winconsistent-missing-destructor-override" +#endif #pragma warning( push ) #pragma warning( disable: 4244 4100 4456 4702) #include "ff_meters/ff_meters.h" #pragma warning (pop ) +#ifdef __clang__ #pragma clang diagnostic pop +#endifs diff --git a/Client/Source/MidiSendThread.h b/Client/Source/MidiSendThread.h index 28c1ac4..0333e54 100644 --- a/Client/Source/MidiSendThread.h +++ b/Client/Source/MidiSendThread.h @@ -4,10 +4,14 @@ #include "MidiController.h" +#ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wextra-semi" +#endif #include "tbb/concurrent_queue.h" +#ifdef __clang__ #pragma clang diagnostic pop +#endif #include #include diff --git a/Client/Source/Tuner.cpp b/Client/Source/Tuner.cpp index 5b5a789..7739693 100644 --- a/Client/Source/Tuner.cpp +++ b/Client/Source/Tuner.cpp @@ -12,6 +12,7 @@ #pragma warning( push ) #pragma warning( disable: 4244 4267 4305 4456) #endif +#ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wfloat-conversion" #pragma clang diagnostic ignored "-Wimplicit-float-conversion" @@ -24,8 +25,11 @@ #pragma clang diagnostic ignored "-Wimplicit-int-conversion" #pragma clang diagnostic ignored "-Wfloat-equal" #pragma clang diagnostic ignored "-Wmissing-field-initializers" +#endif #include +#ifdef __clang__ #pragma clang diagnostic pop +#endif #ifndef __GNUC__ #pragma warning ( pop ) #endif diff --git a/Server/Source/SharedServerTypes.h b/Server/Source/SharedServerTypes.h index 976bbff..e0b2337 100644 --- a/Server/Source/SharedServerTypes.h +++ b/Server/Source/SharedServerTypes.h @@ -11,15 +11,16 @@ #include "JammerNetzPackage.h" #include "PacketStreamQueue.h" +#ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wextra-semi" #pragma clang diagnostic ignored "-Wsign-conversion" - +#endif #include "tbb/concurrent_queue.h" #include "tbb/concurrent_unordered_map.h" - +#ifdef __clang__ #pragma clang diagnostic pop - +#endif #include #include diff --git a/common/JammerNetzPackage.h b/common/JammerNetzPackage.h index 64b744e..455f7c1 100644 --- a/common/JammerNetzPackage.h +++ b/common/JammerNetzPackage.h @@ -8,13 +8,14 @@ #include "JuceHeader.h" +#ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wfloat-equal" - +#endif #include "flatbuffers/flatbuffers.h" - +#ifdef __clang__ #pragma clang diagnostic pop - +#endif #include "JammerNetzAudioData_generated.h" #include "JammerNetzSessionInfo_generated.h" diff --git a/common/PacketStreamQueue.h b/common/PacketStreamQueue.h index c357a80..b8c91af 100644 --- a/common/PacketStreamQueue.h +++ b/common/PacketStreamQueue.h @@ -11,14 +11,15 @@ #include "JammerNetzPackage.h" #include "JammerNetzClientInfoMessage.h" +#ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wsign-conversion" - +#endif #include "tbb/concurrent_hash_map.h" #include "tbb/concurrent_priority_queue.h" - +#ifdef __clang__ #pragma clang diagnostic pop - +#endif #include "RunningStats.h" From fce039182e681c6ed111e2d6a7759595f3726ca0 Mon Sep 17 00:00:00 2001 From: Christof Ruch Date: Sat, 19 Oct 2024 22:04:40 +0200 Subject: [PATCH 13/31] One more ignore for the Github Mac build machine --- Client/Source/Tuner.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Client/Source/Tuner.cpp b/Client/Source/Tuner.cpp index 7739693..ff6a271 100644 --- a/Client/Source/Tuner.cpp +++ b/Client/Source/Tuner.cpp @@ -25,6 +25,7 @@ #pragma clang diagnostic ignored "-Wimplicit-int-conversion" #pragma clang diagnostic ignored "-Wfloat-equal" #pragma clang diagnostic ignored "-Wmissing-field-initializers" +#pragma clang diagnostic ignored "-Wc99-extensions" #endif #include #ifdef __clang__ From 41b44040e76cbb2a0a0498c01ff4356ae61279fd Mon Sep 17 00:00:00 2001 From: Christof Ruch Date: Sat, 19 Oct 2024 22:13:42 +0200 Subject: [PATCH 14/31] Fix --- Client/Source/IncludeFFMeters.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Client/Source/IncludeFFMeters.h b/Client/Source/IncludeFFMeters.h index 3acd30f..dbcfd8f 100644 --- a/Client/Source/IncludeFFMeters.h +++ b/Client/Source/IncludeFFMeters.h @@ -25,4 +25,4 @@ #pragma warning (pop ) #ifdef __clang__ #pragma clang diagnostic pop -#endifs +#endif From 450d8a861963bf72cf22259ee631dc3b3342578a Mon Sep 17 00:00:00 2001 From: Christof Ruch Date: Sat, 19 Oct 2024 23:06:40 +0200 Subject: [PATCH 15/31] Allow remote control of Server settings from client. First item is the FEC setting, that is now coupled with the Heal checkbox on the client side. --- Client/Source/Client.cpp | 79 ++++++++++++++++++++++------------ Client/Source/Client.h | 5 +++ Server/Source/AcceptThread.cpp | 13 ++++-- Server/Source/AcceptThread.h | 8 +++- Server/Source/Main.cpp | 8 +++- Server/Source/SendThread.cpp | 9 ++-- Server/Source/SendThread.h | 4 +- common/JammerNetzPackage.h | 2 +- 8 files changed, 88 insertions(+), 40 deletions(-) diff --git a/Client/Source/Client.cpp b/Client/Source/Client.cpp index cddbd3e..2c535b5 100644 --- a/Client/Source/Client.cpp +++ b/Client/Source/Client.cpp @@ -40,6 +40,9 @@ Client::Client(DatagramSocket& socket) : socket_(socket), messageCounter_(10) /* })); listeners_.push_back(std::make_unique(Data::instance().get().getPropertyAsValue(VALUE_USE_FEC, nullptr), [this](Value& value) { useFEC_ = value.getValue(); + nlohmann::json fecControl; + fecControl["FEC"] = value.getValue().operator bool(); + sendControl(fecControl); })); listeners_.push_back(std::make_unique(Data::getPropertyAsValue(VALUE_SERVER_NAME), [this](Value& value) { ScopedLock lock(serverLock_); @@ -87,34 +90,40 @@ bool Client::sendData(String const &remoteHostname, int remotePort, void *data, return true; } -bool Client::sendData(JammerNetzChannelSetup const& channelSetup, std::shared_ptr> audioBuffer, ControlData controllers) -{ - // If we have FEC data, and the user enabled it, append the last block sent - std::shared_ptr fecBlock; - if (useFEC_ && !fecBuffer_.isEmpty()) { - fecBlock = fecBuffer_.getLast(); - } - MidiSignal toSend = MidiSignal_None; - if (controllers.midiSignal.has_value()) { - toSend = *controllers.midiSignal; - } - - // Create a message - JammerNetzAudioData audioMessage(messageCounter_, Time::getMillisecondCounterHiRes(), channelSetup, SAMPLE_RATE, controllers.bpm, toSend, audioBuffer, fecBlock); - - messageCounter_++; - size_t totalBytes; - audioMessage.serialize(sendBuffer_, totalBytes); - - // Store the audio data somewhere else because we need it for forward error correction - std::shared_ptr redundencyData = std::make_shared(); - redundencyData->messageCounter = audioMessage.messageCounter(); - redundencyData->timestamp = audioMessage.timestamp(); - redundencyData->channelSetup = channelSetup; - redundencyData->audioBuffer = std::make_shared>(); - *redundencyData->audioBuffer = *audioBuffer; // Deep copy - fecBuffer_.push(redundencyData); +bool Client::sendData(JammerNetzChannelSetup const& channelSetup, std::shared_ptr> audioBuffer, ControlData controllers) { + ScopedLock lockSocket(socketLock_); + + // If we have FEC data, and the user enabled it, append the last block sent + std::shared_ptr fecBlock; + if (useFEC_ && !fecBuffer_.isEmpty()) { + fecBlock = fecBuffer_.getLast(); + } + MidiSignal toSend = MidiSignal_None; + if (controllers.midiSignal.has_value()) { + toSend = *controllers.midiSignal; + } + + // Create a message + JammerNetzAudioData audioMessage(messageCounter_, Time::getMillisecondCounterHiRes(), channelSetup, SAMPLE_RATE, + controllers.bpm, toSend, audioBuffer, fecBlock); + + messageCounter_++; + size_t totalBytes; + audioMessage.serialize(sendBuffer_, totalBytes); + + // Store the audio data somewhere else because we need it for forward error correction + std::shared_ptr redundencyData = std::make_shared(); + redundencyData->messageCounter = audioMessage.messageCounter(); + redundencyData->timestamp = audioMessage.timestamp(); + redundencyData->channelSetup = channelSetup; + redundencyData->audioBuffer = std::make_shared>(); + *redundencyData->audioBuffer = *audioBuffer; // Deep copy + fecBuffer_.push(redundencyData); + return sendBufferToServer(totalBytes); +} +bool Client::sendBufferToServer(size_t totalBytes) +{ // Send off to server String servername; { @@ -148,6 +157,22 @@ bool Client::sendData(JammerNetzChannelSetup const& channelSetup, std::shared_pt return true; } +bool Client::sendControl(nlohmann::json &json) +{ + ScopedLock lockSocket(socketLock_); + + JammerNetzControlMessage controlMessage(json); + size_t totalBytes; + controlMessage.serialize(sendBuffer_, totalBytes); + if (totalBytes > 0) { + return sendBufferToServer(totalBytes); + } + else + { + return false; + } +} + int Client::getCurrentBlockSize() const { return currentBlockSize_; diff --git a/Client/Source/Client.h b/Client/Source/Client.h index e7841ad..3949a78 100644 --- a/Client/Source/Client.h +++ b/Client/Source/Client.h @@ -13,6 +13,8 @@ #include "RingOfAudioBuffers.h" #include "ApplicationState.h" +#include "nlohmann/json.hpp" + struct ControlData { std::optional bpm; @@ -25,6 +27,7 @@ class Client { ~Client(); bool sendData(JammerNetzChannelSetup const &channelSetup, std::shared_ptr> audioBuffer, ControlData controllers); + bool sendControl(nlohmann::json &json); // Statistics info int getCurrentBlockSize() const; @@ -32,12 +35,14 @@ class Client { private: void setCryptoKey(const void* keyData, int keyBytes); bool sendData(String const &remoteHostname, int remotePort, void *data, int numbytes); + bool sendBufferToServer(size_t totalBytes); DatagramSocket &socket_; uint64 messageCounter_; uint8 sendBuffer_[65536]; std::atomic_int currentBlockSize_; std::atomic useFEC_; + juce::CriticalSection socketLock_; juce::CriticalSection serverLock_; String serverName_; std::atomic serverPort_; diff --git a/Server/Source/AcceptThread.cpp b/Server/Source/AcceptThread.cpp index 2796986..4247728 100644 --- a/Server/Source/AcceptThread.cpp +++ b/Server/Source/AcceptThread.cpp @@ -29,8 +29,13 @@ class PrintQualityTimer : public HighResolutionTimer { TPacketStreamBundle &data_; }; -AcceptThread::AcceptThread(int serverPort, DatagramSocket &socket, TPacketStreamBundle &incomingData, TMessageQueue &wakeUpQueue, ServerBufferConfig bufferConfig, void *keydata, int keysize) - : Thread("ReceiverThread"), receiveSocket_(socket), incomingData_(incomingData), wakeUpQueue_(wakeUpQueue), bufferConfig_(bufferConfig) +AcceptThread::AcceptThread(int serverPort, DatagramSocket &socket, TPacketStreamBundle &incomingData, TMessageQueue &wakeUpQueue, ServerBufferConfig bufferConfig, void *keydata, int keysize, ValueTree serverConfiguration) + : Thread("ReceiverThread") + , receiveSocket_(socket) + , incomingData_(incomingData) + , wakeUpQueue_(wakeUpQueue) + , serverConfiguration_(serverConfiguration) + , bufferConfig_(bufferConfig) { if (keydata) { blowFish_ = std::make_unique(keydata, keysize); @@ -55,7 +60,9 @@ void AcceptThread::processControlMessage(std::shared_ptrjson_.contains("FEC")) { + serverConfiguration_.setProperty("FEC", message->json_["FEC"].operator bool(), nullptr); + } } } diff --git a/Server/Source/AcceptThread.h b/Server/Source/AcceptThread.h index b8a4074..134c355 100644 --- a/Server/Source/AcceptThread.h +++ b/Server/Source/AcceptThread.h @@ -17,7 +17,12 @@ class PrintQualityTimer; class AcceptThread : public Thread { public: - AcceptThread(int serverPort, DatagramSocket &socket, TPacketStreamBundle &incomingData, TMessageQueue &wakeUpQueue, ServerBufferConfig bufferConfig, void *keydata, int keysize); + AcceptThread(int serverPort, DatagramSocket &socket, + TPacketStreamBundle &incomingData, TMessageQueue &wakeUpQueue, + ServerBufferConfig bufferConfig, + void *keydata, + int keysize, + ValueTree serverConfiguration); virtual ~AcceptThread() override; virtual void run() override; @@ -29,6 +34,7 @@ class AcceptThread : public Thread { DatagramSocket &receiveSocket_; TPacketStreamBundle &incomingData_; TMessageQueue &wakeUpQueue_; + ValueTree serverConfiguration_; uint8 readbuffer[MAXFRAMESIZE]; std::unique_ptr qualityTimer_; ServerBufferConfig bufferConfig_; diff --git a/Server/Source/Main.cpp b/Server/Source/Main.cpp index 20b2f18..fcc708f 100644 --- a/Server/Source/Main.cpp +++ b/Server/Source/Main.cpp @@ -41,9 +41,11 @@ class Server { clientRecorder_(File(), "input", RecordingType::AIFF) , mixdownRecorder_(File::getCurrentWorkingDirectory(), "mixdown", RecordingType::FLAC) , mixdownSetup_(false, { JammerNetzSingleChannelSetup(JammerNetzChannelTarget::Left), JammerNetzSingleChannelSetup(JammerNetzChannelTarget::Right) }) // Setup standard mix down setup - two channels only in stereo + , serverConfiguration_("SERVER_CONFIG") { // Start the recorder of the mix down //mixdownRecorder_.updateChannelInfo(48000, mixdownSetup_); + serverConfiguration_.setProperty("FEC", useFEC, nullptr); // optional crypto key void* cryptoData = nullptr; @@ -53,8 +55,8 @@ class Server { cipherLength = static_cast(cryptoKey->getSize()); } - acceptThread_ = std::make_unique(serverPort, socket_, incomingStreams_, wakeUpQueue_, bufferConfig, cryptoData, cipherLength); - sendThread_ = std::make_unique (socket_, sendQueue_, incomingStreams_, cryptoData, cipherLength, useFEC); + acceptThread_ = std::make_unique(serverPort, socket_, incomingStreams_, wakeUpQueue_, bufferConfig, cryptoData, cipherLength, serverConfiguration_); + sendThread_ = std::make_unique (socket_, sendQueue_, incomingStreams_, cryptoData, cipherLength, serverConfiguration_); mixerThread_ = std::make_unique(incomingStreams_, mixdownSetup_, sendQueue_, wakeUpQueue_, bufferConfig); sendQueue_.set_capacity(128); // This is an arbitrary number only to prevent memory overflow should the sender thread somehow die (i.e. no network or something) @@ -101,6 +103,8 @@ class Server { Recorder clientRecorder_; // Later I need one per client Recorder mixdownRecorder_; JammerNetzChannelSetup mixdownSetup_; // This is the same for everybody + + ValueTree serverConfiguration_; // This is used to share the overall server configuration across the Threads }; int main(int argc, char *argv[]) diff --git a/Server/Source/SendThread.cpp b/Server/Source/SendThread.cpp index 330d38d..bb2e0d9 100644 --- a/Server/Source/SendThread.cpp +++ b/Server/Source/SendThread.cpp @@ -10,12 +10,12 @@ #include "XPlatformUtils.h" #include "ServerLogger.h" -SendThread::SendThread(DatagramSocket& socket, TOutgoingQueue &sendQueue, TPacketStreamBundle &incomingData, void *keydata, int keysize, bool useFEC) +SendThread::SendThread(DatagramSocket& socket, TOutgoingQueue &sendQueue, TPacketStreamBundle &incomingData, void *keydata, int keysize, ValueTree serverConfiguration) : Thread("SenderThread") , sendQueue_(sendQueue) , incomingData_(incomingData) , sendSocket_(socket) - , useFEC_(useFEC) + , serverConfiguration_(serverConfiguration) { if (keydata) { blowFish_ = std::make_unique(keydata, keysize); @@ -34,7 +34,8 @@ void SendThread::sendAudioBlock(std::string const &targetAddress, AudioBlock &au } std::shared_ptr fecBlock; - if (useFEC_ && !fecData_.find(targetAddress)->second.isEmpty()) { + bool useFEC = serverConfiguration_.getProperty("FEC").operator bool(); + if (useFEC && !fecData_.find(targetAddress)->second.isEmpty()) { // Send FEC data fecBlock = fecData_.find(targetAddress)->second.getLast(); //dataForClient.serialize(writebuffer_, bytesWritten, fecData_.find(targetAddress)->second.getLast(), SAMPLE_RATE, FEC_SAMPLERATE_REDUCTION); @@ -84,7 +85,7 @@ void SendThread::sendClientInfoPackage(std::string const &targetAddress) void SendThread::sendSessionInfoPackage(std::string const &targetAddress, JammerNetzChannelSetup &sessionSetup) { // Loop over the incoming data streams and add them to our statistics package we are going to send to the client - JammerNetzSessionInfoMessage sessionInfoMessage; + JammerNetzSessionInfoMessage sessionInfoMessage; sessionInfoMessage.channels_.channels = sessionSetup.channels; size_t bytesWritten = 0; diff --git a/Server/Source/SendThread.h b/Server/Source/SendThread.h index d0cb2e9..2341422 100644 --- a/Server/Source/SendThread.h +++ b/Server/Source/SendThread.h @@ -14,7 +14,7 @@ class SendThread : public Thread { public: - SendThread(DatagramSocket& socket, TOutgoingQueue &sendQueue, TPacketStreamBundle &incomingData, void *keydata, int keysize, bool useFEC); + SendThread(DatagramSocket& socket, TOutgoingQueue &sendQueue, TPacketStreamBundle &incomingData, void *keydata, int keysize, ValueTree serverConfiguration); virtual void run() override; @@ -28,7 +28,7 @@ class SendThread : public Thread { TOutgoingQueue& sendQueue_; TPacketStreamBundle &incomingData_; DatagramSocket& sendSocket_; - bool useFEC_; + ValueTree serverConfiguration_; uint8 writebuffer_[MAXFRAMESIZE]; std::map> fecData_; std::map packageCounters_; diff --git a/common/JammerNetzPackage.h b/common/JammerNetzPackage.h index 455f7c1..90983c2 100644 --- a/common/JammerNetzPackage.h +++ b/common/JammerNetzPackage.h @@ -147,7 +147,7 @@ class JammerNetzFlatbufferMessage : public JammerNetzMessage { // Generic deserialization constructor JammerNetzFlatbufferMessage(size_t size) { - if (size < sizeof(JammerNetzAudioHeader)) { + if (size < sizeof(JammerNetzHeader)) { throw JammerNetzMessageParseException(); } } From 65ae09455c665ef58970b6bb753942770dda4297 Mon Sep 17 00:00:00 2001 From: Christof Ruch Date: Sat, 19 Oct 2024 23:09:23 +0200 Subject: [PATCH 16/31] One more suppression for the gitlab Mac build --- Client/Source/Tuner.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Client/Source/Tuner.cpp b/Client/Source/Tuner.cpp index ff6a271..741d4a2 100644 --- a/Client/Source/Tuner.cpp +++ b/Client/Source/Tuner.cpp @@ -26,6 +26,7 @@ #pragma clang diagnostic ignored "-Wfloat-equal" #pragma clang diagnostic ignored "-Wmissing-field-initializers" #pragma clang diagnostic ignored "-Wc99-extensions" +#pragma clang diagnostic ignored "-Wno-gnu-statement-expression" #endif #include #ifdef __clang__ From 75651e1d65184785f4ac2dc2593a32a54698f900 Mon Sep 17 00:00:00 2001 From: christofmuc Date: Sun, 20 Oct 2024 22:59:55 +0200 Subject: [PATCH 17/31] Fix Windows build --- common/JammerNetzPackage.cpp | 2 +- common/JammerNetzPackage.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/common/JammerNetzPackage.cpp b/common/JammerNetzPackage.cpp index 2385ebb..1186389 100644 --- a/common/JammerNetzPackage.cpp +++ b/common/JammerNetzPackage.cpp @@ -313,7 +313,7 @@ std::shared_ptr JammerNetzAudioData::readAudioHeaderAndBytes(JammerN result->sampleRate = 48000; size_t upsampleRate = block->sampleRate() != 0 ? 48000 / block->sampleRate() : 48000; jassert(block->numberOfSamples() * upsampleRate == SAMPLE_BUFFER_SIZE); - result->audioBuffer = std::make_shared>(block->numChannels(), block->numberOfSamples() * upsampleRate); + result->audioBuffer = std::make_shared>((int) block->numChannels(), (int) (block->numberOfSamples() * upsampleRate)); readAudioBytes(block->channels(), result->audioBuffer, upsampleRate); return result; } diff --git a/common/JammerNetzPackage.h b/common/JammerNetzPackage.h index 90983c2..63bab71 100644 --- a/common/JammerNetzPackage.h +++ b/common/JammerNetzPackage.h @@ -154,7 +154,7 @@ class JammerNetzFlatbufferMessage : public JammerNetzMessage { void serialize(uint8 *output, size_t &byteswritten) const override { - byteswritten = writeHeader(output, getType()); + byteswritten = writeHeader(output, static_cast(getType())); flatbuffers::FlatBufferBuilder fbb; serializeToFlatbuffer(fbb); memcpy(output + byteswritten, fbb.GetBufferPointer(), fbb.GetSize()); @@ -184,7 +184,7 @@ class JammerNetzControlMessage : public JammerNetzFlatbufferMessagecontrol_message_json()->str()); } - catch (nlohmann::json::parse_error &e) { + catch (nlohmann::json::parse_error &) { throw JammerNetzMessageParseException(); } } From 01e6e2506b4639efd5927f34c6c1c9ec4837da35 Mon Sep 17 00:00:00 2001 From: christofmuc Date: Sun, 20 Oct 2024 23:19:29 +0200 Subject: [PATCH 18/31] One more for Mac --- Client/Source/Tuner.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Client/Source/Tuner.cpp b/Client/Source/Tuner.cpp index 741d4a2..053eb52 100644 --- a/Client/Source/Tuner.cpp +++ b/Client/Source/Tuner.cpp @@ -26,7 +26,8 @@ #pragma clang diagnostic ignored "-Wfloat-equal" #pragma clang diagnostic ignored "-Wmissing-field-initializers" #pragma clang diagnostic ignored "-Wc99-extensions" -#pragma clang diagnostic ignored "-Wno-gnu-statement-expression" +#pragma clang diagnostic ignored "-Wgnu-statement-expression" +#pragma clang diagnostic ignored "-Wgnu-statement-expression-from-macro-expansion" #endif #include #ifdef __clang__ From 7dfbe0049497346b7f8d1af8e08e67c5b91a28dc Mon Sep 17 00:00:00 2001 From: christofmuc Date: Sun, 20 Oct 2024 23:29:03 +0200 Subject: [PATCH 19/31] Seems we switch to GNUC pragmas so Linux works and clang keeps working? --- common/JammerNetzPackage.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/common/JammerNetzPackage.h b/common/JammerNetzPackage.h index 63bab71..b62be7d 100644 --- a/common/JammerNetzPackage.h +++ b/common/JammerNetzPackage.h @@ -8,13 +8,13 @@ #include "JuceHeader.h" -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wfloat-equal" +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" #endif #include "flatbuffers/flatbuffers.h" -#ifdef __clang__ -#pragma clang diagnostic pop +#ifdef __GNUC__ +#pragma GCC diagnostic pop #endif #include "JammerNetzAudioData_generated.h" From d447a5e47ecae276947c7248165cf59ebd216444 Mon Sep 17 00:00:00 2001 From: christofmuc Date: Sun, 20 Oct 2024 23:34:36 +0200 Subject: [PATCH 20/31] Switch over all pragmas to GNUC instead of clang. Linux should build again? --- Client/Source/IncludeFFMeters.h | 26 ++++++++++---------- Client/Source/MidiSendThread.h | 10 ++++---- Client/Source/Tuner.cpp | 40 +++++++++++++++---------------- Server/Source/SharedServerTypes.h | 12 +++++----- common/PacketStreamQueue.h | 10 ++++---- 5 files changed, 48 insertions(+), 50 deletions(-) diff --git a/Client/Source/IncludeFFMeters.h b/Client/Source/IncludeFFMeters.h index dbcfd8f..aaf8163 100644 --- a/Client/Source/IncludeFFMeters.h +++ b/Client/Source/IncludeFFMeters.h @@ -7,22 +7,22 @@ #pragma once -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wimplicit-float-conversion" -#pragma clang diagnostic ignored "-Wfloat-conversion" -#pragma clang diagnostic ignored "-Wfloat-equal" -#pragma clang diagnostic ignored "-Wsign-compare" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma clang diagnostic ignored "-Wshadow" -#pragma clang diagnostic ignored "-Wunknown-pragmas" -#pragma clang diagnostic ignored "-Wunused-parameter" -#pragma clang diagnostic ignored "-Winconsistent-missing-destructor-override" +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wimplicit-float-conversion" +#pragma GCC diagnostic ignored "-Wfloat-conversion" +#pragma GCC diagnostic ignored "-Wfloat-equal" +#pragma GCC diagnostic ignored "-Wsign-compare" +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wshadow" +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override" #endif #pragma warning( push ) #pragma warning( disable: 4244 4100 4456 4702) #include "ff_meters/ff_meters.h" #pragma warning (pop ) -#ifdef __clang__ -#pragma clang diagnostic pop +#ifdef __GNUC__ +#pragma GCC diagnostic pop #endif diff --git a/Client/Source/MidiSendThread.h b/Client/Source/MidiSendThread.h index 0333e54..ba7ee41 100644 --- a/Client/Source/MidiSendThread.h +++ b/Client/Source/MidiSendThread.h @@ -4,13 +4,13 @@ #include "MidiController.h" -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wextra-semi" +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wextra-semi" #endif #include "tbb/concurrent_queue.h" -#ifdef __clang__ -#pragma clang diagnostic pop +#ifdef __GNUC__ +#pragma GCC diagnostic pop #endif #include diff --git a/Client/Source/Tuner.cpp b/Client/Source/Tuner.cpp index 053eb52..612a041 100644 --- a/Client/Source/Tuner.cpp +++ b/Client/Source/Tuner.cpp @@ -11,30 +11,28 @@ #ifndef __GNUC__ #pragma warning( push ) #pragma warning( disable: 4244 4267 4305 4456) -#endif -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wfloat-conversion" -#pragma clang diagnostic ignored "-Wimplicit-float-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma clang diagnostic ignored "-Wshorten-64-to-32" -#pragma clang diagnostic ignored "-Wc++98-compat-extra-semi" -#pragma clang diagnostic ignored "-Wextra-semi" -#pragma clang diagnostic ignored "-Wshadow" -#pragma clang diagnostic ignored "-Wshadow-field-in-constructor" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wfloat-equal" -#pragma clang diagnostic ignored "-Wmissing-field-initializers" -#pragma clang diagnostic ignored "-Wc99-extensions" -#pragma clang diagnostic ignored "-Wgnu-statement-expression" -#pragma clang diagnostic ignored "-Wgnu-statement-expression-from-macro-expansion" +#else +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-conversion" +#pragma GCC diagnostic ignored "-Wimplicit-float-conversion" +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wshorten-64-to-32" +#pragma GCC diagnostic ignored "-Wc++98-compat-extra-semi" +#pragma GCC diagnostic ignored "-Wextra-semi" +#pragma GCC diagnostic ignored "-Wshadow" +#pragma GCC diagnostic ignored "-Wshadow-field-in-constructor" +#pragma GCC diagnostic ignored "-Wimplicit-int-conversion" +#pragma GCC diagnostic ignored "-Wfloat-equal" +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#pragma GCC diagnostic ignored "-Wc99-extensions" +#pragma GCC diagnostic ignored "-Wgnu-statement-expression" +#pragma GCC diagnostic ignored "-Wgnu-statement-expression-from-macro-expansion" #endif #include -#ifdef __clang__ -#pragma clang diagnostic pop -#endif #ifndef __GNUC__ -#pragma warning ( pop ) +#pragma warning(pop) +#else +#pragma GCC diagnostic pop #endif diff --git a/Server/Source/SharedServerTypes.h b/Server/Source/SharedServerTypes.h index e0b2337..77a5741 100644 --- a/Server/Source/SharedServerTypes.h +++ b/Server/Source/SharedServerTypes.h @@ -11,15 +11,15 @@ #include "JammerNetzPackage.h" #include "PacketStreamQueue.h" -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wextra-semi" -#pragma clang diagnostic ignored "-Wsign-conversion" +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wextra-semi" +#pragma GCC diagnostic ignored "-Wsign-conversion" #endif #include "tbb/concurrent_queue.h" #include "tbb/concurrent_unordered_map.h" -#ifdef __clang__ -#pragma clang diagnostic pop +#ifdef __GNUC__ +#pragma GCC diagnostic pop #endif #include #include diff --git a/common/PacketStreamQueue.h b/common/PacketStreamQueue.h index b8c91af..f6a5a44 100644 --- a/common/PacketStreamQueue.h +++ b/common/PacketStreamQueue.h @@ -11,14 +11,14 @@ #include "JammerNetzPackage.h" #include "JammerNetzClientInfoMessage.h" -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wsign-conversion" +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" #endif #include "tbb/concurrent_hash_map.h" #include "tbb/concurrent_priority_queue.h" -#ifdef __clang__ -#pragma clang diagnostic pop +#ifdef __GNUC__ +#pragma GCC diagnostic pop #endif #include "RunningStats.h" From d1874e223308940e8ff46cea83620026e537ba7c Mon Sep 17 00:00:00 2001 From: christofmuc Date: Sun, 20 Oct 2024 23:59:38 +0200 Subject: [PATCH 21/31] One more for Linux --- common/PacketStreamQueue.h | 1 + 1 file changed, 1 insertion(+) diff --git a/common/PacketStreamQueue.h b/common/PacketStreamQueue.h index f6a5a44..c6d3958 100644 --- a/common/PacketStreamQueue.h +++ b/common/PacketStreamQueue.h @@ -14,6 +14,7 @@ #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" #endif #include "tbb/concurrent_hash_map.h" #include "tbb/concurrent_priority_queue.h" From 20b9088ede8da98c430c133dfc04c4fe3192b67f Mon Sep 17 00:00:00 2001 From: christofmuc Date: Mon, 21 Oct 2024 00:43:48 +0200 Subject: [PATCH 22/31] Test gcc warning --- common/Recorder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/Recorder.cpp b/common/Recorder.cpp index b5acf2c..d44681d 100644 --- a/common/Recorder.cpp +++ b/common/Recorder.cpp @@ -163,7 +163,7 @@ void Recorder::saveBlock(const float* const* data, int numSamples) { //TODO - need a smarter strategy than that std::cerr << "Ups, FIFO full and can't write block to disk, lost it!" << std::endl; } - samplesWritten_ += (size_t) numSamples; + samplesWritten_ += (juce::uint64) numSamples; } } From a5c24ab8d0b73a28d82c7f6c6cdb1c5a81d6e784 Mon Sep 17 00:00:00 2001 From: christofmuc Date: Mon, 21 Oct 2024 01:35:41 +0200 Subject: [PATCH 23/31] And more GCC fixes... --- Server/Source/SharedServerTypes.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Server/Source/SharedServerTypes.h b/Server/Source/SharedServerTypes.h index 77a5741..10d48c3 100644 --- a/Server/Source/SharedServerTypes.h +++ b/Server/Source/SharedServerTypes.h @@ -15,6 +15,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wextra-semi" #pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wfloat-equal" #endif #include "tbb/concurrent_queue.h" #include "tbb/concurrent_unordered_map.h" From 666e383cb51ae5db78607e19989ed88ffc13d9dd Mon Sep 17 00:00:00 2001 From: christofmuc Date: Mon, 21 Oct 2024 09:39:31 +0200 Subject: [PATCH 24/31] And another GCC find --- Server/Source/MixerThread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Server/Source/MixerThread.cpp b/Server/Source/MixerThread.cpp index 4b2eea1..b5ffd1d 100644 --- a/Server/Source/MixerThread.cpp +++ b/Server/Source/MixerThread.cpp @@ -93,7 +93,7 @@ void MixerThread::run() { if (incomingData.size() > 0) { //TODO - current assumption: all clients provide buffers of the same size. Therefore, take the length of the first client as the output size int bufferLength = (*incomingData.begin()).second->audioBuffer()->getNumSamples(); - serverTime_ += (size_t) bufferLength; // Server time counts time of mixing thread in samples mixed since launch + serverTime_ += (juce::uint64) bufferLength; // Server time counts time of mixing thread in samples mixed since launch // For each client that has delivered data, produce a mix down package and send it back //TODO - also the clients that have not provided data should get a package with a note that they are not contained within - they could do a local fill in. From a56164a9029b831db1331d4dd99d95fda29db994 Mon Sep 17 00:00:00 2001 From: christofmuc Date: Mon, 21 Oct 2024 10:32:17 +0200 Subject: [PATCH 25/31] More GNUC supressions --- Server/Source/ServerLogger.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Server/Source/ServerLogger.cpp b/Server/Source/ServerLogger.cpp index 0124a5f..77cf5d7 100644 --- a/Server/Source/ServerLogger.cpp +++ b/Server/Source/ServerLogger.cpp @@ -41,7 +41,14 @@ void ServerLogger::printAtPosition(int x, int y, std::string text) { if (terminal) { move(x, y); +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-security" +#endif printw(text.c_str()); +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif refresh(); } else { @@ -91,6 +98,9 @@ void ServerLogger::printStatistics(int row, std::string const &clientID, JammerN #ifndef __GNUC__ #pragma warning( push ) #pragma warning( disable : 4996 ) +#else +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-security" #endif snprintf(buffer, 200, "%*d", 6, (int)(quality.packagesPushed - quality.packagesPopped)); mvprintw(y, kColumnHeaders[1].first, buffer); snprintf(buffer, 200, "%*d", 6, (int)quality.outOfOrderPacketCounter); mvprintw(y, kColumnHeaders[2].first, buffer); @@ -104,6 +114,8 @@ void ServerLogger::printStatistics(int row, std::string const &clientID, JammerN snprintf(buffer, 200, "%2.1f", quality.jitterSDMillis); mvprintw(y, kColumnHeaders[10].first, buffer); #ifndef __GNUC__ #pragma warning( pop ) +#else +#pragma GCC diagnostic pop #endif refresh(); } From 379225449131cd3a633f404f172847c950e4dc5a Mon Sep 17 00:00:00 2001 From: christofmuc Date: Mon, 21 Oct 2024 21:48:32 +0200 Subject: [PATCH 26/31] Ok ok, just suppress it for the whole file. --- Server/Source/ServerLogger.cpp | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/Server/Source/ServerLogger.cpp b/Server/Source/ServerLogger.cpp index 77cf5d7..ddfe29f 100644 --- a/Server/Source/ServerLogger.cpp +++ b/Server/Source/ServerLogger.cpp @@ -10,6 +10,11 @@ static SCREEN *terminal; +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-security" +#endif + void ServerLogger::init() { // We're good to good, init screen if possible @@ -41,14 +46,7 @@ void ServerLogger::printAtPosition(int x, int y, std::string text) { if (terminal) { move(x, y); -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wformat-security" -#endif printw(text.c_str()); -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif refresh(); } else { @@ -98,9 +96,6 @@ void ServerLogger::printStatistics(int row, std::string const &clientID, JammerN #ifndef __GNUC__ #pragma warning( push ) #pragma warning( disable : 4996 ) -#else -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wformat-security" #endif snprintf(buffer, 200, "%*d", 6, (int)(quality.packagesPushed - quality.packagesPopped)); mvprintw(y, kColumnHeaders[1].first, buffer); snprintf(buffer, 200, "%*d", 6, (int)quality.outOfOrderPacketCounter); mvprintw(y, kColumnHeaders[2].first, buffer); @@ -114,8 +109,6 @@ void ServerLogger::printStatistics(int row, std::string const &clientID, JammerN snprintf(buffer, 200, "%2.1f", quality.jitterSDMillis); mvprintw(y, kColumnHeaders[10].first, buffer); #ifndef __GNUC__ #pragma warning( pop ) -#else -#pragma GCC diagnostic pop #endif refresh(); } @@ -168,3 +161,7 @@ void ServerLogger::printClientStatus(int row, std::string const &clientID, std:: juce::String ServerLogger::lastMessage; long long ServerLogger::counter = 0; + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif From 8671549179e7abe564f6ba15c28f15c19d6414fc Mon Sep 17 00:00:00 2001 From: christofmuc Date: Mon, 21 Oct 2024 23:45:37 +0200 Subject: [PATCH 27/31] Crazy to split out the pragmas per compiler here --- Client/Source/IncludeFFMeters.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Client/Source/IncludeFFMeters.h b/Client/Source/IncludeFFMeters.h index aaf8163..1861c97 100644 --- a/Client/Source/IncludeFFMeters.h +++ b/Client/Source/IncludeFFMeters.h @@ -9,7 +9,6 @@ #ifdef __GNUC__ #pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wimplicit-float-conversion" #pragma GCC diagnostic ignored "-Wfloat-conversion" #pragma GCC diagnostic ignored "-Wfloat-equal" #pragma GCC diagnostic ignored "-Wsign-compare" @@ -17,12 +16,19 @@ #pragma GCC diagnostic ignored "-Wshadow" #pragma GCC diagnostic ignored "-Wunknown-pragmas" #pragma GCC diagnostic ignored "-Wunused-parameter" -#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override" #endif -#pragma warning( push ) +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wimplicit-float-conversion" +#pragma clang diagnostic ignored "-Winconsistent-missing-destructor-override" +#endif +#pragma warning(push) #pragma warning( disable: 4244 4100 4456 4702) #include "ff_meters/ff_meters.h" #pragma warning (pop ) +#ifdef __clang__ +#pragma clang diagnostic pop +#endif #ifdef __GNUC__ #pragma GCC diagnostic pop #endif From 35886efea8335d2a08e13ee6ac9c829854d64bf4 Mon Sep 17 00:00:00 2001 From: christofmuc Date: Tue, 22 Oct 2024 01:26:52 +0200 Subject: [PATCH 28/31] Fix a real init error in the recording info class --- Client/Source/RecordingInfo.cpp | 2 +- Client/Source/RecordingInfo.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Client/Source/RecordingInfo.cpp b/Client/Source/RecordingInfo.cpp index c649bd0..0eec8c9 100644 --- a/Client/Source/RecordingInfo.cpp +++ b/Client/Source/RecordingInfo.cpp @@ -42,7 +42,7 @@ class RecordingInfo::UpdateTimer : public Timer { RecordingInfo *info_; }; -RecordingInfo::RecordingInfo(std::weak_ptr recorder, String explanation) : recorder_(recorder), diskSpace_(diskSpacePercentage_), diskSpacePercentage_(0.0) +RecordingInfo::RecordingInfo(std::weak_ptr recorder, String explanation) : recorder_(recorder), diskSpacePercentage_(0.0), diskSpace_(diskSpacePercentage_) { explanationText_.setText(explanation, dontSendNotification); addAndMakeVisible(explanationText_); diff --git a/Client/Source/RecordingInfo.h b/Client/Source/RecordingInfo.h index cc68379..c4e561f 100644 --- a/Client/Source/RecordingInfo.h +++ b/Client/Source/RecordingInfo.h @@ -34,6 +34,6 @@ class RecordingInfo : public Component, private TextButton::Listener { ImageButton recording_; Label recordingTime_; Label freeDiskSpace_; - ProgressBar diskSpace_; double diskSpacePercentage_; + ProgressBar diskSpace_; }; From dc6e955eb7d1647811577544ede4693248c6b41d Mon Sep 17 00:00:00 2001 From: christofmuc Date: Wed, 23 Oct 2024 01:37:12 +0200 Subject: [PATCH 29/31] Fix CMakeLists --- Client/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Client/CMakeLists.txt b/Client/CMakeLists.txt index 8872b9c..335a1fd 100644 --- a/Client/CMakeLists.txt +++ b/Client/CMakeLists.txt @@ -86,6 +86,7 @@ set(UICOMPONENT_FILES Source/ClientConfig.h Source/DeviceSelector.cpp Source/DeviceSelector.h + Source/IncludeFFMeters.h Source/MidiDeviceSelector.cpp Source/MidiDeviceSelector.h Source/RecordingInfo.cpp From 971a5ecfc11892536789cb30010e1f2682161ce9 Mon Sep 17 00:00:00 2001 From: christofmuc Date: Wed, 23 Oct 2024 01:45:58 +0200 Subject: [PATCH 30/31] More Linux suppressions --- Client/CMakeLists.txt | 2 +- Client/Source/Tuner.cpp | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Client/CMakeLists.txt b/Client/CMakeLists.txt index 335a1fd..b553807 100644 --- a/Client/CMakeLists.txt +++ b/Client/CMakeLists.txt @@ -159,7 +159,7 @@ if (MSVC) target_compile_options(JammerNetzClient PRIVATE /W4 /WX) else() # lots of warnings and all warnings as errors - target_compile_options(JammerNetzClient PRIVATE -Wall -Wextra -pedantic -Werror -Wno-unknown-pragmas) + target_compile_options(JammerNetzClient PRIVATE -Wall -Wextra -Werror -Wno-unknown-pragmas) endif() IF(WIN32) diff --git a/Client/Source/Tuner.cpp b/Client/Source/Tuner.cpp index 612a041..d4fd696 100644 --- a/Client/Source/Tuner.cpp +++ b/Client/Source/Tuner.cpp @@ -14,19 +14,21 @@ #else #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wfloat-conversion" -#pragma GCC diagnostic ignored "-Wimplicit-float-conversion" #pragma GCC diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wshorten-64-to-32" -#pragma GCC diagnostic ignored "-Wc++98-compat-extra-semi" #pragma GCC diagnostic ignored "-Wextra-semi" #pragma GCC diagnostic ignored "-Wshadow" -#pragma GCC diagnostic ignored "-Wshadow-field-in-constructor" -#pragma GCC diagnostic ignored "-Wimplicit-int-conversion" #pragma GCC diagnostic ignored "-Wfloat-equal" #pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#pragma GCC diagnostic ignored "-Wc99-extensions" -#pragma GCC diagnostic ignored "-Wgnu-statement-expression" -#pragma GCC diagnostic ignored "-Wgnu-statement-expression-from-macro-expansion" +#endif +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wimplicit-float-conversion" +#pragma clang diagnostic ignored "-Wshorten-64-to-32" +#pragma clang diagnostic ignored "-Wc++98-compat-extra-semi" +#pragma clang diagnostic ignored "-Wshadow-field-in-constructor" +#pragma clang diagnostic ignored "-Wimplicit-int-conversion" +#pragma clang diagnostic ignored "-Wc99-extensions" +#pragma clang diagnostic ignored "-Wgnu-statement-expression" +#pragma clang diagnostic ignored "-Wgnu-statement-expression-from-macro-expansion" #endif #include #ifndef __GNUC__ From a1306ddea530980c0761dd911d5b0b42063a192e Mon Sep 17 00:00:00 2001 From: christofmuc Date: Tue, 29 Oct 2024 00:14:09 +0100 Subject: [PATCH 31/31] Added a switch -DBUILD_JAMMERNETZ_CLIENT=OFF to reduce the number of libraries needed to build only the server on Linux --- .gitignore | 2 ++ CMakeLists.txt | 41 +++++++++++++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 2dd287e..d6f242b 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ venv/ .vs/ builds2024/ .conan_venv/ +builds24/ +buildServer/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d1fd44..cc8ed38 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,8 @@ set(CMAKE_OSX_DEPLOYMENT_TARGET "10.11" CACHE STRING "Minimum OS X version to ta project(JammerNetz) +OPTION(BUILD_JAMMERNETZ_CLIENT "Option to turn off the client build" ON) + # Since we also build MacOS, we need C++ 17. Which is not a bad thing. # JUCE 8 seems to force us to C++ 20 now! set(CMAKE_CXX_STANDARD 20) @@ -75,9 +77,11 @@ elseif(UNIX) find_package(OpenGL) # These calls create special `PkgConfig::` variables - pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) - pkg_check_modules(GLEW REQUIRED IMPORTED_TARGET glew) - pkg_check_modules(WEBKIT REQUIRED IMPORTED_TARGET webkit2gtk-4.1) + if(BUILD_JAMMERNETZ_CLIENT) + pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) + pkg_check_modules(GLEW REQUIRED IMPORTED_TARGET glew) + pkg_check_modules(WEBKIT REQUIRED IMPORTED_TARGET webkit2gtk-4.1) + endif() endif() @@ -111,12 +115,17 @@ mark_as_advanced( # Define the list of link libraries required on Linux linking with JUCE, this must be used by any executable / module to run standalone if(UNIX AND NOT APPLE) - set(LINUX_JUCE_LINK_LIBRARIES + if(BUILD_JAMMERNETZ_CLIENT) + set(LINUX_UI_LIBRARIES PkgConfig::WEBKIT PkgConfig::GTK PkgConfig::GLEW + ) + endif() + set(LINUX_JUCE_LINK_LIBRARIES Xext X11 + ${LINUX_UI_LIBRARIES} pthread ${CMAKE_DL_LIBS} freetype @@ -133,13 +142,22 @@ add_subdirectory("third_party/JUCE" EXCLUDE_FROM_ALL) # Build a static library from juce add_library(juce-static STATIC) +if(BUILD_JAMMERNETZ_CLIENT) + set(ADDITIONAL_JUCE_MODULES + juce::juce_graphics + juce::juce_gui_basics + juce::juce_gui_extra + juce::juce_opengl + juce::juce_video + ) +endif() target_link_libraries(juce-static PRIVATE juce::juce_audio_basics juce::juce_audio_devices juce::juce_audio_formats juce::juce_audio_processors juce::juce_audio_utils juce::juce_core juce::juce_cryptography juce::juce_data_structures juce::juce_dsp - juce::juce_events juce::juce_graphics juce::juce_gui_basics - juce::juce_gui_extra juce::juce_opengl juce::juce_video + juce::juce_events + ${ADDITIONAL_JUCE_MODULES} ${LINUX_JUCE_LINK_LIBRARIES} PUBLIC juce::juce_recommended_config_flags @@ -170,10 +188,8 @@ target_compile_definitions(juce-static target_include_directories(juce-static INTERFACE $ -if (WIN32) PRIVATE "${ASIO_SDK_DIRECTORY}" -endif() ) set_target_properties(juce-static PROPERTIES @@ -194,21 +210,26 @@ if(WIN32) endif() # Add subdirectories -add_subdirectory("third_party/JUCE-user-modules") add_subdirectory("third_party/json") add_subdirectory("third_party/fmt") add_subdirectory("third_party/spdlog") add_subdirectory("modules/juce-utils") -add_subdirectory("modules/juce-widgets") +if(BUILD_JAMMERNETZ_CLIENT) + add_subdirectory("third_party/JUCE-user-modules") + add_subdirectory("modules/juce-widgets") +endif() add_subdirectory("modules/MidiKraft") message(${CMAKE_MODULE_PATH}) add_subdirectory("third_party/oneTBB" EXCLUDE_FROM_ALL) add_subdirectory("common") add_subdirectory("Server") + +if(BUILD_JAMMERNETZ_CLIENT) add_subdirectory("Client") # The client installer now contains the server as well for local testing - make sure to always build the server add_dependencies(JammerNetzClient JammerNetzServer) +endif() # For Windows, we additionally build a little test program to check if ASIO initialization works. if(WIN32)