Просмотр исходного кода

Agregados sonidos con la librería SoundManager

Ernesto Blanco Careaga 9 лет назад
Родитель
Сommit
986d846378

+ 32 - 2
TresEnRaya.xcodeproj/project.pbxproj

@@ -7,25 +7,40 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		D28602721E0479F600027A9C /* abucheo.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = D28602711E0479F600027A9C /* abucheo.mp3 */; };
+		D28602741E047A0200027A9C /* aplausos.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = D28602731E047A0200027A9C /* aplausos.mp3 */; };
+		D28602761E047A4600027A9C /* gato.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = D28602751E047A4600027A9C /* gato.mp3 */; };
+		D28602781E047A5600027A9C /* intro.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = D28602771E047A5600027A9C /* intro.mp3 */; };
+		D286027A1E047A7700027A9C /* perro.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = D28602791E047A7700027A9C /* perro.mp3 */; };
+		D286027C1E047A8000027A9C /* vaca.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = D286027B1E047A8000027A9C /* vaca.mp3 */; };
 		D2D27AA81DF9BADF004D2378 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D2D27AA71DF9BADF004D2378 /* main.m */; };
 		D2D27AAB1DF9BADF004D2378 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D2D27AAA1DF9BADF004D2378 /* AppDelegate.m */; };
 		D2D27AAE1DF9BADF004D2378 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D2D27AAD1DF9BADF004D2378 /* ViewController.m */; };
 		D2D27AB11DF9BADF004D2378 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D2D27AAF1DF9BADF004D2378 /* Main.storyboard */; };
 		D2D27AB31DF9BADF004D2378 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D2D27AB21DF9BADF004D2378 /* Assets.xcassets */; };
 		D2D27AB61DF9BADF004D2378 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D2D27AB41DF9BADF004D2378 /* LaunchScreen.storyboard */; };
+		D2F279E41E046C59001C5152 /* SoundManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D2F279E31E046C59001C5152 /* SoundManager.m */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
+		D28602711E0479F600027A9C /* abucheo.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = abucheo.mp3; sourceTree = "<group>"; };
+		D28602731E047A0200027A9C /* aplausos.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = aplausos.mp3; sourceTree = "<group>"; };
+		D28602751E047A4600027A9C /* gato.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = gato.mp3; sourceTree = "<group>"; };
+		D28602771E047A5600027A9C /* intro.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = intro.mp3; sourceTree = "<group>"; };
+		D28602791E047A7700027A9C /* perro.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = perro.mp3; sourceTree = "<group>"; };
+		D286027B1E047A8000027A9C /* vaca.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = vaca.mp3; sourceTree = "<group>"; };
 		D2D27AA31DF9BADF004D2378 /* TresEnRaya.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TresEnRaya.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		D2D27AA71DF9BADF004D2378 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
 		D2D27AA91DF9BADF004D2378 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
 		D2D27AAA1DF9BADF004D2378 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
-		D2D27AAC1DF9BADF004D2378 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
+		D2D27AAC1DF9BADF004D2378 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = text; path = "\U001b\U001b\U001bViewController.h\U001b"; sourceTree = "<group>"; };
 		D2D27AAD1DF9BADF004D2378 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
 		D2D27AB01DF9BADF004D2378 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
 		D2D27AB21DF9BADF004D2378 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
 		D2D27AB51DF9BADF004D2378 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
 		D2D27AB71DF9BADF004D2378 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+		D2F279E21E046C2D001C5152 /* SoundManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SoundManager.h; sourceTree = "<group>"; };
+		D2F279E31E046C59001C5152 /* SoundManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SoundManager.m; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -59,8 +74,16 @@
 			isa = PBXGroup;
 			children = (
 				D2D27AA91DF9BADF004D2378 /* AppDelegate.h */,
+				D28602731E047A0200027A9C /* aplausos.mp3 */,
+				D28602711E0479F600027A9C /* abucheo.mp3 */,
+				D286027B1E047A8000027A9C /* vaca.mp3 */,
+				D28602791E047A7700027A9C /* perro.mp3 */,
+				D28602771E047A5600027A9C /* intro.mp3 */,
+				D28602751E047A4600027A9C /* gato.mp3 */,
 				D2D27AAA1DF9BADF004D2378 /* AppDelegate.m */,
