From 029347619ba35724904b3e21865391d4c0b02bee Mon Sep 17 00:00:00 2001 From: Joshua Moerman Date: Fri, 25 Jan 2013 21:22:36 +0100 Subject: [PATCH] Added very basic support for sound (via AL), also uses CDOpenALSupport --- J.xcodeproj/project.pbxproj | 31 ++++- J/CDOpenALSupport.h | 77 +++++++++++ J/CDOpenALSupport.m | 250 ++++++++++++++++++++++++++++++++++++ J/sound.h | 115 +++++++++++++++++ 4 files changed, 472 insertions(+), 1 deletion(-) create mode 100644 J/CDOpenALSupport.h create mode 100644 J/CDOpenALSupport.m create mode 100644 J/sound.h diff --git a/J.xcodeproj/project.pbxproj b/J.xcodeproj/project.pbxproj index f3a243d..2f9ca95 100644 --- a/J.xcodeproj/project.pbxproj +++ b/J.xcodeproj/project.pbxproj @@ -11,12 +11,17 @@ 425E9DF6140A774D00A81A65 /* basic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 425E9DF5140A774D00A81A65 /* basic.cpp */; }; 425E9DF9140A7EB400A81A65 /* fbo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 425E9DF8140A7EB400A81A65 /* fbo.mm */; }; 425E9DFB140A846700A81A65 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 425E9DFA140A846700A81A65 /* QuartzCore.framework */; }; - 425E9E02140A96C400A81A65 /* J.h in Headers */ = {isa = PBXBuildFile; fileRef = 4268136D140A321800CBF943 /* J.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 425E9E02140A96C400A81A65 /* J.h in Headers */ = {isa = PBXBuildFile; fileRef = 4268136D140A321800CBF943 /* J.h */; settings = {ATTRIBUTES = (); }; }; 42681369140A321800CBF943 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42681368140A321800CBF943 /* Foundation.framework */; }; 4268136F140A321800CBF943 /* J.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4268136E140A321800CBF943 /* J.mm */; }; 4283A45F14115AC400036A5D /* interpolator.h in Headers */ = {isa = PBXBuildFile; fileRef = 4283A45E14115AC300036A5D /* interpolator.h */; }; 4283A4641411707700036A5D /* array.h in Headers */ = {isa = PBXBuildFile; fileRef = 4283A4631411707700036A5D /* array.h */; }; 429E3BAB159616FD0044306C /* texture_objc.mm in Sources */ = {isa = PBXBuildFile; fileRef = 429E3BAA159616FD0044306C /* texture_objc.mm */; }; + 42C7D6C016B31E7200DA372A /* sound.h in Headers */ = {isa = PBXBuildFile; fileRef = 42C7D6BF16B31E7200DA372A /* sound.h */; }; + 42C7D6C316B31E8B00DA372A /* CDOpenALSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 42C7D6C116B31E8B00DA372A /* CDOpenALSupport.h */; }; + 42C7D6C416B31E8B00DA372A /* CDOpenALSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 42C7D6C216B31E8B00DA372A /* CDOpenALSupport.m */; }; + 42C7D6CA16B31F1900DA372A /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C7D6C616B31EE200DA372A /* OpenAL.framework */; }; + 42C7D6CB16B31F1E00DA372A /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C7D6C816B31EE800DA372A /* AudioToolbox.framework */; }; 42ED6A6B140A380000402F76 /* fbo.h in Headers */ = {isa = PBXBuildFile; fileRef = 42ED6A68140A380000402F76 /* fbo.h */; }; 42ED6A6C140A380000402F76 /* shader.h in Headers */ = {isa = PBXBuildFile; fileRef = 42ED6A69140A380000402F76 /* shader.h */; }; 42ED6A6D140A380000402F76 /* to_string.h in Headers */ = {isa = PBXBuildFile; fileRef = 42ED6A6A140A380000402F76 /* to_string.h */; }; @@ -37,6 +42,11 @@ 429E3BA715960FCA0044306C /* texture.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = texture.h; sourceTree = ""; }; 429E3BA9159616C00044306C /* texture_objc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = texture_objc.h; sourceTree = ""; }; 429E3BAA159616FD0044306C /* texture_objc.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = texture_objc.mm; sourceTree = ""; }; + 42C7D6BF16B31E7200DA372A /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = ""; }; + 42C7D6C116B31E8B00DA372A /* CDOpenALSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDOpenALSupport.h; sourceTree = ""; }; + 42C7D6C216B31E8B00DA372A /* CDOpenALSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDOpenALSupport.m; sourceTree = ""; }; + 42C7D6C616B31EE200DA372A /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = System/Library/Frameworks/OpenAL.framework; sourceTree = SDKROOT; }; + 42C7D6C816B31EE800DA372A /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; 42ED6A68140A380000402F76 /* fbo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fbo.h; sourceTree = ""; }; 42ED6A69140A380000402F76 /* shader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shader.h; sourceTree = ""; }; 42ED6A6A140A380000402F76 /* to_string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = to_string.h; sourceTree = ""; }; @@ -47,6 +57,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 42C7D6CB16B31F1E00DA372A /* AudioToolbox.framework in Frameworks */, + 42C7D6CA16B31F1900DA372A /* OpenAL.framework in Frameworks */, 425E9DFB140A846700A81A65 /* QuartzCore.framework in Frameworks */, 42681369140A321800CBF943 /* Foundation.framework in Frameworks */, ); @@ -87,6 +99,8 @@ 42681367140A321800CBF943 /* Frameworks */ = { isa = PBXGroup; children = ( + 42C7D6C816B31EE800DA372A /* AudioToolbox.framework */, + 42C7D6C616B31EE200DA372A /* OpenAL.framework */, 425E9DFA140A846700A81A65 /* QuartzCore.framework */, 42681368140A321800CBF943 /* Foundation.framework */, ); @@ -96,6 +110,7 @@ 4268136A140A321800CBF943 /* J */ = { isa = PBXGroup; children = ( + 42C7D6BE16B31E5400DA372A /* AL */, 4283A46114115AD400036A5D /* GL */, 4283A46214116ECB00036A5D /* utils */, 4268136D140A321800CBF943 /* J.h */, @@ -136,6 +151,16 @@ name = utils; sourceTree = ""; }; + 42C7D6BE16B31E5400DA372A /* AL */ = { + isa = PBXGroup; + children = ( + 42C7D6C116B31E8B00DA372A /* CDOpenALSupport.h */, + 42C7D6C216B31E8B00DA372A /* CDOpenALSupport.m */, + 42C7D6BF16B31E7200DA372A /* sound.h */, + ); + name = AL; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -150,6 +175,8 @@ 425E9DF2140A74DA00A81A65 /* basic.h in Headers */, 4283A45F14115AC400036A5D /* interpolator.h in Headers */, 4283A4641411707700036A5D /* array.h in Headers */, + 42C7D6C016B31E7200DA372A /* sound.h in Headers */, + 42C7D6C316B31E8B00DA372A /* CDOpenALSupport.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -207,6 +234,8 @@ 4268136F140A321800CBF943 /* J.mm in Sources */, 425E9DF6140A774D00A81A65 /* basic.cpp in Sources */, 425E9DF9140A7EB400A81A65 /* fbo.mm in Sources */, + 429E3BAB159616FD0044306C /* texture_objc.mm in Sources */, + 42C7D6C416B31E8B00DA372A /* CDOpenALSupport.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/J/CDOpenALSupport.h b/J/CDOpenALSupport.h new file mode 100644 index 0000000..a479d62 --- /dev/null +++ b/J/CDOpenALSupport.h @@ -0,0 +1,77 @@ +/* + + 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) 2009 Apple Inc. All Rights Reserved. + + $Id$ + */ + +/* + This file contains code from version 1.1 and 1.4 of MyOpenALSupport.h taken from Apple's oalTouch version. + The 1.4 version code is used for loading IMA4 files, however, this code causes very noticeable clicking + when used to load wave files that are looped so the 1.1 version code is used specifically for loading + wav files. + */ + +#ifndef __CD_OPENAL_H +#define __CD_OPENAL_H + +#ifdef __cplusplus +extern "C" { +#endif + + +#include +#include +#include + + +//Taken from oalTouch MyOpenALSupport 1.1 +void* CDloadWaveAudioData(CFURLRef inFileURL, ALsizei *outDataSize, ALenum *outDataFormat, ALsizei* outSampleRate); +void* CDloadCafAudioData(CFURLRef inFileURL, ALsizei *outDataSize, ALenum *outDataFormat, ALsizei* outSampleRate); +void* CDGetOpenALAudioData(CFURLRef inFileURL, ALsizei *outDataSize, ALenum *outDataFormat, ALsizei* outSampleRate); + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/J/CDOpenALSupport.m b/J/CDOpenALSupport.m new file mode 100644 index 0000000..3a333e7 --- /dev/null +++ b/J/CDOpenALSupport.m @@ -0,0 +1,250 @@ +/* + + 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) 2009 Apple Inc. All Rights Reserved. + + $Id: CDOpenALSupport.h 16 2010-03-11 06:22:10Z steveoldmeadow $ + */ + +#include +#include "CDOpenALSupport.h" +#include +#include + +//Taken from oalTouch MyOpenALSupport 1.1 +void* CDloadWaveAudioData(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\n", err); goto Exit; } + + // Get the audio data format + err = AudioFileGetProperty(afid, kAudioFilePropertyDataFormat, &thePropertySize, &theFileFormat); + if(err) { NSLog(@"MyGetOpenALAudioData: AudioFileGetProperty(kAudioFileProperty_DataFormat) FAILED, Error = %ld\n", err); goto Exit; } + + if (theFileFormat.mChannelsPerFrame > 2) { + NSLog(@"MyGetOpenALAudioData - Unsupported Format, channel count is greater than stereo\n"); goto Exit; + } + + if ((theFileFormat.mFormatID != kAudioFormatLinearPCM) || (!TestAudioFormatNativeEndian(theFileFormat))) { + NSLog(@"MyGetOpenALAudioData - Unsupported Format, must be little-endian PCM\n"); 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(@"MyGetOpenALAudioData: AudioFileGetProperty(kAudioFilePropertyAudioDataByteCount) FAILED, Error = %ld\n", err); goto Exit; } + + // Read all the data into memory + UInt32 dataSize = (UInt32)fileDataSize; + theData = malloc(dataSize); + if (theData) + { + memset(theData, 0, dataSize); + + AudioFileReadBytes(afid, false, 0, &dataSize, theData); + if(err == noErr) + { + // success + *outDataSize = (ALsizei)dataSize; + //This fix was added by me, however, 8 bit sounds have a clipping sound at the end so aren't really usable (SO) + if (theFileFormat.mBitsPerChannel == 16) { + *outDataFormat = (theFileFormat.mChannelsPerFrame > 1) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16; + } else { + *outDataFormat = (theFileFormat.mChannelsPerFrame > 1) ? AL_FORMAT_STEREO8 : AL_FORMAT_MONO8; + } + *outSampleRate = (ALsizei)theFileFormat.mSampleRate; + } + else + { + // failure + free (theData); + theData = NULL; // make sure to return NULL + NSLog(@"MyGetOpenALAudioData: ExtAudioFileRead FAILED, Error = %ld\n", err); goto Exit; + } + } + +Exit: + // Dispose the ExtAudioFileRef, it is no longer needed + if (afid) AudioFileClose(afid); + return theData; +} + +//Taken from oalTouch MyOpenALSupport 1.4 +void* CDloadCafAudioData(CFURLRef inFileURL, ALsizei *outDataSize, ALenum *outDataFormat, ALsizei* outSampleRate) +{ + OSStatus status = noErr; + BOOL abort = NO; + SInt64 theFileLengthInFrames = 0; + AudioStreamBasicDescription theFileFormat; + UInt32 thePropertySize = sizeof(theFileFormat); + ExtAudioFileRef extRef = NULL; + void* theData = NULL; + AudioStreamBasicDescription theOutputFormat; + UInt32 dataSize = 0; + + // Open a file with ExtAudioFileOpen() + status = ExtAudioFileOpenURL(inFileURL, &extRef); + if (status != noErr) + { + NSLog(@"MyGetOpenALAudioData: ExtAudioFileOpenURL FAILED, Error = %ld\n", status); + abort = YES; + } + if (abort) + goto Exit; + + // Get the audio data format + status = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &theFileFormat); + if (status != noErr) + { + NSLog(@"MyGetOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_FileDataFormat) FAILED, Error = %ld\n", status); + abort = YES; + } + if (abort) + goto Exit; + + if (theFileFormat.mChannelsPerFrame > 2) + { + NSLog(@"MyGetOpenALAudioData - Unsupported Format, channel count is greater than stereo\n"); + abort = YES; + } + if (abort) + goto Exit; + + // Set the client format to 16 bit signed integer (native-endian) data + // Maintain the channel count and sample rate of the original source format + theOutputFormat.mSampleRate = theFileFormat.mSampleRate; + theOutputFormat.mChannelsPerFrame = theFileFormat.mChannelsPerFrame; + + theOutputFormat.mFormatID = kAudioFormatLinearPCM; + theOutputFormat.mBytesPerPacket = 2 * theOutputFormat.mChannelsPerFrame; + theOutputFormat.mFramesPerPacket = 1; + theOutputFormat.mBytesPerFrame = 2 * theOutputFormat.mChannelsPerFrame; + theOutputFormat.mBitsPerChannel = 16; + theOutputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger; + + // Set the desired client (output) data format + status = ExtAudioFileSetProperty(extRef, kExtAudioFileProperty_ClientDataFormat, sizeof(theOutputFormat), &theOutputFormat); + if (status != noErr) + { + NSLog(@"MyGetOpenALAudioData: ExtAudioFileSetProperty(kExtAudioFileProperty_ClientDataFormat) FAILED, Error = %ld\n", status); + abort = YES; + } + if (abort) + goto Exit; + + // Get the total frame count + thePropertySize = sizeof(theFileLengthInFrames); + status = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileLengthFrames, &thePropertySize, &theFileLengthInFrames); + if (status != noErr) + { + NSLog(@"MyGetOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_FileLengthFrames) FAILED, Error = %ld\n", status); + abort = YES; + } + if (abort) + goto Exit; + + // Read all the data into memory + dataSize = (UInt32) theFileLengthInFrames * theOutputFormat.mBytesPerFrame; + theData = malloc(dataSize); + if (theData) + { + memset(theData, 0, dataSize); + + AudioBufferList theDataBuffer; + theDataBuffer.mNumberBuffers = 1; + theDataBuffer.mBuffers[0].mDataByteSize = dataSize; + theDataBuffer.mBuffers[0].mNumberChannels = theOutputFormat.mChannelsPerFrame; + theDataBuffer.mBuffers[0].mData = theData; + + // Read the data into an AudioBufferList + status = ExtAudioFileRead(extRef, (UInt32*)&theFileLengthInFrames, &theDataBuffer); + if(status == noErr) + { + // success + *outDataSize = (ALsizei)dataSize; + *outDataFormat = (theOutputFormat.mChannelsPerFrame > 1) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16; + *outSampleRate = (ALsizei)theOutputFormat.mSampleRate; + } + else + { + // failure + free (theData); + theData = NULL; // make sure to return NULL + NSLog(@"MyGetOpenALAudioData: ExtAudioFileRead FAILED, Error = %ld\n", status); + abort = YES; + } + } + if (abort) + goto Exit; + +Exit: + // Dispose the ExtAudioFileRef, it is no longer needed + if (extRef) ExtAudioFileDispose(extRef); + return theData; +} + +void* CDGetOpenALAudioData(CFURLRef inFileURL, ALsizei *outDataSize, ALenum *outDataFormat, ALsizei* outSampleRate) { + + CFStringRef extension = CFURLCopyPathExtension(inFileURL); + CFComparisonResult isWavFile = 0; + if (extension != NULL) { + isWavFile = CFStringCompare (extension,(CFStringRef)@"wav", kCFCompareCaseInsensitive); + CFRelease(extension); + } + + if (isWavFile == kCFCompareEqualTo) { + return CDloadWaveAudioData(inFileURL, outDataSize, outDataFormat, outSampleRate); + } else { + return CDloadCafAudioData(inFileURL, outDataSize, outDataFormat, outSampleRate); + } +} + diff --git a/J/sound.h b/J/sound.h new file mode 100644 index 0000000..b3c488d --- /dev/null +++ b/J/sound.h @@ -0,0 +1,115 @@ +// +// Sound.h +// SoundDrop2 +// +// Created by Joshua Moerman on 1/9/13. +// Copyright (c) 2013 Vadovas. All rights reserved. +// + +#ifndef SoundDrop2_Sound_h +#define SoundDrop2_Sound_h + +#include + +#include +#include + +#include "CDOpenALSupport.h" + + +namespace J { + +struct AL { + ALCdevice * device{nullptr}; + ALCcontext * context{nullptr}; + + AL(){ + // Initializing sound: + // NULL for the default device + device = alcOpenDevice(NULL); + if (device) { + // NULL for no attributes + context = alcCreateContext(device, NULL); + alcMakeContextCurrent(context); + } + } + + ~AL(){ + alcMakeContextCurrent(NULL); + alcDestroyContext(context); + alcCloseDevice(device); + } +}; + +struct Buffer { + ALuint buffer; + + Buffer(Buffer const &) = delete; + Buffer & operator=(Buffer const &) = delete; + + Buffer(Buffer && b){ + std::swap(buffer, b.buffer); + } + + Buffer & operator=(Buffer && b){ + std::swap(buffer, b.buffer); + return *this; + } + + Buffer(){ + alGenBuffers(1, &buffer); + } + + ~Buffer(){ + alDeleteBuffers(1, &buffer); + } +}; + +inline Buffer load_wav(std::string filename){ + Buffer b; + + void *data; + ALenum format; + ALsizei sizeInBytes; + ALsizei frequencyInHertz; + + data = CDGetOpenALAudioData((CFURLRef)[NSURL fileURLWithPath: [NSString stringWithUTF8String: filename.c_str()]], &sizeInBytes, &format, &frequencyInHertz); + alBufferData(b.buffer, format, data, sizeInBytes, frequencyInHertz); + free(data); + + return b; +} + +struct Source { + ALuint source; + + Source(Source const &) = delete; + Source & operator=(Source const &) = delete; + + Source(Buffer const & buffer){ + int r = rand() % 10; + float pitch = 0.5 + r*0.5; + + alGenSources(1, &source); + alSourcei(source, AL_BUFFER, buffer.buffer); + alSourcef(source, AL_PITCH, pitch); //? + } + + void play(){ + // will restart if already playing + alSourcePlay(source); + } + + ~Source(){ + // TODO: find out if this is needed + // NOTE: Buffers which are attached to a source can not be deleted + alSourcei(source, AL_BUFFER, 0); + + // this will stop the playing + alDeleteSources(1, &source); + } +}; + +} // namespace J + +#endif