rpcs3/rpcs3/Emu/Cell/Modules/cellVoice.h
2019-12-03 17:23:00 +03:00

213 lines
5 KiB
C++

#pragma once
#include <unordered_map>
#include <deque>
// libvoice = 0x80310801 - 0x803108ff
// libvoice version 100
// Error Codes
enum CellVoiceError : u32
{
CELL_VOICE_ERROR_ADDRESS_INVALID = 0x8031080a,
CELL_VOICE_ERROR_ARGUMENT_INVALID = 0x80310805,
CELL_VOICE_ERROR_CONTAINER_INVALID = 0x80310806,
CELL_VOICE_ERROR_DEVICE_NOT_PRESENT = 0x80310812,
CELL_VOICE_ERROR_EVENT_DISPATCH = 0x80310811,
CELL_VOICE_ERROR_EVENT_QUEUE = 0x8031080f,
CELL_VOICE_ERROR_GENERAL = 0x80310803,
CELL_VOICE_ERROR_LIBVOICE_INITIALIZED = 0x80310802,
CELL_VOICE_ERROR_LIBVOICE_NOT_INIT = 0x80310801,
CELL_VOICE_ERROR_NOT_IMPLEMENTED = 0x80310809,
CELL_VOICE_ERROR_PORT_INVALID = 0x80310804,
CELL_VOICE_ERROR_RESOURCE_INSUFFICIENT = 0x80310808,
CELL_VOICE_ERROR_SERVICE_ATTACHED = 0x8031080c,
CELL_VOICE_ERROR_SERVICE_DETACHED = 0x8031080b,
CELL_VOICE_ERROR_SERVICE_HANDLE = 0x80310810,
CELL_VOICE_ERROR_SERVICE_NOT_FOUND = 0x8031080d,
CELL_VOICE_ERROR_SHAREDMEMORY = 0x8031080e,
CELL_VOICE_ERROR_TOPOLOGY = 0x80310807,
};
enum CellVoiceAppType : u32
{
CELLVOICE_APPTYPE_GAME_1MB = 1 << 29
};
enum CellVoiceBitRate : u32
{
CELLVOICE_BITRATE_NULL = ~0u,
CELLVOICE_BITRATE_3850 = 3850,
CELLVOICE_BITRATE_4650 = 4650,
CELLVOICE_BITRATE_5700 = 5700,
CELLVOICE_BITRATE_7300 = 7300,
CELLVOICE_BITRATE_14400 = 14400,
CELLVOICE_BITRATE_16000 = 16000,
CELLVOICE_BITRATE_22533 = 22533,
};
enum CellVoiceEventType : u32
{
CELLVOICE_EVENT_DATA_ERROR = 1 << 0,
CELLVOICE_EVENT_PORT_ATTACHED = 1 << 1,
CELLVOICE_EVENT_PORT_DETACHED = 1 << 2,
CELLVOICE_EVENT_SERVICE_ATTACHED = 1 << 3,
CELLVOICE_EVENT_SERVICE_DETACHED = 1 << 4,
CELLVOICE_EVENT_PORT_WEAK_ATTACHED = 1 << 5,
CELLVOICE_EVENT_PORT_WEAK_DETACHED = 1 << 6,
};
enum CellVoicePcmDataType : u32
{
CELLVOICE_PCM_NULL = ~0u,
CELLVOICE_PCM_FLOAT = 0,
CELLVOICE_PCM_FLOAT_LITTLE_ENDIAN = 1,
CELLVOICE_PCM_SHORT = 2,
CELLVOICE_PCM_SHORT_LITTLE_ENDIAN = 3,
CELLVOICE_PCM_INTEGER = 4,
CELLVOICE_PCM_INTEGER_LITTLE_ENDIAN = 5,
};
enum CellVoicePortAttr : u32
{
CELLVOICE_ATTR_ENERGY_LEVEL = 1000,
CELLVOICE_ATTR_VAD = 1001,
CELLVOICE_ATTR_DTX = 1002,
CELLVOICE_ATTR_AUTO_RESAMPLE = 1003,
CELLVOICE_ATTR_LATENCY = 1004,
CELLVOICE_ATTR_SILENCE_THRESHOLD = 1005,
};
enum CellVoicePortState : u32
{
CELLVOICE_PORTSTATE_NULL = ~0u,
CELLVOICE_PORTSTATE_IDLE = 0,
CELLVOICE_PORTSTATE_READY = 1,
CELLVOICE_PORTSTATE_BUFFERING = 2,
CELLVOICE_PORTSTATE_RUNNING = 3,
};
enum CellVoicePortType : u32
{
CELLVOICE_PORTTYPE_NULL = ~0u,
CELLVOICE_PORTTYPE_IN_MIC = 0,
CELLVOICE_PORTTYPE_IN_PCMAUDIO = 1,
CELLVOICE_PORTTYPE_IN_VOICE = 2,
CELLVOICE_PORTTYPE_OUT_PCMAUDIO = 3,
CELLVOICE_PORTTYPE_OUT_VOICE = 4,
CELLVOICE_PORTTYPE_OUT_SECONDARY = 5,
};
enum CellVoiceSamplingRate : u32
{
CELLVOICE_SAMPLINGRATE_NULL = ~0u,
CELLVOICE_SAMPLINGRATE_16000 = 16000,
};
enum CellVoiceVersionCheck : u32
{
CELLVOICE_VERSION_100 = 100
};
// Definitions
enum
{
CELLVOICE_MAX_IN_VOICE_PORT = 32,
CELLVOICE_MAX_OUT_VOICE_PORT = 4,
CELLVOICE_GAME_1MB_MAX_IN_VOICE_PORT = 8,
CELLVOICE_GAME_1MB_MAX_OUT_VOICE_PORT = 2,
CELLVOICE_MAX_PORT = 128,
CELLVOICE_INVALID_PORT_ID = 0xff,
};
struct CellVoiceBasePortInfo // aligned(64)
{
be_t<CellVoicePortType> portType;
be_t<CellVoicePortState> state;
be_t<u16> numEdge;
vm::bptr<u32> pEdge;
be_t<u32> numByte;
be_t<u32> frameSize;
};
struct CellVoiceInitParam // aligned(32)
{
be_t<CellVoiceEventType> eventMask;
be_t<CellVoiceVersionCheck> version;
be_t<s32> appType;
u8 reserved[32 - sizeof(s32) * 3];
};
struct CellVoicePCMFormat
{
u8 numChannels;
u8 sampleAlignment;
be_t<CellVoicePcmDataType> dataType;
be_t<CellVoiceSamplingRate> sampleRate;
};
struct CellVoicePortParam // aligned(64)
{
be_t<CellVoicePortType> portType;
be_t<u16> threshold;
be_t<u16> bMute;
be_t<f32> volume;
union
{
struct
{
be_t<CellVoiceBitRate> bitrate;
} voice;
struct
{
be_t<u32> bufSize;
CellVoicePCMFormat format;
} pcmaudio;
struct
{
be_t<u32> playerId;
} device;
};
};
struct CellVoiceStartParam // aligned(32)
{
be_t<u32> container;
u8 reserved[32 - sizeof(s32) * 1];
};
struct voice_manager
{
struct port_t
{
s32 state = CELLVOICE_PORTSTATE_NULL;
CellVoicePortParam info;
};
// See cellVoiceCreatePort
u32 id_ctr = 0;
// For cellVoiceSetNotifyEventQueue
u32 port_source = 0;
std::unordered_map<u16, port_t> ports;
std::unordered_map<u64, std::deque<u64>> queue_keys;
bool voice_service_started = false;
port_t* access_port(u32 id)
{
// Upper 16 bits are ignored
auto pos = ports.find(static_cast<u16>(id));
if (pos == ports.end())
{
return nullptr;
}
return &pos->second;
}
void reset();
shared_mutex mtx;
atomic_t<bool> is_init{ false };
};