Skip to content

Commit

Permalink
Merge pull request #9 Sequence number
Browse files Browse the repository at this point in the history
Protocol changes - added increasing sequence number to audio packets.
  • Loading branch information
ashipo committed Mar 1, 2024
2 parents b6109fc + 163ac5a commit f6cbeca
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 26 deletions.
5 changes: 3 additions & 2 deletions SoundRemote/CapturePipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ void CapturePipe::process(std::span<char> pcmAudio, std::shared_ptr<Server> serv
opusInputSize_,
uncompressed.data()
);
server->sendAudio(compression, uncompressed);
server->sendAudio(compression, audioSequenceNumber_, uncompressed);
} else {
std::vector<char> encodedPacket(Audio::Opus::maxPacketSize);
const auto packetSize = encoder->encode(
Expand All @@ -142,10 +142,11 @@ void CapturePipe::process(std::span<char> pcmAudio, std::shared_ptr<Server> serv
);
encodedPacket.resize(packetSize);
if (packetSize > 0) {
server->sendAudio(compression, encodedPacket);
server->sendAudio(compression, audioSequenceNumber_, encodedPacket);
}
}
}
++audioSequenceNumber_;
pcmAudioBuffer_.consume(opusInputSize_);
}
}
2 changes: 2 additions & 0 deletions SoundRemote/CapturePipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <boost/asio/streambuf.hpp>

#include "AudioUtil.h"
#include "NetDefines.h"

