How to Implementing Voice Chatting :
Another cool feature of the Game Kit framework is its support for voice chat.
The Voice Chat service in the Game Kit enables two devices to establish a voice chat. The voice chat
takes place over either an Internet connection or a Bluetooth connection. This section shows you
how to implement voice chatting over a Bluetooth communication channel.
The Voice Chat service in the Game Kit enables two devices to establish a voice chat. The voice chat
takes place over either an Internet connection or a Bluetooth connection. This section shows you
how to implement voice chatting over a Bluetooth communication channel.
1. Using Xcode, create a new View-based Application project and name it ChatiPhone.
2. Add the GameKit and AVFoundation frameworks to the Frameworks folder of the project (see
Figure C-9).
3. Drag and drop a WAV file onto the Resources folder in Xcode (see Figure C-10).
Figure C-9).
3. Drag and drop a WAV file onto the Resources folder in Xcode (see Figure C-10).
5. Populate the View window with three Round Rect Button views (see Figure 17-11). Name them
MUTE, Disconnect, and Connect.
6. Add the following bold statements to the Chatiphone.h file:
#import <UIKit/UIKit.h>
#import <GameKit/GameKit.h>
#import <AVFoundation/AVFoundation.h>
@interface Chatiphone : UIViewController
<GKVoiceChatClient,
GKPeerPickerControllerDelegate,
GKSessionDelegate> {
GKSession *currentSession;
IBOutlet UIButton *connect;
IBOutlet UIButton *disconnect;
GKPeerPickerController *picker;
}
@property (nonatomic, retain) GKSession *currentSession;
@property (nonatomic, retain) UIButton *connect;
@property (nonatomic, retain) UIButton *disconnect;
-(IBAction)btnMute:(id) sender;
-(IBAction)btnUnmute:(id) sender;
-(IBAction)btnConnect:(id) sender;
-(IBAction)btnDisconnect:(id) sender;
@end
7. In the Chatiphone.xib window, perform the
following connections:
➤➤ Control-click the File’s Owner item and drag and drop
it over the Connect button. Select connect.
➤➤ Control-click the File’s Owner item and drag and drop
it over the Disconnect button. Select disconnect.
➤➤ Control-click the Connect button and drag and drop it
over the File’s Owner item. Select btnConnect:.
➤➤ Control-click the Disconnect button and drag and drop
it over the File’s Owner item. Select btnDisconnect:.
➤➤ Right-click the Mute button and connect the Touch
Down event to the File’s Owner item. Select btnMute:.
➤➤ Right-click the Mute button and connect the Touch
Up Inside event to the File’s Owner item. Select
btnUnmute:.
8. To verify that all the connections are made correctly, rightclick
the File’s Owner item and view its connections (see
Figure C-12).
following connections:
➤➤ Control-click the File’s Owner item and drag and drop
it over the Connect button. Select connect.
➤➤ Control-click the File’s Owner item and drag and drop
it over the Disconnect button. Select disconnect.
➤➤ Control-click the Connect button and drag and drop it
over the File’s Owner item. Select btnConnect:.
➤➤ Control-click the Disconnect button and drag and drop
it over the File’s Owner item. Select btnDisconnect:.
➤➤ Right-click the Mute button and connect the Touch
Down event to the File’s Owner item. Select btnMute:.
➤➤ Right-click the Mute button and connect the Touch
Up Inside event to the File’s Owner item. Select
btnUnmute:.
8. To verify that all the connections are made correctly, rightclick
the File’s Owner item and view its connections (see
Figure C-12).
9. Add the following bold statements to the Chatiphone.m file
#import “Chatiphone.h”
@implementation Chatiphone
@synthesize currentSession;
@synthesize connect
@implementation Chatiphone
@synthesize currentSession;
@synthesize connect
@synthesize disconnect;
NSString *recorderFilePath;
AVAudioPlayer *audioPlayer;
- (void)viewDidLoad {
[connect setHidden:NO];
[disconnect setHidden:YES];
[super viewDidLoad];
}
//---select a nearby Bluetooth device---
-(IBAction) btnConnect:(id) sender {
picker = [[GKPeerPickerController alloc] init];
picker.delegate = self;
picker.connectionTypesMask = GKPeerPickerConnectionTypeNearby;
[connect setHidden:YES];
[disconnect setHidden:NO];
[picker show];
}
//---disconnect from the other device---
-(IBAction) btnDisconnect:(id) sender {
[self.currentSession disconnectFromAllPeers];
[self.currentSession release];
currentSession = nil;
[connect setHidden:NO];
[disconnect setHidden:YES];
}
//---did connect to a peer---
-(void) peerPickerController:(GKPeerPickerController *)pk
didConnectPeer:(NSString *)peerID
toSession:(GKSession *) session {
self.currentSession = session;
session.delegate = self;
[session setDataReceiveHandler:self withContext:nil];
picker.delegate = nil;
[picker dismiss];
[picker autorelease];
}
//---connection was cancelled---
-(void) peerPickerControllerDidCancel:(GKPeerPickerController *)pk {
picker.delegate = nil;
[picker autorelease];
[connect setHidden:NO];
[disconnect setHidden:YES];
}
//---mute
NSString *recorderFilePath;
AVAudioPlayer *audioPlayer;
- (void)viewDidLoad {
[connect setHidden:NO];
[disconnect setHidden:YES];
[super viewDidLoad];
}
//---select a nearby Bluetooth device---
-(IBAction) btnConnect:(id) sender {
picker = [[GKPeerPickerController alloc] init];
picker.delegate = self;
picker.connectionTypesMask = GKPeerPickerConnectionTypeNearby;
[connect setHidden:YES];
[disconnect setHidden:NO];
[picker show];
}
//---disconnect from the other device---
-(IBAction) btnDisconnect:(id) sender {
[self.currentSession disconnectFromAllPeers];
[self.currentSession release];
currentSession = nil;
[connect setHidden:NO];
[disconnect setHidden:YES];
}
//---did connect to a peer---
-(void) peerPickerController:(GKPeerPickerController *)pk
didConnectPeer:(NSString *)peerID
toSession:(GKSession *) session {
self.currentSession = session;
session.delegate = self;
[session setDataReceiveHandler:self withContext:nil];
picker.delegate = nil;
[picker dismiss];
[picker autorelease];
}
//---connection was cancelled---
-(void) peerPickerControllerDidCancel:(GKPeerPickerController *)pk {
picker.delegate = nil;
[picker autorelease];
[connect setHidden:NO];
[disconnect setHidden:YES];
}
//---mute
@synthesize disconnect;
NSString *recorderFilePath;
AVAudioPlayer *audioPlayer;
- (void)viewDidLoad {
[connect setHidden:NO];
[disconnect setHidden:YES];
[super viewDidLoad];
}
//---select a nearby Bluetooth device---
-(IBAction) btnConnect:(id) sender {
picker = [[GKPeerPickerController alloc] init];
picker.delegate = self;
picker.connectionTypesMask = GKPeerPickerConnectionTypeNearby;
[connect setHidden:YES];
[disconnect setHidden:NO];
[picker show];
}
//---disconnect from the other device---
-(IBAction) btnDisconnect:(id) sender {
[self.currentSession disconnectFromAllPeers];
[self.currentSession release];
currentSession = nil;
[connect setHidden:NO];
[disconnect setHidden:YES];
}
//---did connect to a peer---
-(void) peerPickerController:(GKPeerPickerController *)pk
didConnectPeer:(NSString *)peerID
toSession:(GKSession *) session {
self.currentSession = session;
session.delegate = self;
[session setDataReceiveHandler:self withContext:nil];
picker.delegate = nil;
[picker dismiss];
[picker autorelease];
}
//---connection was cancelled---
-(void) peerPickerControllerDidCancel:(GKPeerPickerController *)pk {
picker.delegate = nil;
[picker autorelease];
[connect setHidden:NO];
[disconnect setHidden:YES];
}
setHidden:YES];
}
NSString *recorderFilePath;
AVAudioPlayer *audioPlayer;
- (void)viewDidLoad {
[connect setHidden:NO];
[disconnect setHidden:YES];
[super viewDidLoad];
}
//---select a nearby Bluetooth device---
-(IBAction) btnConnect:(id) sender {
picker = [[GKPeerPickerController alloc] init];
picker.delegate = self;
picker.connectionTypesMask = GKPeerPickerConnectionTypeNearby;
[connect setHidden:YES];
[disconnect setHidden:NO];
[picker show];
}
//---disconnect from the other device---
-(IBAction) btnDisconnect:(id) sender {
[self.currentSession disconnectFromAllPeers];
[self.currentSession release];
currentSession = nil;
[connect setHidden:NO];
[disconnect setHidden:YES];
}
//---did connect to a peer---
-(void) peerPickerController:(GKPeerPickerController *)pk
didConnectPeer:(NSString *)peerID
toSession:(GKSession *) session {
self.currentSession = session;
session.delegate = self;
[session setDataReceiveHandler:self withContext:nil];
picker.delegate = nil;
[picker dismiss];
[picker autorelease];
}
//---connection was cancelled---
-(void) peerPickerControllerDidCancel:(GKPeerPickerController *)pk {
picker.delegate = nil;
[picker autorelease];
[connect setHidden:NO];
[disconnect setHidden:YES];
}
setHidden:YES];
}
-(IBAction) btnMute:(id) sender {
[GKVoiceChatService defaultVoiceChatService].microphoneMuted = YES;
}
//---unmute the voice chat---
-(IBAction) btnUnmute:(id) sender {
[GKVoiceChatService defaultVoiceChatService].microphoneMuted = NO;
}
//---returns a unique ID that identifies the local user---
-(NSString *) participantID {
return currentSession.peerID;
}
//---sends voice chat configuration data to the other party---
-(void) voiceChatService:(GKVoiceChatService *) voiceChatService
sendData:(NSData *) data
toParticipantID:(NSString *) participantID {
[currentSession sendData:data toPeers:
[NSArray arrayWithObject:participantID]
withDataMode:GKSendDataReliable error:nil];
}
//---session state changed---
-(void) session:(GKSession *)session
peer:(NSString *)peerID
didChangeState:(GKPeerConnectionState)state {
switch (state) {
case GKPeerStateConnected: {
//---plays an audio file---
NSString *soundFilePath = [[NSBundle mainBundle]
pathForResource:@”beep”
ofType:@”wav”];
NSURL *fileURL = [[NSURL alloc]
initFileURLWithPath:soundFilePath];
AVAudioPlayer *audioPlayer =
[[AVAudioPlayer alloc] initWithContentsOfURL:fileURL
error:nil];
[fileURL release];
[audioPlayer play];
NSError *error;
AVAudioSession *audioSession= [AVAudioSession sharedInstance];
if (![audioSession
setCategory:AVAudioSessionCategoryPlayAndRecord
error:&error]) {
NSLog(@”Error setting category: %@”,
[error localizedDescription]);
}
if (![audioSession setActive:YES error:&error]) {
[GKVoiceChatService defaultVoiceChatService].microphoneMuted = YES;
}
//---unmute the voice chat---
-(IBAction) btnUnmute:(id) sender {
[GKVoiceChatService defaultVoiceChatService].microphoneMuted = NO;
}
//---returns a unique ID that identifies the local user---
-(NSString *) participantID {
return currentSession.peerID;
}
//---sends voice chat configuration data to the other party---
-(void) voiceChatService:(GKVoiceChatService *) voiceChatService
sendData:(NSData *) data
toParticipantID:(NSString *) participantID {
[currentSession sendData:data toPeers:
[NSArray arrayWithObject:participantID]
withDataMode:GKSendDataReliable error:nil];
}
//---session state changed---
-(void) session:(GKSession *)session
peer:(NSString *)peerID
didChangeState:(GKPeerConnectionState)state {
switch (state) {
case GKPeerStateConnected: {
//---plays an audio file---
NSString *soundFilePath = [[NSBundle mainBundle]
pathForResource:@”beep”
ofType:@”wav”];
NSURL *fileURL = [[NSURL alloc]
initFileURLWithPath:soundFilePath];
AVAudioPlayer *audioPlayer =
[[AVAudioPlayer alloc] initWithContentsOfURL:fileURL
error:nil];
[fileURL release];
[audioPlayer play];
NSError *error;
AVAudioSession *audioSession= [AVAudioSession sharedInstance];
if (![audioSession
setCategory:AVAudioSessionCategoryPlayAndRecord
error:&error]) {
NSLog(@”Error setting category: %@”,
[error localizedDescription]);
}
if (![audioSession setActive:YES error:&error]) {
NSLog(@”Error activating audioSession: %@”,
[error description]);
}
[GKVoiceChatService defaultVoiceChatService].client = self;
//---initiating the voice chat---
if (![[GKVoiceChatService defaultVoiceChatService]
startVoiceChatWithParticipantID:peerID error:&error]) {
NSLog(@”Error starting startVoiceChatWithParticipantID:%@”,
[error userInfo]);
}
} break;
case GKPeerStateDisconnected: {
[[GKVoiceChatService defaultVoiceChatService]
stopVoiceChatWithParticipantID:peerID];
[self.currentSession release];
currentSession = nil;
[connect setHidden:NO];
[disconnect setHidden:YES];
} break;
}
}
//---data received from the other party---
-(void) receiveData:(NSData *)data
fromPeer:(NSString *)peer
inSession:(GKSession *)session
context:(void *)context {
//---start the voice chat when initiated by the client---
[[GKVoiceChatService defaultVoiceChatService]
receivedData:data fromParticipantID:peer];
}
//---session failed with error---
-(void) session:(GKSession *)session
didFailWithError:(NSError *)error {
NSLog(@”%@”,[error description]);
}
[error description]);
}
[GKVoiceChatService defaultVoiceChatService].client = self;
//---initiating the voice chat---
if (![[GKVoiceChatService defaultVoiceChatService]
startVoiceChatWithParticipantID:peerID error:&error]) {
NSLog(@”Error starting startVoiceChatWithParticipantID:%@”,
[error userInfo]);
}
} break;
case GKPeerStateDisconnected: {
[[GKVoiceChatService defaultVoiceChatService]
stopVoiceChatWithParticipantID:peerID];
[self.currentSession release];
currentSession = nil;
[connect setHidden:NO];
[disconnect setHidden:YES];
} break;
}
}
//---data received from the other party---
-(void) receiveData:(NSData *)data
fromPeer:(NSString *)peer
inSession:(GKSession *)session
context:(void *)context {
//---start the voice chat when initiated by the client---
[[GKVoiceChatService defaultVoiceChatService]
receivedData:data fromParticipantID:peer];
}
//---session failed with error---
-(void) session:(GKSession *)session
didFailWithError:(NSError *)error {
NSLog(@”%@”,[error description]);
}
- (void)dealloc {
if (currentSession) [currentSession release];
[connect release];
[disconnect release];
[super dealloc];
}
if (currentSession) [currentSession release];
[connect release];
[disconnect release];
[super dealloc];
}
10. To test the application, deploy it onto two devices. (For the iPod touch, you need to connect it to an
external microphone, as it does not include one.) Then run the application and press the Connect
button to use Bluetooth to connect the two devices. As soon as the two devices are connected, you
can start chatting! To temporarily mute the conversation, press and hold the MUTE button. When it
is released, the conversation resumes. Enjoy with Fun!!!!!!!!!!!!!!!
is released, the conversation resumes. Enjoy with Fun!!!!!!!!!!!!!!!
Read for flow of Programing:
1.When two Bluetooth devices are connected, you fi rst play the beep sound and start the audio session.
2.You then retrieve a singleton instance of the GKVoiceChatService class and call its
startVoiceChatWithParticipantID:error: method to start the voice chat
startVoiceChatWithParticipantID:error: method to start the voice chat
3.Calling the startVoiceChatWithParticipantID:error: method invokes the
voiceChatService:sendData:toParticipantID: method (defined in the GKVoiceChatClient protocol),
which makes use of the current Bluetooth session to send the configuration data to the other connected
device:
voiceChatService:sendData:toParticipantID: method (defined in the GKVoiceChatClient protocol),
which makes use of the current Bluetooth session to send the configuration data to the other connected
device:
4.When it has received the configuration data, the other device starts the Voice Chat service by calling
the receivedData:fromParticipantID: method (also defined in the GKVoiceChatClient protocol.
the receivedData:fromParticipantID: method (also defined in the GKVoiceChatClient protocol.
5.The GKVoiceChatService uses the configuration information that was exchanged between the two
devices and creates its own connection to transfer voice data.
You can mute the microphone by setting the microphoneMuted property to YES
devices and creates its own connection to transfer voice data.
You can mute the microphone by setting the microphoneMuted property to YES
No comments:
Post a Comment