summary refs log tree commit diff stats
path: root/libs/CocosDenshion/CDOpenALSupport.m
diff options
context:
space:
mode:
Diffstat (limited to 'libs/CocosDenshion/CDOpenALSupport.m')
-rwxr-xr-xlibs/CocosDenshion/CDOpenALSupport.m246
1 files changed, 246 insertions, 0 deletions
diff --git a/libs/CocosDenshion/CDOpenALSupport.m b/libs/CocosDenshion/CDOpenALSupport.m new file mode 100755 index 0000000..ab0df8e --- /dev/null +++ b/libs/CocosDenshion/CDOpenALSupport.m
@@ -0,0 +1,246 @@
1/*
2
3 Disclaimer: IMPORTANT: This Apple software is supplied to you by
4 Apple Inc. ("Apple") in consideration of your agreement to the
5 following terms, and your use, installation, modification or
6 redistribution of this Apple software constitutes acceptance of these
7 terms. If you do not agree with these terms, please do not use,
8 install, modify or redistribute this Apple software.
9
10 In consideration of your agreement to abide by the following terms, and
11 subject to these terms, Apple grants you a personal, non-exclusive
12 license, under Apple's copyrights in this original Apple software (the
13 "Apple Software"), to use, reproduce, modify and redistribute the Apple
14 Software, with or without modifications, in source and/or binary forms;
15 provided that if you redistribute the Apple Software in its entirety and
16 without modifications, you must retain this notice and the following
17 text and disclaimers in all such redistributions of the Apple Software.
18 Neither the name, trademarks, service marks or logos of Apple Inc.
19 may be used to endorse or promote products derived from the Apple
20 Software without specific prior written permission from Apple. Except
21 as expressly stated in this notice, no other rights or licenses, express
22 or implied, are granted by Apple herein, including but not limited to
23 any patent rights that may be infringed by your derivative works or by
24 other works in which the Apple Software may be incorporated.
25
26 The Apple Software is provided by Apple on an "AS IS" basis. APPLE
27 MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
28 THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
29 FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
30 OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
31
32 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
33 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
36 MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
37 AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
38 STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
39 POSSIBILITY OF SUCH DAMAGE.
40
41 Copyright (C) 2009 Apple Inc. All Rights Reserved.
42
43 $Id: CDOpenALSupport.h 16 2010-03-11 06:22:10Z steveoldmeadow $
44 */
45
46#import "CDOpenALSupport.h"
47#import "CocosDenshion.h"
48#import <AudioToolbox/AudioToolbox.h>
49#import <AudioToolbox/ExtendedAudioFile.h>
50
51//Taken from oalTouch MyOpenALSupport 1.1
52void* CDloadWaveAudioData(CFURLRef inFileURL, ALsizei *outDataSize, ALenum *outDataFormat, ALsizei* outSampleRate)
53{
54 OSStatus err = noErr;
55 UInt64 fileDataSize = 0;
56 AudioStreamBasicDescription theFileFormat;
57 UInt32 thePropertySize = sizeof(theFileFormat);
58 AudioFileID afid = 0;
59 void* theData = NULL;
60
61 // Open a file with ExtAudioFileOpen()
62 err = AudioFileOpenURL(inFileURL, kAudioFileReadPermission, 0, &afid);
63 if(err) { CDLOG(@"MyGetOpenALAudioData: AudioFileOpenURL FAILED, Error = %ld\n", err); goto Exit; }
64
65 // Get the audio data format
66 err = AudioFileGetProperty(afid, kAudioFilePropertyDataFormat, &thePropertySize, &theFileFormat);
67 if(err) { CDLOG(@"MyGetOpenALAudioData: AudioFileGetProperty(kAudioFileProperty_DataFormat) FAILED, Error = %ld\n", err); goto Exit; }
68
69 if (theFileFormat.mChannelsPerFrame > 2) {
70 CDLOG(@"MyGetOpenALAudioData - Unsupported Format, channel count is greater than stereo\n"); goto Exit;
71 }
72
73 if ((theFileFormat.mFormatID != kAudioFormatLinearPCM) || (!TestAudioFormatNativeEndian(theFileFormat))) {
74 CDLOG(@"MyGetOpenALAudioData - Unsupported Format, must be little-endian PCM\n"); goto Exit;
75 }
76
77 if ((theFileFormat.mBitsPerChannel != 8) && (theFileFormat.mBitsPerChannel != 16)) {
78 CDLOG(@"MyGetOpenALAudioData - Unsupported Format, must be 8 or 16 bit PCM\n"); goto Exit;
79 }
80
81
82 thePropertySize = sizeof(fileDataSize);
83 err = AudioFileGetProperty(afid, kAudioFilePropertyAudioDataByteCount, &thePropertySize, &fileDataSize);
84 if(err) { CDLOG(@"MyGetOpenALAudioData: AudioFileGetProperty(kAudioFilePropertyAudioDataByteCount) FAILED, Error = %ld\n", err); goto Exit; }
85
86 // Read all the data into memory
87 UInt32 dataSize = (UInt32)fileDataSize;
88 theData = malloc(dataSize);
89 if (theData)
90 {
91 AudioFileReadBytes(afid, false, 0, &dataSize, theData);
92 if(err == noErr)
93 {
94 // success
95 *outDataSize = (ALsizei)dataSize;
96 //This fix was added by me, however, 8 bit sounds have a clipping sound at the end so aren't really usable (SO)
97 if (theFileFormat.mBitsPerChannel == 16) {
98 *outDataFormat = (theFileFormat.mChannelsPerFrame > 1) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16;
99 } else {
100 *outDataFormat = (theFileFormat.mChannelsPerFrame > 1) ? AL_FORMAT_STEREO8 : AL_FORMAT_MONO8;
101 }
102 *outSampleRate = (ALsizei)theFileFormat.mSampleRate;
103 }
104 else
105 {
106 // failure
107 free (theData);
108 theData = NULL; // make sure to return NULL
109 CDLOG(@"MyGetOpenALAudioData: ExtAudioFileRead FAILED, Error = %ld\n", err); goto Exit;
110 }
111 }
112
113Exit:
114 // Dispose the ExtAudioFileRef, it is no longer needed
115 if (afid) AudioFileClose(afid);
116 return theData;
117}
118
119//Taken from oalTouch MyOpenALSupport 1.4
120void* CDloadCafAudioData(CFURLRef inFileURL, ALsizei *outDataSize, ALenum *outDataFormat, ALsizei* outSampleRate)
121{
122 OSStatus status = noErr;
123 BOOL abort = NO;
124 SInt64 theFileLengthInFrames = 0;
125 AudioStreamBasicDescription theFileFormat;
126 UInt32 thePropertySize = sizeof(theFileFormat);
127 ExtAudioFileRef extRef = NULL;
128 void* theData = NULL;
129 AudioStreamBasicDescription theOutputFormat;
130 UInt32 dataSize = 0;
131
132 // Open a file with ExtAudioFileOpen()
133 status = ExtAudioFileOpenURL(inFileURL, &extRef);
134 if (status != noErr)
135 {
136 CDLOG(@"MyGetOpenALAudioData: ExtAudioFileOpenURL FAILED, Error = %ld\n", status);
137 abort = YES;
138 }
139 if (abort)
140 goto Exit;
141
142 // Get the audio data format
143 status = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &theFileFormat);
144 if (status != noErr)
145 {
146 CDLOG(@"MyGetOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_FileDataFormat) FAILED, Error = %ld\n", status);
147 abort = YES;
148 }
149 if (abort)
150 goto Exit;
151
152 if (theFileFormat.mChannelsPerFrame > 2)
153 {
154 CDLOG(@"MyGetOpenALAudioData - Unsupported Format, channel count is greater than stereo\n");
155 abort = YES;
156 }
157 if (abort)
158 goto Exit;
159
160 // Set the client format to 16 bit signed integer (native-endian) data
161 // Maintain the channel count and sample rate of the original source format
162 theOutputFormat.mSampleRate = theFileFormat.mSampleRate;
163 theOutputFormat.mChannelsPerFrame = theFileFormat.mChannelsPerFrame;
164
165 theOutputFormat.mFormatID = kAudioFormatLinearPCM;
166 theOutputFormat.mBytesPerPacket = 2 * theOutputFormat.mChannelsPerFrame;
167 theOutputFormat.mFramesPerPacket = 1;
168 theOutputFormat.mBytesPerFrame = 2 * theOutputFormat.mChannelsPerFrame;
169 theOutputFormat.mBitsPerChannel = 16;
170 theOutputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;
171
172 // Set the desired client (output) data format
173 status = ExtAudioFileSetProperty(extRef, kExtAudioFileProperty_ClientDataFormat, sizeof(theOutputFormat), &theOutputFormat);
174 if (status != noErr)
175 {
176 CDLOG(@"MyGetOpenALAudioData: ExtAudioFileSetProperty(kExtAudioFileProperty_ClientDataFormat) FAILED, Error = %ld\n", status);
177 abort = YES;
178 }
179 if (abort)
180 goto Exit;
181
182 // Get the total frame count
183 thePropertySize = sizeof(theFileLengthInFrames);
184 status = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileLengthFrames, &thePropertySize, &theFileLengthInFrames);
185 if (status != noErr)
186 {
187 CDLOG(@"MyGetOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_FileLengthFrames) FAILED, Error = %ld\n", status);
188 abort = YES;
189 }
190 if (abort)
191 goto Exit;
192
193 // Read all the data into memory
194 dataSize = (UInt32) theFileLengthInFrames * theOutputFormat.mBytesPerFrame;
195 theData = malloc(dataSize);
196 if (theData)
197 {
198 AudioBufferList theDataBuffer;
199 theDataBuffer.mNumberBuffers = 1;
200 theDataBuffer.mBuffers[0].mDataByteSize = dataSize;
201 theDataBuffer.mBuffers[0].mNumberChannels = theOutputFormat.mChannelsPerFrame;
202 theDataBuffer.mBuffers[0].mData = theData;
203
204 // Read the data into an AudioBufferList
205 status = ExtAudioFileRead(extRef, (UInt32*)&theFileLengthInFrames, &theDataBuffer);
206 if(status == noErr)
207 {
208 // success
209 *outDataSize = (ALsizei)dataSize;
210 *outDataFormat = (theOutputFormat.mChannelsPerFrame > 1) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16;
211 *outSampleRate = (ALsizei)theOutputFormat.mSampleRate;
212 }
213 else
214 {
215 // failure
216 free (theData);
217 theData = NULL; // make sure to return NULL
218 CDLOG(@"MyGetOpenALAudioData: ExtAudioFileRead FAILED, Error = %ld\n", status);
219 abort = YES;
220 }
221 }
222 if (abort)
223 goto Exit;
224
225Exit:
226 // Dispose the ExtAudioFileRef, it is no longer needed
227 if (extRef) ExtAudioFileDispose(extRef);
228 return theData;
229}
230
231void* CDGetOpenALAudioData(CFURLRef inFileURL, ALsizei *outDataSize, ALenum *outDataFormat, ALsizei* outSampleRate) {
232
233 CFStringRef extension = CFURLCopyPathExtension(inFileURL);
234 CFComparisonResult isWavFile = 0;
235 if (extension != NULL) {
236 isWavFile = CFStringCompare (extension,(CFStringRef)@"wav", kCFCompareCaseInsensitive);
237 CFRelease(extension);
238 }
239
240 if (isWavFile == kCFCompareEqualTo) {
241 return CDloadWaveAudioData(inFileURL, outDataSize, outDataFormat, outSampleRate);
242 } else {
243 return CDloadCafAudioData(inFileURL, outDataSize, outDataFormat, outSampleRate);
244 }
245}
246