1
0
mirror of https://github.com/thes3m/XNI synced 2024-12-26 13:26:06 +01:00
Matej Jan b212fc7d44 Completed Accelerometer support.
MediaPlayer stop corrected.

git-svn-id: http://xni.googlecode.com/svn/XNI@61 ac433895-eea3-a490-d80a-17149a75e588
2011-02-18 13:53:30 +00:00

251 lines
5.1 KiB
Objective-C

//
// MediaPlayer.m
// XNI
//
// Created by Matej Jan on 18.1.11.
// Copyright 2011 Retronator. All rights reserved.
//
#import "MediaPlayer.h"
#import <AudioToolbox/AudioToolbox.h>
#import "Retronator.Xni.Framework.Media.h"
#import "MediaQueue+Internal.h"
#import "Song+Internal.h"
@interface MediaPlayer ()
- (BOOL) checkAvailability;
- (void) setMediaState:(MediaState)value;
- (void) fillSongIndices;
@end
@implementation MediaPlayer
static MediaPlayer *instance;
+ (void) initialize {
if (!instance) {
instance = [[MediaPlayer alloc] init];
}
}
- (id) init
{
self = [super init];
if (self != nil) {
// Start in ambient mode so we let user music play until a call to MediaPlayer play changes this.
[[AVAudioSession sharedInstance]
setCategory: AVAudioSessionCategoryAmbient
error: nil];
queue = [[MediaQueue alloc] init];
isMuted = NO;
volume = 1;
remainingSongIndices = [[NSMutableArray alloc] init];
[queue.activeSongChanged subscribeDelegate:[Delegate delegateWithTarget:self Method:@selector(queueActiveSongChanged)]];
activeSongChanged = [[Event alloc] init];
mediaStateChanged = [[Event alloc] init];
}
return self;
}
- (BOOL) gameHasControl {
UInt32 otherAudioIsPlaying;
UInt32 propertySize = sizeof(otherAudioIsPlaying);
AudioSessionGetProperty (
kAudioSessionProperty_OtherAudioIsPlaying,
&propertySize,
&otherAudioIsPlaying
);
return !otherAudioIsPlaying;
}
@synthesize isMuted;
- (void) setIsMuted:(BOOL)value {
isMuted = value;
if (isMuted) {
queue.activeSong.audioPlayer.volume = 0;
} else {
queue.activeSong.audioPlayer.volume = volume;
}
}
@synthesize isRepeating;
@synthesize isShuffled;
- (NSTimeInterval) playPosition {
return queue.activeSong.audioPlayer.currentTime;
}
@synthesize volume;
- (void) setVolume:(float)value {
volume = value;
if (!isMuted) {
queue.activeSong.audioPlayer.volume = volume;
}
}
@synthesize queue, state, mediaStateChanged;
- (Event *) activeSongChanged {
return queue.activeSongChanged;
}
+ (MediaPlayer*) getInstance {
return instance;
}
+ (void) moveNext { [instance moveNext];}
+ (void) movePrevious { [instance movePrevious];}
+ (void) pause { [instance pause];}
+ (void) playSong:(Song*)song { [instance playSong:song];}
+ (void) resume { [instance resume];}
+ (void) stop { [instance stop];}
- (void) moveNext {
if (![self checkAvailability]) {
return;
}
if ([remainingSongIndices count] == 0) {
[self fillSongIndices];
}
int nextIndex = 0;
if (isShuffled) {
nextIndex = random() % remainingSongIndices.count;
}
queue.activeSongIndex = [((NSNumber*)[remainingSongIndices objectAtIndex:nextIndex]) intValue];
[remainingSongIndices removeObjectAtIndex:nextIndex];
}
- (void) movePrevious {
if (![self checkAvailability]) {
return;
}
if (isShuffled) {
queue.activeSongIndex = random() % queue.count;
} else {
queue.activeSongIndex = (queue.activeSongIndex - 1 + queue.count) % queue.count;
}
}
- (void) pause {
if (![self checkAvailability]) {
return;
}
[queue.activeSong.audioPlayer pause];
[self setMediaState:MediaStatePaused];
}
- (void) playSong:(Song*)song {
if (![self checkAvailability]) {
return;
}
song.audioPlayer.delegate = self;
[queue setSong:song];
[self fillSongIndices];
[self moveNext];
[self resume];
}
- (void) resume {
if (![self checkAvailability] || !queue.activeSong) {
return;
}
[queue.activeSong.audioPlayer play];
[self setMediaState:MediaStatePlaying];
}
- (void) stop {
if (![self checkAvailability] || !queue.activeSong) {
return;
}
queue.activeSong.audioPlayer.currentTime = 0;
[queue.activeSong.audioPlayer stop];
[self setMediaState:MediaStateStopped];
// The music stops, activate the ambient category again.
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryAmbient error:nil];
soloModeActivated = NO;
}
- (BOOL) checkAvailability {
if (!self.gameHasControl) {
return NO;
}
if (!soloModeActivated) {
// Switch to solo mode so we silence user audio before playing our music.
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategorySoloAmbient error:nil];
soloModeActivated = YES;
}
return YES;
}
- (void) queueActiveSongChanged {
[activeSongChanged raiseWithSender:self];
}
- (void) setMediaState:(MediaState)value {
if (state == value) {
return;
}
state = value;
[mediaStateChanged raiseWithSender:self];
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
if ([remainingSongIndices count] == 0 && !isRepeating) {
// The music stops, activate the ambient category again.
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryAmbient error:nil];
soloModeActivated = NO;
return;
}
[self moveNext];
[self resume];
}
- (void) fillSongIndices {
[remainingSongIndices removeAllObjects];
for (int i = 0; i < queue.count; i++) {
[remainingSongIndices addObject:[NSNumber numberWithInt:i]];
}
}
- (void) dealloc
{
[remainingSongIndices release];
[activeSongChanged release];
[mediaStateChanged release];
[queue release];
[super dealloc];
}
@end