From b691c43c44ff180d10e7d4a9afc83b98551ff586 Mon Sep 17 00:00:00 2001 From: daoge_cmd <3523206925@qq.com> Date: Sun, 1 Mar 2026 12:16:08 +0800 Subject: Initial commit --- Minecraft.Client/PS3/Network/SonyVoiceChat.cpp | 764 +++++++++++++++++++++++++ 1 file changed, 764 insertions(+) create mode 100644 Minecraft.Client/PS3/Network/SonyVoiceChat.cpp (limited to 'Minecraft.Client/PS3/Network/SonyVoiceChat.cpp') diff --git a/Minecraft.Client/PS3/Network/SonyVoiceChat.cpp b/Minecraft.Client/PS3/Network/SonyVoiceChat.cpp new file mode 100644 index 00000000..721ddf26 --- /dev/null +++ b/Minecraft.Client/PS3/Network/SonyVoiceChat.cpp @@ -0,0 +1,764 @@ +#include "stdafx.h" + + + + +/* SCE CONFIDENTIAL +PlayStation(R)3 Programmer Tool Runtime Library 430.001 +* Copyright (C) 2008 Sony Computer Entertainment Inc. +* All Rights Reserved. +*/ +#include "SonyVoiceChat.h" +#include /* inet_ntoa() */ + +/* for displaying extra information */ +#ifndef _CONTENT_PACKAGE +#define AVC2_GAME_DEBUG +#endif + +#ifdef AVC2_GAME_DEBUG +#define INF(...) printf( "INF:" __VA_ARGS__ ) +#define ERR(...) printf( "ERR:" __VA_ARGS__ ) +#else +#define INF(...) +#define ERR(...) +#endif + +#define UNUSED_VARIABLE(x) (void)(x) + +//#define DISABLE_VOICE_CHAT + +static CellSysutilAvc2InitParam g_chat_avc2param; + +EAVCEvent SonyVoiceChat::sm_event = AVC_EVENT_EPSILON; +EAVCState SonyVoiceChat::sm_state = AVC_STATE_IDLE; +SQRNetworkManager_PS3* SonyVoiceChat::sm_pNetworkManager; +bool SonyVoiceChat::sm_bEnabled = true; +uint8_t SonyVoiceChat::sm_micStatus = CELL_AVC2_MIC_STATUS_UNKNOWN; +bool SonyVoiceChat::sm_bLoaded = false; +bool SonyVoiceChat::sm_bUnloading = false; +unordered_map SonyVoiceChat::sm_bTalkingMap; +bool SonyVoiceChat::sm_bCanStart = false; +bool SonyVoiceChat::sm_isChatRestricted = false; +int SonyVoiceChat::sm_currentBitrate = 28000; + +void SonyVoiceChat::init( SQRNetworkManager_PS3* pNetMan ) +{ + if(sm_state != AVC_STATE_IDLE) + return; + + sm_pNetworkManager = pNetMan; + setState(AVC_STATE_CHAT_INIT); + ProfileManager.GetChatAndContentRestrictions(0,false,&sm_isChatRestricted,NULL,NULL); +} + +void SonyVoiceChat::shutdown() +{ + if( sm_state == AVC_STATE_IDLE || + sm_state == AVC_STATE_CHAT_LEAVE || + sm_state == AVC_STATE_CHAT_UNLOAD || + sm_state == AVC_STATE_CHAT_RESET ) + { + // we're either shut down already, or in the process + return; + } + + setEvent(AVC_EVENT_EXIT_GAME); +} + +void SonyVoiceChat::setEnabled( bool bEnabled ) +{ + if(sm_bEnabled != bEnabled) + { + if(sm_bCanStart) + { + if(bEnabled) + startStream(); + else + stopStream(); + } + sm_bEnabled = bEnabled; + } +} + + +int SonyVoiceChat::eventcb_load(CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata) +{ + int ret = CELL_OK; + + UNUSED_VARIABLE( event_param ); + UNUSED_VARIABLE( userdata ); + + if( event_id == CELL_AVC2_EVENT_LOAD_SUCCEEDED ) + { + INF( "CELL_AVC2_EVENT_LOAD_SUCCEEDED(0x%x), param(0x%x)\n", event_id, (int)event_param ); + setEvent(AVC_EVENT_CHAT_LOAD_SUCCEEDED); + sm_bLoaded = true; + + // set the packet contention value here + CellSysutilAvc2Attribute attr; + memset( &attr, 0x00, sizeof(attr) ); + attr.attr_id = CELL_SYSUTIL_AVC2_ATTRIBUTE_VOICE_PACKET_CONTENTION; + attr.attr_param.int_param = 3; + int ret = cellSysutilAvc2SetAttribute(&attr); + if( ret != CELL_OK ) + { + app.DebugPrintf("CELL_SYSUTIL_AVC2_ATTRIBUTE_VOICE_PACKET_CONTENTION failed !!! 0x%08x\n", ret); + } + + } + else /* if( event_id == CELL_AVC2_EVENT_LOAD_FAILED ) */ + { + INF( "CELL_AVC2_EVENT_LOAD_FAILED(0x%x), param(0x%x)\n", event_id, (int)event_param ); + setEvent(AVC_EVENT_CHAT_LOAD_FAILED); + } + return ret; +} + +int SonyVoiceChat::eventcb_join(CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata) +{ + int ret = CELL_OK; + + UNUSED_VARIABLE( event_param ); + UNUSED_VARIABLE( userdata ); + + if( event_id == CELL_AVC2_EVENT_JOIN_SUCCEEDED ) + { + INF( "CELL_AVC2_EVENT_JOIN_SUCCEEDED(0x%x), param(0x%x)\n", event_id, (int)event_param ); + setEvent(AVC_EVENT_CHAT_JOIN_SUCCEEDED); + } + else /* if( event_id == CELL_AVC2_EVENT_JOIN_FAILED ) */ + { + INF( "CELL_AVC2_EVENT_JOIN_FAILED(0x%x), param(0x%x)\n", event_id, (int)event_param ); + setEvent(AVC_EVENT_ERROR); + } + sm_bTalkingMap.clear(); + return ret; +} + +int SonyVoiceChat::eventcb_leave( CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata) +{ + int ret = CELL_OK; + + UNUSED_VARIABLE( event_param ); + UNUSED_VARIABLE( userdata ); + + if( event_id == CELL_AVC2_EVENT_LEAVE_SUCCEEDED ) + { + INF( "CELL_AVC2_EVENT_LEAVE_SUCCEEDED(0x%x), param(0x%x)\n", event_id, (int)event_param ); + setState(AVC_STATE_CHAT_LEAVE); + setEvent(AVC_EVENT_CHAT_LEAVE_SUCCEEDED); + } + else /* if( event_id == CELL_AVC2_EVENT_LEAVE_FAILED ) */ + { + INF( "CELL_AVC2_EVENT_LEAVE_FAILED(0x%x), param(0x%x)\n", event_id, (int)event_param ); + setState(AVC_STATE_CHAT_LEAVE); + setEvent(AVC_EVENT_ERROR); + } + return ret; +} + +int SonyVoiceChat::eventcb_unload(CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata) +{ + int ret = CELL_OK; + + UNUSED_VARIABLE( event_param ); + UNUSED_VARIABLE( userdata ); + + if( event_id == CELL_AVC2_EVENT_UNLOAD_SUCCEEDED ) + { + INF( "CELL_AVC2_EVENT_UNLOAD_SUCCEEDED(0x%x), param(0x%x)\n", event_id, (int)event_param ); + setEvent(AVC_EVENT_CHAT_UNLOAD_SUCCEEDED); + sm_bLoaded = false; + sm_bUnloading = false; + } + else /* if( event_id == CELL_AVC2_EVENT_UNLOAD_FAILED ) */ + { + INF( "CELL_AVC2_EVENT_UNLOAD_FAILED(0x%x), param(0x%x)\n", event_id, (int)event_param ); + setEvent(AVC_EVENT_ERROR); + } + return ret; +} + +int SonyVoiceChat::eventcb_voiceDetected(CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata) +{ + UNUSED_VARIABLE( userdata ); + +// To the upper 32 bits, the room member ID of the player is passed. +// In the lower 32 bits, a value of 0 (mute) or a value between 1 (low volume) +// and 10 (high volume) is passed as the audio signal value when the notification +// method is the level method, or a value of 1 (start of speaking) or 0 (end of speaking) +// is stored when the notification method is the trigger method. + + SceNpMatching2RoomMemberId roomMemberID = (SceNpMatching2RoomMemberId)(event_param >> 32); + uint32_t volume = (uint32_t)(event_param & 0xffffffff); + +// The precision of voice detection is not very high. Since the audio signal values may +// always be relatively high depending on the audio input device and the noise level in the +// room, you should set a large reference value for determining whether or not a player is +// speaking. Relatively good results can be obtained when an audio signal value of at +// least 9 is used to determine if a player is speaking. + bool bTalking = false; + if(volume >= 9) + bTalking = true; + + sm_bTalkingMap[roomMemberID] = bTalking; + return CELL_OK; +} + +/* Callback function for handling AV Chat2 Utility events */ +void SonyVoiceChat::eventcb( CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata) +{ + static struct _cb_func_tbl + { + CellSysutilAvc2EventId event; + int (*func)( CellSysutilAvc2EventId event_id, + CellSysutilAvc2EventParam event_param, + void *userdata ); + } event_tbl[] = + { + { CELL_AVC2_EVENT_LOAD_SUCCEEDED, eventcb_load }, + { CELL_AVC2_EVENT_LOAD_FAILED, eventcb_load }, + { CELL_AVC2_EVENT_JOIN_SUCCEEDED, eventcb_join }, + { CELL_AVC2_EVENT_JOIN_FAILED, eventcb_join }, + { CELL_AVC2_EVENT_LEAVE_SUCCEEDED, eventcb_leave }, + { CELL_AVC2_EVENT_LEAVE_FAILED, eventcb_leave }, + { CELL_AVC2_EVENT_UNLOAD_SUCCEEDED, eventcb_unload }, + { CELL_AVC2_EVENT_UNLOAD_FAILED, eventcb_unload }, + { CELL_AVC2_EVENT_SYSTEM_NEW_MEMBER_JOINED, NULL }, + { CELL_AVC2_EVENT_SYSTEM_MEMBER_LEFT, NULL }, + { CELL_AVC2_EVENT_SYSTEM_SESSION_ESTABLISHED, NULL }, + { CELL_AVC2_EVENT_SYSTEM_SESSION_CANNOT_ESTABLISHED,NULL }, + { CELL_AVC2_EVENT_SYSTEM_SESSION_DISCONNECTED, NULL }, + { CELL_AVC2_EVENT_SYSTEM_VOICE_DETECTED, eventcb_voiceDetected }, + + }; + + int ret = 0; + for( unsigned int i=0; im_matchingContext, + SYS_MEMORY_CONTAINER_ID_INVALID, + eventcb, + NULL, + &g_chat_avc2param ); + if( ret != CELL_OK ) + { + ERR( "cellSysutilAvc2LoadAsync: ret=0x%x\n", ret ); + setEvent(AVC_EVENT_ERROR); + return ret; + } + return ret; +} + +int SonyVoiceChat::join() +{ + int ret = CELL_OK; + + INF("---------------------------------------------------\n"); + INF("| cellSysutilAvc2JoinChatRequest \n"); + INF("---------------------------------------------------\n"); + ret = cellSysutilAvc2JoinChatRequest( &sm_pNetworkManager->m_room ); + if( ret != CELL_OK ) + { + ERR( "cellSysutilAvc2JoinChatRequest: ret=0x%x\n", ret ); + setEvent(AVC_EVENT_ERROR); + return ret; + } + return ret; +} + +int SonyVoiceChat::leave() +{ + int ret = CELL_OK; + + INF("-----------------------------------\n"); + INF("| cellSysutilAvc2LeaveChatRequest |\n"); + INF("-----------------------------------\n"); + ret = cellSysutilAvc2LeaveChatRequest(); + if( ret != CELL_OK ) + { + ERR( "cellSysutilAvc2LeaveChatRequest() = 0x%x\n", ret ); + setEvent(AVC_EVENT_ERROR); + return ret; + } + return ret; +} + +int SonyVoiceChat::unload() +{ + int ret = CELL_OK; + + INF("------------------------------\n"); + INF("| cellSysutilAvc2UnloadAsync |\n"); + INF("------------------------------\n"); + + ret = cellSysutilAvc2UnloadAsync(); + if( ret != CELL_OK ) + { + ERR( "cellSysutilAvcUnloadAsync() = 0x%x\n", ret ); + setEvent(AVC_EVENT_ERROR); + return ret; + } + sm_bUnloading = true; + return ret; +} + +int SonyVoiceChat::start() +{ + sm_bCanStart = (sm_isChatRestricted == false); + + int ret = CELL_OK; + if(sm_bEnabled) + ret = startStream(); + + return ret; +} + +int SonyVoiceChat::stop() +{ + sm_bCanStart = false; + + int ret = CELL_OK; + if(sm_bEnabled) + ret = stopStream(); + + setEvent(AVC_EVENT_CHAT_SESSION_STOPPED); + + + return ret; +} + +int SonyVoiceChat::startStream() +{ + int ret = CELL_OK; + + INF("---------------------------------\n"); + INF("| cellSysutilAvc2StartStreaming |\n"); + INF("---------------------------------\n"); + ret = cellSysutilAvc2StartStreaming(); + if( ret != CELL_OK ) + { + ERR( "cellSysutilAvc2StartStreaming: ret=0x%x\n", ret ); + } + + ret = cellSysutilAvc2StartVoiceDetection(); + if( ret != CELL_OK ) + { + ERR( "cellSysutilAvc2StartVoiceDetection: ret=0x%x\n", ret ); + } + return ret; +} + +int SonyVoiceChat::stopStream() +{ + int ret = cellSysutilAvc2StopVoiceDetection(); + if( ret != CELL_OK ) + { + ERR( "cellSysutilAvc2StopVoiceDetection: ret=0x%x\n", ret ); + } + + INF("--------------------------------\n"); + INF("| cellSysutilAvc2StopStreaming |\n"); + INF("--------------------------------\n"); + ret = cellSysutilAvc2StopStreaming(); + if( ret != CELL_OK ) + { + ERR( "cellSysutilAvc2StopStreaming: ret=0x%x\n", ret ); + } + return ret; +} + +int SonyVoiceChat::initialize(void) +{ + int ret; + + /* Must use cellSysutilAvc2InitParam() for clearing CellSysutilAvc2InitParam struct*/ + ret = cellSysutilAvc2InitParam(CELL_SYSUTIL_AVC2_INIT_PARAM_VERSION, &g_chat_avc2param); + if( ret != CELL_OK ) + { + ERR( "cellSysutilAvc2InitParam failed (0x%x)\n", ret ); + return ret; + } + + /* Setting application specific parameters */ + g_chat_avc2param.media_type = CELL_SYSUTIL_AVC2_VOICE_CHAT; + g_chat_avc2param.max_players = AVC2_PARAM_DEFAULT_MAX_PLAYERS; + g_chat_avc2param.voice_param.voice_quality = CELL_SYSUTIL_AVC2_VOICE_QUALITY_NORMAL; + g_chat_avc2param.voice_param.max_speakers = AVC2_PARAM_DEFAULT_MAX_SPEAKERS; + g_chat_avc2param.spu_load_average = 50; + g_chat_avc2param.streaming_mode.mode = CELL_SYSUTIL_AVC2_STREAMING_MODE_NORMAL; + + setEvent(AVC_EVENT_CHAT_INIT_SUCCEEDED); + setState(AVC_STATE_CHAT_INIT); + + return ret; +} + +int SonyVoiceChat::finalize(void) +{ + setEvent(AVC_EVENT_CHAT_FINALIZE_SUCCEEDED); + return CELL_OK; +} + +void SonyVoiceChat::tick() +{ +#ifdef DISABLE_VOICE_CHAT + return; +#endif + + static state_transition_table tbl[] = + { + /* now state event func after the transition state */ + { AVC_STATE_CHAT_INIT, AVC_EVENT_EPSILON, initialize, AVC_STATE_CHAT_INIT }, + { AVC_STATE_CHAT_INIT, AVC_EVENT_EXIT_GAME, invoke_epsilon_event, AVC_STATE_CHAT_RESET }, + { AVC_STATE_CHAT_INIT, AVC_EVENT_ERROR, invoke_epsilon_event, AVC_STATE_CHAT_RESET }, + { AVC_STATE_CHAT_INIT, AVC_EVENT_LAN_DISCONNECT, invoke_epsilon_event, AVC_STATE_CHAT_RESET }, + { AVC_STATE_CHAT_INIT, AVC_EVENT_LAN_DISCONNECT, invoke_epsilon_event, AVC_STATE_CHAT_RESET }, + { AVC_STATE_CHAT_INIT, AVC_EVENT_CHAT_INIT_SUCCEEDED, invoke_epsilon_event, AVC_STATE_CHAT_LOAD }, + { AVC_STATE_CHAT_INIT, AVC_EVENT_NP2_ROOM_DESTROY_OR_KICKEDOUT,invoke_epsilon_event, AVC_STATE_CHAT_RESET }, + + { AVC_STATE_CHAT_LOAD, AVC_EVENT_EPSILON, load, AVC_STATE_CHAT_LOAD }, + { AVC_STATE_CHAT_LOAD, AVC_EVENT_EXIT_GAME, invoke_epsilon_event, AVC_STATE_CHAT_RESET }, + { AVC_STATE_CHAT_LOAD, AVC_EVENT_ERROR, invoke_epsilon_event, AVC_STATE_CHAT_RESET }, + { AVC_STATE_CHAT_LOAD, AVC_EVENT_LAN_DISCONNECT, invoke_epsilon_event, AVC_STATE_CHAT_RESET }, + { AVC_STATE_CHAT_LOAD, AVC_EVENT_CHAT_LOAD_SUCCEEDED, invoke_epsilon_event, AVC_STATE_CHAT_JOIN }, + { AVC_STATE_CHAT_LOAD, AVC_EVENT_NP2_ROOM_DESTROY_OR_KICKEDOUT,invoke_epsilon_event, AVC_STATE_CHAT_RESET }, + + { AVC_STATE_CHAT_JOIN, AVC_EVENT_EPSILON, join, AVC_STATE_CHAT_JOIN }, + { AVC_STATE_CHAT_JOIN, AVC_EVENT_EXIT_GAME, invoke_epsilon_event, AVC_STATE_CHAT_UNLOAD }, + { AVC_STATE_CHAT_JOIN, AVC_EVENT_ERROR, invoke_epsilon_event, AVC_STATE_CHAT_UNLOAD }, + { AVC_STATE_CHAT_JOIN, AVC_EVENT_LAN_DISCONNECT, invoke_epsilon_event, AVC_STATE_CHAT_UNLOAD }, + { AVC_STATE_CHAT_JOIN, AVC_EVENT_CHAT_JOIN_SUCCEEDED, invoke_epsilon_event, AVC_STATE_CHAT_SESSION_PROCESSING }, + { AVC_STATE_CHAT_JOIN, AVC_EVENT_NP2_ROOM_DESTROY_OR_KICKEDOUT,invoke_epsilon_event, AVC_STATE_CHAT_UNLOAD }, + + { AVC_STATE_CHAT_SESSION_PROCESSING,AVC_EVENT_EPSILON, start, AVC_STATE_CHAT_SESSION_PROCESSING }, + { AVC_STATE_CHAT_SESSION_PROCESSING,AVC_EVENT_EXIT_GAME, stop, AVC_STATE_CHAT_SESSION_PROCESSING }, + { AVC_STATE_CHAT_SESSION_PROCESSING,AVC_EVENT_ERROR, stop, AVC_STATE_CHAT_SESSION_PROCESSING }, + { AVC_STATE_CHAT_SESSION_PROCESSING,AVC_EVENT_LAN_DISCONNECT, stop, AVC_STATE_CHAT_SESSION_PROCESSING }, + { AVC_STATE_CHAT_SESSION_PROCESSING,AVC_EVENT_CHAT_SESSION_STOPPED, invoke_epsilon_event, AVC_STATE_CHAT_LEAVE }, + { AVC_STATE_CHAT_SESSION_PROCESSING,AVC_EVENT_NP2_ROOM_DESTROY_OR_KICKEDOUT,stop, AVC_STATE_CHAT_SESSION_PROCESSING }, + + { AVC_STATE_CHAT_LEAVE, AVC_EVENT_EPSILON, leave, AVC_STATE_CHAT_LEAVE }, + { AVC_STATE_CHAT_LEAVE, AVC_EVENT_ERROR, invoke_epsilon_event, AVC_STATE_CHAT_UNLOAD }, + { AVC_STATE_CHAT_LEAVE, AVC_EVENT_CHAT_LEAVE_SUCCEEDED, invoke_epsilon_event, AVC_STATE_CHAT_UNLOAD }, + + { AVC_STATE_CHAT_UNLOAD, AVC_EVENT_EPSILON, unload, AVC_STATE_CHAT_UNLOAD }, + { AVC_STATE_CHAT_UNLOAD, AVC_EVENT_ERROR, invoke_epsilon_event, AVC_STATE_CHAT_RESET }, + { AVC_STATE_CHAT_UNLOAD, AVC_EVENT_CHAT_UNLOAD_SUCCEEDED, invoke_epsilon_event, AVC_STATE_CHAT_RESET }, + + { AVC_STATE_CHAT_RESET, AVC_EVENT_EPSILON, finalize, AVC_STATE_CHAT_RESET }, + { AVC_STATE_CHAT_RESET, AVC_EVENT_ERROR, invoke_epsilon_event, AVC_STATE_CHAT_LEAVE }, + { AVC_STATE_CHAT_RESET, AVC_EVENT_CHAT_FINALIZE_SUCCEEDED, invoke_epsilon_event, AVC_STATE_IDLE }, + + }; + do_state_transition( &tbl[0], sizeof( tbl ) / sizeof( state_transition_table ) ); + + setBitRate(); +} + + + +void SonyVoiceChat::do_state_transition( state_transition_table *tbl, int tbl_size ) +{ + int ret = CELL_OK; + +// if( sm_event == AVC_EVENT_LAN_DISCONNECT || +// sm_event == AVC_EVENT_EXIT_GAME || +// sm_event == AVC_EVENT_ERROR || +// sm_event == AVC_EVENT_FATAL_ERROR ) +// { +// g_gamedata.finalize = 1; +// } +// if( sm_event == AVC_EVENT_FATAL_ERROR ) +// { +// g_gamedata.exit = true; +// } + bool bCalledFunc = false; + for( int i = 0; i < tbl_size; i++ ) + { + if( sm_state == ( tbl + i )->state ) + { + if( sm_event == ( tbl + i )->event ) + { + sm_event = AVC_EVENT_NON; + ret = (*( tbl + i )->func)(); + bCalledFunc = true; + if( ret != CELL_OK ) + { + ERR("ret = 0x%x\n", ret ); + } + + setState(( tbl + i )->new_state); + break; + } + } + } + if(bCalledFunc == false) + { + assert( (sm_event == AVC_EVENT_NON) || + (sm_state == AVC_STATE_IDLE && sm_event == AVC_EVENT_EPSILON) ); + } +} + +int SonyVoiceChat::invoke_epsilon_event(void) +{ + setEvent(AVC_EVENT_EPSILON); + + return CELL_OK; +} + + +bool SonyVoiceChat::hasMicConnected(const SceNpMatching2RoomMemberId *players_id) +{ + CellSysutilAvc2PlayerInfo players_info; + int err = cellSysutilAvc2GetPlayerInfo(players_id, &players_info); + if(err == CELL_OK) + { + if(players_info.connected && players_info.joined) + { + if(players_info.mic_attached == CELL_AVC2_MIC_STATUS_ATTACHED_ON) + return true; + } + } + + return false; +} + +void SonyVoiceChat::mute( bool bMute ) +{ + if(sm_bLoaded && !sm_bUnloading) + { + int err = cellSysutilAvc2SetVoiceMuting(bMute); + assert(err == CELL_OK); + } +} + +void SonyVoiceChat::mutePlayer( const SceNpMatching2RoomMemberId member_id, bool bMute ) /*Turn chat audio from a specified player on or off */ +{ + if(sm_bLoaded && !sm_bUnloading) + { + int err = cellSysutilAvc2SetPlayerVoiceMuting(member_id, bMute); + assert(err == CELL_OK); + } +} + +void SonyVoiceChat::muteLocalPlayer( bool bMute ) /*Turn microphone input on or off */ +{ + if(sm_bLoaded && !sm_bUnloading) + { + int err = cellSysutilAvc2SetVoiceMuting(bMute); + assert(err == CELL_OK); + } +} + + +bool SonyVoiceChat::isMuted() +{ + if(sm_bLoaded && !sm_bUnloading) + { + uint8_t bMute; + int err = cellSysutilAvc2GetVoiceMuting(&bMute); + assert(err == CELL_OK); + return bMute; + } + return false; +} + +bool SonyVoiceChat::isMutedPlayer( const SceNpMatching2RoomMemberId member_id) +{ + if(sm_bLoaded && !sm_bUnloading) + { + uint8_t bMute; + int err = cellSysutilAvc2GetPlayerVoiceMuting(member_id, &bMute); + assert(err == CELL_OK); + return bMute; + } + return false; +} + +bool SonyVoiceChat::isMutedLocalPlayer() +{ + if(sm_bLoaded && !sm_bUnloading) + { + uint8_t bMute; + int err = cellSysutilAvc2GetVoiceMuting(&bMute); + assert(err == CELL_OK); + return bMute; + } + return false; +} + +void SonyVoiceChat::setVolume( float vol ) +{ + if(sm_bLoaded && !sm_bUnloading) + { + // The volume level can be set to a value in the range 0.0 to 40.0. + // Volume levels are linear values such that if 1.0 is specified, the + // volume level will be 1 times the reference power (0dB), and if 0.5 + // is specified, the volume level will be 0.5 times the reference power + // (-6dB). If 0.0 is specified, chat audio will no longer be audible. + + int err =cellSysutilAvc2SetSpeakerVolumeLevel(vol * 40.0f); + assert(err==CELL_OK); + } +} + +float SonyVoiceChat::getVolume() +{ + if(sm_bLoaded && !sm_bUnloading) + { + float vol; + int err = cellSysutilAvc2GetSpeakerVolumeLevel(&vol); + assert(err == CELL_OK); + return (vol / 40.0f); + } + return 0; +} + +bool SonyVoiceChat::isTalking( SceNpMatching2RoomMemberId* players_id ) +{ + AUTO_VAR(it, sm_bTalkingMap.find(*players_id)); + if (it != sm_bTalkingMap.end() ) + return it->second; + return false; +} + +void SonyVoiceChat::setBitRate() +{ + if(sm_state != AVC_STATE_CHAT_SESSION_PROCESSING) + return; + + int numPlayers = sm_pNetworkManager->GetPlayerCount(); +// This internal attribute represents the maximum voice bit rate. attr_param +// is an integer value. The units are bps, and the specifiable values are +// 4000, 8000, 16000, 20000, 24000, and 28000. The initial value is 28000. + + static int bitRates[8] = { 28000, 28000, + 28000, 28000, + 24000, 20000, + 16000, 16000}; + int bitRate = bitRates[numPlayers-1]; + if(bitRate == sm_currentBitrate) + return; + + CellSysutilAvc2Attribute attr; + memset( &attr, 0x00, sizeof(attr) ); + attr.attr_id = CELL_SYSUTIL_AVC2_ATTRIBUTE_VOICE_MAX_BITRATE; + attr.attr_param.int_param = bitRate; + int ret = cellSysutilAvc2SetAttribute(&attr); + if( ret == CELL_OK ) + { + sm_currentBitrate = bitRate; + } + else + { + app.DebugPrintf("SonyVoiceChat::setBitRate failed !!! 0x%08x\n", ret); + } +} + + + +#define CASE_STR_VALUE(s) case s: return #s; + +const char* getStateString(EAVCState state) +{ + + switch(state) + { + + CASE_STR_VALUE(AVC_STATE_IDLE); + CASE_STR_VALUE(AVC_STATE_CHAT_INIT) + CASE_STR_VALUE(AVC_STATE_CHAT_LOAD); + CASE_STR_VALUE(AVC_STATE_CHAT_JOIN); + CASE_STR_VALUE(AVC_STATE_CHAT_SESSION_PROCESSING); + CASE_STR_VALUE(AVC_STATE_CHAT_LEAVE); + CASE_STR_VALUE(AVC_STATE_CHAT_RESET); + CASE_STR_VALUE(AVC_STATE_CHAT_UNLOAD); + CASE_STR_VALUE(AVC_STATE_EXIT); + default: + return "unknown state"; + } +} + +const char* getEventString(EAVCEvent state) +{ + switch(state) + { + CASE_STR_VALUE(AVC_EVENT_NON); + CASE_STR_VALUE(AVC_EVENT_EPSILON); + CASE_STR_VALUE(AVC_EVENT_LAN_DISCONNECT); + CASE_STR_VALUE(AVC_EVENT_ONLINE); + CASE_STR_VALUE(AVC_EVENT_OFFLINE); + CASE_STR_VALUE(AVC_EVENT_EXIT_GAME); + CASE_STR_VALUE(AVC_EVENT_ROOM_CREATE); + CASE_STR_VALUE(AVC_EVENT_ROOM_SEARCH); + CASE_STR_VALUE(AVC_EVENT_ERROR); + CASE_STR_VALUE(AVC_EVENT_FATAL_ERROR); + CASE_STR_VALUE(AVC_EVENT_NETDIALOG_FINISHED); + CASE_STR_VALUE(AVC_EVENT_NETDIALOG_UNLOADED); + CASE_STR_VALUE(AVC_EVENT_NP2_INIT_SUCCEEDED); + CASE_STR_VALUE(AVC_EVENT_NP2_FINALIZE_SUCCEEDED); + CASE_STR_VALUE(AVC_EVENT_NP2_START_CONTEXT_SUCCEEDED); + CASE_STR_VALUE(AVC_EVENT_NP2_STOP_CONTEXT_SUCCEEDED); + CASE_STR_VALUE(AVC_EVENT_NP2_ROOM_DESTROY_OR_KICKEDOUT); + CASE_STR_VALUE(AVC_EVENT_NP2_ROOM_MEMBER_LEFT); + CASE_STR_VALUE(AVC_EVENT_NP2_ROOM_MEMBER_JOINED); + CASE_STR_VALUE(AVC_EVENT_CHAT_LOAD_SUCCEEDED); + CASE_STR_VALUE(AVC_EVENT_CHAT_LOAD_FAILED); + CASE_STR_VALUE(AVC_EVENT_CHAT_JOIN_SUCCEEDED); + CASE_STR_VALUE(AVC_EVENT_CHAT_JOIN_FAILED); + CASE_STR_VALUE(AVC_EVENT_CHAT_LEAVE_SUCCEEDED); + CASE_STR_VALUE(AVC_EVENT_CHAT_LEAVE_FAILED); + CASE_STR_VALUE(AVC_EVENT_CHAT_UNLOAD_SUCCEEDED); + CASE_STR_VALUE(AVC_EVENT_CHAT_UNLOAD_FAILED); + CASE_STR_VALUE(AVC_EVENT_CHAT_INIT_SUCCEEDED); + CASE_STR_VALUE(AVC_EVENT_CHAT_FINALIZE_SUCCEEDED); + CASE_STR_VALUE(AVC_EVENT_CHAT_SESSION_STOPPED); + CASE_STR_VALUE(AVC_EVENT_CREATE_JOIN_ROOM_SUCCEEDED); + CASE_STR_VALUE(AVC_EVENT_SEARCH_ROOM_SUCCEEDED); + CASE_STR_VALUE(AVC_EVENT_JOIN_ROOM_SUCCEEDED); + CASE_STR_VALUE(AVC_EVENT_LEAVE_ROOM_SUCCEEDED); + CASE_STR_VALUE(AVC_EVENT_SIGNALING_ESTABLISHED); + CASE_STR_VALUE(AVC_EVENT_SIGNALING_DEAD); + CASE_STR_VALUE(AVC_EVENT_UI_CLOSE_SUCCEEDED); + default: + return "unknown event"; + } +} + +void SonyVoiceChat::printStateAndEvent() +{ + app.DebugPrintf("============== State %20s, Event %20s\n", getStateString(sm_state), getEventString(sm_event)); +} + + +void SonyVoiceChat::setEvent( EAVCEvent event ) +{ + sm_event = event; + printStateAndEvent(); +} + +void SonyVoiceChat::setState( EAVCState state ) +{ + sm_state = state; + printStateAndEvent(); +} -- cgit v1.2.3