Joshua Moerman
12 years ago
4 changed files with 472 additions and 1 deletions
@ -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 <OpenAL/al.h> |
||||
|
#include <OpenAL/alc.h> |
||||
|
#include <CoreFoundation/CFURL.h> |
||||
|
|
||||
|
|
||||
|
//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 |
||||
|
|
||||
|
|
@ -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 <UIKit/UIKit.h> |
||||
|
#include "CDOpenALSupport.h" |
||||
|
#include <AudioToolbox/AudioToolbox.h> |
||||
|
#include <AudioToolbox/ExtendedAudioFile.h> |
||||
|
|
||||
|
//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); |
||||
|
} |
||||
|
} |
||||
|
|
@ -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 <iostream> |
||||
|
|
||||
|
#include <OpenAL/al.h> |
||||
|
#include <OpenAL/alc.h> |
||||
|
|
||||
|
#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 |
Reference in new issue