Added libs for iOS
This commit is contained in:
1 parent
e6ca2dd14a
commit
90091e7ea9
937 files changed
+163130
-210
No files matched your search
Executable
+77
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
|
||||
File: MyOpenALSupport.h
|
||||
|
||||
Abstract: OpenAL-related functions
|
||||
|
||||
Version: 1.0
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by
|
||||
Apple Inc. ("Apple") in consideration of your agreement to the
|
||||
following terms, and your use, installation, modification or
|
||||
redistribution of this Apple software constitutes acceptance of these
|
||||
terms. If you do not agree with these terms, please do not use,
|
||||
install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc.
|
||||
may be used to endorse or promote products derived from the Apple
|
||||
Software without specific prior written permission from Apple. Except
|
||||
as expressly stated in this notice, no other rights or licenses, express
|
||||
or implied, are granted by Apple herein, including but not limited to
|
||||
any patent rights that may be infringed by your derivative works or by
|
||||
other works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2008 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
|
||||
#import <OpenAL/al.h>
|
||||
#import <OpenAL/alc.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
void TeardownOpenAL(void);
|
||||
|
||||
void TeardownOpenAL()
|
||||
{
|
||||
ALCcontext *context = NULL;
|
||||
ALCdevice *device = NULL;
|
||||
ALuint returnedName;
|
||||
|
||||
// Delete the Sources
|
||||
alDeleteSources(1, &returnedName);
|
||||
// Delete the Buffers
|
||||
alDeleteBuffers(1, &returnedName);
|
||||
|
||||
//Get active context
|
||||
context = alcGetCurrentContext();
|
||||
//Get device for active context
|
||||
device = alcGetContextsDevice(context);
|
||||
//Release context
|
||||
alcDestroyContext(context);
|
||||
//Close device
|
||||
alcCloseDevice(device);
|
||||
}
|
||||
|
||||
Executable
+29
@@ -0,0 +1,29 @@
|
||||
/* cocos2d for iPhone
|
||||
*
|
||||
* http://www.cocos2d-iphone.org
|
||||
*
|
||||
* Copyright (C) 2009 by Florin Dumitrescu.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the 'cocos2d for iPhone' license.
|
||||
*
|
||||
* You will find a copy of this license within the cocos2d for iPhone
|
||||
* distribution inside the "LICENSE" file.
|
||||
*
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <OpenAL/al.h>
|
||||
#import <OpenAL/alc.h>
|
||||
|
||||
@interface PASoundListener : NSObject {
|
||||
CGPoint position;
|
||||
float orientation;
|
||||
}
|
||||
|
||||
@property (readwrite, assign) CGPoint position;
|
||||
@property (readwrite, assign) float orientation;
|
||||
|
||||
- (id)initWithPosition:(CGPoint)pos;
|
||||
|
||||
@end
|
||||
Executable
+81
@@ -0,0 +1,81 @@
|
||||
/* cocos2d for iPhone
|
||||
*
|
||||
* http://www.cocos2d-iphone.org
|
||||
*
|
||||
* Copyright (C) 2009 by Florin Dumitrescu.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the 'cocos2d for iPhone' license.
|
||||
*
|
||||
* You will find a copy of this license within the cocos2d for iPhone
|
||||
* distribution inside the "LICENSE" file.
|
||||
*
|
||||
*/
|
||||
|
||||
#import "PASoundListener.h"
|
||||
|
||||
|
||||
@implementation PASoundListener
|
||||
|
||||
- (id)init {
|
||||
return [self initWithPosition:CGPointMake(0, 0)]; // middle of screen
|
||||
}
|
||||
- (id)initWithPosition:(CGPoint)pos {
|
||||
if ((self = [super init])) {
|
||||
self.position = pos;
|
||||
self.orientation = 0;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (CGPoint)position {
|
||||
return position;
|
||||
}
|
||||
- (void)setPosition:(CGPoint)pos {
|
||||
position = pos;
|
||||
/* needed for Cocos2d demo 'SoundEngineTest'
|
||||
float x,y;
|
||||
switch ( [[CCDirector sharedDirector] deviceOrientation] ) {
|
||||
case CCDeviceOrientationLandscapeLeft:
|
||||
x = pos.x - 240.0f;
|
||||
y = 160.0f - pos.y;
|
||||
break;
|
||||
case CCDeviceOrientationLandscapeRight:
|
||||
// XXX: set correct orientation
|
||||
x = pos.x - 240.0f;
|
||||
y = 160.0f - pos.y;
|
||||
break;
|
||||
case CCDeviceOrientationPortrait:
|
||||
x = pos.x;
|
||||
y = pos.y;
|
||||
break;
|
||||
case CCDeviceOrientationPortraitUpsideDown:
|
||||
// XXX: set correct orientation
|
||||
x = pos.x;
|
||||
y = pos.y;
|
||||
break;
|
||||
}
|
||||
*/
|
||||
float listenerPosAL[] = {pos.x, pos.y, 0.0f};
|
||||
// Move our listener coordinates
|
||||
alListenerfv(AL_POSITION, listenerPosAL);
|
||||
}
|
||||
|
||||
- (float)orientation {
|
||||
return orientation;
|
||||
}
|
||||
- (void)setOrientation:(float)o {
|
||||
orientation = o;
|
||||
// float ori[] = {cos(o + M_PI_2), sin(o + M_PI_2), 0., 0., 0., 1.};
|
||||
float ori[] = {0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}; // I want my listener to stay heads-up always, regardless of the ship's orientation
|
||||
// Set our listener orientation (rotation)
|
||||
alListenerfv(AL_ORIENTATION, ori);
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc {
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
Executable
+44
@@ -0,0 +1,44 @@
|
||||
/* cocos2d for iPhone
|
||||
*
|
||||
* http://www.cocos2d-iphone.org
|
||||
*
|
||||
* Copyright (C) 2009 by Florin Dumitrescu.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the 'cocos2d for iPhone' license.
|
||||
*
|
||||
* You will find a copy of this license within the cocos2d for iPhone
|
||||
* distribution inside the "LICENSE" file.
|
||||
*
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@class PASoundListener, PASoundSource;
|
||||
|
||||
@interface PASoundMgr : NSObject {
|
||||
NSMutableDictionary *sounds;
|
||||
PASoundListener *listener;
|
||||
float soundsMasterGain;
|
||||
}
|
||||
|
||||
@property (readwrite, retain) PASoundListener *listener;
|
||||
@property (readwrite, assign) float soundsMasterGain;
|
||||
|
||||
+ (PASoundMgr *)sharedSoundManager;
|
||||
|
||||
- (PASoundSource *)addSound:(NSString *)name withExtension:(NSString *)ext position:(CGPoint)pos looped:(BOOL)yn;
|
||||
- (PASoundSource *)addSound:(NSString *)name withPosition:(CGPoint)pos looped:(BOOL)yn;
|
||||
|
||||
- (PASoundSource *)sound:(NSString *)name withExtension:(NSString *)ext;
|
||||
- (PASoundSource *)sound:(NSString *)name;
|
||||
|
||||
- (BOOL)play:(NSString *)name withExtension:(NSString *)ext;
|
||||
- (BOOL)play:(NSString *)name;
|
||||
- (BOOL)stop:(NSString *)name withExtension:(NSString *)ext;
|
||||
- (BOOL)stop:(NSString *)name;
|
||||
|
||||
- (void)initOpenAL;
|
||||
- (void)initListener;
|
||||
|
||||
@end
|
||||
Executable
+151
@@ -0,0 +1,151 @@
|
||||
/* cocos2d for iPhone
|
||||
*
|
||||
* http://www.cocos2d-iphone.org
|
||||
*
|
||||
* Copyright (C) 2009 by Florin Dumitrescu.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the 'cocos2d for iPhone' license.
|
||||
*
|
||||
* You will find a copy of this license within the cocos2d for iPhone
|
||||
* distribution inside the "LICENSE" file.
|
||||
*
|
||||
*/
|
||||
|
||||
#import "PASoundMgr.h"
|
||||
#import "MyOpenALSupport.h"
|
||||
#import "PASoundListener.h"
|
||||
#import "PASoundSource.h"
|
||||
|
||||
@implementation PASoundMgr
|
||||
|
||||
@synthesize listener, soundsMasterGain;
|
||||
|
||||
static PASoundMgr *sharedSoundManager = nil;
|
||||
|
||||
+ (PASoundMgr *)sharedSoundManager {
|
||||
@synchronized(self) {
|
||||
if (!sharedSoundManager){
|
||||
sharedSoundManager = [[PASoundMgr alloc] init];
|
||||
}
|
||||
return sharedSoundManager;
|
||||
}
|
||||
// to avoid compiler warning
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (id)alloc {
|
||||
@synchronized(self)
|
||||
{
|
||||
NSAssert(sharedSoundManager == nil, @"Attempted to allocate a second instance of a singleton.");
|
||||
sharedSoundManager = [super alloc];
|
||||
return sharedSoundManager;
|
||||
}
|
||||
// to avoid compiler warning
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
if ((self = [super init])) {
|
||||
sounds = [[NSMutableDictionary alloc] initWithCapacity:3];
|
||||
soundsMasterGain = 1.0f;
|
||||
// setup our audio session
|
||||
OSStatus result = AudioSessionInitialize(NULL, NULL, NULL, self);
|
||||
if (result) printf("Error initializing audio session! %d\n", (int)result);
|
||||
else {
|
||||
UInt32 category = kAudioSessionCategory_AmbientSound;
|
||||
result = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(category), &category);
|
||||
if (result) printf("Error setting audio session category! %d\n", (int)result);
|
||||
else {
|
||||
result = AudioSessionSetActive(true);
|
||||
if (result) printf("Error setting audio session active! %d\n", (int)result);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize our OpenAL environment
|
||||
[self initOpenAL];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)initOpenAL {
|
||||
ALCcontext *newContext = NULL;
|
||||
ALCdevice *newDevice = NULL;
|
||||
|
||||
// Create a new OpenAL Device
|
||||
// Pass NULL to specify the system’s default output device
|
||||
newDevice = alcOpenDevice(NULL);
|
||||
if (newDevice != NULL) {
|
||||
// Create a new OpenAL Context
|
||||
// The new context will render to the OpenAL Device just created
|
||||
newContext = alcCreateContext(newDevice, 0);
|
||||
if (newContext != NULL) {
|
||||
// Make the new context the Current OpenAL Context
|
||||
alcMakeContextCurrent(newContext);
|
||||
}
|
||||
}
|
||||
|
||||
atexit(TeardownOpenAL);
|
||||
alGetError();
|
||||
[self initListener];
|
||||
}
|
||||
|
||||
- (void)initListener {
|
||||
listener = [[PASoundListener alloc] init];
|
||||
}
|
||||
|
||||
- (PASoundSource *)addSound:(NSString *)name withExtension:(NSString *)ext position:(CGPoint)pos looped:(BOOL)yn {
|
||||
PASoundSource *sound = [[PASoundSource alloc] initWithPosition:pos file:name extension:ext looped:yn];
|
||||
if (sound) {
|
||||
[sounds setObject:sound forKey:[NSString stringWithFormat:@"%@.%@",name,ext]];
|
||||
[sound release];
|
||||
}
|
||||
return sound;
|
||||
}
|
||||
- (PASoundSource *)addSound:(NSString *)name withPosition:(CGPoint)pos looped:(BOOL)yn {
|
||||
return [self addSound:name withExtension:@"wav" position:pos looped:yn];
|
||||
}
|
||||
|
||||
- (PASoundSource *)sound:(NSString *)name withExtension:(NSString *)ext {
|
||||
NSString *key = [NSString stringWithFormat:@"%@.%@",name,ext];
|
||||
if ([[sounds allKeys] containsObject:key]) {
|
||||
return [sounds objectForKey:key];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
- (PASoundSource *)sound:(NSString *)name {
|
||||
return [self sound:name withExtension:@"wav"];
|
||||
}
|
||||
|
||||
- (BOOL)play:(NSString *)name withExtension:(NSString *)ext {
|
||||
PASoundSource *sound = [self sound:name withExtension:ext];
|
||||
if (sound) {
|
||||
[sound playAtListenerPosition];
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
- (BOOL)play:(NSString *)name {
|
||||
return [self play:name withExtension:@"wav"];
|
||||
}
|
||||
|
||||
- (BOOL)stop:(NSString *)name withExtension:(NSString *)ext {
|
||||
PASoundSource *sound = [self sound:name withExtension:ext];
|
||||
if (sound) {
|
||||
[sound stop];
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
- (BOOL)stop:(NSString *)name {
|
||||
return [self stop:name withExtension:@"wav"];
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[sounds release];
|
||||
[listener release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
Executable
+64
@@ -0,0 +1,64 @@
|
||||
/* cocos2d for iPhone
|
||||
*
|
||||
* http://www.cocos2d-iphone.org
|
||||
*
|
||||
* Copyright (C) 2009 by Florin Dumitrescu.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the 'cocos2d for iPhone' license.
|
||||
*
|
||||
* You will find a copy of this license within the cocos2d for iPhone
|
||||
* distribution inside the "LICENSE" file.
|
||||
*
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <OpenAL/al.h>
|
||||
#import <OpenAL/alc.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
@interface PASoundSource : NSObject {
|
||||
CGPoint position;
|
||||
float orientation;
|
||||
NSString *file;
|
||||
NSString *extension;
|
||||
BOOL looped;
|
||||
BOOL isPlaying;
|
||||
|
||||
ALuint source;
|
||||
ALuint buffer;
|
||||
|
||||
float gain;
|
||||
}
|
||||
|
||||
@property (readwrite, assign) CGPoint position;
|
||||
@property (readwrite, assign) float orientation;
|
||||
@property (readwrite, copy) NSString *file;
|
||||
@property (readwrite, copy) NSString *extension;
|
||||
@property (readwrite, assign) BOOL looped;
|
||||
@property (readwrite, assign) BOOL isPlaying;
|
||||
|
||||
- (id)initWithPosition:(CGPoint)pos file:(NSString *)f extension:(NSString *)e looped:(BOOL)yn;
|
||||
- (id)initWithPosition:(CGPoint)pos file:(NSString *)f looped:(BOOL)yn;
|
||||
- (id)initWithPosition:(CGPoint)pos file:(NSString *)f;
|
||||
- (id)initWithFile:(NSString *)f extension:(NSString *)e looped:(BOOL)yn;
|
||||
- (id)initWithFile:(NSString *)f looped:(BOOL)yn;
|
||||
- (id)initWithFile:(NSString *)f;
|
||||
|
||||
- (void)initSource;
|
||||
- (void)initBuffer;
|
||||
|
||||
- (void)playAtPosition:(CGPoint)p restart:(BOOL)r;
|
||||
- (void)playAtPosition:(CGPoint)p;
|
||||
- (void)playWithRestart:(BOOL)r;
|
||||
- (void)play;
|
||||
- (void)playAtListenerPositionWithRestart:(BOOL)r;
|
||||
- (void)playAtListenerPosition;
|
||||
|
||||
- (void)stop;
|
||||
|
||||
- (void)setGain:(float)g;
|
||||
- (void)setRolloff:(float)factor;
|
||||
- (void)setPitch:(float)factor;
|
||||
|
||||
@end
|
||||
Executable
+401
@@ -0,0 +1,401 @@
|
||||
/* cocos2d for iPhone
|
||||
*
|
||||
* http://www.cocos2d-iphone.org
|
||||
*
|
||||
* Copyright (C) 2009 by Florin Dumitrescu.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the 'cocos2d for iPhone' license.
|
||||
*
|
||||
* You will find a copy of this license within the cocos2d for iPhone
|
||||
* distribution inside the "LICENSE" file.
|
||||
*
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* Part of the source code in this class has been provided by Apple.
|
||||
* For full distribution terms, see the top of MyOpenALSupport.h header file.
|
||||
*
|
||||
*/
|
||||
|
||||
#import "PASoundSource.h"
|
||||
#import "PASoundMgr.h"
|
||||
#import "PASoundListener.h"
|
||||
#import "ivorbiscodec.h"
|
||||
#import "ivorbisfile.h"
|
||||
|
||||
#define kBuffSize (4096)
|
||||
#define kSoundReferenceDistance 20.0f
|
||||
|
||||
void* MyGetOpenALAudioData(CFURLRef inFileURL, ALsizei *outDataSize, ALenum *outDataFormat, ALsizei *outSampleRate);
|
||||
|
||||
void* MyGetOpenALAudioData(CFURLRef inFileURL, ALsizei *outDataSize, ALenum *outDataFormat, ALsizei *outSampleRate)
|
||||
{
|
||||
OSStatus err = noErr;
|
||||
UInt64 fileDataSize = 0;
|
||||
AudioStreamBasicDescription theFileFormat;
|
||||
UInt32 thePropertySize = sizeof(theFileFormat);
|
||||
AudioFileID afid = 0;
|
||||
void* theData = NULL;
|
||||
|
||||
// Open a file with ExtAudioFileOpen()
|
||||
err = AudioFileOpenURL(inFileURL, kAudioFileReadPermission, 0, &afid);
|
||||
if(err) {
|
||||
NSLog(@"MyGetOpenALAudioData: AudioFileOpenURL FAILED, Error = %ld", err);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// Get the audio data format
|
||||
err = AudioFileGetProperty(afid, kAudioFilePropertyDataFormat, &thePropertySize, &theFileFormat);
|
||||
if(err) {
|
||||
NSLog(@"PASoundEngine#MyGetOpenALAudioData: AudioFileGetProperty(kAudioFileProperty_DataFormat) FAILED, Error = %ld", err);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if (theFileFormat.mChannelsPerFrame > 2) {
|
||||
NSLog(@"PASoundEngine#MyGetOpenALAudioData - Unsupported Format, channel count is greater than stereo");
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ((theFileFormat.mFormatID != kAudioFormatLinearPCM) || (!TestAudioFormatNativeEndian(theFileFormat))) {
|
||||
NSLog(@"PASoundEngine#MyGetOpenALAudioData - Unsupported Format, must be little-endian PCM");
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ((theFileFormat.mBitsPerChannel != 8) && (theFileFormat.mBitsPerChannel != 16)) {
|
||||
NSLog(@"MyGetOpenALAudioData - Unsupported Format, must be 8 or 16 bit PCM\n");
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
|
||||
thePropertySize = sizeof(fileDataSize);
|
||||
err = AudioFileGetProperty(afid, kAudioFilePropertyAudioDataByteCount, &thePropertySize, &fileDataSize);
|
||||
if(err) {
|
||||
NSLog(@"PASoundEngine#MyGetOpenALAudioData: AudioFileGetProperty(kAudioFilePropertyAudioDataByteCount) FAILED, Error = %ld", err);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// Read all the data into memory
|
||||
UInt32 dataSize = (UInt32) fileDataSize;
|
||||
theData = malloc(dataSize);
|
||||
if (theData)
|
||||
{
|
||||
AudioFileReadBytes(afid, false, 0, &dataSize, theData);
|
||||
if(err == noErr)
|
||||
{
|
||||
// success
|
||||
*outDataSize = (ALsizei)dataSize;
|
||||
*outDataFormat = (theFileFormat.mChannelsPerFrame > 1) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16;
|
||||
*outSampleRate = (ALsizei)theFileFormat.mSampleRate;
|
||||
}
|
||||
else
|
||||
{
|
||||
// failure
|
||||
free (theData);
|
||||
theData = NULL; // make sure to return NULL
|
||||
NSLog(@"PASoundEngine#MyGetOpenALAudioData: ExtAudioFileRead FAILED, Error = %ld", err);
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
// Dispose the ExtAudioFileRef, it is no longer needed
|
||||
if (afid) AudioFileClose(afid);
|
||||
return theData;
|
||||
}
|
||||
|
||||
@implementation PASoundSource
|
||||
|
||||
@synthesize file, extension, looped, isPlaying;
|
||||
|
||||
- (id)init {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// initializers with position
|
||||
- (id)initWithPosition:(CGPoint)pos file:(NSString *)f extension:(NSString *)e looped:(BOOL)yn {
|
||||
if ((self = [super init])) {
|
||||
self.file = f;
|
||||
self.extension = e;
|
||||
self.looped = yn;
|
||||
self.isPlaying = NO;
|
||||
[self initBuffer];
|
||||
[self initSource];
|
||||
self.position = pos;
|
||||
self.orientation = 0.0f;
|
||||
gain = 1.0f;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
- (id)initWithPosition:(CGPoint)pos file:(NSString *)f looped:(BOOL)yn{
|
||||
return [self initWithPosition:pos file:f extension:@"wav" looped:yn];
|
||||
}
|
||||
- (id)initWithPosition:(CGPoint)pos file:(NSString *)f {
|
||||
return [self initWithPosition:pos file:f extension:@"wav" looped:NO];
|
||||
}
|
||||
|
||||
// initializers without position (will have to be spcified at play time) -- defaulting to CGPointZero
|
||||
- (id)initWithFile:(NSString *)f extension:(NSString *)e looped:(BOOL)yn {
|
||||
return [self initWithPosition:CGPointZero file:f extension:e looped:yn];
|
||||
}
|
||||
- (id)initWithFile:(NSString *)f looped:(BOOL)yn {
|
||||
return [self initWithPosition:CGPointZero file:f extension:@"wav" looped:yn];
|
||||
}
|
||||
- (id)initWithFile:(NSString *)f {
|
||||
return [self initWithPosition:CGPointZero file:f extension:@"wav" looped:NO];
|
||||
}
|
||||
|
||||
- (void)initBuffer {
|
||||
ALenum error = AL_NO_ERROR;
|
||||
ALenum format = AL_FORMAT_STEREO16;
|
||||
ALvoid* data = NULL;
|
||||
ALsizei size = 0;
|
||||
ALsizei freq = 0;
|
||||
|
||||
NSBundle* bundle = [NSBundle mainBundle];
|
||||
|
||||
// get some audio data from a wave file
|
||||
CFURLRef fileURL = (CFURLRef)[[NSURL fileURLWithPath:[bundle pathForResource:self.file ofType:self.extension]] retain];
|
||||
|
||||
if (fileURL) {
|
||||
|
||||
// load buffer data based on the file format guessed from the extension
|
||||
if ([self.extension isEqualToString:@"wav"]) {
|
||||
// WAV
|
||||
data = MyGetOpenALAudioData(fileURL, &size, &format, &freq);
|
||||
|
||||
} else if ([self.extension isEqualToString:@"ogg"]) {
|
||||
// XXX
|
||||
// XXX Big files will have a lot of performance problems
|
||||
// XXX
|
||||
// XXX is ov_open_callbacks more efficient ?
|
||||
// XXX
|
||||
// OGG
|
||||
NSString *fsPath = [(NSURL *)fileURL path];
|
||||
FILE *fh;
|
||||
if ((fh = fopen([fsPath UTF8String], "r")) != NULL) {
|
||||
// open ogg file
|
||||
OggVorbis_File vf;
|
||||
int eof = 0;
|
||||
int current_section;
|
||||
|
||||
if(ov_open(fh, &vf, NULL, 0) < 0) {
|
||||
NSLog(@"PASoundEngine: Input does not appear to be an Ogg bitstream");
|
||||
[NSException raise:@"PASoundEngine:InvalidOggFormat" format:@"InvalidOggFormat"];
|
||||
}
|
||||
|
||||
// get meta info (sample rate & mono/stereo format)
|
||||
vorbis_info *vi = ov_info(&vf,-1);
|
||||
freq = (ALsizei)vi->rate;
|
||||
format = (vi->channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
|
||||
|
||||
// decode data
|
||||
size = 0;
|
||||
char tmpBuff[kBuffSize];
|
||||
char *newData;
|
||||
while(!eof) {
|
||||
|
||||
int ret = ov_read(&vf, &tmpBuff[0], kBuffSize, ¤t_section);
|
||||
if (ret == 0) {
|
||||
eof = 1;
|
||||
} else if (ret < 0) {
|
||||
/* error in the stream. Not a problem, just reporting it in
|
||||
case we (the app) cares. In this case, we don't. */
|
||||
NSLog(@"PASoundEngine:Error reading buffer");
|
||||
[NSException raise:@"PASoundEngine:Error reading file" format:@"Error reading file"];
|
||||
} else {
|
||||
size += ret;
|
||||
|
||||
// 1st malloc
|
||||
if( !data )
|
||||
newData = malloc(ret);
|
||||
else
|
||||
newData = realloc( data, size);
|
||||
|
||||
if( ! newData ) {
|
||||
NSLog(@"PASoundEngine: Not enough memory");
|
||||
[NSException raise:@"PASoundEngine:NotEnoughMemory" format:@"NotEnoughMemory"];
|
||||
}
|
||||
data = newData;
|
||||
int dst = (int)data + (size-ret);
|
||||
memcpy( (char*)dst, &tmpBuff[0], ret);
|
||||
}
|
||||
}
|
||||
|
||||
// close ogg file
|
||||
ov_clear(&vf);
|
||||
} else {
|
||||
NSLog(@"PASoundEngine: Could not open file");
|
||||
[NSException raise:@"PASoundEngine:InvalidOggFormat" format:@"InvalidOggFormat"];
|
||||
}
|
||||
fclose(fh);
|
||||
}
|
||||
|
||||
CFRelease(fileURL);
|
||||
|
||||
if((error = alGetError()) != AL_NO_ERROR) {
|
||||
NSLog(@"PASoundEngine: Error loading sound: %x", error);
|
||||
[NSException raise:@"PASoundEngine:ErrorLoadingSound" format:@"ErrorLoadingSound"];
|
||||
|
||||
}
|
||||
|
||||
alGenBuffers(1, &buffer);
|
||||
alBufferData(buffer, format, data, size, freq);
|
||||
free(data);
|
||||
|
||||
if((error = alGetError()) != AL_NO_ERROR) {
|
||||
NSLog(@"PASoundEngine: Error attaching audio to buffer: %x", error);
|
||||
}
|
||||
}
|
||||
else {
|
||||
NSLog(@"Could not find file");
|
||||
[NSException raise:@"PASoundEngine:CouldNotFindfile" format:@"CouldNotFindFile"];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)initSource {
|
||||
ALenum error = AL_NO_ERROR;
|
||||
alGetError(); // Clear the error
|
||||
|
||||
alGenSources(1, &source);
|
||||
|
||||
// Turn Looping ON?
|
||||
if (self.looped) {
|
||||
alSourcei(source, AL_LOOPING, AL_TRUE);
|
||||
}
|
||||
|
||||
// Set Source Reference Distance
|
||||
alSourcef(source, AL_REFERENCE_DISTANCE, kSoundReferenceDistance);
|
||||
|
||||
// attach OpenAL Buffer to OpenAL Source
|
||||
alSourcei(source, AL_BUFFER, buffer);
|
||||
|
||||
if((error = alGetError()) != AL_NO_ERROR) {
|
||||
NSLog(@"PASoundEngine: Error attaching buffer to source: %x", error);
|
||||
[NSException raise:@"PASoundEngine:AttachingToBuffer" format:@"AttachingToBuffer"];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setGain:(float)g {
|
||||
gain = g;
|
||||
alSourcef(source, AL_GAIN, g * [[PASoundMgr sharedSoundManager] soundsMasterGain]);
|
||||
}
|
||||
- (void)setRolloff:(float)factor{
|
||||
alSourcef(source, AL_ROLLOFF_FACTOR, factor);
|
||||
}
|
||||
- (void)setPitch:(float)factor {
|
||||
alSourcef(source, AL_PITCH, factor);
|
||||
}
|
||||
|
||||
// play messages
|
||||
- (void)playAtPosition:(CGPoint)p restart:(BOOL)r {
|
||||
CGPoint currentPos = [self position];
|
||||
ALint state;
|
||||
if ((p.x != currentPos.x) || (p.y != currentPos.y)) {
|
||||
[self setPosition:p];
|
||||
}
|
||||
alGetSourcei(source, AL_SOURCE_STATE, &state);
|
||||
if ((state == AL_PLAYING) && r) {
|
||||
// stop it before replaying
|
||||
[self stop];
|
||||
// get current state
|
||||
alGetSourcei(source, AL_SOURCE_STATE, &state);
|
||||
}
|
||||
if (state != AL_PLAYING) {
|
||||
alGetError();
|
||||
ALenum error;
|
||||
[self setGain:gain];
|
||||
alSourcePlay(source);
|
||||
if((error = alGetError()) != AL_NO_ERROR) {
|
||||
NSLog(@"PASoundEngine: Error starting source: %x", error);
|
||||
} else {
|
||||
// Mark our state as playing (the view looks at this)
|
||||
self.isPlaying = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
- (void)playAtPosition:(CGPoint)p {
|
||||
return [self playAtPosition:p restart:NO];
|
||||
}
|
||||
- (void)playWithRestart:(BOOL)r {
|
||||
return [self playAtPosition:self.position restart:r];
|
||||
}
|
||||
- (void)play {
|
||||
return [self playAtPosition:self.position restart:NO];
|
||||
}
|
||||
- (void)playAtListenerPositionWithRestart:(BOOL)r {
|
||||
return [self playAtPosition:[[[PASoundMgr sharedSoundManager] listener] position] restart:r];
|
||||
}
|
||||
- (void)playAtListenerPosition {
|
||||
return [self playAtListenerPositionWithRestart:NO];
|
||||
}
|
||||
|
||||
- (void)stop {
|
||||
alGetError();
|
||||
ALenum error;
|
||||
alSourceStop(source);
|
||||
if((error = alGetError()) != AL_NO_ERROR) {
|
||||
NSLog(@"PASoundEngine: Error stopping source: %x", error);
|
||||
} else {
|
||||
// Mark our state as not playing (the view looks at this)
|
||||
self.isPlaying = NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (CGPoint)position {
|
||||
return position;
|
||||
}
|
||||
- (void)setPosition:(CGPoint)pos {
|
||||
/* needed for Cocos2d demo 'SoundEngineTest'
|
||||
float x,y;
|
||||
position = pos;
|
||||
switch ( [[CCDirector sharedDirector] deviceOrientation] ) {
|
||||
case CCDeviceOrientationLandscapeLeft:
|
||||
x = pos.x - 240.0f;
|
||||
y = 160.0f - pos.y;
|
||||
break;
|
||||
case CCDeviceOrientationLandscapeRight:
|
||||
// XXX: set correct orientation
|
||||
x = pos.x - 240.0f;
|
||||
y = 160.0f - pos.y;
|
||||
break;
|
||||
case CCDeviceOrientationPortrait:
|
||||
x = pos.x;
|
||||
y = pos.y;
|
||||
break;
|
||||
case CCDeviceOrientationPortraitUpsideDown:
|
||||
// XXX: set correct orientation
|
||||
x = pos.x;
|
||||
y = pos.y;
|
||||
break;
|
||||
}
|
||||
*/
|
||||
float sourcePosAL[] = {pos.x, pos.y, 0.0f};
|
||||
alSourcefv(source, AL_POSITION, sourcePosAL);
|
||||
}
|
||||
|
||||
- (float)orientation {
|
||||
return orientation;
|
||||
}
|
||||
- (void)setOrientation:(float)o {
|
||||
orientation = o;
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc {
|
||||
[self stop];
|
||||
|
||||
alGetError();
|
||||
ALenum error;
|
||||
alSourcei(source, AL_BUFFER, 0); // dissasociate buffer
|
||||
alDeleteBuffers(1, &buffer);
|
||||
if((error = alGetError()) != AL_NO_ERROR) {
|
||||
printf("error deleting buffer: %x\n", error);
|
||||
}
|
||||
alDeleteSources(1, &source);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
//
|
||||
// Prefix header for all source files of the 'vorbis' target in the 'vorbis' project
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Foundation/Foundation.h>
|
||||
#endif
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// vorbis.h
|
||||
// vorbis
|
||||
//
|
||||
// Created by Danila Shikulin on 16/4/12.
|
||||
// Copyright (c) 2012 COS. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface vorbis : NSObject
|
||||
|
||||
@end
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// vorbis.m
|
||||
// vorbis
|
||||
//
|
||||
// Created by Danila Shikulin on 16/4/12.
|
||||
// Copyright (c) 2012 COS. All rights reserved.
|
||||
//
|
||||
|
||||
#import "vorbis.h"
|
||||
|
||||
@implementation vorbis
|
||||
|
||||
@end
|
||||
Reference in new issue
Block a user