the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 764 lines 23 kB view raw
1#include "stdafx.h" 2 3 4 5 6/* SCE CONFIDENTIAL 7PlayStation(R)3 Programmer Tool Runtime Library 430.001 8* Copyright (C) 2008 Sony Computer Entertainment Inc. 9* All Rights Reserved. 10*/ 11#include "SonyVoiceChat.h" 12#include <arpa/inet.h> /* inet_ntoa() */ 13 14/* for displaying extra information */ 15#ifndef _CONTENT_PACKAGE 16#define AVC2_GAME_DEBUG 17#endif 18 19#ifdef AVC2_GAME_DEBUG 20#define INF(...) printf( "INF:" __VA_ARGS__ ) 21#define ERR(...) printf( "ERR:" __VA_ARGS__ ) 22#else 23#define INF(...) 24#define ERR(...) 25#endif 26 27#define UNUSED_VARIABLE(x) (void)(x) 28 29//#define DISABLE_VOICE_CHAT 30 31static CellSysutilAvc2InitParam g_chat_avc2param; 32 33EAVCEvent SonyVoiceChat::sm_event = AVC_EVENT_EPSILON; 34EAVCState SonyVoiceChat::sm_state = AVC_STATE_IDLE; 35SQRNetworkManager_PS3* SonyVoiceChat::sm_pNetworkManager; 36bool SonyVoiceChat::sm_bEnabled = true; 37uint8_t SonyVoiceChat::sm_micStatus = CELL_AVC2_MIC_STATUS_UNKNOWN; 38bool SonyVoiceChat::sm_bLoaded = false; 39bool SonyVoiceChat::sm_bUnloading = false; 40unordered_map<SceNpMatching2RoomMemberId, bool> SonyVoiceChat::sm_bTalkingMap; 41bool SonyVoiceChat::sm_bCanStart = false; 42bool SonyVoiceChat::sm_isChatRestricted = false; 43int SonyVoiceChat::sm_currentBitrate = 28000; 44 45void SonyVoiceChat::init( SQRNetworkManager_PS3* pNetMan ) 46{ 47 if(sm_state != AVC_STATE_IDLE) 48 return; 49 50 sm_pNetworkManager = pNetMan; 51 setState(AVC_STATE_CHAT_INIT); 52 ProfileManager.GetChatAndContentRestrictions(0,false,&sm_isChatRestricted,NULL,NULL); 53} 54 55void SonyVoiceChat::shutdown() 56{ 57 if( sm_state == AVC_STATE_IDLE || 58 sm_state == AVC_STATE_CHAT_LEAVE || 59 sm_state == AVC_STATE_CHAT_UNLOAD || 60 sm_state == AVC_STATE_CHAT_RESET ) 61 { 62 // we're either shut down already, or in the process 63 return; 64 } 65 66 setEvent(AVC_EVENT_EXIT_GAME); 67} 68 69void SonyVoiceChat::setEnabled( bool bEnabled ) 70{ 71 if(sm_bEnabled != bEnabled) 72 { 73 if(sm_bCanStart) 74 { 75 if(bEnabled) 76 startStream(); 77 else 78 stopStream(); 79 } 80 sm_bEnabled = bEnabled; 81 } 82} 83 84 85int SonyVoiceChat::eventcb_load(CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata) 86{ 87 int ret = CELL_OK; 88 89 UNUSED_VARIABLE( event_param ); 90 UNUSED_VARIABLE( userdata ); 91 92 if( event_id == CELL_AVC2_EVENT_LOAD_SUCCEEDED ) 93 { 94 INF( "<AVC CB>CELL_AVC2_EVENT_LOAD_SUCCEEDED(0x%x), param(0x%x)\n", event_id, (int)event_param ); 95 setEvent(AVC_EVENT_CHAT_LOAD_SUCCEEDED); 96 sm_bLoaded = true; 97 98 // set the packet contention value here 99 CellSysutilAvc2Attribute attr; 100 memset( &attr, 0x00, sizeof(attr) ); 101 attr.attr_id = CELL_SYSUTIL_AVC2_ATTRIBUTE_VOICE_PACKET_CONTENTION; 102 attr.attr_param.int_param = 3; 103 int ret = cellSysutilAvc2SetAttribute(&attr); 104 if( ret != CELL_OK ) 105 { 106 app.DebugPrintf("CELL_SYSUTIL_AVC2_ATTRIBUTE_VOICE_PACKET_CONTENTION failed !!! 0x%08x\n", ret); 107 } 108 109 } 110 else /* if( event_id == CELL_AVC2_EVENT_LOAD_FAILED ) */ 111 { 112 INF( "<AVC CB>CELL_AVC2_EVENT_LOAD_FAILED(0x%x), param(0x%x)\n", event_id, (int)event_param ); 113 setEvent(AVC_EVENT_CHAT_LOAD_FAILED); 114 } 115 return ret; 116} 117 118int SonyVoiceChat::eventcb_join(CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata) 119{ 120 int ret = CELL_OK; 121 122 UNUSED_VARIABLE( event_param ); 123 UNUSED_VARIABLE( userdata ); 124 125 if( event_id == CELL_AVC2_EVENT_JOIN_SUCCEEDED ) 126 { 127 INF( "<AVC CB>CELL_AVC2_EVENT_JOIN_SUCCEEDED(0x%x), param(0x%x)\n", event_id, (int)event_param ); 128 setEvent(AVC_EVENT_CHAT_JOIN_SUCCEEDED); 129 } 130 else /* if( event_id == CELL_AVC2_EVENT_JOIN_FAILED ) */ 131 { 132 INF( "<AVC CB>CELL_AVC2_EVENT_JOIN_FAILED(0x%x), param(0x%x)\n", event_id, (int)event_param ); 133 setEvent(AVC_EVENT_ERROR); 134 } 135 sm_bTalkingMap.clear(); 136 return ret; 137} 138 139int SonyVoiceChat::eventcb_leave( CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata) 140{ 141 int ret = CELL_OK; 142 143 UNUSED_VARIABLE( event_param ); 144 UNUSED_VARIABLE( userdata ); 145 146 if( event_id == CELL_AVC2_EVENT_LEAVE_SUCCEEDED ) 147 { 148 INF( "<AVC CB>CELL_AVC2_EVENT_LEAVE_SUCCEEDED(0x%x), param(0x%x)\n", event_id, (int)event_param ); 149 setState(AVC_STATE_CHAT_LEAVE); 150 setEvent(AVC_EVENT_CHAT_LEAVE_SUCCEEDED); 151 } 152 else /* if( event_id == CELL_AVC2_EVENT_LEAVE_FAILED ) */ 153 { 154 INF( "<AVC CB>CELL_AVC2_EVENT_LEAVE_FAILED(0x%x), param(0x%x)\n", event_id, (int)event_param ); 155 setState(AVC_STATE_CHAT_LEAVE); 156 setEvent(AVC_EVENT_ERROR); 157 } 158 return ret; 159} 160 161int SonyVoiceChat::eventcb_unload(CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata) 162{ 163 int ret = CELL_OK; 164 165 UNUSED_VARIABLE( event_param ); 166 UNUSED_VARIABLE( userdata ); 167 168 if( event_id == CELL_AVC2_EVENT_UNLOAD_SUCCEEDED ) 169 { 170 INF( "<AVC CB>CELL_AVC2_EVENT_UNLOAD_SUCCEEDED(0x%x), param(0x%x)\n", event_id, (int)event_param ); 171 setEvent(AVC_EVENT_CHAT_UNLOAD_SUCCEEDED); 172 sm_bLoaded = false; 173 sm_bUnloading = false; 174 } 175 else /* if( event_id == CELL_AVC2_EVENT_UNLOAD_FAILED ) */ 176 { 177 INF( "<AVC CB>CELL_AVC2_EVENT_UNLOAD_FAILED(0x%x), param(0x%x)\n", event_id, (int)event_param ); 178 setEvent(AVC_EVENT_ERROR); 179 } 180 return ret; 181} 182 183int SonyVoiceChat::eventcb_voiceDetected(CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata) 184{ 185 UNUSED_VARIABLE( userdata ); 186 187// To the upper 32 bits, the room member ID of the player is passed. 188// In the lower 32 bits, a value of 0 (mute) or a value between 1 (low volume) 189// and 10 (high volume) is passed as the audio signal value when the notification 190// method is the level method, or a value of 1 (start of speaking) or 0 (end of speaking) 191// is stored when the notification method is the trigger method. 192 193 SceNpMatching2RoomMemberId roomMemberID = (SceNpMatching2RoomMemberId)(event_param >> 32); 194 uint32_t volume = (uint32_t)(event_param & 0xffffffff); 195 196// The precision of voice detection is not very high. Since the audio signal values may 197// always be relatively high depending on the audio input device and the noise level in the 198// room, you should set a large reference value for determining whether or not a player is 199// speaking. Relatively good results can be obtained when an audio signal value of at 200// least 9 is used to determine if a player is speaking. 201 bool bTalking = false; 202 if(volume >= 9) 203 bTalking = true; 204 205 sm_bTalkingMap[roomMemberID] = bTalking; 206 return CELL_OK; 207} 208 209/* Callback function for handling AV Chat2 Utility events */ 210void SonyVoiceChat::eventcb( CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata) 211{ 212 static struct _cb_func_tbl 213 { 214 CellSysutilAvc2EventId event; 215 int (*func)( CellSysutilAvc2EventId event_id, 216 CellSysutilAvc2EventParam event_param, 217 void *userdata ); 218 } event_tbl[] = 219 { 220 { CELL_AVC2_EVENT_LOAD_SUCCEEDED, eventcb_load }, 221 { CELL_AVC2_EVENT_LOAD_FAILED, eventcb_load }, 222 { CELL_AVC2_EVENT_JOIN_SUCCEEDED, eventcb_join }, 223 { CELL_AVC2_EVENT_JOIN_FAILED, eventcb_join }, 224 { CELL_AVC2_EVENT_LEAVE_SUCCEEDED, eventcb_leave }, 225 { CELL_AVC2_EVENT_LEAVE_FAILED, eventcb_leave }, 226 { CELL_AVC2_EVENT_UNLOAD_SUCCEEDED, eventcb_unload }, 227 { CELL_AVC2_EVENT_UNLOAD_FAILED, eventcb_unload }, 228 { CELL_AVC2_EVENT_SYSTEM_NEW_MEMBER_JOINED, NULL }, 229 { CELL_AVC2_EVENT_SYSTEM_MEMBER_LEFT, NULL }, 230 { CELL_AVC2_EVENT_SYSTEM_SESSION_ESTABLISHED, NULL }, 231 { CELL_AVC2_EVENT_SYSTEM_SESSION_CANNOT_ESTABLISHED,NULL }, 232 { CELL_AVC2_EVENT_SYSTEM_SESSION_DISCONNECTED, NULL }, 233 { CELL_AVC2_EVENT_SYSTEM_VOICE_DETECTED, eventcb_voiceDetected }, 234 235 }; 236 237 int ret = 0; 238 for( unsigned int i=0; i<sizeof(event_tbl)/sizeof(struct _cb_func_tbl) ; ++i ) 239 { 240 if( event_tbl[ i ].event == event_id && event_tbl[ i ].func ) 241 { 242 ret = (*event_tbl[ i ].func)( event_id, event_param, userdata ); 243 if( ret < 0 ) 244 { 245 ERR("ret=0x%x\n", ret ); 246 } 247 break; 248 } 249 } 250} 251 252int SonyVoiceChat::load() 253{ 254 int ret = CELL_OK; 255 INF("----------------------------\n"); 256 INF("| cellSysutilAvc2LoadAsync |\n"); 257 INF("----------------------------\n"); 258 ret = cellSysutilAvc2LoadAsync( sm_pNetworkManager->m_matchingContext, 259 SYS_MEMORY_CONTAINER_ID_INVALID, 260 eventcb, 261 NULL, 262 &g_chat_avc2param ); 263 if( ret != CELL_OK ) 264 { 265 ERR( "cellSysutilAvc2LoadAsync: ret=0x%x\n", ret ); 266 setEvent(AVC_EVENT_ERROR); 267 return ret; 268 } 269 return ret; 270} 271 272int SonyVoiceChat::join() 273{ 274 int ret = CELL_OK; 275 276 INF("---------------------------------------------------\n"); 277 INF("| cellSysutilAvc2JoinChatRequest \n"); 278 INF("---------------------------------------------------\n"); 279 ret = cellSysutilAvc2JoinChatRequest( &sm_pNetworkManager->m_room ); 280 if( ret != CELL_OK ) 281 { 282 ERR( "cellSysutilAvc2JoinChatRequest: ret=0x%x\n", ret ); 283 setEvent(AVC_EVENT_ERROR); 284 return ret; 285 } 286 return ret; 287} 288 289int SonyVoiceChat::leave() 290{ 291 int ret = CELL_OK; 292 293 INF("-----------------------------------\n"); 294 INF("| cellSysutilAvc2LeaveChatRequest |\n"); 295 INF("-----------------------------------\n"); 296 ret = cellSysutilAvc2LeaveChatRequest(); 297 if( ret != CELL_OK ) 298 { 299 ERR( "cellSysutilAvc2LeaveChatRequest() = 0x%x\n", ret ); 300 setEvent(AVC_EVENT_ERROR); 301 return ret; 302 } 303 return ret; 304} 305 306int SonyVoiceChat::unload() 307{ 308 int ret = CELL_OK; 309 310 INF("------------------------------\n"); 311 INF("| cellSysutilAvc2UnloadAsync |\n"); 312 INF("------------------------------\n"); 313 314 ret = cellSysutilAvc2UnloadAsync(); 315 if( ret != CELL_OK ) 316 { 317 ERR( "cellSysutilAvcUnloadAsync() = 0x%x\n", ret ); 318 setEvent(AVC_EVENT_ERROR); 319 return ret; 320 } 321 sm_bUnloading = true; 322 return ret; 323} 324 325int SonyVoiceChat::start() 326{ 327 sm_bCanStart = (sm_isChatRestricted == false); 328 329 int ret = CELL_OK; 330 if(sm_bEnabled) 331 ret = startStream(); 332 333 return ret; 334} 335 336int SonyVoiceChat::stop() 337{ 338 sm_bCanStart = false; 339 340 int ret = CELL_OK; 341 if(sm_bEnabled) 342 ret = stopStream(); 343 344 setEvent(AVC_EVENT_CHAT_SESSION_STOPPED); 345 346 347 return ret; 348} 349 350int SonyVoiceChat::startStream() 351{ 352 int ret = CELL_OK; 353 354 INF("---------------------------------\n"); 355 INF("| cellSysutilAvc2StartStreaming |\n"); 356 INF("---------------------------------\n"); 357 ret = cellSysutilAvc2StartStreaming(); 358 if( ret != CELL_OK ) 359 { 360 ERR( "cellSysutilAvc2StartStreaming: ret=0x%x\n", ret ); 361 } 362 363 ret = cellSysutilAvc2StartVoiceDetection(); 364 if( ret != CELL_OK ) 365 { 366 ERR( "cellSysutilAvc2StartVoiceDetection: ret=0x%x\n", ret ); 367 } 368 return ret; 369} 370 371int SonyVoiceChat::stopStream() 372{ 373 int ret = cellSysutilAvc2StopVoiceDetection(); 374 if( ret != CELL_OK ) 375 { 376 ERR( "cellSysutilAvc2StopVoiceDetection: ret=0x%x\n", ret ); 377 } 378 379 INF("--------------------------------\n"); 380 INF("| cellSysutilAvc2StopStreaming |\n"); 381 INF("--------------------------------\n"); 382 ret = cellSysutilAvc2StopStreaming(); 383 if( ret != CELL_OK ) 384 { 385 ERR( "cellSysutilAvc2StopStreaming: ret=0x%x\n", ret ); 386 } 387 return ret; 388} 389 390int SonyVoiceChat::initialize(void) 391{ 392 int ret; 393 394 /* Must use cellSysutilAvc2InitParam() for clearing CellSysutilAvc2InitParam struct*/ 395 ret = cellSysutilAvc2InitParam(CELL_SYSUTIL_AVC2_INIT_PARAM_VERSION, &g_chat_avc2param); 396 if( ret != CELL_OK ) 397 { 398 ERR( "cellSysutilAvc2InitParam failed (0x%x)\n", ret ); 399 return ret; 400 } 401 402 /* Setting application specific parameters */ 403 g_chat_avc2param.media_type = CELL_SYSUTIL_AVC2_VOICE_CHAT; 404 g_chat_avc2param.max_players = AVC2_PARAM_DEFAULT_MAX_PLAYERS; 405 g_chat_avc2param.voice_param.voice_quality = CELL_SYSUTIL_AVC2_VOICE_QUALITY_NORMAL; 406 g_chat_avc2param.voice_param.max_speakers = AVC2_PARAM_DEFAULT_MAX_SPEAKERS; 407 g_chat_avc2param.spu_load_average = 50; 408 g_chat_avc2param.streaming_mode.mode = CELL_SYSUTIL_AVC2_STREAMING_MODE_NORMAL; 409 410 setEvent(AVC_EVENT_CHAT_INIT_SUCCEEDED); 411 setState(AVC_STATE_CHAT_INIT); 412 413 return ret; 414} 415 416int SonyVoiceChat::finalize(void) 417{ 418 setEvent(AVC_EVENT_CHAT_FINALIZE_SUCCEEDED); 419 return CELL_OK; 420} 421 422void SonyVoiceChat::tick() 423{ 424#ifdef DISABLE_VOICE_CHAT 425 return; 426#endif 427 428 static state_transition_table tbl[] = 429 { 430 /* now state event func after the transition state */ 431 { AVC_STATE_CHAT_INIT, AVC_EVENT_EPSILON, initialize, AVC_STATE_CHAT_INIT }, 432 { AVC_STATE_CHAT_INIT, AVC_EVENT_EXIT_GAME, invoke_epsilon_event, AVC_STATE_CHAT_RESET }, 433 { AVC_STATE_CHAT_INIT, AVC_EVENT_ERROR, invoke_epsilon_event, AVC_STATE_CHAT_RESET }, 434 { AVC_STATE_CHAT_INIT, AVC_EVENT_LAN_DISCONNECT, invoke_epsilon_event, AVC_STATE_CHAT_RESET }, 435 { AVC_STATE_CHAT_INIT, AVC_EVENT_LAN_DISCONNECT, invoke_epsilon_event, AVC_STATE_CHAT_RESET }, 436 { AVC_STATE_CHAT_INIT, AVC_EVENT_CHAT_INIT_SUCCEEDED, invoke_epsilon_event, AVC_STATE_CHAT_LOAD }, 437 { AVC_STATE_CHAT_INIT, AVC_EVENT_NP2_ROOM_DESTROY_OR_KICKEDOUT,invoke_epsilon_event, AVC_STATE_CHAT_RESET }, 438 439 { AVC_STATE_CHAT_LOAD, AVC_EVENT_EPSILON, load, AVC_STATE_CHAT_LOAD }, 440 { AVC_STATE_CHAT_LOAD, AVC_EVENT_EXIT_GAME, invoke_epsilon_event, AVC_STATE_CHAT_RESET }, 441 { AVC_STATE_CHAT_LOAD, AVC_EVENT_ERROR, invoke_epsilon_event, AVC_STATE_CHAT_RESET }, 442 { AVC_STATE_CHAT_LOAD, AVC_EVENT_LAN_DISCONNECT, invoke_epsilon_event, AVC_STATE_CHAT_RESET }, 443 { AVC_STATE_CHAT_LOAD, AVC_EVENT_CHAT_LOAD_SUCCEEDED, invoke_epsilon_event, AVC_STATE_CHAT_JOIN }, 444 { AVC_STATE_CHAT_LOAD, AVC_EVENT_NP2_ROOM_DESTROY_OR_KICKEDOUT,invoke_epsilon_event, AVC_STATE_CHAT_RESET }, 445 446 { AVC_STATE_CHAT_JOIN, AVC_EVENT_EPSILON, join, AVC_STATE_CHAT_JOIN }, 447 { AVC_STATE_CHAT_JOIN, AVC_EVENT_EXIT_GAME, invoke_epsilon_event, AVC_STATE_CHAT_UNLOAD }, 448 { AVC_STATE_CHAT_JOIN, AVC_EVENT_ERROR, invoke_epsilon_event, AVC_STATE_CHAT_UNLOAD }, 449 { AVC_STATE_CHAT_JOIN, AVC_EVENT_LAN_DISCONNECT, invoke_epsilon_event, AVC_STATE_CHAT_UNLOAD }, 450 { AVC_STATE_CHAT_JOIN, AVC_EVENT_CHAT_JOIN_SUCCEEDED, invoke_epsilon_event, AVC_STATE_CHAT_SESSION_PROCESSING }, 451 { AVC_STATE_CHAT_JOIN, AVC_EVENT_NP2_ROOM_DESTROY_OR_KICKEDOUT,invoke_epsilon_event, AVC_STATE_CHAT_UNLOAD }, 452 453 { AVC_STATE_CHAT_SESSION_PROCESSING,AVC_EVENT_EPSILON, start, AVC_STATE_CHAT_SESSION_PROCESSING }, 454 { AVC_STATE_CHAT_SESSION_PROCESSING,AVC_EVENT_EXIT_GAME, stop, AVC_STATE_CHAT_SESSION_PROCESSING }, 455 { AVC_STATE_CHAT_SESSION_PROCESSING,AVC_EVENT_ERROR, stop, AVC_STATE_CHAT_SESSION_PROCESSING }, 456 { AVC_STATE_CHAT_SESSION_PROCESSING,AVC_EVENT_LAN_DISCONNECT, stop, AVC_STATE_CHAT_SESSION_PROCESSING }, 457 { AVC_STATE_CHAT_SESSION_PROCESSING,AVC_EVENT_CHAT_SESSION_STOPPED, invoke_epsilon_event, AVC_STATE_CHAT_LEAVE }, 458 { AVC_STATE_CHAT_SESSION_PROCESSING,AVC_EVENT_NP2_ROOM_DESTROY_OR_KICKEDOUT,stop, AVC_STATE_CHAT_SESSION_PROCESSING }, 459 460 { AVC_STATE_CHAT_LEAVE, AVC_EVENT_EPSILON, leave, AVC_STATE_CHAT_LEAVE }, 461 { AVC_STATE_CHAT_LEAVE, AVC_EVENT_ERROR, invoke_epsilon_event, AVC_STATE_CHAT_UNLOAD }, 462 { AVC_STATE_CHAT_LEAVE, AVC_EVENT_CHAT_LEAVE_SUCCEEDED, invoke_epsilon_event, AVC_STATE_CHAT_UNLOAD }, 463 464 { AVC_STATE_CHAT_UNLOAD, AVC_EVENT_EPSILON, unload, AVC_STATE_CHAT_UNLOAD }, 465 { AVC_STATE_CHAT_UNLOAD, AVC_EVENT_ERROR, invoke_epsilon_event, AVC_STATE_CHAT_RESET }, 466 { AVC_STATE_CHAT_UNLOAD, AVC_EVENT_CHAT_UNLOAD_SUCCEEDED, invoke_epsilon_event, AVC_STATE_CHAT_RESET }, 467 468 { AVC_STATE_CHAT_RESET, AVC_EVENT_EPSILON, finalize, AVC_STATE_CHAT_RESET }, 469 { AVC_STATE_CHAT_RESET, AVC_EVENT_ERROR, invoke_epsilon_event, AVC_STATE_CHAT_LEAVE }, 470 { AVC_STATE_CHAT_RESET, AVC_EVENT_CHAT_FINALIZE_SUCCEEDED, invoke_epsilon_event, AVC_STATE_IDLE }, 471 472 }; 473 do_state_transition( &tbl[0], sizeof( tbl ) / sizeof( state_transition_table ) ); 474 475 setBitRate(); 476} 477 478 479 480void SonyVoiceChat::do_state_transition( state_transition_table *tbl, int tbl_size ) 481{ 482 int ret = CELL_OK; 483 484// if( sm_event == AVC_EVENT_LAN_DISCONNECT || 485// sm_event == AVC_EVENT_EXIT_GAME || 486// sm_event == AVC_EVENT_ERROR || 487// sm_event == AVC_EVENT_FATAL_ERROR ) 488// { 489// g_gamedata.finalize = 1; 490// } 491// if( sm_event == AVC_EVENT_FATAL_ERROR ) 492// { 493// g_gamedata.exit = true; 494// } 495 bool bCalledFunc = false; 496 for( int i = 0; i < tbl_size; i++ ) 497 { 498 if( sm_state == ( tbl + i )->state ) 499 { 500 if( sm_event == ( tbl + i )->event ) 501 { 502 sm_event = AVC_EVENT_NON; 503 ret = (*( tbl + i )->func)(); 504 bCalledFunc = true; 505 if( ret != CELL_OK ) 506 { 507 ERR("ret = 0x%x\n", ret ); 508 } 509 510 setState(( tbl + i )->new_state); 511 break; 512 } 513 } 514 } 515 if(bCalledFunc == false) 516 { 517 assert( (sm_event == AVC_EVENT_NON) || 518 (sm_state == AVC_STATE_IDLE && sm_event == AVC_EVENT_EPSILON) ); 519 } 520} 521 522int SonyVoiceChat::invoke_epsilon_event(void) 523{ 524 setEvent(AVC_EVENT_EPSILON); 525 526 return CELL_OK; 527} 528 529 530bool SonyVoiceChat::hasMicConnected(const SceNpMatching2RoomMemberId *players_id) 531{ 532 CellSysutilAvc2PlayerInfo players_info; 533 int err = cellSysutilAvc2GetPlayerInfo(players_id, &players_info); 534 if(err == CELL_OK) 535 { 536 if(players_info.connected && players_info.joined) 537 { 538 if(players_info.mic_attached == CELL_AVC2_MIC_STATUS_ATTACHED_ON) 539 return true; 540 } 541 } 542 543 return false; 544} 545 546void SonyVoiceChat::mute( bool bMute ) 547{ 548 if(sm_bLoaded && !sm_bUnloading) 549 { 550 int err = cellSysutilAvc2SetVoiceMuting(bMute); 551 assert(err == CELL_OK); 552 } 553} 554 555void SonyVoiceChat::mutePlayer( const SceNpMatching2RoomMemberId member_id, bool bMute ) /*Turn chat audio from a specified player on or off */ 556{ 557 if(sm_bLoaded && !sm_bUnloading) 558 { 559 int err = cellSysutilAvc2SetPlayerVoiceMuting(member_id, bMute); 560 assert(err == CELL_OK); 561 } 562} 563 564void SonyVoiceChat::muteLocalPlayer( bool bMute ) /*Turn microphone input on or off */ 565{ 566 if(sm_bLoaded && !sm_bUnloading) 567 { 568 int err = cellSysutilAvc2SetVoiceMuting(bMute); 569 assert(err == CELL_OK); 570 } 571} 572 573 574bool SonyVoiceChat::isMuted() 575{ 576 if(sm_bLoaded && !sm_bUnloading) 577 { 578 uint8_t bMute; 579 int err = cellSysutilAvc2GetVoiceMuting(&bMute); 580 assert(err == CELL_OK); 581 return bMute; 582 } 583 return false; 584} 585 586bool SonyVoiceChat::isMutedPlayer( const SceNpMatching2RoomMemberId member_id) 587{ 588 if(sm_bLoaded && !sm_bUnloading) 589 { 590 uint8_t bMute; 591 int err = cellSysutilAvc2GetPlayerVoiceMuting(member_id, &bMute); 592 assert(err == CELL_OK); 593 return bMute; 594 } 595 return false; 596} 597 598bool SonyVoiceChat::isMutedLocalPlayer() 599{ 600 if(sm_bLoaded && !sm_bUnloading) 601 { 602 uint8_t bMute; 603 int err = cellSysutilAvc2GetVoiceMuting(&bMute); 604 assert(err == CELL_OK); 605 return bMute; 606 } 607 return false; 608} 609 610void SonyVoiceChat::setVolume( float vol ) 611{ 612 if(sm_bLoaded && !sm_bUnloading) 613 { 614 // The volume level can be set to a value in the range 0.0 to 40.0. 615 // Volume levels are linear values such that if 1.0 is specified, the 616 // volume level will be 1 times the reference power (0dB), and if 0.5 617 // is specified, the volume level will be 0.5 times the reference power 618 // (-6dB). If 0.0 is specified, chat audio will no longer be audible. 619 620 int err =cellSysutilAvc2SetSpeakerVolumeLevel(vol * 40.0f); 621 assert(err==CELL_OK); 622 } 623} 624 625float SonyVoiceChat::getVolume() 626{ 627 if(sm_bLoaded && !sm_bUnloading) 628 { 629 float vol; 630 int err = cellSysutilAvc2GetSpeakerVolumeLevel(&vol); 631 assert(err == CELL_OK); 632 return (vol / 40.0f); 633 } 634 return 0; 635} 636 637bool SonyVoiceChat::isTalking( SceNpMatching2RoomMemberId* players_id ) 638{ 639 AUTO_VAR(it, sm_bTalkingMap.find(*players_id)); 640 if (it != sm_bTalkingMap.end() ) 641 return it->second; 642 return false; 643} 644 645void SonyVoiceChat::setBitRate() 646{ 647 if(sm_state != AVC_STATE_CHAT_SESSION_PROCESSING) 648 return; 649 650 int numPlayers = sm_pNetworkManager->GetPlayerCount(); 651// This internal attribute represents the maximum voice bit rate. attr_param 652// is an integer value. The units are bps, and the specifiable values are 653// 4000, 8000, 16000, 20000, 24000, and 28000. The initial value is 28000. 654 655 static int bitRates[8] = { 28000, 28000, 656 28000, 28000, 657 24000, 20000, 658 16000, 16000}; 659 int bitRate = bitRates[numPlayers-1]; 660 if(bitRate == sm_currentBitrate) 661 return; 662 663 CellSysutilAvc2Attribute attr; 664 memset( &attr, 0x00, sizeof(attr) ); 665 attr.attr_id = CELL_SYSUTIL_AVC2_ATTRIBUTE_VOICE_MAX_BITRATE; 666 attr.attr_param.int_param = bitRate; 667 int ret = cellSysutilAvc2SetAttribute(&attr); 668 if( ret == CELL_OK ) 669 { 670 sm_currentBitrate = bitRate; 671 } 672 else 673 { 674 app.DebugPrintf("SonyVoiceChat::setBitRate failed !!! 0x%08x\n", ret); 675 } 676} 677 678 679 680#define CASE_STR_VALUE(s) case s: return #s; 681 682const char* getStateString(EAVCState state) 683{ 684 685 switch(state) 686 { 687 688 CASE_STR_VALUE(AVC_STATE_IDLE); 689 CASE_STR_VALUE(AVC_STATE_CHAT_INIT) 690 CASE_STR_VALUE(AVC_STATE_CHAT_LOAD); 691 CASE_STR_VALUE(AVC_STATE_CHAT_JOIN); 692 CASE_STR_VALUE(AVC_STATE_CHAT_SESSION_PROCESSING); 693 CASE_STR_VALUE(AVC_STATE_CHAT_LEAVE); 694 CASE_STR_VALUE(AVC_STATE_CHAT_RESET); 695 CASE_STR_VALUE(AVC_STATE_CHAT_UNLOAD); 696 CASE_STR_VALUE(AVC_STATE_EXIT); 697 default: 698 return "unknown state"; 699 } 700} 701 702const char* getEventString(EAVCEvent state) 703{ 704 switch(state) 705 { 706 CASE_STR_VALUE(AVC_EVENT_NON); 707 CASE_STR_VALUE(AVC_EVENT_EPSILON); 708 CASE_STR_VALUE(AVC_EVENT_LAN_DISCONNECT); 709 CASE_STR_VALUE(AVC_EVENT_ONLINE); 710 CASE_STR_VALUE(AVC_EVENT_OFFLINE); 711 CASE_STR_VALUE(AVC_EVENT_EXIT_GAME); 712 CASE_STR_VALUE(AVC_EVENT_ROOM_CREATE); 713 CASE_STR_VALUE(AVC_EVENT_ROOM_SEARCH); 714 CASE_STR_VALUE(AVC_EVENT_ERROR); 715 CASE_STR_VALUE(AVC_EVENT_FATAL_ERROR); 716 CASE_STR_VALUE(AVC_EVENT_NETDIALOG_FINISHED); 717 CASE_STR_VALUE(AVC_EVENT_NETDIALOG_UNLOADED); 718 CASE_STR_VALUE(AVC_EVENT_NP2_INIT_SUCCEEDED); 719 CASE_STR_VALUE(AVC_EVENT_NP2_FINALIZE_SUCCEEDED); 720 CASE_STR_VALUE(AVC_EVENT_NP2_START_CONTEXT_SUCCEEDED); 721 CASE_STR_VALUE(AVC_EVENT_NP2_STOP_CONTEXT_SUCCEEDED); 722 CASE_STR_VALUE(AVC_EVENT_NP2_ROOM_DESTROY_OR_KICKEDOUT); 723 CASE_STR_VALUE(AVC_EVENT_NP2_ROOM_MEMBER_LEFT); 724 CASE_STR_VALUE(AVC_EVENT_NP2_ROOM_MEMBER_JOINED); 725 CASE_STR_VALUE(AVC_EVENT_CHAT_LOAD_SUCCEEDED); 726 CASE_STR_VALUE(AVC_EVENT_CHAT_LOAD_FAILED); 727 CASE_STR_VALUE(AVC_EVENT_CHAT_JOIN_SUCCEEDED); 728 CASE_STR_VALUE(AVC_EVENT_CHAT_JOIN_FAILED); 729 CASE_STR_VALUE(AVC_EVENT_CHAT_LEAVE_SUCCEEDED); 730 CASE_STR_VALUE(AVC_EVENT_CHAT_LEAVE_FAILED); 731 CASE_STR_VALUE(AVC_EVENT_CHAT_UNLOAD_SUCCEEDED); 732 CASE_STR_VALUE(AVC_EVENT_CHAT_UNLOAD_FAILED); 733 CASE_STR_VALUE(AVC_EVENT_CHAT_INIT_SUCCEEDED); 734 CASE_STR_VALUE(AVC_EVENT_CHAT_FINALIZE_SUCCEEDED); 735 CASE_STR_VALUE(AVC_EVENT_CHAT_SESSION_STOPPED); 736 CASE_STR_VALUE(AVC_EVENT_CREATE_JOIN_ROOM_SUCCEEDED); 737 CASE_STR_VALUE(AVC_EVENT_SEARCH_ROOM_SUCCEEDED); 738 CASE_STR_VALUE(AVC_EVENT_JOIN_ROOM_SUCCEEDED); 739 CASE_STR_VALUE(AVC_EVENT_LEAVE_ROOM_SUCCEEDED); 740 CASE_STR_VALUE(AVC_EVENT_SIGNALING_ESTABLISHED); 741 CASE_STR_VALUE(AVC_EVENT_SIGNALING_DEAD); 742 CASE_STR_VALUE(AVC_EVENT_UI_CLOSE_SUCCEEDED); 743 default: 744 return "unknown event"; 745 } 746} 747 748void SonyVoiceChat::printStateAndEvent() 749{ 750 app.DebugPrintf("============== State %20s, Event %20s\n", getStateString(sm_state), getEventString(sm_event)); 751} 752 753 754void SonyVoiceChat::setEvent( EAVCEvent event ) 755{ 756 sm_event = event; 757 printStateAndEvent(); 758} 759 760void SonyVoiceChat::setState( EAVCState state ) 761{ 762 sm_state = state; 763 printStateAndEvent(); 764}