-				D2D27AAC1DF9BADF004D2378 /* ViewController.h */,
+				D2F279E21E046C2D001C5152 /* SoundManager.h */,
+				D2F279E31E046C59001C5152 /* SoundManager.m */,
+				D2D27AAC1DF9BADF004D2378 /* ViewController.h */,
 				D2D27AAD1DF9BADF004D2378 /* ViewController.m */,
 				D2D27AAF1DF9BADF004D2378 /* Main.storyboard */,
 				D2D27AB21DF9BADF004D2378 /* Assets.xcassets */,
@@ -138,9 +161,15 @@
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				D28602721E0479F600027A9C /* abucheo.mp3 in Resources */,
 				D2D27AB61DF9BADF004D2378 /* LaunchScreen.storyboard in Resources */,
+				D286027C1E047A8000027A9C /* vaca.mp3 in Resources */,
 				D2D27AB31DF9BADF004D2378 /* Assets.xcassets in Resources */,
+				D28602741E047A0200027A9C /* aplausos.mp3 in Resources */,
+				D28602781E047A5600027A9C /* intro.mp3 in Resources */,
 				D2D27AB11DF9BADF004D2378 /* Main.storyboard in Resources */,
+				D28602761E047A4600027A9C /* gato.mp3 in Resources */,
+				D286027A1E047A7700027A9C /* perro.mp3 in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -152,6 +181,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				D2D27AAE1DF9BADF004D2378 /* ViewController.m in Sources */,
+				D2F279E41E046C59001C5152 /* SoundManager.m in Sources */,
 				D2D27AAB1DF9BADF004D2378 /* AppDelegate.m in Sources */,
 				D2D27AA81DF9BADF004D2378 /* main.m in Sources */,
 			);

BIN
TresEnRaya.xcodeproj/project.xcworkspace/xcuserdata/ernestoblancocareaga.xcuserdatad/UserInterfaceState.xcuserstate


+ 183 - 0
TresEnRaya/SoundManager.h

