diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f76ac54a2..cf7550ccca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -428,8 +428,10 @@ elseif(IOS) ios/AppDelegate.m ios/AppDelegate.h ios/ViewController.mm - ios/ViewController.h) - set(nativeExtraLibs ${nativeExtraLibs} "-framework Foundation -framework AudioToolbox -framework CoreGraphics -framework QuartzCore -framework OpenGLES -framework UIKit -framework GLKit") + ios/ViewController.h + ios/AudioEngine.mm + ios/AudioEngine.h) + set(nativeExtraLibs ${nativeExtraLibs} "-framework Foundation -framework AudioToolbox -framework CoreGraphics -framework QuartzCore -framework OpenGLES -framework UIKit -framework GLKit -framework AudioToolbox -framework OpenAL") set(TargetBin PPSSPP) elseif(USING_QT_UI) # Currently unused diff --git a/Core/HLE/__sceAudio.cpp b/Core/HLE/__sceAudio.cpp index 3b7c885812..8f5a9e3ca3 100644 --- a/Core/HLE/__sceAudio.cpp +++ b/Core/HLE/__sceAudio.cpp @@ -273,5 +273,5 @@ int __AudioMix(short *outstereo, int numFrames) // DEBUG_LOG(HLE, "No underrun, mixed %i samples fine", numFrames); } section.unlock(); - return numFrames; + return underrun; } diff --git a/android/jni/NativeApp.cpp b/android/jni/NativeApp.cpp index 31f4cbb87b..fd4fc1e02f 100644 --- a/android/jni/NativeApp.cpp +++ b/android/jni/NativeApp.cpp @@ -149,6 +149,13 @@ void NativeMix(short *audio, int num_samples) } } +int NativeMixCount(short *audio, int num_samples) +{ + if (g_mixer) + return g_mixer->Mix(audio, num_samples); + return 0; +} + void NativeGetAppInfo(std::string *app_dir_name, std::string *app_nice_name, bool *landscape) { *app_nice_name = "PPSSPP"; diff --git a/ios/AudioEngine.h b/ios/AudioEngine.h new file mode 100644 index 0000000000..6613513b27 --- /dev/null +++ b/ios/AudioEngine.h @@ -0,0 +1,13 @@ +// +// AudioEngine.h +// PPSSPP +// +// Created by rock88 on 15/03/2013. +// Copyright (c) 2013 Homebrew. All rights reserved. +// + +#import + +@interface AudioEngine : NSObject + +@end diff --git a/ios/AudioEngine.mm b/ios/AudioEngine.mm new file mode 100644 index 0000000000..aeb187cbe5 --- /dev/null +++ b/ios/AudioEngine.mm @@ -0,0 +1,149 @@ +// +// AudioEngine.mm +// PPSSPP +// +// Created by rock88 on 15/03/2013. +// Copyright (c) 2013 Homebrew. All rights reserved. +// + +#import "AudioEngine.h" +#import +#import +#import +#import + +#import + +static volatile BOOL done = 0; + +#define SAMPLE_SIZE 44100 +static short stream[SAMPLE_SIZE]; + +int NativeMixCount(short *audio, int num_samples); + +@interface AudioEngine () + +@property (nonatomic,assign) ALCdevice *alcDevice; +@property (nonatomic,assign) ALCcontext *alContext; +@property (nonatomic,assign) ALuint buffer; +@property (nonatomic,assign) ALuint source; + +@end + +@implementation AudioEngine +@synthesize alcDevice,alContext,buffer,source; + +- (id)init +{ + self = [super init]; + if (self) + { + [self audioInit]; + [self audioLoop]; + } + return self; +} + +- (void)dealloc +{ + [self audioShutdown]; + [super dealloc]; +} + +- (void)checkALError +{ + ALenum ErrCode; + std::string Err = "OpenAL error: "; + if ((ErrCode = alGetError()) != AL_NO_ERROR) + { + Err += (char *)alGetString(ErrCode); + printf("%s\n",Err.c_str()); + } +} + +- (void)audioInit +{ + done = 0; + alcDevice = alcOpenDevice(NULL); + + if (alcDevice) + { + NSLog(@"OpenAL device opened: %s",alcGetString(alcDevice, ALC_DEVICE_SPECIFIER)); + } + else + { + NSLog(@"WARNING: could not open OpenAL device"); + return; + } + + alContext = alcCreateContext(alcDevice, NULL); + + if (alContext) + { + alcMakeContextCurrent(alContext); + } + else + { + NSLog(@"ERROR: no OpenAL context"); + return; + } + + alGenSources(1, &source); + alGenBuffers(1, &buffer); +} + +- (void)audioShutdown +{ + done = 1; + alcMakeContextCurrent(NULL); + + if (alContext) + { + alcDestroyContext(alContext); + alContext = NULL; + } + + if (alcDevice) + { + alcCloseDevice(alcDevice); + alcDevice = NULL; + } +} + +- (bool)playing +{ + ALenum state; + alGetSourcei(source, AL_SOURCE_STATE, &state); + return (state == AL_PLAYING); +} + +- (void)audioLoop +{ + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){ + while (!done) + { + size_t frames_ready; + if (![self playing]) + frames_ready = NativeMixCount(stream, SAMPLE_SIZE / 2); + else + frames_ready = 0; + + if (frames_ready > 0) + { + const size_t bytes_ready = frames_ready * sizeof(short) * 2; + alSourcei(source, AL_BUFFER, 0); + alBufferData(buffer, AL_FORMAT_STEREO16, stream, bytes_ready, 44100); + alSourcei(source, AL_BUFFER, buffer); + alSourcePlay(source); + + // TODO: Maybe this could get behind? + usleep((1000000 * frames_ready) / 44100); + } + else + usleep(100); + pthread_yield_np(); + } + }); +} + +@end diff --git a/ios/PPSSPP-Info.plist b/ios/PPSSPP-Info.plist index 0f42d9ca8a..3fa62a8d8f 100644 --- a/ios/PPSSPP-Info.plist +++ b/ios/PPSSPP-Info.plist @@ -47,5 +47,7 @@ assets/Icon.png assets/Icon@2x.png + UILaunchImageFile + assets/Default.png diff --git a/ios/ViewController.mm b/ios/ViewController.mm index 2f154fafec..6841b6aae2 100644 --- a/ios/ViewController.mm +++ b/ios/ViewController.mm @@ -6,6 +6,7 @@ // #import "ViewController.h" +#import "AudioEngine.h" #import #include "base/display.h" @@ -41,11 +42,12 @@ ViewController* sharedViewController; @property (nonatomic,retain) NSString* documentsPath; @property (nonatomic,retain) NSString* bundlePath; @property (nonatomic,retain) NSMutableArray* touches; +@property (nonatomic,retain) AudioEngine* audioEngine; @end @implementation ViewController -@synthesize documentsPath,bundlePath,touches; +@synthesize documentsPath,bundlePath,touches,audioEngine; - (id)init { @@ -104,7 +106,9 @@ ViewController* sharedViewController; dp_xscale = (float)dp_xres / (float)pixel_xres; dp_yscale = (float)dp_yres / (float)pixel_yres; - + + if (g_Config.bEnableSound) + self.audioEngine = [[[AudioEngine alloc] init] autorelease]; /* UISwipeGestureRecognizer* gesture = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)] autorelease]; [self.view addGestureRecognizer:gesture]; @@ -129,7 +133,8 @@ ViewController* sharedViewController; - (void)dealloc { [self viewDidUnload]; - + + self.audioEngine = nil; self.touches = nil; self.documentsPath = nil; self.bundlePath = nil; diff --git a/ios/assets/Default-568h@2x.png b/ios/assets/Default-568h@2x.png new file mode 100644 index 0000000000..0891b7aabf Binary files /dev/null and b/ios/assets/Default-568h@2x.png differ