Programming4us
         
 
 
Programming

iPhone SDK : GameKit Voice Chat

11/13/2010 5:19:25 PM

GameKit’s In-Game Voice service lets applications create a walkie-talkie-style voice channel connecting two devices together. You can use this service with iPhones, taking advantage of their built-in speaker and microphone, or with second generation or later iPod touch units by adding an external microphone. The standard iPhone earbuds with their built-in mic work very well with iPod touches, routing the audio into the earbuds and picking up voice input through the microphone.

GameKit as Middleman

To adapt this code for Voice Chat, you need to think of the GameKit communications as a voice chat middleman. GameKit handles the data throughput, both receipt and delivery.

The voice additions, provided by the GKVoiceChatService class, sit outside normal GameKit. Chat services connect into the iPhone’s audio playback and recording system, so Voice Chat can listen to and play back audio. Voice Chat then sends its data through GameKit and plays back the data it receives from GameKit. Figure 1 shows this separation of responsibilities.

Unfortunately, you cannot use the GameKit Voice Chat service over a connection other than Bluetooth. GKVoice expects a GKSession with GKPeers in order to transmit its data. If you need to use voice transmission for another connection style, you’ll have to write that layer yourself.

Figure 1. Voice Chat adds a layer outside normal GameKit communications to enable live peer-to-peer audio.


Implementing Voice Chat

When working with voice, there’s no difference in the way you get started. You display a peer picker and negotiate the connection, as you would normally do with GameKit. The difference arrives once the peer connects. You need to establish the voice chat and redirect the data to and from that service.

Upon connecting to the new peer, set up the voice chat basics. The peer connection method in Recipe 1 activates a play-and-record audio session, sets the default chat service client, and starts a new voice chat with that peer. By setting the client property, you ensure that your class receives the voice chat callbacks needed for negotiating data.

Your primary class must declare the GKVoiceChatClient protocol to do this. When the chat service gathers data through the microphone, it triggers the voiceChatService:sendData:toParticipantID: callback. Here, you can redirect voice data to your normal GameKit session. For a voice-only connection, just send along the data. When your application handles both voice and other data, build a dictionary and tag the data with a key such as @"voice" or When your class receives data through the normal receiveData:fromPeer:inSession:context: callback, the same approaches apply. For voice only, use receivedData:fromParticipantID: to send the data off to the chat service. Voice Chat allows you to mix game audio with in-game voice. For voice-data hybrid applications, deserialize the data, determine whether the packet included voice or regular data, and redirect that data to the appropriate recipient.

Recipe 1. Adding In-Game Voice Chat Services
- (void)voiceChatService:(GKVoiceChatService *)voiceChatService
sendData:(NSData *)data toParticipantID:(NSString *)participantID
{
// Send the next burst of data to peers
[self.session sendData: data toPeers:[NSArray arrayWithObject:
participantID] withDataMode: GKSendDataReliable error: nil];
}

- (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession:
(GKSession *)session context:(void *)context
{
// Redirect any voice data to the voice chat service
[[GKVoiceChatService defaultVoiceChatService]
receivedData:data fromParticipantID:peer];
}

- (NSString *)participantID
{
// provide the session's participant ID for the chat
return self.session.peerID;
}

- (void)peerPickerController:(GKPeerPickerController *)picker
didConnectPeer:(NSString *)peerID toSession: (GKSession *) session{

// Upon connection, close the picker and set the data handler
[picker dismiss];
[picker release];
isConnected = YES;
[self.session setDataReceiveHandler:self withContext:nil];

// Start the audio session
NSError *error;
AVAudioSession *audioSession = [AVAudioSession sharedInstance];

if (![audioSession setCategory:AVAudioSessionCategoryPlayAndRecord
error:&error])
{
NSLog(@"Error setting the AV play/record category: %@", [error
localizedDescription]);
showAlert(@"Could not establish an Audio Connection. Sorry!");
return;
}

if (![audioSession setActive: YES error: &error])
{
NSLog(@"Error activating the audio session: %@", [error
localizedDescription]);
showAlert(@"Could not establish an Audio Connection. Sorry!");
return;
}

// Set the voice chat client and start voice chat
[GKVoiceChatService defaultVoiceChatService].client = self;
if (![[GKVoiceChatService defaultVoiceChatService]
startVoiceChatWithParticipantID: peerID error: &error])
{
showAlert(@"Could not start voice chat. Sorry!");
NSLog(@"Error starting voice chat");
}
}
Other -----------------
- iPhone SDK : Creating Basic GameKit Services (part 2) : Sending and Receiving Data
- iPhone SDK : Creating Basic GameKit Services (part 1)
- iPad : Navigating with Maps
- Adding iPad to the Mix
- A Brief History of Legacy .NET Distributed Technologies : .NET Remoting
- A Brief History of Legacy .NET Distributed Technologies : .NET Enterprise Services
- iPad SDK : Outputting to an External Screen
- iPad SDK : Displaying Multiple Videos
- Parallel Programming Drivers
- Parallel Programming with Microsoft .Net : Parallel Loops - An Example
- Parallel Programming with Microsoft .Net : Parallel Loops - The Basics
- What is New in iPhone SDK 3.2 for the iPad (part 2)
- What is New in iPhone SDK 3.2 for the iPad (part 1)
- Programming with DirectX : Rendering Geometry - Colors
- ASP.NET Security : The Membership and Role Management API (part 3) - Role
- ASP.NET Security : The Membership and Role Management API (part 2) - Provider
- ASP.NET Security : The Membership and Role Management API (part 1)
- ASP.NET Security : Security-Related Controls (part 2)
- ASP.NET Security : Security-Related Controls (part 1)
- WCF Security Concepts
 
 
Most View
- Exchange Server 2010 : Risk Mitigation
- Implementing Edge Services for an Exchange Server 2007 Environment : Utilizing the Basic Sender and Recipient Connection Filters (part 1)
- iPad : Navigating with Maps
- Windows Server 2008 : Installing the Web Server Role (part 2)
- SQL Server 2008 : Developing Custom Managed Database Objects (part 7) - Using Transactions & Using the Related System Catalogs
- Active Directory Domain Services 2008 : Transfer the PDC Emulator Role
- Windows 7 : Creating a Windows Network - Installing Network Wiring
- SharePoint 2010 : Change the Name, Description, Icon, or URL of a Site
- BizTalk 2010 Recipes: Business Rules Framework - Creating Facts
- SQL Server 2008 Analysis Services : Understanding SSAS and OLAP
Top 10
- Implementing Edge Services for an Exchange Server 2007 Environment : Utilizing the Basic Sender and Recipient Connection Filters (part 3) - Configuring Recipient Filtering
- Implementing Edge Services for an Exchange Server 2007 Environment : Utilizing the Basic Sender and Recipient Connection Filters (part 2)
- Implementing Edge Services for an Exchange Server 2007 Environment : Utilizing the Basic Sender and Recipient Connection Filters (part 1)
- Implementing Edge Services for an Exchange Server 2007 Environment : Installing and Configuring the Edge Transport Server Components
- What's New in SharePoint 2013 (part 7) - BCS
- What's New in SharePoint 2013 (part 6) - SEARCH
- What's New in SharePoint 2013 (part 6) - WEB CONTENT MANAGEMENT
- What's New in SharePoint 2013 (part 5) - ENTERPRISE CONTENT MANAGEMENT
- What's New in SharePoint 2013 (part 4) - WORKFLOWS
- What's New in SharePoint 2013 (part 3) - REMOTE EVENTS