@@ -0,0 +1,183 @@
+//
+//  SoundManager.h
+//
+//  Version 1.3.1
+//
+//  Created by Nick Lockwood on 29/01/2011.
+//  Copyright 2010 Charcoal Design
+//
+//  Distributed under the permissive zlib license
+//  Get the latest version from either of these locations:
+//
+//  http://charcoaldesign.co.uk/source/cocoa#soundmanager
+//  https://github.com/nicklockwood/SoundManager
+//
+//  This software is provided 'as-is', without any express or implied
+//  warranty.  In no event will the authors be held liable for any damages
+//  arising from the use of this software.
+//
+//  Permission is granted to anyone to use this software for any purpose,
+//  including commercial applications, and to alter it and redistribute it
+//  freely, subject to the following restrictions:
+//
+//  1. The origin of this software must not be misrepresented; you must not
+//  claim that you wrote the original software. If you use this software
+//  in a product, an acknowledgment in the product documentation would be
+//  appreciated but is not required.
+//
+//  2. Altered source versions must be plainly marked as such, and must not be
+//  misrepresented as being the original software.
+//
+//  3. This notice may not be removed or altered from any source distribution.
+//
+
+//
+//  ARC Helper
+//
+//  Version 1.3
+//
+//  Created by Nick Lockwood on 05/01/2012.
+//  Copyright 2012 Charcoal Design
+//
+//  Distributed under the permissive zlib license
+//  Get the latest version from here:
+//
+//  https://gist.github.com/1563325
+//
+
+#ifndef AH_RETAIN
+#if __has_feature(objc_arc)
+#define AH_RETAIN(x) (x)
+#define AH_RELEASE(x) (void)(x)
+#define AH_AUTORELEASE(x) (x)
+#define AH_SUPER_DEALLOC (void)(0)
+#define __AH_BRIDGE __bridge
+#else
+#define __AH_WEAK
+#define AH_WEAK assign
+#define AH_RETAIN(x) [(x) retain]
+#define AH_RELEASE(x) [(x) release]
+#define AH_AUTORELEASE(x) [(x) autorelease]
+#define AH_SUPER_DEALLOC [super dealloc]
+#define __AH_BRIDGE
+#endif
+#endif
+
+//  ARC Helper ends
+
+
+#import <Availability.h>
+#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED)
+#import <UIKit/UIKit.h>
+#define SM_USE_AV_AUDIO_PLAYER
+#else
+#import <Cocoa/Cocoa.h>
+#if __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_6
+#define SM_USE_AV_AUDIO_PLAYER
+#endif
+#endif
+
+
+#ifdef SM_USE_AV_AUDIO_PLAYER
+#import <AVFoundation/AVFoundation.h>
+#define SM_SOUND AVAudioPlayer
+#else
+#define SM_SOUND NSSound
+#endif
+
+
+extern NSString *const SoundDidFinishPlayingNotification;
+
+
+typedef void (^SoundCompletionHandler)(BOOL didFinish);
+
+
+@interface Sound : NSObject
+
+//required for 32-bit Macs
+#ifdef __i386__
+{
+@private
+    
+    float baseVolume;
+    float startVolume;
+    float targetVolume;
+    NSTimeInterval fadeTime;
+    NSTimeInterval fadeStart;
+    NSTimer *timer;
+    Sound *selfReference;
+    NSURL *url;
+    SM_SOUND *sound;
+    SoundCompletionHandler completionHandler;
+}
+#endif
+
++ (Sound *)soundNamed:(NSString *)name;
++ (Sound *)soundWithContentsOfFile:(NSString *)path;
+- (Sound *)initWithContentsOfFile:(NSString *)path;
++ (Sound *)soundWithContentsOfURL:(NSURL *)url;
+- (Sound *)initWithContentsOfURL:(NSURL *)url;
+
+@property (nonatomic, readonly, copy) NSString *name;
+@property (nonatomic, readonly, strong) NSURL *url;
+@property (nonatomic, readonly, getter = isPlaying) BOOL playing;
+@property (nonatomic, assign, getter = isLooping) BOOL looping;
+@property (nonatomic, copy) SoundCompletionHandler completionHandler;
+@property (nonatomic, assign) float baseVolume;
+@property (nonatomic, assign) float volume;
+
+- (void)fadeTo:(float)volume duration:(NSTimeInterval)duration;
+- (void)fadeIn:(NSTimeInterval)duration;
+- (void)fadeOut:(NSTimeInterval)duration;
+- (void)play;
+- (void)stop;
+
+@end
+
+
+@interface SoundManager : NSObject
+
+//required for 32-bit Macs
+#ifdef __i386__
+{
+@private
+    
+    Sound *currentMusic;
+    NSMutableArray *currentSounds;
+    BOOL allowsBackgroundMusic;
+    float soundVolume;
+    float musicVolume;
+    NSTimeInterval soundFadeDuration;
+    NSTimeInterval musicFadeDuration;
+}
+#endif
+
+@property (nonatomic, readonly, getter = isPlayingMusic) BOOL playingMusic;
+@property (nonatomic, assign) BOOL allowsBackgroundMusic;
+@property (nonatomic, assign) float soundVolume;
+@property (nonatomic, assign) float musicVolume;
+@property (nonatomic, assign) NSTimeInterval soundFadeDuration;
+@property (nonatomic, assign) NSTimeInterval musicFadeDuration;
+
++ (SoundManager *)sharedManager;
+
+- (void)prepareToPlayWithSound:(id)soundOrName;
+- (void)prepareToPlay;
+
+- (void)playMusic:(id)soundOrName looping:(BOOL)looping fadeIn:(BOOL)fadeIn;
+- (void)playMusic:(id)soundOrName looping:(BOOL)looping;
+- (void)playMusic:(id)soundOrName;
+
+- (void)stopMusic:(BOOL)fadeOut;
+- (void)stopMusic;
+
+- (void)playSound:(id)soundOrName looping:(BOOL)looping fadeIn:(BOOL)fadeIn;
+- (void)playSound:(id)soundOrName looping:(BOOL)looping;
+- (void)playSound:(id)soundOrName;
+
+- (void)stopSound:(id)soundOrName fadeOut:(BOOL)fadeOut;
+- (void)stopSound:(id)soundOrName;
+- (void)stopAllSounds:(BOOL)fadeOut;
+- (void)stopAllSounds;
+
+@end

+ 612 - 0
TresEnRaya/SoundManager.m