class AudioCapture;
class AudioResampler;
Expand Down Expand Up @@ -46,4 +47,5 @@ class CapturePipe {
std::atomic_bool muted_ = false;
std::unordered_map<Audio::Compression, std::unique_ptr<EncoderOpus>> encoders_;
int opusInputSize_;
Net::Packet::SequenceNumberType audioSequenceNumber_ = 1u;
};
3 changes: 3 additions & 0 deletions SoundRemote/NetDefines.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace Net {
using CompressionType = uint8_t;
using KeyType = uint8_t;
using ModsType = uint8_t;
using SequenceNumberType = uint32_t;
constexpr int ackCustomDataSize = 4;
// Header data
constexpr int headerSize = sizeof SignatureType + sizeof CategoryType + sizeof SizeType;
Expand All @@ -26,6 +27,8 @@ namespace Net {
constexpr int keystrokeSize = sizeof KeyType + sizeof ModsType;
constexpr int ackSize = sizeof RequestIdType + ackCustomDataSize;
constexpr int ackCustomDataOffset = dataOffset + sizeof RequestIdType;
constexpr int sequenceNumberSize = sizeof SequenceNumberType;
constexpr int audioDataOffset = dataOffset + sequenceNumberSize;
struct ConnectData {
ProtocolVersionType protocol;
RequestIdType requestId;
Expand Down
19 changes: 16 additions & 3 deletions SoundRemote/NetUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ namespace {
return data[offset];
}

void writeUInt32B(uint32_t value, const std::span<char>& dest, size_t offset) {
assert((offset + 4) <= dest.size_bytes());
dest[offset] = value >> 24;
dest[offset + 1] = value >> 16;
dest[offset + 2] = value >> 8;
dest[offset + 3] = value >> 0;
}

void writeUInt16B(uint16_t value, const std::span<char>& dest, size_t offset) {
assert((offset + 2) <= dest.size_bytes());
dest[offset] = value >> 8;
Expand Down Expand Up @@ -120,11 +128,16 @@ std::optional<Audio::Compression> Net::compressionFromNetworkValue(Net::Packet::
}
}

std::vector<char> Net::createAudioPacket(Net::Packet::Category category, const std::span<const char>& audioData) {
std::vector<char> packet(Net::Packet::headerSize + audioData.size_bytes());
std::vector<char> Net::createAudioPacket(
Net::Packet::Category category,
Net::Packet::SequenceNumberType sequenceNumber,
const std::span<const char>& audioData
) {
std::vector<char> packet(Net::Packet::headerSize + Net::Packet::sequenceNumberSize + audioData.size_bytes());
std::span<char> packetData{ packet.data(), packet.size() };
writeHeader(category, packetData);
std::copy_n(audioData.data(), audioData.size_bytes(), packet.data() + Net::Packet::dataOffset);
writeUInt32B(sequenceNumber, packetData, Net::Packet::dataOffset);
std::copy_n(audioData.data(), audioData.size_bytes(), packet.data() + Net::Packet::audioDataOffset);
return packet;
}

Expand Down
6 changes: 5 additions & 1 deletion SoundRemote/NetUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ namespace Net {
/// argument is not a valid compression value.</returns>
std::optional<Audio::Compression> compressionFromNetworkValue(Net::Packet::CompressionType compression);

std::vector<char> createAudioPacket(Net::Packet::Category category, const std::span<const char>& audioData);
std::vector<char> createAudioPacket(
Net::Packet::Category category,
Net::Packet::SequenceNumberType sequenceNumber,
const std::span<const char>& audioData
);
std::vector<char> createKeepAlivePacket();
std::vector<char> createDisconnectPacket();
std::vector<char> createAckConnectPacket(Net::Packet::RequestIdType requestId);
Expand Down
15 changes: 9 additions & 6 deletions SoundRemote/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,16 @@ void Server::onClientsUpdate(std::forward_list<ClientInfo> clients) {
clientsCache_ = std::move(newClients);
}

void Server::sendAudio(Audio::Compression compression, std::vector<char> data) {
auto category = Net::Packet::Category::AudioDataOpus;
if (compression == Audio::Compression::none) {
category = Net::Packet::Category::AudioDataUncompressed;
}
void Server::sendAudio(
Audio::Compression compression,
Net::Packet::SequenceNumberType sequenceNumber,
std::vector<char> data
) {
auto category = compression == Audio::Compression::none ?
Net::Packet::Category::AudioDataUncompressed :
Net::Packet::Category::AudioDataOpus;
auto packet = std::make_shared<std::vector<char>>(
Net::createAudioPacket(category, { data.data(), data.size() })
Net::createAudioPacket(category, sequenceNumber, { data.data(), data.size() })
);
for (auto&& address : clientsCache_[compression]) {
send(address, packet);
Expand Down
6 changes: 5 additions & 1 deletion SoundRemote/Server.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ class Server {
Server(int clientPort, int serverPort, boost::asio::io_context& ioContext, std::shared_ptr<Clients> clients);
~Server();
void onClientsUpdate(std::forward_list<ClientInfo> clients);
void sendAudio(Audio::Compression compression, std::vector<char> data);
void sendAudio(
Audio::Compression compression,
Net::Packet::SequenceNumberType sequenceNumber,
std::vector<char> data
);
/*
* Sends disconnect packet to all the clients blocking the current thread.
*
Expand Down
30 changes: 17 additions & 13 deletions Tests/NetUtilTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,29 @@ namespace {

// createAudioPacket
TEST(Net, createAudioPacketUncompressed) {
//std::vector<char> expectedLE = initPacket({ 0x71, 0xA5, 0x20, 0x09, 0, 0xFA, 0xFB, 0x01, 0x12 });
std::vector<char> expectedBE = initPacket({ 0xA5, 0x71, 0x20, 0, 0x09, 0xFA, 0xFB, 0x01, 0x12 });
std::vector<char> expectedBE = initPacket({
0xA5, 0x71, 0x20, 0x00, 0x0D,
0x00, 0xFF, 0x00, 0x00,
0xFA, 0xFB, 0x01, 0x12});

const auto actual = Net::createAudioPacket(Category::AudioDataUncompressed, audioData);
const auto actual = Net::createAudioPacket(Category::AudioDataUncompressed, 16'711'680u, audioData);

EXPECT_EQ(actual, expectedBE);
}

TEST(Net, createAudioPacketOpus) {
//std::vector<char> expectedLE = initPacket({ 0x71, 0xA5, 0x21, 0x09, 0, 0xFA, 0xFB, 0x01, 0x12 });
std::vector<char> expectedBE = initPacket({ 0xA5, 0x71, 0x21, 0, 0x09, 0xFA, 0xFB, 0x01, 0x12 });
std::vector<char> expectedBE = initPacket({
0xA5, 0x71, 0x21, 0x00, 0x0D,
0xEE, 0x6B, 0x28, 0x00,
0xFA, 0xFB, 0x01, 0x12 });

const auto actual = Net::createAudioPacket(Category::AudioDataOpus, audioData);
const auto actual = Net::createAudioPacket(Category::AudioDataOpus, 4'000'000'000u, audioData);

EXPECT_EQ(actual, expectedBE);
}

// createKeepAlivePacket
TEST(Net, createKeepAlivePacket) {
//std::vector<char> expectedLE = initPacket({ 0x71, 0xA5, 0x31, 0x05, 0 });
std::vector<char> expectedBE = initPacket({ 0xA5, 0x71, 0x31, 0 , 0x05 });

const auto actual = Net::createKeepAlivePacket();
Expand All @@ -57,7 +60,6 @@ namespace {

// createDisconnectPacket
TEST(Net, createDisconnectPacket) {
//std::vector<char> expectedLE = initPacket({ 0x71, 0xA5, 0x02, 0x05, 0 });
std::vector<char> expectedBE = initPacket({ 0xA5, 0x71, 0x02, 0, 0x05 });

const auto actual = Net::createDisconnectPacket();
Expand Down Expand Up @@ -95,8 +97,9 @@ namespace {

// createAckConnectPacket
TEST(Net, createAckConnectPacket) {
//std::vector<char> expectedLE = initPacket({ 0x71, 0xA5, 0xF0, 0x0B, 0, 0xD5, 0xDD, Net::protocolVersion, 0, 0, 0 });
std::vector<char> expectedBE = initPacket({ 0xA5, 0x71, 0xF0, 0, 0x0B, 0xDD, 0xD5, Net::protocolVersion, 0, 0, 0 });
std::vector<char> expectedBE = initPacket({
0xA5, 0x71, 0xF0, 0, 0x0B,
0xDD, 0xD5, Net::protocolVersion, 0, 0, 0 });

RequestIdType requestId = 0xDDD5;
const auto actual = Net::createAckConnectPacket(requestId);
Expand All @@ -106,8 +109,9 @@ namespace {

// createAckSetFormatPacket
TEST(Net, createAckSetFormatPacket) {
//std::vector<char> expectedLE = initPacket({ 0x71, 0xA5, 0xF0, 0x0B, 0, 0xF1, 0xF0, 0, 0, 0, 0 });
std::vector<char> expectedBE = initPacket({ 0xA5, 0x71, 0xF0, 0, 0x0B, 0xF0, 0xF1, 0, 0, 0, 0 });
std::vector<char> expectedBE = initPacket({
0xA5, 0x71, 0xF0, 0, 0x0B,
0xF0, 0xF1, 0, 0, 0, 0 });

RequestIdType requestId = 0xF0F1;
const auto actual = Net::createAckSetFormatPacket(requestId);
Expand All @@ -118,7 +122,7 @@ namespace {
// getPacketCategory
TEST(Net, getPacketCategory) {
Net::Packet::Category expected = Net::Packet::Category::Disconnect;
std::array<char, 5> packet{ 0xA5, 0x71, 0x02, 0, 0 };
std::array<char, 5> packet{ static_cast<char>(0xA5), 0x71, 0x02, 0, 0 };

const auto actual = Net::getPacketCategory({ packet.data(), packet.size()});

Expand Down

0 comments on commit f6cbeca

Please sign in to comment.