Get SE-compatible voice transmission working

This commit is contained in:
Kae 2023-07-16 23:04:09 +10:00
parent da098c7b48
commit 848b11399f
5 changed files with 22 additions and 11 deletions

View File

@ -345,7 +345,10 @@ public:
m_sdlAudioInputDevice = SDL_OpenAudioDevice(name, 1, &desired, &obtained, 0); m_sdlAudioInputDevice = SDL_OpenAudioDevice(name, 1, &desired, &obtained, 0);
if (m_sdlAudioInputDevice) { if (m_sdlAudioInputDevice) {
Logger::info("Opened audio input device '{}'", SDL_GetAudioDeviceName(m_sdlAudioInputDevice, 1)); if (name)
Logger::info("Opened audio input device '{}'", name);
else
Logger::info("Opened default audio input device");
SDL_PauseAudioDevice(m_sdlAudioInputDevice, 0); SDL_PauseAudioDevice(m_sdlAudioInputDevice, 0);
} }
else else
@ -356,7 +359,7 @@ public:
bool closeAudioInputDevice() { bool closeAudioInputDevice() {
if (m_sdlAudioInputDevice) { if (m_sdlAudioInputDevice) {
Logger::info("Closing audio input device '{}'", SDL_GetAudioDeviceName(m_sdlAudioInputDevice, 1)); Logger::info("Closing audio input device");
SDL_CloseAudioDevice(m_sdlAudioInputDevice); SDL_CloseAudioDevice(m_sdlAudioInputDevice);
m_sdlAudioInputDevice = 0; m_sdlAudioInputDevice = 0;
return true; return true;

View File

@ -16,7 +16,7 @@
#include "StarRootLoader.hpp" #include "StarRootLoader.hpp"
#include "StarInput.hpp" #include "StarInput.hpp"
#include "StarVoice.hpp" #include "StarVoice.hpp"
#include "StarCurve25519.hpp"
#include "StarInterfaceLuaBindings.hpp" #include "StarInterfaceLuaBindings.hpp"
#include "StarInputLuaBindings.hpp" #include "StarInputLuaBindings.hpp"
@ -855,9 +855,8 @@ void ClientApplication::updateRunning() {
m_voice->setInput(m_input->bindHeld("opensb", "pushToTalk")); m_voice->setInput(m_input->bindHeld("opensb", "pushToTalk"));
DataStreamBuffer voiceData; DataStreamBuffer voiceData;
voiceData.setByteOrder(ByteOrder::LittleEndian); voiceData.setByteOrder(ByteOrder::LittleEndian);
voiceData.writeBytes(VoiceBroadcastPrefix.utf8Bytes()); //voiceData.writeBytes(VoiceBroadcastPrefix.utf8Bytes()); transmitting with SE compat for now
bool needstoSendVoice = m_voice->send(voiceData, 5000); bool needstoSendVoice = m_voice->send(voiceData, 5000);
m_universeClient->update(); m_universeClient->update();
if (checkDisconnection()) if (checkDisconnection())
@ -881,8 +880,13 @@ void ClientApplication::updateRunning() {
} }
if (worldClient->inWorld()) { if (worldClient->inWorld()) {
if (needstoSendVoice) if (needstoSendVoice) {
worldClient->sendSecretBroadcast(StringView(voiceData.ptr(), voiceData.size())); auto signature = Curve25519::sign(voiceData.ptr(), voiceData.size());
std::string_view signatureView((char*)signature.data(), signature.size());
std::string_view audioDataView(voiceData.ptr(), voiceData.size());
auto broadcast = strf("data\0voice\0{}{}"s, signatureView, audioDataView);
worldClient->sendSecretBroadcast(broadcast, true);
}
m_voice->setLocalSpeaker(worldClient->connection()); m_voice->setLocalSpeaker(worldClient->connection());
} }
worldClient->setInteractiveHighlightMode(isActionTaken(InterfaceAction::ShowLabels)); worldClient->setInteractiveHighlightMode(isActionTaken(InterfaceAction::ShowLabels));

View File

@ -269,7 +269,6 @@ void Voice::mix(int16_t* buffer, size_t frameCount, unsigned channels) {
speaker->decibelLevel = getAudioLoudness(speakerBuffer.data(), samples); speaker->decibelLevel = getAudioLoudness(speakerBuffer.data(), samples);
auto channelVolumes = speaker->channelVolumes.load(); auto channelVolumes = speaker->channelVolumes.load();
for (size_t i = 0; i != samples; ++i) for (size_t i = 0; i != samples; ++i)
sharedBuffer[i] += (int32_t)(speakerBuffer[i]) * channelVolumes[i % 2]; sharedBuffer[i] += (int32_t)(speakerBuffer[i]) * channelVolumes[i % 2];
} }
@ -366,6 +365,8 @@ bool Voice::receive(SpeakerPtr speaker, std::string_view view) {
uint32_t opusLength = 0; uint32_t opusLength = 0;
while (!reader.atEnd()) { while (!reader.atEnd()) {
reader >> opusLength; reader >> opusLength;
if (reader.pos() + opusLength > reader.size())
throw VoiceException("Opus packet length goes past end of buffer"s, false);
auto opusData = (unsigned char*)reader.ptr() + reader.pos(); auto opusData = (unsigned char*)reader.ptr() + reader.pos();
reader.seek(opusLength, IOSeek::Relative); reader.seek(opusLength, IOSeek::Relative);
@ -536,7 +537,7 @@ void Voice::thread() {
{ {
MutexLocker lock(m_encodeMutex); MutexLocker lock(m_encodeMutex);
m_encodedChunks.emplace_back(move(encoded)); // reset takes ownership of data buffer m_encodedChunks.emplace_back(move(encoded));
m_encodedChunksLength += encodedSize; m_encodedChunksLength += encodedSize;
encoded = ByteArray(VOICE_MAX_PACKET_SIZE, 0); encoded = ByteArray(VOICE_MAX_PACKET_SIZE, 0);

View File

@ -171,7 +171,7 @@ private:
int64_t m_lastThresholdTime = 0; int64_t m_lastThresholdTime = 0;
int64_t m_nextSaveTime = 0; int64_t m_nextSaveTime = 0;
bool m_enabled = true; bool m_enabled = true;
bool m_inputEnabled = true; bool m_inputEnabled = false;
int m_deviceChannels = 1; int m_deviceChannels = 1;
bool m_deviceOpen = false; bool m_deviceOpen = false;

View File

@ -966,7 +966,10 @@ void WorldClient::update() {
// Secret broadcasts are transmitted through DamageNotifications for vanilla server compatibility. // Secret broadcasts are transmitted through DamageNotifications for vanilla server compatibility.
// Because DamageNotification packets are spoofable, we have to sign the data so other clients can validate that it is legitimate. // Because DamageNotification packets are spoofable, we have to sign the data so other clients can validate that it is legitimate.
auto& publicKey = Curve25519::publicKey(); auto& publicKey = Curve25519::publicKey();
m_mainPlayer->setSecretProperty(SECRET_BROADCAST_PUBLIC_KEY, String((const char*)publicKey.data(), publicKey.size())); String publicKeyString((const char*)publicKey.data(), publicKey.size());
m_mainPlayer->setSecretProperty(SECRET_BROADCAST_PUBLIC_KEY, publicKeyString);
// Temporary: Backwards compatibility with StarExtensions
m_mainPlayer->effectsAnimator()->setGlobalTag("\0SE_VOICE_SIGNING_KEY"s, publicKeyString);
++m_currentStep; ++m_currentStep;
//m_interpolationTracker.update(m_currentStep); //m_interpolationTracker.update(m_currentStep);