@@ -0,0 +1,612 @@
+//
+//  SoundManager.m
+//
+//  Version 1.3.1
+//
+//  Created by Nick Lockwood on 29/01/2011.
+//  Copyright 2010 Charcoal Design
+//
+//  Distributed under the permissive zlib license
+//  Get the latest version from either of these locations:
+//
+//  http://charcoaldesign.co.uk/source/cocoa#soundmanager
+//  https://github.com/nicklockwood/SoundManager
+//
+//  This software is provided 'as-is', without any express or implied
+//  warranty.  In no event will the authors be held liable for any damages
+//  arising from the use of this software.
+//
+//  Permission is granted to anyone to use this software for any purpose,
+//  including commercial applications, and to alter it and redistribute it
+//  freely, subject to the following restrictions:
+//
+//  1. The origin of this software must not be misrepresented; you must not
+//  claim that you wrote the original software. If you use this software
+//  in a product, an acknowledgment in the product documentation would be
+//  appreciated but is not required.
+//
+//  2. Altered source versions must be plainly marked as such, and must not be
+//  misrepresented as being the original software.
+//
+//  3. This notice may not be removed or altered from any source distribution.
+//
+
+#import "SoundManager.h"
+
+
+#pragma mark Sound class
+
+
+NSString *const SoundDidFinishPlayingNotification = @"SoundDidFinishPlayingNotification";
+
+
+#ifdef SM_USE_AV_AUDIO_PLAYER
+@interface Sound() <AVAudioPlayerDelegate>
+#else
+@interface Sound() <NSSoundDelegate>
+#endif
+
+@property (nonatomic, assign) float startVolume;
+@property (nonatomic, assign) float targetVolume;
+@property (nonatomic, assign) NSTimeInterval fadeTime;
+@property (nonatomic, assign) NSTimeInterval fadeStart;
+@property (nonatomic, strong) NSTimer *timer;
+@property (nonatomic, strong) Sound *selfReference;
+@property (nonatomic, strong) SM_SOUND *sound;
+
+- (void)prepareToPlay;
+
+@end
+
+
+@implementation Sound
+
+@synthesize baseVolume;
+@synthesize startVolume;
+@synthesize targetVolume;
+@synthesize fadeTime;
+@synthesize fadeStart;
+@synthesize timer;
+@synthesize selfReference;
+@synthesize url;
+@synthesize sound;
+@synthesize completionHandler;
+
++ (Sound *)soundNamed:(NSString *)name
+{
+    NSString *path = name;
+    if (![path isAbsolutePath])
+    {
+        if ([[name pathExtension] isEqualToString:@""])
+        {
+            name = [name stringByAppendingPathExtension:@"caf"];
+        }
+        path = [[NSBundle mainBundle] pathForResource:name ofType:@""];
+    }
+    return [self soundWithContentsOfFile:path];
+}
+
++ (Sound *)soundWithContentsOfFile:(NSString *)path
+{
+    return AH_AUTORELEASE([[self alloc] initWithContentsOfFile:path]);
+}
+
++ (Sound *)soundWithContentsOfURL:(NSURL *)url
+{
+    return AH_AUTORELEASE([[self alloc] initWithContentsOfURL:url]);
+}
+
+- (Sound *)initWithContentsOfFile:(NSString *)path;
+{
+    return [self initWithContentsOfURL:path? [NSURL fileURLWithPath:path]: nil];
+}
+
+- (Sound *)initWithContentsOfURL:(NSURL *)_url;
+{
+    
+#ifdef DEBUG
+    
+    if ([_url isFileURL] && ![[NSFileManager defaultManager] fileExistsAtPath:[_url path]])
+    {
+        NSLog(@"Sound file '%@' does not exist", [_url path]);
+    }
+    
+#endif
+    
+    if ((self = [super init]))
+    {
+        url = AH_RETAIN(_url);
+        baseVolume = 1.0f;
+        
+#ifdef SM_USE_AV_AUDIO_PLAYER
+        sound = [[AVAudioPlayer alloc] initWithContentsOfURL:_url error:NULL];
+#else
+        sound = [[NSSound alloc] initWithContentsOfURL:_url byReference:YES];
+#endif
+        self.volume = 1.0f;
+    }
+    return self;
+}
+
+- (void)prepareToPlay
+{
+    //avoid overhead from repeated calls
+    static BOOL prepared = NO;
+    if (prepared) return;
+    prepared = YES;
+    
+#ifdef SM_USE_AV_AUDIO_PLAYER
+    
+#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
+    [AVAudioSession sharedInstance];
+#endif
+    
+    [sound prepareToPlay];
+    
+#else
+    
+    [sound setVolume:0.0f];
+    [self play];
+    [self performSelector:@selector(stop) withObject:nil afterDelay:0.0];
+    
+#endif
+    
+}
+
+- (NSString *)name
+{
+    return [[url path] lastPathComponent];
+}
+
+- (void)setbaseVolume:(float)_baseVolume
+{
+    _baseVolume = fminf(1.0f, fmaxf(0.0f, _baseVolume));
+    
+    if (baseVolume != _baseVolume)
+    {
+        float previousVolume = self.volume;
+        baseVolume = _baseVolume;
+        self.volume = previousVolume;
+    }
+}
+
+- (float)volume
+{
+    if (timer)
+    {
+        return targetVolume / baseVolume;
+    }
+    else
+    {
+        return [sound volume] / baseVolume;
+    }
+}
+
+- (void)setVolume:(float)volume
+{
+    volume = fminf(1.0f, fmaxf(0.0f, volume));
+    
+    if (timer)
+    {
+        targetVolume = volume * baseVolume;
+    }
+    else
+    {
+        [sound setVolume:volume * baseVolume];
+    }
+}
+
+- (BOOL)isLooping
+{
+    
+#ifdef SM_USE_AV_AUDIO_PLAYER
+    return [sound numberOfLoops] == -1;
+#else
+    return [sound loops];
+#endif
+    
+}
+
+- (void)setLooping:(BOOL)looping
+{
+    
+#ifdef SM_USE_AV_AUDIO_PLAYER
+    [sound setNumberOfLoops:looping? -1: 0];
+#else
+    [sound setLoops:looping];
+#endif
+    
+}
+
+- (BOOL)isPlaying
+{
+    return [sound isPlaying];
+}
+
+- (void)play
+{
+    if (!self.playing)
+    {
+        self.selfReference = self;
+        [sound setDelegate:self];
+        
+        //play sound
+        [sound play];
+    }
+}
+
+- (void)stop
+{
+    if (self.playing)
+    {
+        //stop playing
+        [sound stop];
+        
+        //stop timer
+        [timer invalidate];
+        self.timer = nil;
+        
+        //fire events
+        if (completionHandler) completionHandler(NO);
+        [[NSNotificationCenter defaultCenter] postNotificationName:SoundDidFinishPlayingNotification object:self];
+        
+        //set to nil on next runloop update so sound is not released unexpectedly
+        [self performSelector:@selector(setSelfReference:) withObject:nil afterDelay:0.0];
+    }
+}
+
+#ifdef SM_USE_AV_AUDIO_PLAYER
+- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)finishedPlaying
+#else
+- (void)sound:(NSSound *)_sound didFinishPlaying:(BOOL)finishedPlaying
+#endif
+{
+    //stop timer
+    [timer invalidate];
+    self.timer = nil;
+    
+    //fire events
+    if (completionHandler) completionHandler(NO);
+    [[NSNotificationCenter defaultCenter] postNotificationName:SoundDidFinishPlayingNotification object:self];
+    
+    //set to nil on next runloop update so sound is not released unexpectedly
+    [self performSelector:@selector(setSelfReference:) withObject:nil afterDelay:0.0];
+}
+
+- (void)fadeTo:(float)volume duration:(NSTimeInterval)duration
+{
+    startVolume = [sound volume];
+    targetVolume = volume * baseVolume;
+    fadeTime = duration;
+    fadeStart = [[NSDate date] timeIntervalSinceReferenceDate];
+    if (timer == nil)
+    {
+        self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0/60.0
+                                                      target:self
+                                                    selector:@selector(tick)
+                                                    userInfo:nil
+                                                     repeats:YES];
+    }
+}
+
+- (void)fadeIn:(NSTimeInterval)duration
+{
+    [sound setVolume:0.0f];
+    [self fadeTo:1.0f duration:duration];
+}
+
+- (void)fadeOut:(NSTimeInterval)duration
+{
+    [self fadeTo:0.0f duration:duration];
+}
+
+- (void)tick
+{
+    NSTimeInterval now = [[NSDate date] timeIntervalSinceReferenceDate];
+    float delta = (now - fadeStart)/fadeTime * (targetVolume - startVolume);
+    [sound setVolume:(startVolume + delta) * baseVolume];
+    if ((delta > 0.0f && [sound volume] >= targetVolume) ||
+        (delta < 0.0f && [sound volume] <= targetVolume))
+    {
+        [sound setVolume:targetVolume * baseVolume];
+        [timer invalidate];
+        self.timer = nil;
+        if ([sound volume] == 0.0f)
+        {
+            [self stop];
+        }
+    }
+}
+
+- (void)dealloc
+{
+    [timer invalidate];
+    AH_RELEASE(timer);
+    AH_RELEASE(url);
+    AH_RELEASE(sound);
+    AH_RELEASE(completionHandler);
+    AH_SUPER_DEALLOC;
+}
+
+@end
+
+
+#pragma mark SoundManager class
+
+
+@interface SoundManager ()
+
+@property (nonatomic, strong) Sound *currentMusic;
+@property (nonatomic, strong) NSMutableArray *currentSounds;
+
+@end
+
+
+@implementation SoundManager
+
+@synthesize currentMusic;
+@synthesize currentSounds;
+@synthesize allowsBackgroundMusic;
+@synthesize soundVolume;
+@synthesize musicVolume;
+@synthesize soundFadeDuration;
+@synthesize musicFadeDuration;
+
++ (SoundManager *)sharedManager
+{
+    static SoundManager *sharedManager = nil;
+    if (sharedManager == nil)
+    {
+        sharedManager = [[self alloc] init];
+    }
+    return sharedManager;
+}
+
+- (SoundManager *)init
+{
+    if ((self = [super init]))
+    {
+        soundVolume = 1.0f;
+        musicVolume = 1.0f;
+        soundFadeDuration = 1.0;
+        musicFadeDuration = 1.0;
+        currentSounds = [[NSMutableArray alloc] init];
+    }
+    return self;
+}
+
+- (void)setAllowsBackgroundMusic:(BOOL)allow
+{
+    if (allowsBackgroundMusic != allow)
+    {
+        
+#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
+        
+        allowsBackgroundMusic = allow;
+        AVAudioSession *session = [AVAudioSession sharedInstance];
+        [session setCategory:allow? AVAudioSessionCategoryAmbient: AVAudioSessionCategorySoloAmbient error:NULL];
+#endif
+        
+    }
+}
+
+- (void)prepareToPlayWithSound:(id)soundOrName
+{
+    Sound *sound = [soundOrName isKindOfClass:[Sound class]]? soundOrName: [Sound soundNamed:soundOrName];
+    [sound prepareToPlay];
+}
+
+- (void)prepareToPlay
+{
+    @autoreleasepool
+    {
+        NSArray *extensions = [NSArray arrayWithObjects:@"caf", @"m4a", @"mp4", @"mp3", @"wav", @"aif", nil];
+        NSArray *paths = nil;
+        BOOL foundSound = NO;
+        for (NSString *extension in extensions)
+        {
+            paths = [[NSBundle mainBundle] pathsForResourcesOfType:extension inDirectory:nil];
+            if ([paths count])
+            {
+                [self prepareToPlayWithSound:[paths objectAtIndex:0]];
+                NSLog(@"SoundManager prepareToPlay:%@", [paths objectAtIndex:0]);
+                foundSound = YES;
+                break;
+            }
+        }
+        if (!foundSound)
+        {
+            NSLog(@"SoundManager prepareToPlay failed to find sound in application bundle. Use prepareToPlayWithSound: instead to specify a suitable sound file.");
+        }
+    }
+}
+
+- (void)playMusic:(id)soundOrName looping:(BOOL)looping fadeIn:(BOOL)fadeIn
+{
+    Sound *music = [soundOrName isKindOfClass:[Sound class]]? soundOrName: [Sound soundNamed:soundOrName];
+    if (![music.url isEqual:currentMusic.url])
+    {
+        if (currentMusic && currentMusic.playing)
+        {
+            [currentMusic fadeOut:musicFadeDuration];
+        }
+        self.currentMusic = music;
+        [[NSNotificationCenter defaultCenter] addObserver:self
+                                                 selector:@selector(musicFinished:)
+                                                     name:SoundDidFinishPlayingNotification
+                                                   object:music];
+        currentMusic.looping = looping;
+        currentMusic.volume = fadeIn? 0.0f: musicVolume;
+        [currentMusic play];
+        if (fadeIn)
+        {
+            [currentMusic fadeTo:musicVolume duration:musicFadeDuration];
+        }
+    }
+}
+
+- (void)playMusic:(id)soundOrName looping:(BOOL)looping
+{
+    [self playMusic:soundOrName looping:looping fadeIn:YES];
+}
+
+- (void)playMusic:(id)soundOrName
+{
+    [self playMusic:soundOrName looping:YES fadeIn:YES];
+}
+
+- (void)stopMusic:(BOOL)fadeOut
+{
+    if (fadeOut)
+    {
+        [currentMusic fadeOut:musicFadeDuration];
+    }
+    else
+    {
+        [currentMusic stop];
+    }
+    self.currentMusic = nil;
+}
+
+- (void)stopMusic
+{
+    [self stopMusic:YES];
+}
+
+- (void)playSound:(id)soundOrName looping:(BOOL)looping fadeIn:(BOOL)fadeIn
+{
+    Sound *sound = [soundOrName isKindOfClass:[Sound class]]? soundOrName: [Sound soundNamed:soundOrName];
+    if (![currentSounds containsObject:sound])
+    {
+        [currentSounds addObject:sound];
+        [[NSNotificationCenter defaultCenter] addObserver:self
+                                                 selector:@selector(soundFinished:)
+                                                     name:SoundDidFinishPlayingNotification
+                                                   object:sound];
+    }
+    sound.looping = looping;
+    sound.volume = fadeIn? 0.0f: soundVolume;
+    [sound play];
+    if (fadeIn)
+    {
+        [sound fadeTo:soundVolume duration:soundFadeDuration];
+    }
+}
+
+- (void)playSound:(id)soundOrName looping:(BOOL)looping
+{
+    [self playSound:soundOrName looping:looping fadeIn:NO];
+}
+
+- (void)playSound:(id)soundOrName
+{
+    [self playSound:soundOrName looping:NO fadeIn:NO];
+}
+
+- (void)stopSound:(id)soundOrName fadeOut:(BOOL)fadeOut
+{
+    if ([soundOrName isKindOfClass:[Sound class]])
+    {
+        if (fadeOut)
+        {
+            [(Sound *)soundOrName fadeOut:soundFadeDuration];
+        }
+        else
+        {
+            [(Sound *)soundOrName stop];
+        }
+        //[currentSounds removeObject:soundOrName];
+        return;
+    }
+    
+    if ([[soundOrName pathExtension] isEqualToString:@""])
+    {
+        soundOrName = [soundOrName stringByAppendingPathExtension:@"mp3"];
+    }
+    
+    for (Sound *sound in [currentSounds reverseObjectEnumerator])
+    {
+        if ([sound.name isEqualToString:soundOrName] || [[sound.url path] isEqualToString:soundOrName])
+        {
+            if (fadeOut)
+            {
+                [sound fadeOut:soundFadeDuration];
+            }
+            else
+            {
+                [sound stop];
+            }
+            //[currentSounds removeObject:sound];
+        }
+    }
+}
+
+- (void)stopSound:(id)soundOrName
+{
+    [self stopSound:soundOrName fadeOut:YES];
+}
+
+- (void)stopAllSounds:(BOOL)fadeOut
+{
+    for (Sound *sound in currentSounds)
+    {
+        [self stopSound:sound fadeOut:YES];
+    }
+    [currentSounds removeAllObjects];
+}
+
+- (void)stopAllSounds
+{
+    [self stopAllSounds:YES];
+}
+
+- (BOOL)isPlayingMusic
+{
+    return currentMusic != nil;
+}
+
+- (void)setSoundVolume:(float)newVolume
+{
+    soundVolume = newVolume;
+    for (Sound *sound in currentSounds)
+    {
+        sound.volume = soundVolume;
+    }
+}
+
+- (void)setMusicVolume:(float)newVolume
+{
+    musicVolume = newVolume;
+    currentMusic.volume = musicVolume;
+}
+
+- (void)soundFinished:(NSNotification *)notification
+{
+    Sound *sound = [notification object];
+    [currentSounds removeObject:sound];
+    [[NSNotificationCenter defaultCenter] removeObserver:self
+                                                    name:SoundDidFinishPlayingNotification
+                                                  object:sound];
+}
+
+- (void)musicFinished:(NSNotification *)notification
+{
+    Sound *sound = [notification object];
+    if (sound == currentMusic)
+    {
+        self.currentMusic = nil;
+        [[NSNotificationCenter defaultCenter] removeObserver:self
+                                                        name:SoundDidFinishPlayingNotification
+                                                      object:sound];
+    }
+}
+
+- (void)dealloc
+{
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+    AH_RELEASE(currentMusic);
+    AH_RELEASE(currentSounds);
+    AH_SUPER_DEALLOC;
+}
+
+@end

