first commit
This commit is contained in:
215
Minecraft.Client/Orbis/Network/SonyVoiceChat_Orbis.h
Normal file
215
Minecraft.Client/Orbis/Network/SonyVoiceChat_Orbis.h
Normal file
@@ -0,0 +1,215 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <voice_qos.h>
|
||||
#include "Common/Network/Sony/SQRNetworkPlayer.h"
|
||||
|
||||
static const int sc_maxVoiceDataSize = 2048;
|
||||
|
||||
|
||||
class VoicePacket
|
||||
{
|
||||
static const int MAX_LOCAL_PLAYER_COUNT = 4;
|
||||
|
||||
public:
|
||||
struct Flags
|
||||
{
|
||||
bool m_bTalking : 1;
|
||||
bool m_bHasMicConnected : 1;
|
||||
};
|
||||
|
||||
Flags m_localPlayerFlags[MAX_LOCAL_PLAYER_COUNT];
|
||||
uint32_t m_frameSendIndex;
|
||||
uint32_t m_numFrames;
|
||||
uint32_t m_checkSum;
|
||||
uint32_t m_playerIndexFlags;
|
||||
char m_data[sc_maxVoiceDataSize];
|
||||
|
||||
static int getPacketSize(int dataSize) { return (uint64_t)&((VoicePacket*)0)->m_data[dataSize];}
|
||||
void setChecksum(int dataSize)
|
||||
{
|
||||
m_checkSum = 0;
|
||||
for(int i=0;i<dataSize;i++)
|
||||
m_checkSum += m_data[i];
|
||||
}
|
||||
void verifyData(int packetSize, int frameSize)
|
||||
{
|
||||
if(m_numFrames == 0)
|
||||
return;
|
||||
int dataSize = m_numFrames*frameSize;
|
||||
assert(packetSize == getPacketSize(dataSize));
|
||||
int checkSum = 0;
|
||||
for(int i=0;i<dataSize;i++)
|
||||
checkSum += m_data[i];
|
||||
assert(checkSum == m_checkSum);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// read-write-safe ring buffer implementation: does not use mutex protection
|
||||
// the writer thread changes pointer <buf_free>,
|
||||
// the reader thread changes pointer <buf_full>
|
||||
class RingBuffer
|
||||
{
|
||||
public:
|
||||
RingBuffer(int sizeBytes);
|
||||
~RingBuffer() { delete buffer; }
|
||||
void Reset(void) { buf_full = buf_free = 0; }
|
||||
unsigned int DataSize(void) { return (buf_free - buf_full); }
|
||||
int Write(char* data, int len_);
|
||||
int Read(char* data, int max_bytes_);
|
||||
int getDataSize() { return buf_free - buf_full; }
|
||||
void ResetByWriter(void) { buf_free = buf_full; }
|
||||
void ResetByReader(void) { buf_full = buf_free; }
|
||||
|
||||
private:
|
||||
char* buffer;
|
||||
unsigned int buf_size;
|
||||
unsigned int buf_full;
|
||||
unsigned int buf_free;
|
||||
};
|
||||
|
||||
|
||||
static const int sc_ringBufferSize = 16384;
|
||||
|
||||
class SQRLocalVoiceDevice
|
||||
{
|
||||
public:
|
||||
uint32_t m_headsetPort;
|
||||
uint32_t m_microphonePort;
|
||||
uint8_t m_localConnections[4]; // connection between this devices mic and other local player's headsets
|
||||
bool m_bChatRestricted;
|
||||
bool m_bFlaggedForShutdown;
|
||||
SceUserServiceUserId m_localUserID;
|
||||
|
||||
public:
|
||||
SQRLocalVoiceDevice()
|
||||
: m_headsetPort(SCE_VOICE_INVALID_PORT_ID)
|
||||
, m_microphonePort(SCE_VOICE_INVALID_PORT_ID)
|
||||
, m_localUserID(SCE_USER_SERVICE_USER_ID_INVALID)
|
||||
{
|
||||
for(int i=0;i<4;i++)
|
||||
m_localConnections[i] = 0;
|
||||
}
|
||||
|
||||
void init(SceUserServiceUserId localUserID, bool bChatRestricted);
|
||||
void flagForShutdown() { m_bFlaggedForShutdown = true;}
|
||||
void shutdownWhenFlagged();
|
||||
bool isValid() { return m_localUserID != SCE_USER_SERVICE_USER_ID_INVALID; }
|
||||
// void setBitRate()
|
||||
// {
|
||||
// int err = sceVoiceSetBitRate(uint32_t portId,
|
||||
// SceVoiceBitRate bitrate
|
||||
// );
|
||||
// }
|
||||
};
|
||||
|
||||
#define VOICE_ENCODED_FORMAT SCE_VOICE_BITRATE_7300
|
||||
|
||||
|
||||
|
||||
class SQRVoiceConnection
|
||||
{
|
||||
static const int MAX_LOCAL_PLAYER_COUNT = 4;
|
||||
static const int SNP_MAX_PAYLOAD = 1346; // This is the default RUDP payload size - if we want to change this we'll need to use cellRudpSetOption to set something else & adjust segment size
|
||||
class QueuedSendBlock
|
||||
{
|
||||
public:
|
||||
unsigned char *start;
|
||||
unsigned char *end;
|
||||
unsigned char *current;
|
||||
};
|
||||
|
||||
std::queue<QueuedSendBlock> m_sendQueue;
|
||||
CRITICAL_SECTION m_csQueue;
|
||||
|
||||
public:
|
||||
int m_rudpCtx;
|
||||
bool m_bConnected;
|
||||
uint32_t m_voiceInPort; // 1 input port per connection, incoming UDP packets are written to each of these, and then they're connected out to all headsets
|
||||
int m_headsetConnectionMask; // 1 bit per player, if the headset connection has been made
|
||||
RingBuffer m_playRingBuffer;
|
||||
SceNpMatching2RoomMemberId m_remoteRoomMemberId; // Assigned by Matching2 lib, we can use to indicate which machine this player belongs to (note - 16 bits)
|
||||
std::queue<VoicePacket> m_receivedVoicePackets;
|
||||
CRITICAL_SECTION m_csPacketQueue;
|
||||
VoicePacket::Flags m_remotePlayerFlags[MAX_LOCAL_PLAYER_COUNT];
|
||||
uint32_t m_nextExpectedFrameIndex;
|
||||
bool m_bFlaggedForShutdown;
|
||||
SQRVoiceConnection(int rudpCtx, SceNpMatching2RoomMemberId remoteRoomMemberId);
|
||||
~SQRVoiceConnection();
|
||||
|
||||
void SendInternal(const void *data, unsigned int dataSize);
|
||||
void SendMoreInternal();
|
||||
void readRemoteData();
|
||||
bool getNextPacket(VoicePacket& packet);
|
||||
void addPacket(VoicePacket& packet);
|
||||
|
||||
|
||||
};
|
||||
|
||||
class SonyVoiceChat_Orbis
|
||||
{
|
||||
public:
|
||||
|
||||
static void init();
|
||||
static void start();
|
||||
static void shutdown();
|
||||
static void tick();
|
||||
static void checkFinished();
|
||||
static void setEnabled(bool bEnabled);
|
||||
static bool hasMicConnected(SQRNetworkPlayer* pNetPlayer);
|
||||
static bool isTalking(SQRNetworkPlayer* pNetPlayer);
|
||||
static void mute(bool bMute); //Turn chat audio on or off
|
||||
static void mutePlayer(const SceNpMatching2RoomMemberId member_id, bool bMute); //Turn chat audio from a specified player on or off;
|
||||
static void muteLocalPlayer(bool bMute); //Turn microphone input on or off;
|
||||
|
||||
static bool isMuted();
|
||||
static bool isMutedPlayer(const PlayerUID& memberUID);
|
||||
static bool isMutedLocalPlayer(); //Turn microphone input on or off;
|
||||
|
||||
static void initLocalPlayer(int playerIndex);
|
||||
|
||||
static SQRVoiceConnection* addRemoteConnection(int RudpCxt, SceNpMatching2RoomMemberId peerMemberId);
|
||||
static void connectPlayer(SQRVoiceConnection* pConnection, int playerIndex);
|
||||
static void connectPlayerToAll(int playerIndex);
|
||||
static void disconnectLocalPlayer(int localIdx);
|
||||
static void disconnectRemoteConnection( SQRVoiceConnection* pVoice );
|
||||
|
||||
static void VoiceEventCallback( SceVoiceEventData* pEvent );
|
||||
|
||||
static std::vector<SQRVoiceConnection*> m_remoteConnections;
|
||||
static void connectPorts(uint32_t inPort, uint32_t outPort);
|
||||
static void disconnectPorts(uint32_t inPort, uint32_t outPort);
|
||||
static void makeLocalConnections();
|
||||
static void breakLocalConnections(int playerIdx);
|
||||
|
||||
static void sendAllVoiceData();
|
||||
static void playAllReceivedData();
|
||||
|
||||
static void sendPCMMicData();
|
||||
static SQRVoiceConnection* getVoiceConnectionFromRoomMemberID(SceNpMatching2RoomMemberId roomMemberID);
|
||||
|
||||
static SQRVoiceConnection* GetVoiceConnectionFromRudpCtx(int RudpCtx);
|
||||
static void setConnected(int RudpCtx);
|
||||
|
||||
private:
|
||||
static const int MAX_LOCAL_PLAYER_COUNT = 4;
|
||||
|
||||
static bool m_bVoiceStarted;
|
||||
static int m_numLocalDevicesConnected;
|
||||
static SQRLocalVoiceDevice m_localVoiceDevices[MAX_LOCAL_PLAYER_COUNT];
|
||||
|
||||
static uint32_t m_voiceOutPort; // single output port that all local devices are mixed to, and then sent out to all other remote machines
|
||||
|
||||
static RingBuffer m_recordRingBuffer;
|
||||
static RingBuffer m_playRingBuffer;
|
||||
static VoicePacket::Flags m_localPlayerFlags[MAX_LOCAL_PLAYER_COUNT];
|
||||
static bool m_forceSendPacket; // force a packet across the network, even if there's no data, so we can update flags
|
||||
static bool m_bInitialised;
|
||||
static CRITICAL_SECTION m_csRemoteConnections;
|
||||
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user