+ 0 - 5
TresEnRaya/ViewController.h

@@ -1,5 +0,0 @@
-#import <UIKit/UIKit.h>
-
-@interface ViewController : UIViewController
-
-@end

+ 23 - 5
TresEnRaya/ViewController.m

@@ -1,10 +1,12 @@
 #import "ViewController.h"
+#import "SoundManager.h";
 
 @interface ViewController ()
 
 @end
 
 @implementation ViewController
+
 NSMutableArray *arrayDeBotones;
 UIButton *nuevoBoton;
 UIView *menu;
@@ -18,7 +20,9 @@ int jugada=0;
     anchoVentana=self.view.bounds.size.width;
     altoVentana=self.view.bounds.size.height;
 	[self agregarBotones];
-    }
+	[[SoundManager sharedManager] setMusicVolume:0.2];
+			[[SoundManager sharedManager] playMusic:@"intro.mp3" looping:YES];
+			    }
 
 	- (void) agregarBotones{
 float anchoBoton=anchoVentana/3;
@@ -58,10 +62,12 @@ nuevoBoton.titleLabel.font = [UIFont boldSystemFontOfSize:15];
         case 1:
             [sender setAccessibilityLabel:@"X"];
             [sender setTitle:@"X" forState:UIControlStateNormal];
+			[[SoundManager sharedManager] playSound:@"gato.mp3" looping:NO];
 			            						            break;
         case 2:
             [sender setAccessibilityLabel:@"O"];
             [sender setTitle:@"O" forState:UIControlStateNormal];
+			[[SoundManager sharedManager] playSound:@"perro.mp3" looping:NO];
 			                        						            break;
     }
                      jugada=jugada+1;
@@ -71,6 +77,8 @@ nuevoBoton.titleLabel.font = [UIFont boldSystemFontOfSize:15];
 	}else{
 	[self turnoSiguiente];
 	}
+	}else{
+	[[SoundManager sharedManager] playSound:@"vaca.mp3" looping:NO];
 	}
 }
 
@@ -107,8 +115,16 @@ for(UIButton *boton in arrayDeBotones){
 
 -(void) finPartida:(int) resultado{
     NSString *mensajeAlerta;
-if(resultado==1) mensajeAlerta=[NSString stringWithFormat:@"Ha ganado el jugador %i",jugador];
-if (resultado==2) mensajeAlerta=@"La partida ha finalizado con un empate";
+switch(resultado){
+case 1:
+mensajeAlerta=[NSString stringWithFormat:@"Ha ganado el jugador %i",jugador];
+[[SoundManager sharedManager] playSound:@"aplausos.mp3" looping:NO];
+break;
+case 2:
+mensajeAlerta=@"La partida ha finalizado con un empate";
+[[SoundManager sharedManager] playSound:@"abucheo.mp3" looping:NO];
+break;
+}
 	UIAlertController *alerta = [UIAlertController 
 	alertControllerWithTitle:@"¡Partida terminada!" 
 	message:mensajeAlerta
@@ -128,6 +144,8 @@ handler:^(UIAlertAction *action)
 -(void) menuPartida:(NSString*) mensaje{
 jugador=0;
 jugada=0;
+[[SoundManager sharedManager] stopMusic:NO];
+[[SoundManager sharedManager] stopAllSounds:NO];
 for(UIButton *boton in arrayDeBotones){
 [boton removeFromSuperview];
 }
@@ -161,11 +179,11 @@ menuBoton.titleLabel.font = [UIFont boldSystemFontOfSize:15];
 [menu removeFromSuperview];
 [self agregarBotones];
 jugador=1;
+[[SoundManager sharedManager] playMusic:@"intro.mp3" looping:YES];
 }
 
 - (void)didReceiveMemoryWarning {
     [super didReceiveMemoryWarning];
-    
-}
+  }
 
 				 @end

BIN
TresEnRaya/abucheo.mp3


BIN
TresEnRaya/aplausos.mp3


BIN
TresEnRaya/gato.mp3


BIN
TresEnRaya/intro.mp3


BIN
TresEnRaya/perro.mp3


BIN
TresEnRaya/vaca.mp3


BIN
TresEnRaya/vol_ocell.mp3