OpenAL-61

This commit is contained in:
Lubos Dolezel 2020-02-13 09:56:58 +01:00
commit 109647f605
34 changed files with 20553 additions and 0 deletions

View File

@ -0,0 +1,745 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 42;
objects = {
/* Begin PBXAggregateTarget section */
8ACAAC9906528C3A00E2D337 /* All */ = {
isa = PBXAggregateTarget;
buildConfigurationList = 8ACD0BB40885C20A00D0637F /* Build configuration list for PBXAggregateTarget "All" */;
buildPhases = (
);
dependencies = (
8ACAAC9B06528C7E00E2D337 /* PBXTargetDependency */,
);
name = All;
productName = All;
};
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
8A0CB5BF097F5FC000B17352 /* CAAudioUnitOutputCapturer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A0CB5BD097F5FC000B17352 /* CAAudioUnitOutputCapturer.h */; };
8A10679108D8C3460060359C /* CAThreadSafeList.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A10678F08D8C3460060359C /* CAThreadSafeList.h */; };
8A3A1DA308EC575A008DD7C5 /* CABufferList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A3A1DA108EC575A008DD7C5 /* CABufferList.cpp */; };
8A3A1DA408EC575A008DD7C5 /* CABufferList.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A3A1DA208EC575A008DD7C5 /* CABufferList.h */; };
8A5E140608EB104300AFA934 /* oalCaptureDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A5E140408EB104300AFA934 /* oalCaptureDevice.h */; };
8A5E140708EB104300AFA934 /* oalCaptureDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A5E140508EB104300AFA934 /* oalCaptureDevice.cpp */; };
8A787DF406E7B40500CD7287 /* CADebugMacros.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A787DF306E7B40500CD7287 /* CADebugMacros.cpp */; };
8A7EE4560A02DD3900D94919 /* MacOSX_OALExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A7EE4550A02DD3900D94919 /* MacOSX_OALExtensions.h */; settings = {ATTRIBUTES = (Public, ); }; };
8A7EE4840A02DEB700D94919 /* alut.h in Headers */ = {isa = PBXBuildFile; fileRef = 984FDEC60433F5A20042B474 /* alut.h */; settings = {ATTRIBUTES = (); }; };
8A87DAC108B1099D00178F66 /* oalSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A87DABF08B1099D00178F66 /* oalSource.cpp */; };
8AC6BDCE09B39D9400242AEF /* al.h in Headers */ = {isa = PBXBuildFile; fileRef = 984FDEC20433F5A20042B474 /* al.h */; settings = {ATTRIBUTES = (Public, ); }; };
8AC6BDCF09B39D9400242AEF /* alc.h in Headers */ = {isa = PBXBuildFile; fileRef = 984FDEC30433F5A20042B474 /* alc.h */; settings = {ATTRIBUTES = (Public, ); }; };
8AC6BDD009B39D9400242AEF /* oalBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AB7B234053B3AC100A9757A /* oalBuffer.h */; };
8AC6BDD109B39D9400242AEF /* oalContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AB7B22C053B3AA700A9757A /* oalContext.h */; };
8AC6BDD209B39D9400242AEF /* oalDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A39B0B20533393F006B1D0F /* oalDevice.h */; };
8AC6BDD309B39D9400242AEF /* oalImp.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A986533053763B9003F7FA0 /* oalImp.h */; };
8AC6BDD409B39D9400242AEF /* oalOSX.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A0561E40546034200A003E7 /* oalOSX.h */; };
8AC6BDD509B39D9400242AEF /* oalSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AB7B230053B3AB500A9757A /* oalSource.h */; };
8AC6BDD709B39D9400242AEF /* CADebugMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = F40E4D31065E5DB9004336C3 /* CADebugMacros.h */; };
8AC6BDD809B39D9400242AEF /* CAGuard.h in Headers */ = {isa = PBXBuildFile; fileRef = F40E4D37065E5DB9004336C3 /* CAGuard.h */; };
8AC6BDD909B39D9400242AEF /* CAHostTimeBase.h in Headers */ = {isa = PBXBuildFile; fileRef = F40E4D3C065E5DB9004336C3 /* CAHostTimeBase.h */; };
8AC6BDDA09B39D9400242AEF /* CAMath.h in Headers */ = {isa = PBXBuildFile; fileRef = F40E4D42065E5DB9004336C3 /* CAMath.h */; };
8AC6BDDB09B39D9400242AEF /* CAMutex.h in Headers */ = {isa = PBXBuildFile; fileRef = F40E4D46065E5DB9004336C3 /* CAMutex.h */; };
8AC6BDDC09B39D9400242AEF /* CAStreamBasicDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = F40E4D54065E5DB9004336C3 /* CAStreamBasicDescription.h */; };
8AC6BDDD09B39D9400242AEF /* CAThreadSafeList.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A10678F08D8C3460060359C /* CAThreadSafeList.h */; };
8AC6BDDE09B39D9400242AEF /* oalCaptureDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A5E140408EB104300AFA934 /* oalCaptureDevice.h */; };
8AC6BDDF09B39D9400242AEF /* CABufferList.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A3A1DA208EC575A008DD7C5 /* CABufferList.h */; };
8AC6BDE009B39D9400242AEF /* CAAudioUnitOutputCapturer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A0CB5BD097F5FC000B17352 /* CAAudioUnitOutputCapturer.h */; };
8AC6BDE209B39D9400242AEF /* oalContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8AB7B22D053B3AA700A9757A /* oalContext.cpp */; };
8AC6BDE309B39D9400242AEF /* oalDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A39B0B30533393F006B1D0F /* oalDevice.cpp */; };
8AC6BDE409B39D9400242AEF /* oalImp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A986534053763B9003F7FA0 /* oalImp.cpp */; };
8AC6BDE509B39D9400242AEF /* oalOSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0561E50546034200A003E7 /* oalOSX.cpp */; };
8AC6BDE609B39D9400242AEF /* CAGuard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F40E4D36065E5DB9004336C3 /* CAGuard.cpp */; };
8AC6BDE709B39D9400242AEF /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F40E4D3B065E5DB9004336C3 /* CAHostTimeBase.cpp */; };
8AC6BDE809B39D9400242AEF /* CAMutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F40E4D45065E5DB9004336C3 /* CAMutex.cpp */; };
8AC6BDE909B39D9400242AEF /* CAStreamBasicDescription.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F40E4D53065E5DB9004336C3 /* CAStreamBasicDescription.cpp */; };
8AC6BDEB09B39D9400242AEF /* CADebugMacros.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A787DF306E7B40500CD7287 /* CADebugMacros.cpp */; };
8AC6BDEC09B39D9400242AEF /* oalSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A87DABF08B1099D00178F66 /* oalSource.cpp */; };
8AC6BDED09B39D9400242AEF /* oalBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8AF8503708D2513B004B64E7 /* oalBuffer.cpp */; };
8AC6BDEE09B39D9400242AEF /* oalCaptureDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A5E140508EB104300AFA934 /* oalCaptureDevice.cpp */; };
8AC6BDEF09B39D9400242AEF /* CABufferList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A3A1DA108EC575A008DD7C5 /* CABufferList.cpp */; };
8AC6BDF209B39D9400242AEF /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 981B79AD0523A4A500940F97 /* CoreAudio.framework */; };
8AC6BDF309B39D9400242AEF /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A482665053C8B290040E37D /* CoreFoundation.framework */; };
8AC6BDF409B39D9400242AEF /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A482667053C8B3F0040E37D /* AudioToolbox.framework */; };
8AC6BDF509B39D9400242AEF /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A482668053C8B3F0040E37D /* AudioUnit.framework */; };
8AC6BDF609B39D9400242AEF /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A8C7E59058A3C5800C746A3 /* CoreServices.framework */; };
8ACAAC7106528BF200E2D337 /* oalImp.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A986533053763B9003F7FA0 /* oalImp.h */; };
8ACAAC7206528BF200E2D337 /* oalContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AB7B22C053B3AA700A9757A /* oalContext.h */; };
8ACAAC7306528BF200E2D337 /* oalSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AB7B230053B3AB500A9757A /* oalSource.h */; };
8ACAAC7406528BF200E2D337 /* oalBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AB7B234053B3AC100A9757A /* oalBuffer.h */; };
8ACAAC7506528BF200E2D337 /* oalDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A39B0B20533393F006B1D0F /* oalDevice.h */; };
8ACAAC7606528BF200E2D337 /* oalOSX.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A0561E40546034200A003E7 /* oalOSX.h */; };
8ACAAC8006528BF200E2D337 /* oalDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A39B0B30533393F006B1D0F /* oalDevice.cpp */; };
8ACAAC8106528BF200E2D337 /* oalImp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A986534053763B9003F7FA0 /* oalImp.cpp */; };
8ACAAC8206528BF200E2D337 /* oalContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8AB7B22D053B3AA700A9757A /* oalContext.cpp */; };
8ACAAC8406528BF200E2D337 /* oalOSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0561E50546034200A003E7 /* oalOSX.cpp */; };
8ACAAC8B06528BF200E2D337 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 981B79AD0523A4A500940F97 /* CoreAudio.framework */; };
8ACAAC8D06528BF200E2D337 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A482665053C8B290040E37D /* CoreFoundation.framework */; };
8ACAAC8E06528BF200E2D337 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A482667053C8B3F0040E37D /* AudioToolbox.framework */; };
8ACAAC8F06528BF200E2D337 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A482668053C8B3F0040E37D /* AudioUnit.framework */; };
8ACAAC9006528BF200E2D337 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A8C7E59058A3C5800C746A3 /* CoreServices.framework */; };
8AE33A27090F0C1B00AF30D6 /* alc.h in Headers */ = {isa = PBXBuildFile; fileRef = 984FDEC30433F5A20042B474 /* alc.h */; settings = {ATTRIBUTES = (Public, ); }; };
8AE33A29090F0C3D00AF30D6 /* al.h in Headers */ = {isa = PBXBuildFile; fileRef = 984FDEC20433F5A20042B474 /* al.h */; settings = {ATTRIBUTES = (Public, ); }; };
8AF8503908D2513B004B64E7 /* oalBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8AF8503708D2513B004B64E7 /* oalBuffer.cpp */; };
F4A98A17065E622600F04966 /* CAStreamBasicDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = F40E4D54065E5DB9004336C3 /* CAStreamBasicDescription.h */; };
F4A98A18065E622600F04966 /* CAStreamBasicDescription.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F40E4D53065E5DB9004336C3 /* CAStreamBasicDescription.cpp */; };
F4A98A19065E622700F04966 /* CAMutex.h in Headers */ = {isa = PBXBuildFile; fileRef = F40E4D46065E5DB9004336C3 /* CAMutex.h */; };
F4A98A1A065E622700F04966 /* CAMutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F40E4D45065E5DB9004336C3 /* CAMutex.cpp */; };
F4A98A1B065E622700F04966 /* CAMath.h in Headers */ = {isa = PBXBuildFile; fileRef = F40E4D42065E5DB9004336C3 /* CAMath.h */; };
F4A98A1C065E622800F04966 /* CAHostTimeBase.h in Headers */ = {isa = PBXBuildFile; fileRef = F40E4D3C065E5DB9004336C3 /* CAHostTimeBase.h */; };
F4A98A1D065E622800F04966 /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F40E4D3B065E5DB9004336C3 /* CAHostTimeBase.cpp */; };
F4A98A1E065E622900F04966 /* CAGuard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F40E4D36065E5DB9004336C3 /* CAGuard.cpp */; };
F4A98A1F065E622A00F04966 /* CAGuard.h in Headers */ = {isa = PBXBuildFile; fileRef = F40E4D37065E5DB9004336C3 /* CAGuard.h */; };
F4A98A20065E622A00F04966 /* CADebugMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = F40E4D31065E5DB9004336C3 /* CADebugMacros.h */; };
F749ED7F0B6EC85B00589706 /* OpenAL.plist in Copy Plist */ = {isa = PBXBuildFile; fileRef = F749ED7D0B6EC85700589706 /* OpenAL.plist */; };
F749ED830B6ECB3200589706 /* OpenAL.txt in Copy License */ = {isa = PBXBuildFile; fileRef = F749ED810B6ECB2A00589706 /* OpenAL.txt */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
8ACAAC9A06528C7E00E2D337 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 8ACAAC6A06528BF200E2D337;
remoteInfo = OpenAL;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
8AC6BDF809B39D9400242AEF /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 8;
dstPath = /Developer/Examples/CoreAudio/OpenAL;
dstSubfolderSpec = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
};
F749ED780B6EC79700589706 /* Copy Plist */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 8;
dstPath = /usr/local/OpenSourceVersions/;
dstSubfolderSpec = 0;
files = (
F749ED7F0B6EC85B00589706 /* OpenAL.plist in Copy Plist */,
);
name = "Copy Plist";
runOnlyForDeploymentPostprocessing = 1;
};
F749ED7C0B6EC84D00589706 /* Copy License */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 8;
dstPath = /usr/local/OpenSourceLicenses;
dstSubfolderSpec = 0;
files = (
F749ED830B6ECB3200589706 /* OpenAL.txt in Copy License */,
);
name = "Copy License";
runOnlyForDeploymentPostprocessing = 1;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
8A0561E40546034200A003E7 /* oalOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oalOSX.h; sourceTree = "<group>"; };
8A0561E50546034200A003E7 /* oalOSX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oalOSX.cpp; sourceTree = "<group>"; };
8A0CB5BD097F5FC000B17352 /* CAAudioUnitOutputCapturer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAAudioUnitOutputCapturer.h; sourceTree = "<group>"; };
8A10678F08D8C3460060359C /* CAThreadSafeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAThreadSafeList.h; sourceTree = "<group>"; };
8A39B0B20533393F006B1D0F /* oalDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oalDevice.h; sourceTree = "<group>"; };
8A39B0B30533393F006B1D0F /* oalDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oalDevice.cpp; sourceTree = "<group>"; };
8A3A1DA108EC575A008DD7C5 /* CABufferList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CABufferList.cpp; sourceTree = "<group>"; };
8A3A1DA208EC575A008DD7C5 /* CABufferList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CABufferList.h; sourceTree = "<group>"; };
8A482665053C8B290040E37D /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
8A482667053C8B3F0040E37D /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = "<absolute>"; };
8A482668053C8B3F0040E37D /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = /System/Library/Frameworks/AudioUnit.framework; sourceTree = "<absolute>"; };
8A5E140408EB104300AFA934 /* oalCaptureDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oalCaptureDevice.h; sourceTree = "<group>"; };
8A5E140508EB104300AFA934 /* oalCaptureDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oalCaptureDevice.cpp; sourceTree = "<group>"; };
8A681A8C0736ACD900730BF4 /* OpenAL.exp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.exports; path = OpenAL.exp; sourceTree = "<group>"; };
8A787DF306E7B40500CD7287 /* CADebugMacros.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CADebugMacros.cpp; sourceTree = "<group>"; };
8A7EE4550A02DD3900D94919 /* MacOSX_OALExtensions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MacOSX_OALExtensions.h; path = Source/OpenAL/MacOSX_OALExtensions.h; sourceTree = SOURCE_ROOT; };
8A87DABF08B1099D00178F66 /* oalSource.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = oalSource.cpp; sourceTree = "<group>"; };
8A8C7E59058A3C5800C746A3 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = "<absolute>"; };
8A986533053763B9003F7FA0 /* oalImp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oalImp.h; sourceTree = "<group>"; };
8A986534053763B9003F7FA0 /* oalImp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oalImp.cpp; sourceTree = "<group>"; };
8AB7B22C053B3AA700A9757A /* oalContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oalContext.h; sourceTree = "<group>"; };
8AB7B22D053B3AA700A9757A /* oalContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oalContext.cpp; sourceTree = "<group>"; };
8AB7B230053B3AB500A9757A /* oalSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oalSource.h; sourceTree = "<group>"; };
8AB7B234053B3AC100A9757A /* oalBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oalBuffer.h; sourceTree = "<group>"; };
8AC6BDFE09B39D9400242AEF /* openal.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = openal.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
8ACAAC9406528BF300E2D337 /* OpenAL.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OpenAL.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8AF8503708D2513B004B64E7 /* oalBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oalBuffer.cpp; sourceTree = "<group>"; };
981B79AD0523A4A500940F97 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = "<absolute>"; };
984FDEC20433F5A20042B474 /* al.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = al.h; sourceTree = "<group>"; };
984FDEC30433F5A20042B474 /* alc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = alc.h; sourceTree = "<group>"; };
984FDEC60433F5A20042B474 /* alut.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = alut.h; sourceTree = "<group>"; };
F40E4D31065E5DB9004336C3 /* CADebugMacros.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CADebugMacros.h; sourceTree = "<group>"; };
F40E4D36065E5DB9004336C3 /* CAGuard.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAGuard.cpp; sourceTree = "<group>"; };
F40E4D37065E5DB9004336C3 /* CAGuard.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAGuard.h; sourceTree = "<group>"; };
F40E4D3B065E5DB9004336C3 /* CAHostTimeBase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAHostTimeBase.cpp; sourceTree = "<group>"; };
F40E4D3C065E5DB9004336C3 /* CAHostTimeBase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAHostTimeBase.h; sourceTree = "<group>"; };
F40E4D42065E5DB9004336C3 /* CAMath.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAMath.h; sourceTree = "<group>"; };
F40E4D45065E5DB9004336C3 /* CAMutex.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAMutex.cpp; sourceTree = "<group>"; };
F40E4D46065E5DB9004336C3 /* CAMutex.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAMutex.h; sourceTree = "<group>"; };
F40E4D53065E5DB9004336C3 /* CAStreamBasicDescription.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAStreamBasicDescription.cpp; sourceTree = "<group>"; };
F40E4D54065E5DB9004336C3 /* CAStreamBasicDescription.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAStreamBasicDescription.h; sourceTree = "<group>"; };
F749ED7D0B6EC85700589706 /* OpenAL.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; name = OpenAL.plist; path = Source/OpenAL/OpenAL.plist; sourceTree = "<group>"; };
F749ED810B6ECB2A00589706 /* OpenAL.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = OpenAL.txt; path = Source/OpenAL/OpenAL.txt; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8AC6BDF009B39D9400242AEF /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8AC6BDF209B39D9400242AEF /* CoreAudio.framework in Frameworks */,
8AC6BDF309B39D9400242AEF /* CoreFoundation.framework in Frameworks */,
8AC6BDF409B39D9400242AEF /* AudioToolbox.framework in Frameworks */,
8AC6BDF509B39D9400242AEF /* AudioUnit.framework in Frameworks */,
8AC6BDF609B39D9400242AEF /* CoreServices.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
8ACAAC8A06528BF200E2D337 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8ACAAC8B06528BF200E2D337 /* CoreAudio.framework in Frameworks */,
8ACAAC8D06528BF200E2D337 /* CoreFoundation.framework in Frameworks */,
8ACAAC8E06528BF200E2D337 /* AudioToolbox.framework in Frameworks */,
8ACAAC8F06528BF200E2D337 /* AudioUnit.framework in Frameworks */,
8ACAAC9006528BF200E2D337 /* CoreServices.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
034768DDFF38A45A11DB9C8B /* Products */ = {
isa = PBXGroup;
children = (
8ACAAC9406528BF300E2D337 /* OpenAL.framework */,
8AC6BDFE09B39D9400242AEF /* openal.dylib */,
);
name = Products;
sourceTree = "<group>";
};
0867D691FE84028FC02AAC07 /* al_osx */ = {
isa = PBXGroup;
children = (
F749ED810B6ECB2A00589706 /* OpenAL.txt */,
F749ED7D0B6EC85700589706 /* OpenAL.plist */,
08FB77ACFE841707C02AAC07 /* OpenAL */,
F40E4CDD065E5DB9004336C3 /* PublicUtility */,
0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */,
034768DDFF38A45A11DB9C8B /* Products */,
);
name = al_osx;
sourceTree = "<group>";
};
0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = {
isa = PBXGroup;
children = (
8A482668053C8B3F0040E37D /* AudioUnit.framework */,
8A482667053C8B3F0040E37D /* AudioToolbox.framework */,
981B79AD0523A4A500940F97 /* CoreAudio.framework */,
8A482665053C8B290040E37D /* CoreFoundation.framework */,
8A8C7E59058A3C5800C746A3 /* CoreServices.framework */,
);
name = "External Frameworks and Libraries";
sourceTree = "<group>";
};
08FB77ACFE841707C02AAC07 /* OpenAL */ = {
isa = PBXGroup;
children = (
989FD9DC0444FB92005F25BE /* al */,
8AB7B234053B3AC100A9757A /* oalBuffer.h */,
8AF8503708D2513B004B64E7 /* oalBuffer.cpp */,
8A5E140408EB104300AFA934 /* oalCaptureDevice.h */,
8A5E140508EB104300AFA934 /* oalCaptureDevice.cpp */,
8AB7B22C053B3AA700A9757A /* oalContext.h */,
8AB7B22D053B3AA700A9757A /* oalContext.cpp */,
8A39B0B20533393F006B1D0F /* oalDevice.h */,
8A39B0B30533393F006B1D0F /* oalDevice.cpp */,
8A986533053763B9003F7FA0 /* oalImp.h */,
8A986534053763B9003F7FA0 /* oalImp.cpp */,
8A0561E40546034200A003E7 /* oalOSX.h */,
8A0561E50546034200A003E7 /* oalOSX.cpp */,
8AB7B230053B3AB500A9757A /* oalSource.h */,
8A87DABF08B1099D00178F66 /* oalSource.cpp */,
8A681A8C0736ACD900730BF4 /* OpenAL.exp */,
);
name = OpenAL;
path = Source/OpenAL;
sourceTree = "<group>";
};
989FD9DC0444FB92005F25BE /* al */ = {
isa = PBXGroup;
children = (
8A7EE4550A02DD3900D94919 /* MacOSX_OALExtensions.h */,
984FDEC60433F5A20042B474 /* alut.h */,
984FDEC20433F5A20042B474 /* al.h */,
984FDEC30433F5A20042B474 /* alc.h */,
);
path = al;
sourceTree = "<group>";
};
F40E4CDD065E5DB9004336C3 /* PublicUtility */ = {
isa = PBXGroup;
children = (
8A0CB5BD097F5FC000B17352 /* CAAudioUnitOutputCapturer.h */,
8A3A1DA108EC575A008DD7C5 /* CABufferList.cpp */,
8A3A1DA208EC575A008DD7C5 /* CABufferList.h */,
8A787DF306E7B40500CD7287 /* CADebugMacros.cpp */,
F40E4D31065E5DB9004336C3 /* CADebugMacros.h */,
F40E4D36065E5DB9004336C3 /* CAGuard.cpp */,
F40E4D37065E5DB9004336C3 /* CAGuard.h */,
F40E4D3B065E5DB9004336C3 /* CAHostTimeBase.cpp */,
F40E4D3C065E5DB9004336C3 /* CAHostTimeBase.h */,
F40E4D42065E5DB9004336C3 /* CAMath.h */,
F40E4D45065E5DB9004336C3 /* CAMutex.cpp */,
F40E4D46065E5DB9004336C3 /* CAMutex.h */,
F40E4D53065E5DB9004336C3 /* CAStreamBasicDescription.cpp */,
F40E4D54065E5DB9004336C3 /* CAStreamBasicDescription.h */,
8A10678F08D8C3460060359C /* CAThreadSafeList.h */,
);
name = PublicUtility;
path = /Library/Developer/CoreAudio/PublicUtility;
sourceTree = "<absolute>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
8AC6BDCD09B39D9400242AEF /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
8AC6BDCE09B39D9400242AEF /* al.h in Headers */,
8AC6BDCF09B39D9400242AEF /* alc.h in Headers */,
8AC6BDD009B39D9400242AEF /* oalBuffer.h in Headers */,
8AC6BDD109B39D9400242AEF /* oalContext.h in Headers */,
8AC6BDD209B39D9400242AEF /* oalDevice.h in Headers */,
8AC6BDD309B39D9400242AEF /* oalImp.h in Headers */,
8AC6BDD409B39D9400242AEF /* oalOSX.h in Headers */,
8AC6BDD509B39D9400242AEF /* oalSource.h in Headers */,
8AC6BDD709B39D9400242AEF /* CADebugMacros.h in Headers */,
8AC6BDD809B39D9400242AEF /* CAGuard.h in Headers */,
8AC6BDD909B39D9400242AEF /* CAHostTimeBase.h in Headers */,
8AC6BDDA09B39D9400242AEF /* CAMath.h in Headers */,
8AC6BDDB09B39D9400242AEF /* CAMutex.h in Headers */,
8AC6BDDC09B39D9400242AEF /* CAStreamBasicDescription.h in Headers */,
8AC6BDDD09B39D9400242AEF /* CAThreadSafeList.h in Headers */,
8AC6BDDE09B39D9400242AEF /* oalCaptureDevice.h in Headers */,
8AC6BDDF09B39D9400242AEF /* CABufferList.h in Headers */,
8AC6BDE009B39D9400242AEF /* CAAudioUnitOutputCapturer.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
8ACAAC6B06528BF200E2D337 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
8ACAAC7106528BF200E2D337 /* oalImp.h in Headers */,
8ACAAC7206528BF200E2D337 /* oalContext.h in Headers */,
8ACAAC7306528BF200E2D337 /* oalSource.h in Headers */,
8ACAAC7406528BF200E2D337 /* oalBuffer.h in Headers */,
8ACAAC7506528BF200E2D337 /* oalDevice.h in Headers */,
8ACAAC7606528BF200E2D337 /* oalOSX.h in Headers */,
F4A98A17065E622600F04966 /* CAStreamBasicDescription.h in Headers */,
F4A98A19065E622700F04966 /* CAMutex.h in Headers */,
F4A98A1B065E622700F04966 /* CAMath.h in Headers */,
F4A98A1C065E622800F04966 /* CAHostTimeBase.h in Headers */,
F4A98A1F065E622A00F04966 /* CAGuard.h in Headers */,
F4A98A20065E622A00F04966 /* CADebugMacros.h in Headers */,
8A10679108D8C3460060359C /* CAThreadSafeList.h in Headers */,
8A5E140608EB104300AFA934 /* oalCaptureDevice.h in Headers */,
8A3A1DA408EC575A008DD7C5 /* CABufferList.h in Headers */,
8AE33A27090F0C1B00AF30D6 /* alc.h in Headers */,
8AE33A29090F0C3D00AF30D6 /* al.h in Headers */,
8A0CB5BF097F5FC000B17352 /* CAAudioUnitOutputCapturer.h in Headers */,
8A7EE4560A02DD3900D94919 /* MacOSX_OALExtensions.h in Headers */,
8A7EE4840A02DEB700D94919 /* alut.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
8AC6BDCC09B39D9400242AEF /* openal.dylib */ = {
isa = PBXNativeTarget;
buildConfigurationList = 8AC6BDFA09B39D9400242AEF /* Build configuration list for PBXNativeTarget "openal.dylib" */;
buildPhases = (
8AC6BDCD09B39D9400242AEF /* Headers */,
8AC6BDE109B39D9400242AEF /* Sources */,
8AC6BDF009B39D9400242AEF /* Frameworks */,
8AC6BDF709B39D9400242AEF /* Rez */,
8AC6BDF809B39D9400242AEF /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = openal.dylib;
productInstallPath = /Developer/Examples/CoreAudio/OpenAL;
productName = openal.dylib;
productReference = 8AC6BDFE09B39D9400242AEF /* openal.dylib */;
productType = "com.apple.product-type.library.dynamic";
};
8ACAAC6A06528BF200E2D337 /* OpenAL */ = {
isa = PBXNativeTarget;
buildConfigurationList = 8ACD0BB00885C20A00D0637F /* Build configuration list for PBXNativeTarget "OpenAL" */;
buildPhases = (
8ACAAC6B06528BF200E2D337 /* Headers */,
8ACAAC7D06528BF200E2D337 /* Resources */,
8ACAAC7F06528BF200E2D337 /* Sources */,
8ACAAC8A06528BF200E2D337 /* Frameworks */,
8ACAAC9106528BF200E2D337 /* Rez */,
F749ED780B6EC79700589706 /* Copy Plist */,
F749ED7C0B6EC84D00589706 /* Copy License */,
);
buildRules = (
);
dependencies = (
);
name = OpenAL;
productInstallPath = "$(HOME)/Library/Frameworks";
productName = al_osx;
productReference = 8ACAAC9406528BF300E2D337 /* OpenAL.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
0867D690FE84028FC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 8ACD0BBC0885C20A00D0637F /* Build configuration list for PBXProject "OpenALOpenSource" */;
compatibilityVersion = "Xcode 2.4";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
Japanese,
French,
German,
);
mainGroup = 0867D691FE84028FC02AAC07 /* al_osx */;
productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
8ACAAC9906528C3A00E2D337 /* All */,
8ACAAC6A06528BF200E2D337 /* OpenAL */,
8AC6BDCC09B39D9400242AEF /* openal.dylib */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
8ACAAC7D06528BF200E2D337 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXRezBuildPhase section */
8AC6BDF709B39D9400242AEF /* Rez */ = {
isa = PBXRezBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
8ACAAC9106528BF200E2D337 /* Rez */ = {
isa = PBXRezBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXRezBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
8AC6BDE109B39D9400242AEF /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8AC6BDE209B39D9400242AEF /* oalContext.cpp in Sources */,
8AC6BDE309B39D9400242AEF /* oalDevice.cpp in Sources */,
8AC6BDE409B39D9400242AEF /* oalImp.cpp in Sources */,
8AC6BDE509B39D9400242AEF /* oalOSX.cpp in Sources */,
8AC6BDE609B39D9400242AEF /* CAGuard.cpp in Sources */,
8AC6BDE709B39D9400242AEF /* CAHostTimeBase.cpp in Sources */,
8AC6BDE809B39D9400242AEF /* CAMutex.cpp in Sources */,
8AC6BDE909B39D9400242AEF /* CAStreamBasicDescription.cpp in Sources */,
8AC6BDEB09B39D9400242AEF /* CADebugMacros.cpp in Sources */,
8AC6BDEC09B39D9400242AEF /* oalSource.cpp in Sources */,
8AC6BDED09B39D9400242AEF /* oalBuffer.cpp in Sources */,
8AC6BDEE09B39D9400242AEF /* oalCaptureDevice.cpp in Sources */,
8AC6BDEF09B39D9400242AEF /* CABufferList.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
8ACAAC7F06528BF200E2D337 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8ACAAC8006528BF200E2D337 /* oalDevice.cpp in Sources */,
8ACAAC8106528BF200E2D337 /* oalImp.cpp in Sources */,
8ACAAC8206528BF200E2D337 /* oalContext.cpp in Sources */,
8ACAAC8406528BF200E2D337 /* oalOSX.cpp in Sources */,
F4A98A18065E622600F04966 /* CAStreamBasicDescription.cpp in Sources */,
F4A98A1A065E622700F04966 /* CAMutex.cpp in Sources */,
F4A98A1D065E622800F04966 /* CAHostTimeBase.cpp in Sources */,
F4A98A1E065E622900F04966 /* CAGuard.cpp in Sources */,
8A787DF406E7B40500CD7287 /* CADebugMacros.cpp in Sources */,
8A87DAC108B1099D00178F66 /* oalSource.cpp in Sources */,
8AF8503908D2513B004B64E7 /* oalBuffer.cpp in Sources */,
8A5E140708EB104300AFA934 /* oalCaptureDevice.cpp in Sources */,
8A3A1DA308EC575A008DD7C5 /* CABufferList.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
8ACAAC9B06528C7E00E2D337 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 8ACAAC6A06528BF200E2D337 /* OpenAL */;
targetProxy = 8ACAAC9A06528C7E00E2D337 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
8AC6BDFB09B39D9400242AEF /* Deployment */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
ppc,
i386,
);
COPY_PHASE_STRIP = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_SEARCH_PATHS = /Volumes/Ultraman/XMen/CoreAudio/build;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_OPTIMIZATION_LEVEL = s;
GCC_PREPROCESSOR_DEFINITIONS = __MACOSX__;
INSTALL_PATH = /Developer/Examples/CoreAudio/OpenAL;
LIBRARY_STYLE = DYNAMIC;
MACH_O_TYPE = mh_dylib;
OTHER_CFLAGS = "\U0001";
OTHER_LIBTOOL_FLAGS = "";
OTHER_REZFLAGS = "";
PRODUCT_NAME = openal;
REZ_EXECUTABLE = YES;
SECTORDER_FLAGS = "";
WARNING_CFLAGS = (
"-Wmost",
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
);
ZERO_LINK = NO;
};
name = Deployment;
};
8AC6BDFC09B39D9400242AEF /* Development */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
__MACOSX__,
DEBUG,
"CoreAudio_Debug=1",
);
INSTALL_PATH = /Developer/Examples/CoreAudio/OpenAL;
LIBRARY_STYLE = DYNAMIC;
MACH_O_TYPE = mh_dylib;
OTHER_CFLAGS = "";
OTHER_REZFLAGS = "-d DEBUG=1 -d CoreAudio_Debug=1";
PRODUCT_NAME = openal;
REZ_EXECUTABLE = YES;
WARNING_CFLAGS = (
"-Wmost",
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
);
};
name = Development;
};
8ACD0BB10885C20A00D0637F /* Deployment */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
EXPORTED_SYMBOLS_FILE = Source/OpenAL/OpenAL.exp;
FRAMEWORK_VERSION = A;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_OPTIMIZATION_LEVEL = s;
INFOPLIST_FILE = "Source/OpenAL/OpenAL-Info.plist";
INSTALL_PATH = /System/Library/Frameworks;
OTHER_CFLAGS = (
"$(value)",
"-D__MACOSX__",
);
PRODUCT_NAME = OpenAL;
WARNING_CFLAGS = (
"-Wmost",
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
);
WRAPPER_EXTENSION = framework;
ZERO_LINK = NO;
};
name = Deployment;
};
8ACD0BB20885C20A00D0637F /* Development */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
EXPORTED_SYMBOLS_FILE = Source/OpenAL/OpenAL.exp;
FRAMEWORK_VERSION = A;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
INFOPLIST_FILE = "Source/OpenAL/OpenAL-Info.plist";
INSTALL_PATH = /System/Library/Frameworks;
OTHER_CFLAGS = (
"-D__MACOSX__",
"-DDEBUG",
"-DCoreAudio_Debug=1",
);
OTHER_REZFLAGS = "-d DEBUG=1 -d CoreAudio_Debug=1";
PRODUCT_NAME = OpenAL;
WARNING_CFLAGS = (
"-Wmost",
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
);
WRAPPER_EXTENSION = framework;
};
name = Development;
};
8ACD0BB50885C20A00D0637F /* Deployment */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = YES;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_OPTIMIZATION_LEVEL = 3;
OTHER_CFLAGS = "-D__MACOSX__";
OTHER_LDFLAGS = "";
OTHER_REZFLAGS = "";
PRODUCT_NAME = All;
SECTORDER_FLAGS = "";
WARNING_CFLAGS = (
"-Wmost",
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
);
ZERO_LINK = NO;
};
name = Deployment;
};
8ACD0BB60885C20A00D0637F /* Development */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
DEBUGGING_SYMBOLS = YES;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
OTHER_CFLAGS = (
"-D__MACOSX__",
"-DDEBUG",
"-DCoreAudio_Debug=1",
);
OTHER_LDFLAGS = "";
OTHER_REZFLAGS = "-d DEBUG=1 -d CoreAudio_Debug=1";
PRODUCT_NAME = All;
SECTORDER_FLAGS = "";
WARNING_CFLAGS = (
"-Wmost",
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
);
ZERO_LINK = NO;
};
name = Development;
};
8ACD0BBD0885C20A00D0637F /* Deployment */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)";
ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc";
GCC_DEBUGGING_SYMBOLS = full;
GCC_OPTIMIZATION_LEVEL = s;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
};
name = Deployment;
};
8ACD0BBE0885C20A00D0637F /* Development */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ONLY_ACTIVE_ARCH_PRE_XCODE_3_1)";
GCC_DEBUGGING_SYMBOLS = full;
GCC_OPTIMIZATION_LEVEL = s;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
ONLY_ACTIVE_ARCH_PRE_XCODE_3_1 = "$(NATIVE_ARCH_ACTUAL)";
};
name = Development;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
8AC6BDFA09B39D9400242AEF /* Build configuration list for PBXNativeTarget "openal.dylib" */ = {
isa = XCConfigurationList;
buildConfigurations = (
8AC6BDFB09B39D9400242AEF /* Deployment */,
8AC6BDFC09B39D9400242AEF /* Development */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Deployment;
};
8ACD0BB00885C20A00D0637F /* Build configuration list for PBXNativeTarget "OpenAL" */ = {
isa = XCConfigurationList;
buildConfigurations = (
8ACD0BB10885C20A00D0637F /* Deployment */,
8ACD0BB20885C20A00D0637F /* Development */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Deployment;
};
8ACD0BB40885C20A00D0637F /* Build configuration list for PBXAggregateTarget "All" */ = {
isa = XCConfigurationList;
buildConfigurations = (
8ACD0BB50885C20A00D0637F /* Deployment */,
8ACD0BB60885C20A00D0637F /* Development */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Deployment;
};
8ACD0BBC0885C20A00D0637F /* Build configuration list for PBXProject "OpenALOpenSource" */ = {
isa = XCConfigurationList;
buildConfigurations = (
8ACD0BBD0885C20A00D0637F /* Deployment */,
8ACD0BBE0885C20A00D0637F /* Development */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Deployment;
};
/* End XCConfigurationList section */
};
rootObject = 0867D690FE84028FC02AAC07 /* Project object */;
}

Binary file not shown.

View File

@ -0,0 +1,335 @@
/**********************************************************************************************************************************
*
* OpenAL cross platform audio library
* Copyright (c) 2006, Apple Computer, Inc., Copyright (c) 2014, Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Inc. ("Apple") nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************************************************************************/
#ifndef __MAC_OSX_OAL_EXTENSIONS_H__
#define __MAC_OSX_OAL_EXTENSIONS_H__
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/*
Convert Data When Loading.
Default false, currently applies only to monophonic sounds. Use with alEnable()/alDisable()
*/
#define ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING 0xF001
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ALC_EXT_MAC_OSX
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
typedef ALvoid (*alcMacOSXRenderingQualityProcPtr) (ALint value);
typedef ALvoid (*alMacOSXRenderChannelCountProcPtr) (ALint value);
typedef ALvoid (*alcMacOSXMixerMaxiumumBussesProcPtr) (ALint value);
typedef ALvoid (*alcMacOSXMixerOutputRateProcPtr) (ALdouble value);
typedef ALint (*alcMacOSXGetRenderingQualityProcPtr) (void);
typedef ALint (*alMacOSXGetRenderChannelCountProcPtr) (void);
typedef ALint (*alcMacOSXGetMixerMaxiumumBussesProcPtr) (void);
typedef ALdouble (*alcMacOSXGetMixerOutputRateProcPtr) (void);
/* Render Quality. Used with alcMacOSXRenderingQuality() */
#define ALC_MAC_OSX_SPATIAL_RENDERING_QUALITY_HIGH 'rqhi'
#define ALC_MAC_OSX_SPATIAL_RENDERING_QUALITY_LOW 'rdlo'
/*
Render Channels. Used with alMacOSXRenderChannelCount()
Allows a user to force OpenAL to render to stereo, regardless of the audio hardware being used
*/
#define ALC_MAC_OSX_RENDER_CHANNEL_COUNT_STEREO 'rcst'
#define ALC_MAC_OSX_RENDER_CHANNEL_COUNT_MULTICHANNEL 'rcmc'
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AL_EXT_SOURCE_SPATIALIZATION
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/*
Allows the rendering quality to be explicitly set on a source object, overriding the default
render quality set via alcMacOSXRenderingQuality(). A subsequent call to alcMacOSXRenderingQuality()
resets the render quality of all source objects.
Uses the same render settings (defined above) as alcMacOSXRenderingQuality():
ALC_MAC_OSX_SPATIAL_RENDERING_QUALITY_HIGH
ALC_MAC_OSX_SPATIAL_RENDERING_QUALITY_LOW
ALC_IPHONE_SPATIAL_RENDERING_QUALITY_HEADPHONES
Retrieve functions via alcGetProcAddress() by passing in strings: alSourceRenderingQuality or alSourceGetRenderingQuality
*/
typedef ALvoid (*alSourceRenderingQualityProcPtr) (ALuint sid, ALint value);
typedef ALint (*alSourceGetRenderingQualityProcPtr) (ALuint sid);
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AL_EXT_STATIC_BUFFER
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
typedef ALvoid AL_APIENTRY (*alBufferDataStaticProcPtr) (ALint bid, ALenum format, const ALvoid* __nonnull data, ALsizei size, ALsizei freq);
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AL_EXT_SOURCE_NOTIFICATIONS
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/*
Source Notifications
Eliminates the need for continuous polling for source state by providing a
mechanism for the application to receive source state change notifications.
Upon receiving a notification, the application can retrieve the actual state
corresponding to the notification ID for which the notification was sent.
*/
#define AL_QUEUE_HAS_LOOPED 0x9000
/*
Notification Proc: ALSourceNotificationProc
sid - source id
notificationID - id of state that has changed
userData - user data provided to alSourceAddNotification()
*/
typedef ALvoid (*alSourceNotificationProc)(ALuint sid, ALuint notificationID, ALvoid* __nullable userData);
/*
API: alSourceAddNotification
sid - source id
notificationID - id of state for which caller wants to be notified of a change
notifyProc - notification proc
userData - ptr to applications user data, will be returned in the notification proc
Returns AL_NO_ERROR if request is successful.
Valid IDs:
AL_SOURCE_STATE
AL_BUFFERS_PROCESSED
AL_QUEUE_HAS_LOOPED - notification sent when a looping source has looped to it's start point
*/
typedef ALenum (*alSourceAddNotificationProcPtr) (ALuint sid, ALuint notificationID, alSourceNotificationProc __nonnull notifyProc, ALvoid* __nullable userData);
/*
API: alSourceRemoveStateNotification
sid - source id
notificationID - id of state for which caller wants to remove an existing notification
notifyProc - notification proc
userData - ptr to applications user data, will be returned in the notification proc
*/
typedef ALvoid (*alSourceRemoveNotificationProcPtr) (ALuint sid, ALuint notificationID, alSourceNotificationProc __nonnull notifyProc, ALvoid* __nullable userData);
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ALC_EXT_ASA : Apple Spatial Audio Extension
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/*
Used with the ASA API calls: alcASAGetSource(), alcASASetSource(), alcASAGetListener(), alcASASetListener()
*/
typedef ALenum (*alcASAGetSourceProcPtr) (ALuint property, ALuint source, ALvoid* __nonnull data, ALuint* __nonnull dataSize);
typedef ALenum (*alcASASetSourceProcPtr) (ALuint property, ALuint source, ALvoid* __nonnull data, ALuint dataSize);
typedef ALenum (*alcASAGetListenerProcPtr) (ALuint property, ALvoid* __nonnull data, ALuint* __nonnull dataSize);
typedef ALenum (*alcASASetListenerProcPtr) (ALuint property, ALvoid* __nonnull data, ALuint dataSize);
/* listener properties */
#define ALC_ASA_REVERB_ON 'rvon' // type ALuint
#define ALC_ASA_REVERB_GLOBAL_LEVEL 'rvgl' // type ALfloat -40.0 db - 40.0 db
#define ALC_ASA_REVERB_ROOM_TYPE 'rvrt' // type ALint
/* reverb room type presets for the ALC_ASA_REVERB_ROOM_TYPE property */
#define ALC_ASA_REVERB_ROOM_TYPE_SmallRoom 0
#define ALC_ASA_REVERB_ROOM_TYPE_MediumRoom 1
#define ALC_ASA_REVERB_ROOM_TYPE_LargeRoom 2
#define ALC_ASA_REVERB_ROOM_TYPE_MediumHall 3
#define ALC_ASA_REVERB_ROOM_TYPE_LargeHall 4
#define ALC_ASA_REVERB_ROOM_TYPE_Plate 5
#define ALC_ASA_REVERB_ROOM_TYPE_MediumChamber 6
#define ALC_ASA_REVERB_ROOM_TYPE_LargeChamber 7
#define ALC_ASA_REVERB_ROOM_TYPE_Cathedral 8
#define ALC_ASA_REVERB_ROOM_TYPE_LargeRoom2 9
#define ALC_ASA_REVERB_ROOM_TYPE_MediumHall2 10
#define ALC_ASA_REVERB_ROOM_TYPE_MediumHall3 11
#define ALC_ASA_REVERB_ROOM_TYPE_LargeHall2 12
#define ALC_ASA_REVERB_PRESET 'rvps' // type ALchar* - (set only) path to an au preset file
#define ALC_ASA_REVERB_EQ_GAIN 'rveg' // type ALfloat
#define ALC_ASA_REVERB_EQ_BANDWITH 'rveb' // type ALfloat
#define ALC_ASA_REVERB_EQ_FREQ 'rvef' // type ALfloat
#define ALC_ASA_REVERB_QUALITY 'rvqt' // type ALint
/* reverb quality settings for the ALC_ASA_REVERB_QUALITY property */
#define ALC_ASA_REVERB_QUALITY_Max 0x7F
#define ALC_ASA_REVERB_QUALITY_High 0x60
#define ALC_ASA_REVERB_QUALITY_Medium 0x40
#define ALC_ASA_REVERB_QUALITY_Low 0x20
#define ALC_ASA_REVERB_QUALITY_Min 0
/* source properties */
#define ALC_ASA_REVERB_SEND_LEVEL 'rvsl' // type ALfloat 0.0 (dry) - 1.0 (wet) (0-100% dry/wet mix, 0.0 default)
#define ALC_ASA_OCCLUSION 'occl' // type ALfloat -100.0 db (most occlusion) - 0.0 db (no occlusion, 0.0 default)
#define ALC_ASA_OBSTRUCTION 'obst' // type ALfloat -100.0 db (most obstruction) - 0.0 db (no obstruction, 0.0 default)
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ALC_EXT_ASA_ROGER_BEEP : Apple Spatial Audio Extension for Roger Beep Effect
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/*
Roger Beep : an effect to simulate effects such as Walkie Talkie noise. It is designed to replace the
source audio data with a specific 'tone' when falling below a specified db threshold for a specified time.
This Extension will be present when the Roger Beep Audio Unit is present on the system (10.5 or greater)
Use the alcASAGetSource() and alcASASetSource() APIs in the ALC_EXT_ASA extension.
*/
/* source properties */
#define ALC_ASA_ROGER_BEEP_ENABLE 'rben' // type ALboolean - initializes Roger Beep for use - returns error if source is not in a Stopped or Initial state
#define ALC_ASA_ROGER_BEEP_ON 'rbon' // type ALboolean - set effect on/off (bypass) - default setting is true (on)
#define ALC_ASA_ROGER_BEEP_GAIN 'rbgn' // type ALfloat - 20.0 (db) apply maximum effect : -80.0(db) apply minimum effect amount
#define ALC_ASA_ROGER_BEEP_SENSITIVITY 'rbsn' // type ALint - specifiy a predefined sensitivity setting
#define ALC_ASA_ROGER_BEEP_TYPE 'rbtp' // type ALint - choose predefined specific Roger Beep tone
#define ALC_ASA_ROGER_BEEP_PRESET 'rbps' // type ALchar* - path to an au preset file (set only)
/* settings for the ALC_ASA_ROGER_BEEP_TYPE property */
#define ALC_ASA_ROGER_BEEP_TYPE_quindartone 0
#define ALC_ASA_ROGER_BEEP_TYPE_whitenoise 1
#define ALC_ASA_ROGER_BEEP_TYPE_walkietalkie 2
/* settings for the ALC_ASA_ROGER_BEEP_SENSITIVITY property */
#define ALC_ASA_ROGER_BEEP_SENSITIVITY_Light 0
#define ALC_ASA_ROGER_BEEP_SENSITIVITY_Medium 1
#define ALC_ASA_ROGER_BEEP_SENSITIVITY_Heavy 2
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ALC_EXT_ASA_DISTORTION : Apple Spatial Audio Extension for Distortion Effect
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/*
Distortion Effect
This Extension will be present when the Distortion Audio Unit is present on the system (10.5 or greater)
Use the alcASAGetSource() and alcASASetSource() APIs in the ALC_EXT_ASA extension.
*/
/* source properties */
#define ALC_ASA_DISTORTION_ENABLE 'dsen' // type ALboolean - initializes Distortion for use - returns error if source is not in a Stopped or Initial state
#define ALC_ASA_DISTORTION_ON 'dson' // type ALboolean - set effect on/off (bypass) - default setting is true (on)
#define ALC_ASA_DISTORTION_MIX 'dsmx' // type ALfloat - mix balance between dry signal and distortion effect - 0.0 (no effect) - 100.0 (all effect)
#define ALC_ASA_DISTORTION_TYPE 'dstp' // type ALint - choose predefined distortion settings
#define ALC_ASA_DISTORTION_PRESET 'dsps' // type ALchar* - path to an au preset file (set only)
/* settings for the ALC_ASA_DISTORTION_TYPE property */
#define ALC_ASA_DISTORTION_TYPE_BitBrush 0
#define ALC_ASA_DISTORTION_TYPE_BufferBeats 1
#define ALC_ASA_DISTORTION_TYPE_LoFi 2
#define ALC_ASA_DISTORTION_TYPE_BrokenSpeaker 3
#define ALC_ASA_DISTORTION_TYPE_Cellphone 4
#define ALC_ASA_DISTORTION_TYPE_Decimated1 5
#define ALC_ASA_DISTORTION_TYPE_Decimated2 6
#define ALC_ASA_DISTORTION_TYPE_Decimated3 7
#define ALC_ASA_DISTORTION_TYPE_Decimated4 8
#define ALC_ASA_DISTORTION_TYPE_DistortedFunk 9
#define ALC_ASA_DISTORTION_TYPE_DistortionCubed 10
#define ALC_ASA_DISTORTION_TYPE_DistortionSquared 11
#define ALC_ASA_DISTORTION_TYPE_Echo1 12
#define ALC_ASA_DISTORTION_TYPE_Echo2 13
#define ALC_ASA_DISTORTION_TYPE_EchoTight1 14
#define ALC_ASA_DISTORTION_TYPE_EchoTight2 15
#define ALC_ASA_DISTORTION_TYPE_EverythingBroken 16
#define ALC_ASA_DISTORTION_TYPE_AlienChatter 17
#define ALC_ASA_DISTORTION_TYPE_CosmicInteference 18
#define ALC_ASA_DISTORTION_TYPE_GoldenPi 19
#define ALC_ASA_DISTORTION_TYPE_RadioTower 20
#define ALC_ASA_DISTORTION_TYPE_Waves 21
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ALC_EXT_OUTPUT_CAPTURER
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/*
Allows an application to capture the rendered output of the current context.
The application prepares OpenAL for capturing the context output by specifying the data format
of the captured audio output data. Once capture has been started, the application then queries OpenAL
for the available number of captured samples, and requests the samples by providing a buffer to fill.
Retrieve functions via alcGetProcAddress() by passing in strings: alcOutputCapturerPrepare, alcOutputCapturerStart,
alcOutputCapturerStop, alcOutputCapturerAvailableSamples and alcOutputCapturerSamples
*/
/*
API: alcOutputCapturerPrepare
Prepare output capturing of the current context by specifying the data format desired from OpenAL.
frequency - Sampling rate of the captured output.
format - Data format of the captured data. Specified as one of the native OpenAL data format types:
AL_FORMAT_MONO8
AL_FORMAT_MONO16
AL_FORMAT_STEREO8
AL_FORMAT_STEREO16
maxsamplecount - The maximum number of samples that will be requested by the application.
*/
typedef ALvoid AL_APIENTRY (*alcOutputCapturerPrepareProcPtr) (ALCuint frequency, ALCenum format, ALCsizei maxsamplecount);
/*
API: alcOutputCapturerStart
Start capturing samples rendered by the current context to a maximum of the sample count specified when calling alcOutputCapturerPrepare.
*/
typedef ALvoid AL_APIENTRY (*alcOutputCapturerStartProcPtr) (void);
/*
API: alcOutputCapturerStop
Stop capturing samples rendered by the context. This function resets the captured audio samples to 0.
*/
typedef ALvoid AL_APIENTRY (*alcOutputCapturerStopProcPtr) (void);
/*
API: alcOutputCapturerAvailableSamples
Get the number of captured samples currently available.
*/
typedef ALint AL_APIENTRY (*alcOutputCapturerAvailableSamplesProcPtr) (void);
/*
API: alcOutputCapturerSamples
Write captured samples to an application provided buffer.
buffer - Application provided buffer to be filled with the requested amount of samples and must be of size
samplecount * size of sample. i.e. 100 samples of AL_FORMAT_STEREO16 data -> 100 * 4 = 400 bytes
The buffer must NOT be deallocated before the call to alcOutputCapturerSamples returns.
samplecount - Number of samples to be copied to the provided buffer.
Requesting more samples than currently available is an error.
*/
typedef ALvoid AL_APIENTRY (*alcOutputCapturerSamplesProcPtr) (ALCvoid * __nonnull buffer, ALCsizei samplecount);
#endif // __MAC_OSX_OAL_EXTENSIONS_H__

View File

@ -0,0 +1,6 @@
framework module OpenAL [extern_c] {
umbrella header "OpenAL.h"
export *
module * { export * }
}

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>OpenAL</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.apple.audio.OpenAL</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>OpenAL</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.8</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.8</string>
<key>CSResourcesFileMapped</key>
<true/>
</dict>
</plist>

125
Source/OpenAL/OpenAL.exp Normal file
View File

@ -0,0 +1,125 @@
# from al.h
_alEnable
_alDisable
_alIsEnabled
_alGetBoolean
_alGetInteger
_alGetFloat
_alGetDouble
_alGetBooleanv
_alGetIntegerv
_alGetFloatv
_alGetDoublev
_alGetString
_alSetInteger
_alSetDouble
_alGetError
_alIsExtensionPresent
_alGetProcAddress
_alGetEnumValue
_alListeneri
_alListener3i
_alListeneriv
_alListenerf
_alListener3f
_alListenerfv
_alGetListeneri
_alGetListener3i
_alGetListeneriv
_alGetListenerf
_alGetListener3f
_alGetListenerfv
_alGenSources
_alDeleteSources
_alIsSource
_alSourcei
_alSource3i
_alSourceiv
_alSourcef
_alSource3f
_alSourcefv
_alGetSourcei
_alGetSource3i
_alGetSourceiv
_alGetSourcef
_alGetSource3f
_alGetSourcefv
_alSourcePlayv
_alSourcePausev
_alSourceStopv
_alSourceRewindv
_alSourcePlay
_alSourcePause
_alSourceStop
_alSourceRewind
_alGenBuffers
_alDeleteBuffers
_alIsBuffer
_alBufferData
_alBufferf
_alBuffer3f
_alBufferfv
_alBufferi
_alBuffer3i
_alBufferiv
_alGetBufferi
_alGetBuffer3i
_alGetBufferiv
_alGetBufferf
_alGetBuffer3f
_alGetBufferfv
_alSourceQueueBuffers
_alSourceUnqueueBuffers
_alDistanceModel
_alDopplerFactor
_alDopplerVelocity
_alSpeedOfSound
_alHint
# from alc.h
_alcGetString
_alcGetIntegerv
_alcOpenDevice
_alcCloseDevice
_alcCreateContext
_alcMakeContextCurrent
_alcProcessContext
_alcGetCurrentContext
_alcGetContextsDevice
_alcSuspendContext
_alcDestroyContext
_alcGetError
_alcIsExtensionPresent
_alcGetProcAddress
_alcGetEnumValue
_alcCaptureOpenDevice
_alcCaptureCloseDevice
_alcCaptureStart
_alcCaptureStop
_alcCaptureSamples
# from alut.h
_alutInit
_alutExit
_alutLoadWAVFile
_alutLoadWAVMemory
_alutUnloadWAV
# from OSX_EXTENSION
_alcMacOSXRenderingQuality
_alMacOSXRenderChannelCount
_alcMacOSXMixerMaxiumumBusses
_alcMacOSXMixerOutputRate
_alcMacOSXGetRenderingQuality
_alMacOSXGetRenderChannelCount
_alcMacOSXGetMixerMaxiumumBusses
_alcMacOSXGetMixerOutputRate
_alBufferDataStatic
# from APPLE_ENVIRONMENTAL_AUDIO_EXTENSION
_alcASAGetSource
_alcASASetSource
_alcASAGetListener
_alcASASetListener

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>OpenSourceImportDate</key>
<string>2003-11-12</string>
<key>OpenSourceLicense</key>
<string>LGPL 2.1 (with clarification from Creative Labs)</string>
<key>OpenSourceLicenseFile</key>
<string>OpenAL.txt</string>
<key>OpenSourceModifications</key>
<string></string>
<key>OpenSourceProject</key>
<string>OpenAL</string>
<key>OpenSourceSHA1</key>
<string>345ada582eed14706a63d33aa4dee4e2a9d3c0da</string>
<key>OpenSourceURL</key>
<string>http://developer.creative.com/articles/article.asp?cat=1&amp;sbcat=31&amp;top=38&amp;aid=97&amp;file=OpenAL_Installer_OSX.dmg</string>
<key>OpenSourceVersion</key>
<string>1.1</string>
<key>OpenSourceWebsiteURL</key>
<string>http://developer.creative.com/landing.asp?cat=1&amp;sbcat=31&amp;top=38</string>
</dict>
</plist>

510
Source/OpenAL/OpenAL.txt Normal file
View File

@ -0,0 +1,510 @@
This file is part of the OpenAL software.
The licenses which components of this software fall under are as follows.
All components are under a LGPL license.
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

84
Source/OpenAL/READ_ME Normal file
View File

@ -0,0 +1,84 @@
----------------------------------------------------------------------------------------------------------------------
READ ME: OPEN AL - OSX IMPLEMENTATION USING THE 3DMIXER AUDIOUNIT
----------------------------------------------------------------------------------------------------------------------
This Read Me should accompany the 3DMixer implementation of OpenAL (Open Audio Library).
CoreAudio Version requirements
-----------------------
It is recommended that this implementation is run on MAC OS X SnowLeopard (10.6) or later. Certain features may not be
supported on older OS versions.
Xcode Version requirements
--------------------
If Xcode 4.3 or later is installed, the CoreAudio Utility Classes must be installed at /Library/Developer
The CoreAudio Utility Classes can be obtained from the Mac OS X Developer Library located at the url https://developer.apple.com
If the Xcode version is older than 4.3, the path to the PublicUtility folder in the OpenAL Xcode project file should be changed to
/Developer/Extras/CoreAudio/PublicUtility
----------------------------------------------------------------------------------------------------------------------
OpenAL Extensions:
----------------------------------------------------------------------------------------------------------------------
This implementation has the following OpenAL extensions. More information on usage and setting specifics can be found in the
MacOSX_OALExtensions.h header file.
***** ALC_EXT_MAC_OSX
The 'Apple Mac OSX Extension' contains various support for controlling aspects of Apple's OpenAL implementation that are specific to the platform.
The extension provides settings for:
Rendering Quality - The Rendering Quality setting enables the application to specify from a number of available stereo/multi-channel
rendering algorithms.
Channel Count - Apple's OpenAL implementation will render to stereo or multi-channel audio hardware based on the users system setup.
This setting can be used to force stereo rendering on a multi speaker audio system.
Maximum Buses - This sets a maximum number of buses allocated by the system's 3DMixer AudioUnit, which provides the spatialized mixing of OpenAL
Output Rate - Allows the application to optimize audio mixing performance based on the sampling rate of its audio assets (files)
***** ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING
This extension allows the caller to tell OpenAL to preconvert to the native CoreAudio format, the audio data passed to the
library with the alBufferData() call. Preconverting the audio data, reduces CPU usage by removing an audio data conversion
(per source) at render time at the expense of a larger memory footprint.
***** AL_EXT_STATIC_BUFFER
This extension provides a means for the caller to avoid the overhead associated with the alBufferData call which performs a physical copy
of the data provided by the caller to internal buffers. When using the AL_EXT_STATIC_BUFFER extension, OpenAL's internal buffers use
the data pointer provided by the caller for all data access.
Note: It is important that the caller does NOT free these buffers until OpenAL returns from alDeleteBuffers() without returning an error.
***** ALC_EXT_ASA
The ASA (Apple Spatial Audio) extension currently provides three main effects: reverb, occlusion and obstruction.
Reverb: A reverb effect with multiple presets and quality settings. Post EQ settings available for additional tonal control.
Occlusion: An effect that applies a low pass filter to an OpenAL source object for simulating objects
in different 'spaces' from the listener (post EQ, causing send to reverb to also be filtered)
Obstruction: An effect that applies a low pass filter to an OpenAL source object for simulating objects being 'obstructed'
from the listener (pre-EQ, allowing high frequencies of source object to remain in the reverb)
**** ALC_EXT_ASA_ROGER_BEEP
This extension allows use of the Roger Beep effect to simulate effects such as Walkie Talkie noise. Effect is activated when
the source audio data falls below a specified db threshold for a specified time.
**** ALC_EXT_ASA_DISTORTION
This extension applies a distortion effect to a specified OpenAL source object. Different settings can be used to specify the style and
degree of distortion applied.
**** AL_EXT_float32
The AL_EXT_float32 extension provides support for 32-bit float audio data (mono/stereo).
**** AL_EXT_SOURCE_NOTIFICATIONS
This extension provides an alternative to the OpenAL polling mechanism used for obtaining state about Source and Buffer objects. The caller subscribes to
the notification scheme by providing a callback function for the desired notification type. When a notification is received, the caller should then proceed
to get the current state using the native OpenAL api calls.
The available notification types are
AL_SOURCE_STATE - there is a change in the source's state
AL_BUFFERS_PROCESSED - there is a change in the number of buffers processed
AL_QUEUE_HAS_LOOPED - the buffer queue has looped (if looping is enabled)
----------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------

15
Source/OpenAL/al/OpenAL.h Normal file
View File

@ -0,0 +1,15 @@
/*!
@file OpenAL.h
@framework OpenAL.framework
@copyright (c) 2002-2015 by Apple, Inc., all rights reserved.
@abstract Umbrella header for OpenAL framework.
*/
#ifndef OpenAL_OpenAL_h
#define OpenAL_OpenAL_h
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#include <OpenAL/MacOSX_OALExtensions.h>
#endif /* defined(OpenAL_OpenAL_h) */

724
Source/OpenAL/al/al.h Normal file
View File

@ -0,0 +1,724 @@
#ifndef AL_AL_H
#define AL_AL_H
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(_WIN32) && !defined(_XBOX)
/* _OPENAL32LIB is deprecated */
#if defined(AL_BUILD_LIBRARY) || defined (_OPENAL32LIB)
#define AL_API __declspec(dllexport)
#else
#define AL_API __declspec(dllimport)
#endif
#else
#if defined(AL_BUILD_LIBRARY) && defined(HAVE_GCC_VISIBILITY)
#define AL_API __attribute__((visibility("default")))
#else
#define AL_API extern
#endif
#endif
#if defined(_WIN32)
#define AL_APIENTRY __cdecl
#else
#define AL_APIENTRY
#endif
#if defined(TARGET_OS_MAC) && TARGET_OS_MAC
#pragma export on
#endif
/*
* The OPENAL, ALAPI, ALAPIENTRY, AL_INVALID, AL_ILLEGAL_ENUM, and
* AL_ILLEGAL_COMMAND macros are deprecated, but are included for
* applications porting code from AL 1.0
*/
#define OPENAL
#define ALAPI AL_API
#define ALAPIENTRY AL_APIENTRY
#define AL_INVALID (-1)
#define AL_ILLEGAL_ENUM AL_INVALID_ENUM
#define AL_ILLEGAL_COMMAND AL_INVALID_OPERATION
#define AL_VERSION_1_0
#define AL_VERSION_1_1
/** 8-bit boolean */
typedef char ALboolean;
/** character */
typedef char ALchar;
/** signed 8-bit 2's complement integer */
typedef char ALbyte;
/** unsigned 8-bit integer */
typedef unsigned char ALubyte;
/** signed 16-bit 2's complement integer */
typedef short ALshort;
/** unsigned 16-bit integer */
typedef unsigned short ALushort;
/** signed 32-bit 2's complement integer */
typedef int ALint;
/** unsigned 32-bit integer */
typedef unsigned int ALuint;
/** non-negative 32-bit binary integer size */
typedef int ALsizei;
/** enumerated 32-bit value */
typedef int ALenum;
/** 32-bit IEEE754 floating-point */
typedef float ALfloat;
/** 64-bit IEEE754 floating-point */
typedef double ALdouble;
/** void type (for opaque pointers only) */
typedef void ALvoid;
/* Enumerant values begin at column 50. No tabs. */
/* "no distance model" or "no buffer" */
#define AL_NONE 0
/* Boolean False. */
#define AL_FALSE 0
/** Boolean True. */
#define AL_TRUE 1
/** Indicate Source has relative coordinates. */
#define AL_SOURCE_RELATIVE 0x202
/**
* Directional source, inner cone angle, in degrees.
* Range: [0-360]
* Default: 360
*/
#define AL_CONE_INNER_ANGLE 0x1001
/**
* Directional source, outer cone angle, in degrees.
* Range: [0-360]
* Default: 360
*/
#define AL_CONE_OUTER_ANGLE 0x1002
/**
* Specify the pitch to be applied, either at source,
* or on mixer results, at listener.
* Range: [0.5-2.0]
* Default: 1.0
*/
#define AL_PITCH 0x1003
/**
* Specify the current location in three dimensional space.
* OpenAL, like OpenGL, uses a right handed coordinate system,
* where in a frontal default view X (thumb) points right,
* Y points up (index finger), and Z points towards the
* viewer/camera (middle finger).
* To switch from a left handed coordinate system, flip the
* sign on the Z coordinate.
* Listener position is always in the world coordinate system.
*/
#define AL_POSITION 0x1004
/** Specify the current direction. */
#define AL_DIRECTION 0x1005
/** Specify the current velocity in three dimensional space. */
#define AL_VELOCITY 0x1006
/**
* Indicate whether source is looping.
* Type: ALboolean?
* Range: [AL_TRUE, AL_FALSE]
* Default: FALSE.
*/
#define AL_LOOPING 0x1007
/**
* Indicate the buffer to provide sound samples.
* Type: ALuint.
* Range: any valid Buffer id.
*/
#define AL_BUFFER 0x1009
/**
* Indicate the gain (volume amplification) applied.
* Type: ALfloat.
* Range: ]0.0- ]
* A value of 1.0 means un-attenuated/unchanged.
* Each division by 2 equals an attenuation of -6dB.
* Each multiplicaton with 2 equals an amplification of +6dB.
* A value of 0.0 is meaningless with respect to a logarithmic
* scale; it is interpreted as zero volume - the channel
* is effectively disabled.
*/
#define AL_GAIN 0x100A
/*
* Indicate minimum source attenuation
* Type: ALfloat
* Range: [0.0 - 1.0]
*
* Logarthmic
*/
#define AL_MIN_GAIN 0x100D
/**
* Indicate maximum source attenuation
* Type: ALfloat
* Range: [0.0 - 1.0]
*
* Logarthmic
*/
#define AL_MAX_GAIN 0x100E
/**
* Indicate listener orientation.
*
* at/up
*/
#define AL_ORIENTATION 0x100F
/**
* Source state information.
*/
#define AL_SOURCE_STATE 0x1010
#define AL_INITIAL 0x1011
#define AL_PLAYING 0x1012
#define AL_PAUSED 0x1013
#define AL_STOPPED 0x1014
/**
* Buffer Queue params
*/
#define AL_BUFFERS_QUEUED 0x1015
#define AL_BUFFERS_PROCESSED 0x1016
/**
* Source buffer position information
*/
#define AL_SEC_OFFSET 0x1024
#define AL_SAMPLE_OFFSET 0x1025
#define AL_BYTE_OFFSET 0x1026
/*
* Source type (Static, Streaming or undetermined)
* Source is Static if a Buffer has been attached using AL_BUFFER
* Source is Streaming if one or more Buffers have been attached using alSourceQueueBuffers
* Source is undetermined when it has the NULL buffer attached
*/
#define AL_SOURCE_TYPE 0x1027
#define AL_STATIC 0x1028
#define AL_STREAMING 0x1029
#define AL_UNDETERMINED 0x1030
/** Sound samples: format specifier. */
#define AL_FORMAT_MONO8 0x1100
#define AL_FORMAT_MONO16 0x1101
#define AL_FORMAT_STEREO8 0x1102
#define AL_FORMAT_STEREO16 0x1103
/**
* source specific reference distance
* Type: ALfloat
* Range: 0.0 - +inf
*
* At 0.0, no distance attenuation occurs. Default is
* 1.0.
*/
#define AL_REFERENCE_DISTANCE 0x1020
/**
* source specific rolloff factor
* Type: ALfloat
* Range: 0.0 - +inf
*
*/
#define AL_ROLLOFF_FACTOR 0x1021
/**
* Directional source, outer cone gain.
*
* Default: 0.0
* Range: [0.0 - 1.0]
* Logarithmic
*/
#define AL_CONE_OUTER_GAIN 0x1022
/**
* Indicate distance above which sources are not
* attenuated using the inverse clamped distance model.
*
* Default: +inf
* Type: ALfloat
* Range: 0.0 - +inf
*/
#define AL_MAX_DISTANCE 0x1023
/**
* Sound samples: frequency, in units of Hertz [Hz].
* This is the number of samples per second. Half of the
* sample frequency marks the maximum significant
* frequency component.
*/
#define AL_FREQUENCY 0x2001
#define AL_BITS 0x2002
#define AL_CHANNELS 0x2003
#define AL_SIZE 0x2004
/**
* Buffer state.
*
* Not supported for public use (yet).
*/
#define AL_UNUSED 0x2010
#define AL_PENDING 0x2011
#define AL_PROCESSED 0x2012
/** Errors: No Error. */
#define AL_NO_ERROR AL_FALSE
/**
* Invalid Name paramater passed to AL call.
*/
#define AL_INVALID_NAME 0xA001
/**
* Invalid parameter passed to AL call.
*/
#define AL_INVALID_ENUM 0xA002
/**
* Invalid enum parameter value.
*/
#define AL_INVALID_VALUE 0xA003
/**
* Illegal call.
*/
#define AL_INVALID_OPERATION 0xA004
/**
* No mojo.
*/
#define AL_OUT_OF_MEMORY 0xA005
/** Context strings: Vendor Name. */
#define AL_VENDOR 0xB001
#define AL_VERSION 0xB002
#define AL_RENDERER 0xB003
#define AL_EXTENSIONS 0xB004
/** Global tweakage. */
/**
* Doppler scale. Default 1.0
*/
#define AL_DOPPLER_FACTOR 0xC000
/**
* Tweaks speed of propagation.
*/
#define AL_DOPPLER_VELOCITY 0xC001
/**
* Speed of Sound in units per second
*/
#define AL_SPEED_OF_SOUND 0xC003
/**
* Distance models
*
* used in conjunction with DistanceModel
*
* implicit: NONE, which disances distance attenuation.
*/
#define AL_DISTANCE_MODEL 0xD000
#define AL_INVERSE_DISTANCE 0xD001
#define AL_INVERSE_DISTANCE_CLAMPED 0xD002
#define AL_LINEAR_DISTANCE 0xD003
#define AL_LINEAR_DISTANCE_CLAMPED 0xD004
#define AL_EXPONENT_DISTANCE 0xD005
#define AL_EXPONENT_DISTANCE_CLAMPED 0xD006
/*
* Renderer State management
*/
AL_API void AL_APIENTRY alEnable( ALenum capability );
AL_API void AL_APIENTRY alDisable( ALenum capability );
AL_API ALboolean AL_APIENTRY alIsEnabled( ALenum capability );
/*
* State retrieval
*/
AL_API const ALchar* AL_APIENTRY alGetString( ALenum param );
AL_API void AL_APIENTRY alGetBooleanv( ALenum param, ALboolean* data );
AL_API void AL_APIENTRY alGetIntegerv( ALenum param, ALint* data );
AL_API void AL_APIENTRY alGetFloatv( ALenum param, ALfloat* data );
AL_API void AL_APIENTRY alGetDoublev( ALenum param, ALdouble* data );
AL_API ALboolean AL_APIENTRY alGetBoolean( ALenum param );
AL_API ALint AL_APIENTRY alGetInteger( ALenum param );
AL_API ALfloat AL_APIENTRY alGetFloat( ALenum param );
AL_API ALdouble AL_APIENTRY alGetDouble( ALenum param );
/*
* Error support.
* Obtain the most recent error generated in the AL state machine.
*/
AL_API ALenum AL_APIENTRY alGetError( void );
/*
* Extension support.
* Query for the presence of an extension, and obtain any appropriate
* function pointers and enum values.
*/
AL_API ALboolean AL_APIENTRY alIsExtensionPresent( const ALchar* extname );
AL_API void* AL_APIENTRY alGetProcAddress( const ALchar* fname );
AL_API ALenum AL_APIENTRY alGetEnumValue( const ALchar* ename );
/*
* LISTENER
* Listener represents the location and orientation of the
* 'user' in 3D-space.
*
* Properties include: -
*
* Gain AL_GAIN ALfloat
* Position AL_POSITION ALfloat[3]
* Velocity AL_VELOCITY ALfloat[3]
* Orientation AL_ORIENTATION ALfloat[6] (Forward then Up vectors)
*/
/*
* Set Listener parameters
*/
AL_API void AL_APIENTRY alListenerf( ALenum param, ALfloat value );
AL_API void AL_APIENTRY alListener3f( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
AL_API void AL_APIENTRY alListenerfv( ALenum param, const ALfloat* values );
AL_API void AL_APIENTRY alListeneri( ALenum param, ALint value );
AL_API void AL_APIENTRY alListener3i( ALenum param, ALint value1, ALint value2, ALint value3 );
AL_API void AL_APIENTRY alListeneriv( ALenum param, const ALint* values );
/*
* Get Listener parameters
*/
AL_API void AL_APIENTRY alGetListenerf( ALenum param, ALfloat* value );
AL_API void AL_APIENTRY alGetListener3f( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 );
AL_API void AL_APIENTRY alGetListenerfv( ALenum param, ALfloat* values );
AL_API void AL_APIENTRY alGetListeneri( ALenum param, ALint* value );
AL_API void AL_APIENTRY alGetListener3i( ALenum param, ALint *value1, ALint *value2, ALint *value3 );
AL_API void AL_APIENTRY alGetListeneriv( ALenum param, ALint* values );
/**
* SOURCE
* Sources represent individual sound objects in 3D-space.
* Sources take the PCM data provided in the specified Buffer,
* apply Source-specific modifications, and then
* submit them to be mixed according to spatial arrangement etc.
*
* Properties include: -
*
* Gain AL_GAIN ALfloat
* Min Gain AL_MIN_GAIN ALfloat
* Max Gain AL_MAX_GAIN ALfloat
* Position AL_POSITION ALfloat[3]
* Velocity AL_VELOCITY ALfloat[3]
* Direction AL_DIRECTION ALfloat[3]
* Head Relative Mode AL_SOURCE_RELATIVE ALint (AL_TRUE or AL_FALSE)
* Reference Distance AL_REFERENCE_DISTANCE ALfloat
* Max Distance AL_MAX_DISTANCE ALfloat
* RollOff Factor AL_ROLLOFF_FACTOR ALfloat
* Inner Angle AL_CONE_INNER_ANGLE ALint or ALfloat
* Outer Angle AL_CONE_OUTER_ANGLE ALint or ALfloat
* Cone Outer Gain AL_CONE_OUTER_GAIN ALint or ALfloat
* Pitch AL_PITCH ALfloat
* Looping AL_LOOPING ALint (AL_TRUE or AL_FALSE)
* MS Offset AL_MSEC_OFFSET ALint or ALfloat
* Byte Offset AL_BYTE_OFFSET ALint or ALfloat
* Sample Offset AL_SAMPLE_OFFSET ALint or ALfloat
* Attached Buffer AL_BUFFER ALint
* State (Query only) AL_SOURCE_STATE ALint
* Buffers Queued (Query only) AL_BUFFERS_QUEUED ALint
* Buffers Processed (Query only) AL_BUFFERS_PROCESSED ALint
*/
/* Create Source objects */
AL_API void AL_APIENTRY alGenSources( ALsizei n, ALuint* sources );
/* Delete Source objects */
AL_API void AL_APIENTRY alDeleteSources( ALsizei n, const ALuint* sources );
/* Verify a handle is a valid Source */
AL_API ALboolean AL_APIENTRY alIsSource( ALuint sid );
/*
* Set Source parameters
*/
AL_API void AL_APIENTRY alSourcef( ALuint sid, ALenum param, ALfloat value );
AL_API void AL_APIENTRY alSource3f( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
AL_API void AL_APIENTRY alSourcefv( ALuint sid, ALenum param, const ALfloat* values );
AL_API void AL_APIENTRY alSourcei( ALuint sid, ALenum param, ALint value );
AL_API void AL_APIENTRY alSource3i( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 );
AL_API void AL_APIENTRY alSourceiv( ALuint sid, ALenum param, const ALint* values );
/*
* Get Source parameters
*/
AL_API void AL_APIENTRY alGetSourcef( ALuint sid, ALenum param, ALfloat* value );
AL_API void AL_APIENTRY alGetSource3f( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
AL_API void AL_APIENTRY alGetSourcefv( ALuint sid, ALenum param, ALfloat* values );
AL_API void AL_APIENTRY alGetSourcei( ALuint sid, ALenum param, ALint* value );
AL_API void AL_APIENTRY alGetSource3i( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
AL_API void AL_APIENTRY alGetSourceiv( ALuint sid, ALenum param, ALint* values );
/*
* Source vector based playback calls
*/
/* Play, replay, or resume (if paused) a list of Sources */
AL_API void AL_APIENTRY alSourcePlayv( ALsizei ns, const ALuint *sids );
/* Stop a list of Sources */
AL_API void AL_APIENTRY alSourceStopv( ALsizei ns, const ALuint *sids );
/* Rewind a list of Sources */
AL_API void AL_APIENTRY alSourceRewindv( ALsizei ns, const ALuint *sids );
/* Pause a list of Sources */
AL_API void AL_APIENTRY alSourcePausev( ALsizei ns, const ALuint *sids );
/*
* Source based playback calls
*/
/* Play, replay, or resume a Source */
AL_API void AL_APIENTRY alSourcePlay( ALuint sid );
/* Stop a Source */
AL_API void AL_APIENTRY alSourceStop( ALuint sid );
/* Rewind a Source (set playback postiton to beginning) */
AL_API void AL_APIENTRY alSourceRewind( ALuint sid );
/* Pause a Source */
AL_API void AL_APIENTRY alSourcePause( ALuint sid );
/*
* Source Queuing
*/
AL_API void AL_APIENTRY alSourceQueueBuffers( ALuint sid, ALsizei numEntries, const ALuint *bids );
AL_API void AL_APIENTRY alSourceUnqueueBuffers( ALuint sid, ALsizei numEntries, ALuint *bids );
/**
* BUFFER
* Buffer objects are storage space for sample data.
* Buffers are referred to by Sources. One Buffer can be used
* by multiple Sources.
*
* Properties include: -
*
* Frequency (Query only) AL_FREQUENCY ALint
* Size (Query only) AL_SIZE ALint
* Bits (Query only) AL_BITS ALint
* Channels (Query only) AL_CHANNELS ALint
*/
/* Create Buffer objects */
AL_API void AL_APIENTRY alGenBuffers( ALsizei n, ALuint* buffers );
/* Delete Buffer objects */
AL_API void AL_APIENTRY alDeleteBuffers( ALsizei n, const ALuint* buffers );
/* Verify a handle is a valid Buffer */
AL_API ALboolean AL_APIENTRY alIsBuffer( ALuint bid );
/* Specify the data to be copied into a buffer */
AL_API void AL_APIENTRY alBufferData( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq );
/*
* Set Buffer parameters
*/
AL_API void AL_APIENTRY alBufferf( ALuint bid, ALenum param, ALfloat value );
AL_API void AL_APIENTRY alBuffer3f( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
AL_API void AL_APIENTRY alBufferfv( ALuint bid, ALenum param, const ALfloat* values );
AL_API void AL_APIENTRY alBufferi( ALuint bid, ALenum param, ALint value );
AL_API void AL_APIENTRY alBuffer3i( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 );
AL_API void AL_APIENTRY alBufferiv( ALuint bid, ALenum param, const ALint* values );
/*
* Get Buffer parameters
*/
AL_API void AL_APIENTRY alGetBufferf( ALuint bid, ALenum param, ALfloat* value );
AL_API void AL_APIENTRY alGetBuffer3f( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
AL_API void AL_APIENTRY alGetBufferfv( ALuint bid, ALenum param, ALfloat* values );
AL_API void AL_APIENTRY alGetBufferi( ALuint bid, ALenum param, ALint* value );
AL_API void AL_APIENTRY alGetBuffer3i( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
AL_API void AL_APIENTRY alGetBufferiv( ALuint bid, ALenum param, ALint* values );
/*
* Global Parameters
*/
AL_API void AL_APIENTRY alDopplerFactor( ALfloat value );
AL_API void AL_APIENTRY alDopplerVelocity( ALfloat value );
AL_API void AL_APIENTRY alSpeedOfSound( ALfloat value );
AL_API void AL_APIENTRY alDistanceModel( ALenum distanceModel );
/*
* Pointer-to-function types, useful for dynamically getting AL entry points.
*/
typedef void (AL_APIENTRY *LPALENABLE)( ALenum capability );
typedef void (AL_APIENTRY *LPALDISABLE)( ALenum capability );
typedef ALboolean (AL_APIENTRY *LPALISENABLED)( ALenum capability );
typedef const ALchar* (AL_APIENTRY *LPALGETSTRING)( ALenum param );
typedef void (AL_APIENTRY *LPALGETBOOLEANV)( ALenum param, ALboolean* data );
typedef void (AL_APIENTRY *LPALGETINTEGERV)( ALenum param, ALint* data );
typedef void (AL_APIENTRY *LPALGETFLOATV)( ALenum param, ALfloat* data );
typedef void (AL_APIENTRY *LPALGETDOUBLEV)( ALenum param, ALdouble* data );
typedef ALboolean (AL_APIENTRY *LPALGETBOOLEAN)( ALenum param );
typedef ALint (AL_APIENTRY *LPALGETINTEGER)( ALenum param );
typedef ALfloat (AL_APIENTRY *LPALGETFLOAT)( ALenum param );
typedef ALdouble (AL_APIENTRY *LPALGETDOUBLE)( ALenum param );
typedef ALenum (AL_APIENTRY *LPALGETERROR)( void );
typedef ALboolean (AL_APIENTRY *LPALISEXTENSIONPRESENT)(const ALchar* extname );
typedef void* (AL_APIENTRY *LPALGETPROCADDRESS)( const ALchar* fname );
typedef ALenum (AL_APIENTRY *LPALGETENUMVALUE)( const ALchar* ename );
typedef void (AL_APIENTRY *LPALLISTENERF)( ALenum param, ALfloat value );
typedef void (AL_APIENTRY *LPALLISTENER3F)( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
typedef void (AL_APIENTRY *LPALLISTENERFV)( ALenum param, const ALfloat* values );
typedef void (AL_APIENTRY *LPALLISTENERI)( ALenum param, ALint value );
typedef void (AL_APIENTRY *LPALLISTENER3I)( ALenum param, ALint value1, ALint value2, ALint value3 );
typedef void (AL_APIENTRY *LPALLISTENERIV)( ALenum param, const ALint* values );
typedef void (AL_APIENTRY *LPALGETLISTENERF)( ALenum param, ALfloat* value );
typedef void (AL_APIENTRY *LPALGETLISTENER3F)( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 );
typedef void (AL_APIENTRY *LPALGETLISTENERFV)( ALenum param, ALfloat* values );
typedef void (AL_APIENTRY *LPALGETLISTENERI)( ALenum param, ALint* value );
typedef void (AL_APIENTRY *LPALGETLISTENER3I)( ALenum param, ALint *value1, ALint *value2, ALint *value3 );
typedef void (AL_APIENTRY *LPALGETLISTENERIV)( ALenum param, ALint* values );
typedef void (AL_APIENTRY *LPALGENSOURCES)( ALsizei n, ALuint* sources );
typedef void (AL_APIENTRY *LPALDELETESOURCES)( ALsizei n, const ALuint* sources );
typedef ALboolean (AL_APIENTRY *LPALISSOURCE)( ALuint sid );
typedef void (AL_APIENTRY *LPALSOURCEF)( ALuint sid, ALenum param, ALfloat value);
typedef void (AL_APIENTRY *LPALSOURCE3F)( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
typedef void (AL_APIENTRY *LPALSOURCEFV)( ALuint sid, ALenum param, const ALfloat* values );
typedef void (AL_APIENTRY *LPALSOURCEI)( ALuint sid, ALenum param, ALint value);
typedef void (AL_APIENTRY *LPALSOURCE3I)( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 );
typedef void (AL_APIENTRY *LPALSOURCEIV)( ALuint sid, ALenum param, const ALint* values );
typedef void (AL_APIENTRY *LPALGETSOURCEF)( ALuint sid, ALenum param, ALfloat* value );
typedef void (AL_APIENTRY *LPALGETSOURCE3F)( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
typedef void (AL_APIENTRY *LPALGETSOURCEFV)( ALuint sid, ALenum param, ALfloat* values );
typedef void (AL_APIENTRY *LPALGETSOURCEI)( ALuint sid, ALenum param, ALint* value );
typedef void (AL_APIENTRY *LPALGETSOURCE3I)( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
typedef void (AL_APIENTRY *LPALGETSOURCEIV)( ALuint sid, ALenum param, ALint* values );
typedef void (AL_APIENTRY *LPALSOURCEPLAYV)( ALsizei ns, const ALuint *sids );
typedef void (AL_APIENTRY *LPALSOURCESTOPV)( ALsizei ns, const ALuint *sids );
typedef void (AL_APIENTRY *LPALSOURCEREWINDV)( ALsizei ns, const ALuint *sids );
typedef void (AL_APIENTRY *LPALSOURCEPAUSEV)( ALsizei ns, const ALuint *sids );
typedef void (AL_APIENTRY *LPALSOURCEPLAY)( ALuint sid );
typedef void (AL_APIENTRY *LPALSOURCESTOP)( ALuint sid );
typedef void (AL_APIENTRY *LPALSOURCEREWIND)( ALuint sid );
typedef void (AL_APIENTRY *LPALSOURCEPAUSE)( ALuint sid );
typedef void (AL_APIENTRY *LPALSOURCEQUEUEBUFFERS)(ALuint sid, ALsizei numEntries, const ALuint *bids );
typedef void (AL_APIENTRY *LPALSOURCEUNQUEUEBUFFERS)(ALuint sid, ALsizei numEntries, ALuint *bids );
typedef void (AL_APIENTRY *LPALGENBUFFERS)( ALsizei n, ALuint* buffers );
typedef void (AL_APIENTRY *LPALDELETEBUFFERS)( ALsizei n, const ALuint* buffers );
typedef ALboolean (AL_APIENTRY *LPALISBUFFER)( ALuint bid );
typedef void (AL_APIENTRY *LPALBUFFERDATA)( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq );
typedef void (AL_APIENTRY *LPALBUFFERF)( ALuint bid, ALenum param, ALfloat value);
typedef void (AL_APIENTRY *LPALBUFFER3F)( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
typedef void (AL_APIENTRY *LPALBUFFERFV)( ALuint bid, ALenum param, const ALfloat* values );
typedef void (AL_APIENTRY *LPALBUFFERI)( ALuint bid, ALenum param, ALint value);
typedef void (AL_APIENTRY *LPALBUFFER3I)( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 );
typedef void (AL_APIENTRY *LPALBUFFERIV)( ALuint bid, ALenum param, const ALint* values );
typedef void (AL_APIENTRY *LPALGETBUFFERF)( ALuint bid, ALenum param, ALfloat* value );
typedef void (AL_APIENTRY *LPALGETBUFFER3F)( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
typedef void (AL_APIENTRY *LPALGETBUFFERFV)( ALuint bid, ALenum param, ALfloat* values );
typedef void (AL_APIENTRY *LPALGETBUFFERI)( ALuint bid, ALenum param, ALint* value );
typedef void (AL_APIENTRY *LPALGETBUFFER3I)( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
typedef void (AL_APIENTRY *LPALGETBUFFERIV)( ALuint bid, ALenum param, ALint* values );
typedef void (AL_APIENTRY *LPALDOPPLERFACTOR)( ALfloat value );
typedef void (AL_APIENTRY *LPALDOPPLERVELOCITY)( ALfloat value );
typedef void (AL_APIENTRY *LPALSPEEDOFSOUND)( ALfloat value );
typedef void (AL_APIENTRY *LPALDISTANCEMODEL)( ALenum distanceModel );
#if defined(TARGET_OS_MAC) && TARGET_OS_MAC
#pragma export off
#endif
#if defined(__cplusplus)
} /* extern "C" */
#endif
#endif /* AL_AL_H */

281
Source/OpenAL/al/alc.h Normal file
View File

@ -0,0 +1,281 @@
#ifndef AL_ALC_H
#define AL_ALC_H
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(_WIN32) && !defined(_XBOX)
/* _OPENAL32LIB is deprecated */
#if defined(AL_BUILD_LIBRARY) || defined (_OPENAL32LIB)
#define ALC_API __declspec(dllexport)
#else
#define ALC_API __declspec(dllimport)
#endif
#else
#if defined(AL_BUILD_LIBRARY) && defined(HAVE_GCC_VISIBILITY)
#define ALC_API __attribute__((visibility("default")))
#else
#define ALC_API extern
#endif
#endif
#if defined(_WIN32)
#define ALC_APIENTRY __cdecl
#else
#define ALC_APIENTRY
#endif
#if defined(TARGET_OS_MAC) && TARGET_OS_MAC
#pragma export on
#endif
/*
* The ALCAPI, ALCAPIENTRY, and ALC_INVALID macros are deprecated, but are
* included for applications porting code from AL 1.0
*/
#define ALCAPI ALC_API
#define ALCAPIENTRY ALC_APIENTRY
#define ALC_INVALID 0
#define ALC_VERSION_0_1 1
typedef struct ALCdevice_struct ALCdevice;
typedef struct ALCcontext_struct ALCcontext;
/** 8-bit boolean */
typedef char ALCboolean;
/** character */
typedef char ALCchar;
/** signed 8-bit 2's complement integer */
typedef char ALCbyte;
/** unsigned 8-bit integer */
typedef unsigned char ALCubyte;
/** signed 16-bit 2's complement integer */
typedef short ALCshort;
/** unsigned 16-bit integer */
typedef unsigned short ALCushort;
/** signed 32-bit 2's complement integer */
typedef int ALCint;
/** unsigned 32-bit integer */
typedef unsigned int ALCuint;
/** non-negative 32-bit binary integer size */
typedef int ALCsizei;
/** enumerated 32-bit value */
typedef int ALCenum;
/** 32-bit IEEE754 floating-point */
typedef float ALCfloat;
/** 64-bit IEEE754 floating-point */
typedef double ALCdouble;
/** void type (for opaque pointers only) */
typedef void ALCvoid;
/* Enumerant values begin at column 50. No tabs. */
/* Boolean False. */
#define ALC_FALSE 0
/* Boolean True. */
#define ALC_TRUE 1
/**
* followed by <int> Hz
*/
#define ALC_FREQUENCY 0x1007
/**
* followed by <int> Hz
*/
#define ALC_REFRESH 0x1008
/**
* followed by AL_TRUE, AL_FALSE
*/
#define ALC_SYNC 0x1009
/**
* followed by <int> Num of requested Mono (3D) Sources
*/
#define ALC_MONO_SOURCES 0x1010
/**
* followed by <int> Num of requested Stereo Sources
*/
#define ALC_STEREO_SOURCES 0x1011
/**
* errors
*/
/**
* No error
*/
#define ALC_NO_ERROR ALC_FALSE
/**
* No device
*/
#define ALC_INVALID_DEVICE 0xA001
/**
* invalid context ID
*/
#define ALC_INVALID_CONTEXT 0xA002
/**
* bad enum
*/
#define ALC_INVALID_ENUM 0xA003
/**
* bad value
*/
#define ALC_INVALID_VALUE 0xA004
/**
* Out of memory.
*/
#define ALC_OUT_OF_MEMORY 0xA005
/**
* The Specifier string for default device
*/
#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004
#define ALC_DEVICE_SPECIFIER 0x1005
#define ALC_EXTENSIONS 0x1006
#define ALC_MAJOR_VERSION 0x1000
#define ALC_MINOR_VERSION 0x1001
#define ALC_ATTRIBUTES_SIZE 0x1002
#define ALC_ALL_ATTRIBUTES 0x1003
/**
* ALC_ENUMERATE_ALL_EXT enums
*/
#define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012
#define ALC_ALL_DEVICES_SPECIFIER 0x1013
/**
* Capture extension
*/
#define ALC_CAPTURE_DEVICE_SPECIFIER 0x310
#define ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER 0x311
#define ALC_CAPTURE_SAMPLES 0x312
/*
* Context Management
*/
ALC_API ALCcontext * ALC_APIENTRY alcCreateContext( ALCdevice *device, const ALCint* attrlist );
ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent( ALCcontext *context );
ALC_API void ALC_APIENTRY alcProcessContext( ALCcontext *context );
ALC_API void ALC_APIENTRY alcSuspendContext( ALCcontext *context );
ALC_API void ALC_APIENTRY alcDestroyContext( ALCcontext *context );
ALC_API ALCcontext * ALC_APIENTRY alcGetCurrentContext( void );
ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice( ALCcontext *context );
/*
* Device Management
*/
ALC_API ALCdevice * ALC_APIENTRY alcOpenDevice( const ALCchar *devicename );
ALC_API ALCboolean ALC_APIENTRY alcCloseDevice( ALCdevice *device );
/*
* Error support.
* Obtain the most recent Context error
*/
ALC_API ALCenum ALC_APIENTRY alcGetError( ALCdevice *device );
/*
* Extension support.
* Query for the presence of an extension, and obtain any appropriate
* function pointers and enum values.
*/
ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent( ALCdevice *device, const ALCchar *extname );
ALC_API void * ALC_APIENTRY alcGetProcAddress( ALCdevice *device, const ALCchar *funcname );
ALC_API ALCenum ALC_APIENTRY alcGetEnumValue( ALCdevice *device, const ALCchar *enumname );
/*
* Query functions
*/
ALC_API const ALCchar * ALC_APIENTRY alcGetString( ALCdevice *device, ALCenum param );
ALC_API void ALC_APIENTRY alcGetIntegerv( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *data );
/*
* Capture functions
*/
ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize );
ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice( ALCdevice *device );
ALC_API void ALC_APIENTRY alcCaptureStart( ALCdevice *device );
ALC_API void ALC_APIENTRY alcCaptureStop( ALCdevice *device );
ALC_API void ALC_APIENTRY alcCaptureSamples( ALCdevice *device, ALCvoid *buffer, ALCsizei samples );
/*
* Pointer-to-function types, useful for dynamically getting ALC entry points.
*/
typedef ALCcontext * (ALC_APIENTRY *LPALCCREATECONTEXT) (ALCdevice *device, const ALCint *attrlist);
typedef ALCboolean (ALC_APIENTRY *LPALCMAKECONTEXTCURRENT)( ALCcontext *context );
typedef void (ALC_APIENTRY *LPALCPROCESSCONTEXT)( ALCcontext *context );
typedef void (ALC_APIENTRY *LPALCSUSPENDCONTEXT)( ALCcontext *context );
typedef void (ALC_APIENTRY *LPALCDESTROYCONTEXT)( ALCcontext *context );
typedef ALCcontext * (ALC_APIENTRY *LPALCGETCURRENTCONTEXT)( void );
typedef ALCdevice * (ALC_APIENTRY *LPALCGETCONTEXTSDEVICE)( ALCcontext *context );
typedef ALCdevice * (ALC_APIENTRY *LPALCOPENDEVICE)( const ALCchar *devicename );
typedef ALCboolean (ALC_APIENTRY *LPALCCLOSEDEVICE)( ALCdevice *device );
typedef ALCenum (ALC_APIENTRY *LPALCGETERROR)( ALCdevice *device );
typedef ALCboolean (ALC_APIENTRY *LPALCISEXTENSIONPRESENT)( ALCdevice *device, const ALCchar *extname );
typedef void * (ALC_APIENTRY *LPALCGETPROCADDRESS)(ALCdevice *device, const ALCchar *funcname );
typedef ALCenum (ALC_APIENTRY *LPALCGETENUMVALUE)(ALCdevice *device, const ALCchar *enumname );
typedef const ALCchar* (ALC_APIENTRY *LPALCGETSTRING)( ALCdevice *device, ALCenum param );
typedef void (ALC_APIENTRY *LPALCGETINTEGERV)( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *dest );
typedef ALCdevice * (ALC_APIENTRY *LPALCCAPTUREOPENDEVICE)( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize );
typedef ALCboolean (ALC_APIENTRY *LPALCCAPTURECLOSEDEVICE)( ALCdevice *device );
typedef void (ALC_APIENTRY *LPALCCAPTURESTART)( ALCdevice *device );
typedef void (ALC_APIENTRY *LPALCCAPTURESTOP)( ALCdevice *device );
typedef void (ALC_APIENTRY *LPALCCAPTURESAMPLES)( ALCdevice *device, ALCvoid *buffer, ALCsizei samples );
#if defined(TARGET_OS_MAC) && TARGET_OS_MAC
#pragma export off
#endif
#if defined(__cplusplus)
}
#endif
#endif /* AL_ALC_H */

165
Source/OpenAL/al/alctypes.h Normal file
View File

@ -0,0 +1,165 @@
#ifndef _ALCTYPES_H_
#define _ALCTYPES_H_
/**
* OpenAL cross platform audio library
* Copyright (C) 1999-2000 by authors.
* Portions Copyright (C) 2004 by Apple Computer Inc.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* Or go to http://www.gnu.org/copyleft/lgpl.html
*/
#ifdef __cplusplus
extern "C" {
#endif
/** ALC boolean type. */
typedef char ALCboolean;
/** ALC 8bit signed byte. */
typedef char ALCbyte;
/** ALC 8bit unsigned byte. */
typedef unsigned char ALCubyte;
/** ALC 16bit signed short integer type. */
typedef short ALCshort;
/** ALC 16bit unsigned short integer type. */
typedef unsigned short ALCushort;
/** ALC 32bit unsigned integer type. */
typedef unsigned ALCuint;
/** ALC 32bit signed integer type. */
typedef int ALCint;
/** ALC 32bit floating point type. */
typedef float ALCfloat;
/** ALC 64bit double point type. */
typedef double ALCdouble;
/** ALC 32bit type. */
typedef unsigned int ALCsizei;
/** ALC void type */
typedef void ALCvoid;
/** ALC enumerations. */
typedef int ALCenum;
/* Bad value. */
#define ALC_INVALID (-1)
/* Boolean False. */
#define ALC_FALSE 0
/* Boolean True. */
#define ALC_TRUE 1
/** Errors: No Error. */
#define ALC_NO_ERROR ALC_FALSE
#define ALC_MAJOR_VERSION 0x1000
#define ALC_MINOR_VERSION 0x1001
#define ALC_ATTRIBUTES_SIZE 0x1002
#define ALC_ALL_ATTRIBUTES 0x1003
#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004
#define ALC_DEVICE_SPECIFIER 0x1005
#define ALC_EXTENSIONS 0x1006
#define ALC_FREQUENCY 0x1007
#define ALC_REFRESH 0x1008
#define ALC_SYNC 0x1009
/**
* The device argument does not name a valid dvice.
*/
#define ALC_INVALID_DEVICE 0xA001
/**
* The context argument does not name a valid context.
*/
#define ALC_INVALID_CONTEXT 0xA002
/**
* A function was called at inappropriate time,
* or in an inappropriate way, causing an illegal state.
* This can be an incompatible ALenum, object ID,
* and/or function.
*/
#define ALC_INVALID_ENUM 0xA003
/**
* Illegal value passed as an argument to an AL call.
* Applies to parameter values, but not to enumerations.
*/
#define ALC_INVALID_VALUE 0xA004
/**
* A function could not be completed,
* because there is not enough memory available.
*/
#define ALC_OUT_OF_MEMORY 0xA005
/* ********************************************************************************
OSX Specific Properties
******************************************************************************** */
/**
* Convert Data When Loading. Default false, currently applies only to monophonic sounds
*/
#define ALC_CONVERT_DATA_UPON_LOADING 0xF001
/**
* Render Quality.
*/
#define ALC_SPATIAL_RENDERING_QUALITY 0xF002
#define ALC_SPATIAL_RENDERING_QUALITY_HIGH 'rqhi'
#define ALC_SPATIAL_RENDERING_QUALITY_LOW 'rdlo'
/**
* Mixer Output Rate.
*/
#define ALC_MIXER_OUTPUT_RATE 0xF003
/**
* Maximum Mixer Busses.
* Set this before opening a new OAL device to indicate how many busses on the mixer
* are desired. Get returns either the current devices bus count value, or the value
* that will be used to open a device
*/
#define ALC_MIXER_MAXIMUM_BUSSES 0xF004
/**
* Render Channels.
* Allows a user to force OpenAL to render to stereo, regardless of the audio hardware being used
*/
#define ALC_RENDER_CHANNEL_COUNT 0xF005
#define ALC_RENDER_CHANNEL_COUNT_STEREO 'rcst'
#define ALC_RENDER_CHANNEL_COUNT_MULTICHANNEL 'rcmc'
#ifdef __cplusplus
}
#endif
#endif

326
Source/OpenAL/al/altypes.h Normal file
View File

@ -0,0 +1,326 @@
#ifndef _ALTYPES_H_
#define _ALTYPES_H_
/**
* OpenAL cross platform audio library
* Copyright (C) 1999-2000 by authors.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* Or go to http://www.gnu.org/copyleft/lgpl.html
*/
#ifdef __cplusplus
extern "C" {
#endif
/** OpenAL boolean type. */
typedef char ALboolean;
/** OpenAL 8bit signed byte. */
typedef char ALbyte;
/** OpenAL 8bit unsigned byte. */
typedef unsigned char ALubyte;
/** OpenAL 16bit signed short integer type. */
typedef short ALshort;
/** OpenAL 16bit unsigned short integer type. */
typedef unsigned short ALushort;
/** OpenAL 32bit unsigned integer type. */
typedef unsigned ALuint;
/** OpenAL 32bit signed integer type. */
typedef int ALint;
/** OpenAL 32bit floating point type. */
typedef float ALfloat;
/** OpenAL 64bit double point type. */
typedef double ALdouble;
/** OpenAL 32bit type. */
typedef unsigned int ALsizei;
/** OpenAL void type */
typedef void ALvoid;
/** OpenAL enumerations. */
typedef int ALenum;
/* Bad value. */
#define AL_INVALID (-1)
/* Disable value. */
#define AL_NONE 0
/* Boolean False. */
#define AL_FALSE 0
/* Boolean True. */
#define AL_TRUE 1
/**
* Indicate the type of AL_SOURCE.
* Sources can be spatialized
*/
#define AL_SOURCE_TYPE 0x200
/** Indicate source has absolute coordinates. */
#define AL_SOURCE_ABSOLUTE 0x201
/** Indicate Source has listener relative coordinates. */
#define AL_SOURCE_RELATIVE 0x202
/**
* Directional source, inner cone angle, in degrees.
* Range: [0-360]
* Default: 360
*/
#define AL_CONE_INNER_ANGLE 0x1001
/**
* Directional source, outer cone angle, in degrees.
* Range: [0-360]
* Default: 360
*/
#define AL_CONE_OUTER_ANGLE 0x1002
/**
* Specify the pitch to be applied, either at source,
* or on mixer results, at listener.
* Range: [0.5-2.0]
* Default: 1.0
*/
#define AL_PITCH 0x1003
/**
* Specify the current location in three dimensional space.
* OpenAL, like OpenGL, uses a right handed coordinate system,
* where in a frontal default view X (thumb) points right,
* Y points up (index finger), and Z points towards the
* viewer/camera (middle finger).
* To switch from a left handed coordinate system, flip the
* sign on the Z coordinate.
* Listener position is always in the world coordinate system.
*/
#define AL_POSITION 0x1004
/** Specify the current direction as forward vector. */
#define AL_DIRECTION 0x1005
/** Specify the current velocity in three dimensional space. */
#define AL_VELOCITY 0x1006
/**
* Indicate whether source has to loop infinite.
* Type: ALboolean
* Range: [AL_TRUE, AL_FALSE]
* Default: AL_FALSE
*/
#define AL_LOOPING 0x1007
/**
* Indicate the buffer to provide sound samples.
* Type: ALuint.
* Range: any valid Buffer id.
*/
#define AL_BUFFER 0x1009
/**
* Indicate the gain (volume amplification) applied.
* Type: ALfloat.
* Range: ]0.0- ]
* A value of 1.0 means un-attenuated/unchanged.
* Each division by 2 equals an attenuation of -6dB.
* Each multiplicaton with 2 equals an amplification of +6dB.
* A value of 0.0 is meaningless with respect to a logarithmic
* scale; it is interpreted as zero volume - the channel
* is effectively disabled.
*/
#define AL_GAIN 0x100A
/**
* Indicate minimum source attenuation.
* Type: ALfloat
* Range: [0.0 - 1.0]
*/
#define AL_MIN_GAIN 0x100D
/**
* Indicate maximum source attenuation.
* Type: ALfloat
* Range: [0.0 - 1.0]
*/
#define AL_MAX_GAIN 0x100E
/**
* Specify the current orientation.
* Type: ALfv6 (at/up)
* Range: N/A
*/
#define AL_ORIENTATION 0x100F
/* byte offset into source (in canon format). -1 if source
* is not playing. Don't set this, get this.
*
* Type: ALfloat
* Range: [0.0 - ]
* Default: 1.0
*/
#define AL_REFERENCE_DISTANCE 0x1020
/**
* Indicate the rolloff factor for the source.
* Type: ALfloat
* Range: [0.0 - ]
* Default: 1.0
*/
#define AL_ROLLOFF_FACTOR 0x1021
/**
* Indicate the gain (volume amplification) applied.
* Type: ALfloat.
* Range: ]0.0- ]
* A value of 1.0 means un-attenuated/unchanged.
* Each division by 2 equals an attenuation of -6dB.
* Each multiplicaton with 2 equals an amplification of +6dB.
* A value of 0.0 is meaningless with respect to a logarithmic
* scale; it is interpreted as zero volume - the channel
* is effectively disabled.
*/
#define AL_CONE_OUTER_GAIN 0x1022
/**
* Specify the maximum distance.
* Type: ALfloat
* Range: [0.0 - ]
*/
#define AL_MAX_DISTANCE 0x1023
/**
* Source state information
*/
#define AL_SOURCE_STATE 0x1010
#define AL_INITIAL 0x1011
#define AL_PLAYING 0x1012
#define AL_PAUSED 0x1013
#define AL_STOPPED 0x1014
/**
* Buffer Queue params
*/
#define AL_BUFFERS_QUEUED 0x1015
#define AL_BUFFERS_PROCESSED 0x1016
/** Sound buffers: format specifier. */
#define AL_FORMAT_MONO8 0x1100
#define AL_FORMAT_MONO16 0x1101
#define AL_FORMAT_STEREO8 0x1102
#define AL_FORMAT_STEREO16 0x1103
/**
* Sound buffers: frequency, in units of Hertz [Hz].
* This is the number of samples per second. Half of the
* sample frequency marks the maximum significant
* frequency component.
*/
#define AL_FREQUENCY 0x2001
#define AL_BITS 0x2002
#define AL_CHANNELS 0x2003
#define AL_SIZE 0x2004
#define AL_DATA 0x2005
/**
* Buffer state.
*
* Not supported for public use (yet).
*/
#define AL_UNUSED 0x2010
#define AL_PENDING 0x2011
#define AL_PROCESSED 0x2012
/** Errors: No Error. */
#define AL_NO_ERROR AL_FALSE
/**
* Illegal name passed as an argument to an AL call.
*/
#define AL_INVALID_NAME 0xA001
/**
* Illegal enum passed as an argument to an AL call.
*/
#define AL_INVALID_ENUM 0xA002
/**
* Illegal value passed as an argument to an AL call.
* Applies to parameter values, but not to enumerations.
*/
#define AL_INVALID_VALUE 0xA003
/**
* A function was called at inappropriate time,
* or in an inappropriate way, causing an illegal state.
* This can be an incompatible ALenum, object ID,
* and/or function.
*/
#define AL_INVALID_OPERATION 0xA004
/**
* A function could not be completed,
* because there is not enough memory available.
*/
#define AL_OUT_OF_MEMORY 0xA005
/** Context strings: Vendor Name. */
#define AL_VENDOR 0xB001
#define AL_VERSION 0xB002
#define AL_RENDERER 0xB003
#define AL_EXTENSIONS 0xB004
/** Global tweakage. */
/**
* Doppler scale. Default 1.0
*/
#define AL_DOPPLER_FACTOR 0xC000
/**
* Doppler velocity. Default 1.0
*/
#define AL_DOPPLER_VELOCITY 0xC001
/**
* Distance model. Default AL_INVERSE_DISTANCE_CLAMPED
*/
#define AL_DISTANCE_MODEL 0xD000
/** Distance models. */
#define AL_INVERSE_DISTANCE 0xD001
#define AL_INVERSE_DISTANCE_CLAMPED 0xD002
/**
* enables
*/
#ifdef __cplusplus
}
#endif
#endif

55
Source/OpenAL/al/alut.h Normal file
View File

@ -0,0 +1,55 @@
/**
* OpenAL cross platform audio library
* Copyright (C) 1999-2000 by authors.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* Or go to http://www.gnu.org/copyleft/lgpl.html
*/
#ifndef _ALUT_H_
#define _ALUT_H_
#define ALUTAPI
#define ALUTAPIENTRY
#include "al.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef TARGET_OS_MAC
#if TARGET_OS_MAC
#pragma export on
#endif
#endif
ALUTAPI ALvoid ALUTAPIENTRY alutInit(ALint *argc,ALbyte **argv);
ALUTAPI ALvoid ALUTAPIENTRY alutExit(ALvoid);
ALUTAPI ALvoid ALUTAPIENTRY alutLoadWAVFile(ALbyte *file,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq);
ALUTAPI ALvoid ALUTAPIENTRY alutLoadWAVMemory(ALbyte *memory,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq);
ALUTAPI ALvoid ALUTAPIENTRY alutUnloadWAV(ALenum format,ALvoid *data,ALsizei size,ALsizei freq);
#ifdef TARGET_OS_MAC
#if TARGET_OS_MAC
#pragma export off
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif

514
Source/OpenAL/oalBuffer.cpp Normal file
View File

@ -0,0 +1,514 @@
/**********************************************************************************************************************************
*
* OpenAL cross platform audio library
* Copyright (c) 2004, Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************************************************************************/
#include "oalBuffer.h"
#include "oalSource.h"
#include "oalImp.h"
#include "CAGuard.h"
#define LOG_VERBOSE 0
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark _____Support Methods_____
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// OALBuffers
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark ***** OALBuffers *****
OALBuffer::OALBuffer (ALuint inSelfToken)
: mSelfToken (inSelfToken),
#if USE_SOURCE_LIST_MUTEX
mSourceListGuard ("OALBuffer::SourceListGuard"),
#endif
mBufferLock ("OALBuffer::EditLock"),
mInUseFlag(0),
mData(NULL),
mAppOwnsBufferMemory(false),
mDataSize (0),
mPreConvertedDataSize(0),
mDataHasBeenConverted(false),
mAttachedSourceList(NULL),
mIsInPostRenderMessageQueue(false)
{
#if LOG_VERBOSE
DebugMessageN1("OALBuffer::OALBuffer() - OALBuffer = %ld", (long int) mSelfToken);
#endif
mAttachedSourceList = new AttachedSourceList (); // create a source list map
mAttachedSourceList->Reserve(128);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OALBuffer::~OALBuffer()
{
#if LOG_VERBOSE
DebugMessageN1("OALBuffer::~OALBuffer() - OALBuffer = %ld", (long int) mSelfToken);
#endif
if (!mAppOwnsBufferMemory && (mData != NULL))
free (mData);
// should never be deleted unless this object said it was ok
#if USE_SOURCE_LIST_MUTEX
bool wasLocked = mSourceListGuard.Lock();
#endif
if (mAttachedSourceList)
delete mAttachedSourceList;
#if USE_SOURCE_LIST_MUTEX
if (wasLocked) mSourceListGuard.Unlock();
#endif
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool OALBuffer::CanBeRemovedFromBufferMap()
{
#if LOG_VERBOSE
DebugMessageN1("OALBuffer::CanBeRemovedFromBufferMap() - OALBuffer = %ld", (long int) mSelfToken);
#endif
bool returnValue = true;
#if USE_SOURCE_LIST_MUTEX
bool wasLocked = mSourceListGuard.Lock();
#endif
// if the buffer object is not attached to a source, it's ok to remove
if (mAttachedSourceList->Size() == 0)
returnValue = true;
else
{
// if all attached sources are transitioning to flush, it can be removed from buffer map,
// but the OALBuffer object must be deleted at a later time
for (UInt32 i = 0; i < mAttachedSourceList->Size(); i++)
{
OALSource *curSource = mAttachedSourceList->GetSourceByIndex(i);
if (curSource)
{
if (!curSource->IsSourceTransitioningToFlushQ())
{
returnValue = false;
goto Finished;
}
}
}
}
Finished:
#if USE_SOURCE_LIST_MUTEX
if (wasLocked) mSourceListGuard.Unlock();
#endif
return returnValue; // all attached sources are transitioning to flush
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool OALBuffer::IsPurgable()
{
#if LOG_VERBOSE
DebugMessageN1("OALBuffer::IsPurgable() - OALBuffer = %ld", (long int) mSelfToken);
#endif
bool returnValue = false;
#if USE_SOURCE_LIST_MUTEX
bool wasLocked = mSourceListGuard.Lock();
#endif
// make sure that no other source has attached this buffer, and that no other thread is editing it
if ((mAttachedSourceList->Size() == 0) && mBufferLock.IsFree() && (mInUseFlag <= 0) && (!IsInPostRenderMessageQueue()))
returnValue = true;
#if USE_SOURCE_LIST_MUTEX
if (wasLocked) mSourceListGuard.Unlock();
#endif
return returnValue;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OSStatus OALBuffer::AddAudioDataStatic(char* inAudioData, UInt32 inAudioDataSize, ALenum format, ALsizei freq)
{
#if LOG_VERBOSE
DebugMessageN5("OALBuffer::AddAudioDataStatic() - OALBuffer:inAudioData:inAudioDataSize:format:freq = %ld:%p:%ld:%d:%d", (long int) mSelfToken, inAudioData, (long int) inAudioDataSize, format, freq);
#endif
#if LOG_EXTRAS
DebugMessage("AddAudioDataStatic called: Converting Data Now");
#endif
CAGuard::Locker bufferLock(mBufferLock);
try {
if (!IsFormatSupported(format))
throw ((OSStatus) AL_INVALID_VALUE); // this is not a valid buffer token or is an invalid format
// don't allow if the buffer is in a queue
if (mAttachedSourceList->Size() > 0)
{
DebugMessage("AddAudioDataStatic ATTACHMENT > 0");
throw ((OSStatus) AL_INVALID_OPERATION);
}
mPreConvertedDataSize = (UInt32) inAudioDataSize;
OSStatus result = noErr;
// if this buffer was using memory created by the library, free it now and initialize mData
if (!mAppOwnsBufferMemory && (mData != NULL))
{
free (mData);
mData = NULL;
}
mData = (UInt8*) inAudioData;
mDataSize = (UInt32) inAudioDataSize;
result = FillInASBD(mDataFormat, format, freq);
THROW_RESULT
mPreConvertedDataFormat.SetFrom(mDataFormat); // make sure they are the same so original format info can be returned to caller
}
catch (OSStatus result) {
mData = NULL;
mAppOwnsBufferMemory = false;
DebugMessageN1("AddAudioDataStatic Failed - err = %ld\n", (long int) result);
alSetError(result);
}
catch (...) {
mData = NULL;
mAppOwnsBufferMemory = false;
DebugMessage("AddAudioDataStatic Failed");
alSetError(AL_INVALID_OPERATION);
}
mAppOwnsBufferMemory = true;
return noErr;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OSStatus OALBuffer::AddAudioData(char* inAudioData, UInt32 inAudioDataSize, ALenum format, ALsizei freq, bool inPreConvertToHalFormat)
{
#if LOG_VERBOSE
DebugMessageN6("OALBuffer::AddAudioData() - OALBuffer:inAudioData:inAudioDataSize:format:freq:inPreConvertToHalFormat = %ld:%p:%ld:%d:%d:%d", (long int) mSelfToken, inAudioData, (long int) inAudioDataSize, format, freq, inPreConvertToHalFormat);
#endif
// creates memory if needed
// reallocs if needed
// returns an error if buffer is in use
CAGuard::Locker bufferLock(mBufferLock);
try {
if (!IsFormatSupported(format))
throw ((OSStatus) AL_INVALID_VALUE); // this is not a valid buffer token or is an invalid format
#if USE_SOURCE_LIST_MUTEX
bool wasLocked = mSourceListGuard.Lock();
#endif
// don't allow if the buffer is in a queue
UInt32 attachedCount = mAttachedSourceList->Size();
#if USE_SOURCE_LIST_MUTEX
if (wasLocked) mSourceListGuard.Unlock();
#endif
if (attachedCount > 0)
{
DebugMessage("WAITING: AddAudioData ---> WaitOneRenderCycle");
// Let a render cycle go by and try again
WaitOneRenderCycle();
#if USE_SOURCE_LIST_MUTEX
wasLocked = mSourceListGuard.Lock();
#endif
attachedCount = mAttachedSourceList->Size();
#if USE_SOURCE_LIST_MUTEX
if (wasLocked) mSourceListGuard.Unlock();
#endif
if (attachedCount > 0){
DebugMessageN2("OALBuffer::AddAudioData: buffer ATTACHMENT > 0 - mSelfToken:mAttachedSourceList->Size() = %ld:%ld", (long int) mSelfToken, (long int) mAttachedSourceList->Size());
throw ((OSStatus) AL_INVALID_OPERATION);
}
}
if (mAppOwnsBufferMemory)
{
mData = NULL; // we were using the apps memory before so just initialize mData incase we fail
mAppOwnsBufferMemory = false;
}
mPreConvertedDataSize = (UInt32) inAudioDataSize;
// do not pre-convert stereo sounds, let the AC do the deinterleaving
OSStatus result = noErr;
if (!inPreConvertToHalFormat || ((format == AL_FORMAT_STEREO16) || (format == AL_FORMAT_STEREO8)))
{
if (mData != NULL)
{
if (mDataSize != (UInt32) inAudioDataSize)
{
mDataSize = (UInt32) inAudioDataSize;
void *newDataPtr = realloc(mData, mDataSize);
mData = (UInt8 *) newDataPtr;
}
}
else
{
mDataSize = (UInt32) inAudioDataSize;
mData = (UInt8 *) malloc (mDataSize);
}
if (mData)
{
result = FillInASBD(mDataFormat, format, freq);
THROW_RESULT
mPreConvertedDataFormat.SetFrom(mDataFormat); // make sure they are the same so original format info can be returned to caller
memcpy (mData, inAudioData, mDataSize);
}
}
else
{
#if LOG_EXTRAS
DebugMessage("alBufferData called: Converting Data Now");
#endif
result = ConvertDataForBuffer(inAudioData, inAudioDataSize, format, freq); // convert the data to the mixer's format and copy to the buffer
THROW_RESULT
}
}
catch (OSStatus result) {
DebugMessageN1("OALBuffer::AddAudioData Failed - err = %ld\n", (long int) result);
alSetError(result);
throw result;
}
catch (...) {
DebugMessage("OALBuffer::AddAudioData Failed");
alSetError(AL_INVALID_OPERATION);
throw -1;
}
return noErr;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// This currently will only work for cbr formats
OSStatus OALBuffer::ConvertDataForBuffer(void *inData, UInt32 inDataSize, UInt32 inDataFormat, UInt32 inDataSampleRate)
{
#if LOG_VERBOSE
DebugMessageN5("OALBuffer::ConvertDataForBuffer() - OALBuffer:inData:inDataSize:inDataFormat:inDataSampleRate = %ld:%p:%ld:%ld:%ld", (long int) mSelfToken, inData, (long int) inDataSize, (long int) inDataFormat, (long int) inDataSampleRate);
#endif
OSStatus result = noErr;
try {
AudioConverterRef converter;
CAStreamBasicDescription destFormat;
UInt32 framesOfSource = 0;
if (inData == NULL)
throw ((OSStatus) AL_INVALID_OPERATION);
result = FillInASBD(mPreConvertedDataFormat, inDataFormat, inDataSampleRate);
THROW_RESULT
if (mPreConvertedDataFormat.NumberChannels() == 1)
mPreConvertedDataFormat.mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
destFormat.mChannelsPerFrame = mPreConvertedDataFormat.NumberChannels();
destFormat.mSampleRate = mPreConvertedDataFormat.mSampleRate;
destFormat.mFormatID = kAudioFormatLinearPCM;
if (mPreConvertedDataFormat.NumberChannels() == 1)
destFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved;
else
destFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked; // leave stereo data interleaved, and an AC will be used for deinterleaving later on
destFormat.mFramesPerPacket = 1;
destFormat.mBitsPerChannel = sizeof (Float32) * 8;
destFormat.mBytesPerPacket = sizeof (Float32) * destFormat.NumberChannels();
destFormat.mBytesPerFrame = sizeof (Float32) * destFormat.NumberChannels();
result = FillInASBD(mDataFormat, inDataFormat, UInt32(destFormat.mSampleRate));
THROW_RESULT
result = AudioConverterNew(&mPreConvertedDataFormat, &destFormat, &converter);
THROW_RESULT
framesOfSource = inDataSize / mPreConvertedDataFormat.mBytesPerFrame; // THIS ONLY WORKS FOR CBR FORMATS
UInt32 dataSize = framesOfSource * sizeof(Float32) * destFormat.NumberChannels();
mDataSize = (UInt32) dataSize;
if (mData != NULL)
{
if (mDataSize != dataSize)
{
mDataSize = dataSize;
void *newDataPtr = realloc(mData, mDataSize);
if (newDataPtr == NULL)
throw ((OSStatus) AL_INVALID_OPERATION);
mData = (UInt8 *) newDataPtr;
}
}
else
{
mDataSize = dataSize;
mData = (UInt8 *) malloc (mDataSize);
if (mData == NULL)
throw ((OSStatus) AL_INVALID_OPERATION);
}
if (mData != NULL)
{
result = AudioConverterConvertBuffer(converter, inDataSize, inData, &mDataSize, mData);
if (result == noErr)
{
mDataFormat.SetFrom(destFormat);
if (mPreConvertedDataFormat.NumberChannels() == 1)
mDataHasBeenConverted = true;
else
mDataHasBeenConverted = false;
}
}
AudioConverterDispose(converter);
}
catch (OSStatus result) {
return (result);
}
catch (...) {
result = (OSStatus) AL_INVALID_OPERATION;
}
return (result);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Methods called from OALSource objects
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UInt32 OALBuffer::GetFramesToBytes(UInt32 inOffsetInFrames)
{
#if LOG_VERBOSE
DebugMessageN2("OALBuffer::GetFramesToBytes() - OALBuffer:inOffsetInFrames = %ld:%ld", (long int) mSelfToken, (long int) inOffsetInFrames);
#endif
UInt32 returnValue = 0;
if (GetFramesPerPacket() == 1)
{
// pcm - it's easy
returnValue = inOffsetInFrames * GetBytesPerPacket();
}
else
{
// discover which packet conatins the frame we want to offset to
// CURRENTLY UNNECESSARY BECAUSE WE ARE ONLY STORING PCM DATA
}
return returnValue;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UInt32 OALBuffer::GetFrameCount()
{
#if LOG_VERBOSE
DebugMessageN1("OALBuffer::GetFrameCount() - OALBuffer = %ld", (long int) mSelfToken);
#endif
UInt32 totalPackets = (mDataFormat.mBytesPerPacket == 0) ? 0 : mDataSize/mDataFormat.mBytesPerPacket;
return totalPackets * mDataFormat.mFramesPerPacket;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool OALBuffer::UseThisBuffer(OALSource* inSource)
{
#if LOG_VERBOSE
DebugMessageN1("OALBuffer::UseThisBuffer() - OALBuffer = %ld", (long int) mSelfToken);
#endif
#if USE_SOURCE_LIST_MUTEX
bool wasLocked = mSourceListGuard.Lock();
#endif
// see if this source is in list already
if (mAttachedSourceList->SourceExists(inSource) == true)
mAttachedSourceList->IncreaseAttachmentCount(inSource);
else
{
SourceAttachedInfo nuSourceInfo;
nuSourceInfo.mSource = inSource;
nuSourceInfo.mAttachedCount = 1;
mAttachedSourceList->Add(nuSourceInfo);
}
#if USE_SOURCE_LIST_MUTEX
if (wasLocked) mSourceListGuard.Unlock();
#endif
#if LOG_EXTRAS
DebugMessageN2("OALBuffer::UseThisBuffer - BufferToken:SourceToken = %ld:%ld", (long int)mSelfToken, (long int)inSource->GetToken());
#endif
return noErr;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Called by OALSource's BufferQueue::RemoveQueueEntryByIndex() class
bool OALBuffer::ReleaseBuffer(OALSource* inSource)
{
#if LOG_VERBOSE
DebugMessageN2("OALBuffer::ReleaseBuffer() - OALBuffer:inSource = %ld:%ld", (long int) mSelfToken, (long int) inSource->GetToken());
#endif
bool returnValue = false;
#if LOG_EXTRAS
DebugMessageN2("OALBuffer::ReleaseBuffer - BufferToken:SourceToken = %ld:%ld", mSelfToken, inSource->GetToken());
#endif
#if USE_SOURCE_LIST_MUTEX
bool wasLocked = mSourceListGuard.Lock();
#endif
// see if this source is in list already
if (mAttachedSourceList->SourceExists(inSource) == true)
{
UInt32 attachmentCount = mAttachedSourceList->DecreaseAttachmentCount(inSource);
if (attachmentCount == 0)
{
//DebugMessageN2("OALBuffer::ReleaseBuffer - BufferToken:SourceToken = %ld:%ld", (long int) mSelfToken, (long int) inSource->GetToken());
mAttachedSourceList->Remove(inSource);
returnValue = true;
}
}
#if USE_SOURCE_LIST_MUTEX
if (wasLocked) mSourceListGuard.Unlock();
#endif
return returnValue;
}

250
Source/OpenAL/oalBuffer.h Normal file
View File

@ -0,0 +1,250 @@
/**********************************************************************************************************************************
*
* OpenAL cross platform audio library
* Copyright (c) 2004, Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************************************************************************/
#ifndef __OAL_BUFFER__
#define __OAL_BUFFER__
#include <Carbon/Carbon.h>
#include <CoreAudio/CoreAudioTypes.h>
#include "CAStreamBasicDescription.h"
#include <map>
#include <vector>
#include "al.h"
#include <libkern/OSAtomic.h>
#define USE_SOURCE_LIST_MUTEX 1
#if USE_SOURCE_LIST_MUTEX
#include "CAGuard.h"
#endif
class OALSource; // forward declaration
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark _____AttachedSourceList_____
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct SourceAttachedInfo {
OALSource* mSource;
UInt32 mAttachedCount;
};
class AttachedSourceList : std::vector<SourceAttachedInfo> {
public:
void Add(SourceAttachedInfo& inSourceInfo)
{
push_back(value_type (inSourceInfo));
}
void Remove(OALSource* inSource) {
iterator it = begin();
while (it != end()) {
if ((*it).mSource == inSource)
{
erase(it);
return;
}
else
++it;
}
return;
}
bool SourceExists(OALSource* inSource) {
iterator it = begin();
while (it != end()) {
if ((*it).mSource == inSource)
return true;
else
++it;
}
return false;
}
void IncreaseAttachmentCount(OALSource* inSource) {
iterator it = begin();
while (it != end()) {
if ((*it).mSource == inSource) {
(*it).mAttachedCount++;
return;
}
else
++it;
}
return;
}
UInt32 DecreaseAttachmentCount(OALSource* inSource) {
iterator it = begin();
while (it != end()) {
if ((*it).mSource == inSource) {
(*it).mAttachedCount--;
return (*it).mAttachedCount;
}
else
++it;
}
return 0;
}
UInt32 GetAttachmentCount(OALSource* inSource) {
iterator it = begin();
while (it != end()) {
if ((*it).mSource == inSource)
return (*it).mAttachedCount;
else
++it;
}
return 0;
}
OALSource* GetSourceByIndex(short index) {
iterator it = begin();
std::advance(it, index);
if (it != end())
return((*it).mSource);
return (NULL);
}
UInt32 Size () const { return size(); }
bool Empty () const { return empty(); }
void Reserve(UInt32 reserveSize) {return reserve(reserveSize); }
};
typedef AttachedSourceList AttachedSourceList;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark _____OALBuffer_____
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class OALBuffer
{
public:
OALBuffer(ALuint inSelfToken);
~OALBuffer();
OSStatus AddAudioData( char* inAudioData, UInt32 inAudioDataSize, ALenum format, ALsizei freq, bool inPreConvertToHalFormat);
OSStatus AddAudioDataStatic(char* inAudioData, UInt32 inAudioDataSize, ALenum format, ALsizei freq);
void SetInUseFlag() { OSAtomicIncrement32Barrier(&mInUseFlag); }
void ClearInUseFlag() { OSAtomicDecrement32Barrier(&mInUseFlag); }
void SetIsInPostRenderMessageQueue(bool state) { mIsInPostRenderMessageQueue = state; }
bool IsInPostRenderMessageQueue() { return mIsInPostRenderMessageQueue == true; }
bool IsPurgable();
bool HasBeenConverted(){return mDataHasBeenConverted;}
ALuint GetToken(){return mSelfToken;}
UInt32 GetFrameCount();
UInt32 GetFramesToBytes(UInt32 inOffsetInFrames) ;
Float64 GetSampleRate(){return mDataFormat.mSampleRate;}
UInt32 GetBytesPerPacket(){return mDataFormat.mBytesPerPacket;}
UInt32 GetFramesPerPacket(){return mDataFormat.mFramesPerPacket;}
UInt32 GetPreConvertedBitsPerChannel(){return mPreConvertedDataFormat.mBitsPerChannel;}
UInt32 GetNumberChannels(){return mDataFormat.NumberChannels();}
UInt32 GetPreConvertedDataSize(){return mPreConvertedDataSize;}
UInt8* GetDataPtr(){return mData;}
UInt32 GetDataSize(){return mDataSize;}
CAStreamBasicDescription* GetFormat(){return &mDataFormat;}
bool CanBeRemovedFromBufferMap();
// called from OAL Source object
bool UseThisBuffer(OALSource* inSource); // one entry per source regardless of how many uses in the Q there are
bool ReleaseBuffer(OALSource* inSource); // when source does not need this buffer, remove it from the source list
void PrintFormat(){mDataFormat.Print();}
private:
ALuint mSelfToken;
#if USE_SOURCE_LIST_MUTEX
CAGuard mSourceListGuard;
#endif
CAGuard mBufferLock; // lock to serialize all buffer manipulations
volatile int32_t mInUseFlag; // flag to indicate if the buffer is currently being edited by one or more threads
UInt8 *mData; // ptr to the actual audio data
bool mAppOwnsBufferMemory; // true when data is passed in via the alBufferDtatStatic API (extension)
UInt32 mDataSize; // size in bytes of the audio data ptr
CAStreamBasicDescription mDataFormat; // format of the data of the data as it sits in memory
UInt32 mPreConvertedDataSize; // if data gets converted on the way in, it is necessary to remember the original size
CAStreamBasicDescription mPreConvertedDataFormat; // if data gets converted on the way in, it is necessary to remember the original format
bool mDataHasBeenConverted; // was the data converted to the mixer format when handed to the library?
AttachedSourceList* mAttachedSourceList; // all the OAL Source objects that use this buffer
bool mIsInPostRenderMessageQueue; // flag to indicate that the buffer is in the post render message list and cannot be deleted
OSStatus ConvertDataForBuffer (void *inData, UInt32 inDataSize, UInt32 inDataFormat, UInt32 inDataSampleRate);
};
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark _____OALBufferMap_____
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class OALBufferMap : std::multimap<ALuint, OALBuffer*, std::less<ALuint> > {
public:
void Add (const ALuint inBufferToken, OALBuffer **inBuffer)
{
iterator it = upper_bound(inBufferToken);
insert(it, value_type (inBufferToken, *inBuffer));
}
OALBuffer* GetBufferByIndex(UInt32 inIndex) {
iterator it = begin();
for (UInt32 i = 0; i < inIndex; i++){
if (it != end())
++it;
else
i = inIndex;
}
if (it != end())
return ((*it).second);
return (NULL);
}
OALBuffer* Get(ALuint inBufferToken) {
iterator it = find(inBufferToken);
if (it != end())
return ((*it).second);
return (NULL);
}
void Remove (const ALuint inBufferToken) {
iterator it = find(inBufferToken);
if (it != end())
erase(it);
}
OALBuffer* GetFirstItem() {
iterator it = begin();
if (it != end())
return ((*it).second);
return (NULL);
}
UInt32 Size () const { return size(); }
bool Empty () const { return empty(); }
};
#endif

View File

@ -0,0 +1,406 @@
/**********************************************************************************************************************************
*
* OpenAL cross platform audio library
* Copyright (c) 2005, Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************************************************************************/
#include "OALCaptureDevice.h"
#define LOG_CAPTURE 0
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark ***** OALCaptureDevices *****
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OALCaptureDevice::OALCaptureDevice (const char* inDeviceName, uintptr_t inSelfToken, UInt32 inSampleRate, UInt32 inFormat, UInt32 inBufferSize)
:
#if LOG_CAPTUREDEVICE_VERBOSE
mSelfToken (inSelfToken),
#endif
mCurrentError(ALC_NO_ERROR),
mCaptureOn(false),
mStoreSampleTime(0),
mFetchSampleTime(0),
mInputUnit(0),
mRingBuffer(NULL),
mBufferData(NULL),
mSampleRateRatio(1.0),
mRequestedRingFrames(inBufferSize),
mAudioInputPtrs(NULL),
mInUseFlag(0)
{
char *useThisDevice = (char *) inDeviceName;
try {
// translate the sample rate and data format parameters into an ASBD - this method throws
FillInASBD(mRequestedFormat, inFormat, inSampleRate);
// inBufferSize must be at least as big as one packet of the requested output formnat
if (inBufferSize < mRequestedFormat.mBytesPerPacket)
throw ((OSStatus) AL_INVALID_VALUE);
// until the ALC_ENUMERATION_EXT extension is supported only use the default input device
useThisDevice = NULL;
InitializeAU(useThisDevice);
if(mRequestedFormat.mSampleRate != mNativeFormat.mSampleRate)
{
#if LOG_CAPTURE
DebugMessageN2("OALCaptureDevice::OALCaptureDevice - Hardware Sample Rate: %5.1f Requested Sample Rate: %5.1f", mNativeFormat.mSampleRate, mRequestedFormat.mSampleRate);
#endif
mSampleRateRatio = mNativeFormat.mSampleRate / mRequestedFormat.mSampleRate;
mBufferData = (UInt8*)malloc(mRequestedFormat.mBytesPerFrame*mRequestedRingFrames*mSampleRateRatio);
OSStatus result = AudioConverterNew(&mOutputFormat, &mRequestedFormat, &mAudioConverter);
THROW_RESULT
}
mAudioInputPtrs = CABufferList::New("WriteBufferList", mRequestedFormat);
mRingBuffer = new OALRingBuffer();
mRingBuffer->Allocate(mRequestedFormat.mBytesPerFrame, mRequestedRingFrames*mSampleRateRatio);
}
catch (OSStatus result) {
if (mRingBuffer) delete (mRingBuffer);
if (mBufferData) free(mBufferData);
if (mAudioInputPtrs) delete (mAudioInputPtrs);
throw result;
}
catch (...) {
if (mRingBuffer) delete (mRingBuffer);
if (mBufferData) free(mBufferData);
if (mAudioInputPtrs) delete (mAudioInputPtrs);
throw -1;
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OALCaptureDevice::~OALCaptureDevice()
{
#if LOG_CAPTUREDEVICE_VERBOSE
DebugMessageN1("OALCaptureDevice::~OALCaptureDevice() - OALCaptureDevice = %ld", (long int) mSelfToken);
#endif
if (mInputUnit)
CloseComponent(mInputUnit);
if (mBufferData)
free(mBufferData);
delete mRingBuffer;
delete mAudioInputPtrs;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void OALCaptureDevice::SetError(ALenum errorCode)
{
#if LOG_CAPTUREDEVICE_VERBOSE
DebugMessageN2("OALCaptureDevice::SetError() - OALCaptureDevice:errorCode = %ld:%d", (long int) mSelfToken, errorCode);
#endif
if (mCurrentError == ALC_NO_ERROR)
return;
mCurrentError = errorCode;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ALenum OALCaptureDevice::GetError()
{
#if LOG_CAPTUREDEVICE_VERBOSE
DebugMessageN1("OALCaptureDevice::~OALCaptureDevice() - OALCaptureDevice = %ld", (long int) mSelfToken);
#endif
ALenum latestError = mCurrentError;
mCurrentError = ALC_NO_ERROR;
return latestError;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void OALCaptureDevice::InitializeAU(const char* inDeviceName)
{
#if LOG_CAPTUREDEVICE_VERBOSE
DebugMessageN2("OALCaptureDevice::InitializeAU() - OALCaptureDevice = %ld:%s", (long int) mSelfToken, inDeviceName);
#endif
// open input unit
OSStatus result = noErr;
Component comp;
ComponentDescription desc;
try {
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_HALOutput;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
comp = FindNextComponent(NULL, &desc);
if (comp == NULL)
throw -1;
result = OpenAComponent(comp, &mInputUnit);
THROW_RESULT
UInt32 enableIO;
UInt32 propSize;
// turn off output
enableIO = 0;
result = AudioUnitSetProperty(mInputUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO));
THROW_RESULT
// turn on input
enableIO = 1;
result = AudioUnitSetProperty(mInputUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO));
THROW_RESULT
// get the default input device
propSize = sizeof(AudioDeviceID);
AudioDeviceID inputDevice;
result = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &propSize, &inputDevice);
THROW_RESULT
if (inputDevice == kAudioDeviceUnknown)
throw -1; // there is no input device
// track the default input device with our AUHal
result = AudioUnitSetProperty(mInputUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &inputDevice, sizeof(inputDevice));
THROW_RESULT
// set render callback
AURenderCallbackStruct input;
input.inputProc = InputProc;
input.inputProcRefCon = this;
result = AudioUnitSetProperty(mInputUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &input, sizeof(input));
THROW_RESULT
result = AudioUnitInitialize(mInputUnit);
THROW_RESULT
// get the hardware format
propSize = sizeof(mNativeFormat);
result = AudioUnitGetProperty(mInputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 1, &mNativeFormat, &propSize);
THROW_RESULT
mOutputFormat = mRequestedFormat;
mOutputFormat.mSampleRate = mNativeFormat.mSampleRate;
// the output format should be the requested format, but using the native hardware sample rate, i.e. the output format
result = AudioUnitSetProperty(mInputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, (void *)&mOutputFormat, sizeof(mOutputFormat));
THROW_RESULT
}
catch (OSStatus result) {
if (mInputUnit) CloseComponent(mInputUnit);
throw result;
}
catch (...) {
if (mInputUnit) CloseComponent(mInputUnit);
throw - 1;
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OSStatus OALCaptureDevice::InputProc(void * inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * ioData)
{
#if LOG_CAPTUREDEVICE_VERBOSE
DebugMessage("OALCaptureDevice::InputProc() - OALCaptureDevice");
#endif
OALCaptureDevice *This = static_cast<OALCaptureDevice *>(inRefCon);
AudioUnitRenderActionFlags flags = 0;
AudioBufferList *abl = &This->mAudioInputPtrs->GetModifiableBufferList();
for (UInt32 i = 0; i < abl->mNumberBuffers; ++i)
abl->mBuffers[i].mData = NULL;
OSStatus err = AudioUnitRender(This->mInputUnit, &flags, inTimeStamp, 1, inNumberFrames, abl);
if (err)
return err;
if(This->mRingBuffer->Store((const Byte*)abl->mBuffers[0].mData, inNumberFrames, This->mStoreSampleTime))
This->mStoreSampleTime += inNumberFrames;
return noErr;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OSStatus OALCaptureDevice::ACComplexInputDataProc ( AudioConverterRef inAudioConverter,
UInt32 *ioNumberDataPackets,
AudioBufferList *ioData,
AudioStreamPacketDescription **outDataPacketDescription,
void* inUserData)
{
OALCaptureDevice* THIS = (OALCaptureDevice*)inUserData;
UInt32 nFramesRemaining;
ioData->mNumberBuffers = 1;
ioData->mBuffers[0].mNumberChannels = THIS->mRequestedFormat.NumberChannels();
ioData->mBuffers[0].mData = THIS->mRingBuffer->GetFramePtr(THIS->mFetchSampleTime, nFramesRemaining);
*ioNumberDataPackets = ((*ioNumberDataPackets) > nFramesRemaining) ? nFramesRemaining : (*ioNumberDataPackets);
ioData->mBuffers[0].mDataByteSize = (*ioNumberDataPackets) * THIS->mRequestedFormat.mBytesPerFrame;
if (nFramesRemaining == 0)
{
#if LOG_CAPTURE
DebugMessage("OALCaptureDevice::ACComplexInputDataProc - buffer is empty" );
#endif
return -1;
}
THIS->mFetchSampleTime += *ioNumberDataPackets;
return noErr;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// PUBLIC METHODS
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void OALCaptureDevice::StartCapture()
{
#if LOG_CAPTUREDEVICE_VERBOSE
DebugMessageN1("OALCaptureDevice::StartCapture() - OALCaptureDevice = %ld", (long int) mSelfToken);
#endif
OSStatus result = AudioOutputUnitStart(mInputUnit);
THROW_RESULT
mCaptureOn = true;
mRingBuffer->Clear();
#if LOG_CAPTURE
DebugMessage("OALCaptureDevice::StartCapture");
#endif
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void OALCaptureDevice::StopCapture()
{
#if LOG_CAPTUREDEVICE_VERBOSE
DebugMessageN1("OALCaptureDevice::StopCapture() - OALCaptureDevice = %ld", (long int) mSelfToken);
#endif
OSStatus result = AudioOutputUnitStop(mInputUnit);
THROW_RESULT
mCaptureOn = false;
mRingBuffer->Clear();
#if LOG_CAPTURE
DebugMessage("OALCaptureDevice::StopCapture");
#endif
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OSStatus OALCaptureDevice::GetFrames(UInt32 inFrameCount, UInt8* inBuffer)
{
#if LOG_CAPTUREDEVICE_VERBOSE
DebugMessageN1("OALCaptureDevice::GetFrames() - OALCaptureDevice = %ld", (long int) mSelfToken);
#endif
OSStatus result = noErr;
if (!mCaptureOn)
throw ((OSStatus) AL_INVALID_OPERATION); // error condition, device not currently capturing
#if LOG_CAPTURE
DebugMessageN1("OALCaptureDevice::GetFrames - requested frames: %ld", inFrameCount);
#endif
if (inFrameCount > AvailableFrames())
{
#if LOG_CAPTURE
DebugMessage("OALCaptureDevice::GetFrames - Not enough frames available");
#endif
return -1; // error condition, there aren't enough valid frames to satisfy request
}
if (mSampleRateRatio != 1.0)
{
UInt32 theFramesToCopy = inFrameCount;
AudioBufferList abl;
abl.mNumberBuffers = 1;
abl.mBuffers[0].mNumberChannels = mRequestedFormat.NumberChannels();
abl.mBuffers[0].mDataByteSize = theFramesToCopy * mRequestedFormat.mBytesPerFrame;
abl.mBuffers[0].mData = inBuffer;
result = AudioConverterFillComplexBuffer(mAudioConverter, ACComplexInputDataProc, this, &theFramesToCopy, &abl, NULL);
if (result)
{
#if LOG_CAPTURE
DebugMessageN1("OALCaptureDevice::GetFrames - AudioConverterFillComplexBuffer Failed result = %ld", result);
#endif
return result;
}
if (theFramesToCopy != inFrameCount)
{
#if LOG_CAPTURE
DebugMessageN1("OALCaptureDevice::GetFrames - AudioConverterFillComplexBuffer returned invalid number of frames = %ld", theFramesToCopy);
#endif
return -1;
}
}
else
{
result = mRingBuffer->Fetch((Byte*)inBuffer, inFrameCount, mFetchSampleTime);
if (result)
{
#if LOG_CAPTURE
DebugMessageN1("OALCaptureDevice::GetFrames - mRingBuffer->Fetch Failed result = %ld", result);
#endif
return result;
}
if (result == noErr)
mFetchSampleTime += inFrameCount;
}
#if LOG_CAPTURE
DebugMessageN1("OALCaptureDevice::GetFrames - new mFetchSampleTime = %qd", mFetchSampleTime);
#endif
return result;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UInt32 OALCaptureDevice::AvailableFrames()
{
#if LOG_CAPTUREDEVICE_VERBOSE
DebugMessageN1("OALCaptureDevice::AvailableFrames() - OALCaptureDevice = %ld", (long int) mSelfToken);
#endif
SInt64 start, end;
mRingBuffer->GetTimeBounds(start, end);
if (mFetchSampleTime < start)
mFetchSampleTime = start; // move up our fetch starting point, we have fallen too far behind
UInt32 availableFrames = end - mFetchSampleTime;
if (availableFrames > mRequestedRingFrames*mSampleRateRatio)
availableFrames = mRequestedRingFrames*mSampleRateRatio;
#if LOG_CAPTURE
DebugMessageN2("OALCaptureDevice::AvailableFrames - buffer: %ld actual: %ld", availableFrames, (UInt32)(availableFrames / mSampleRateRatio));
#endif
return availableFrames / mSampleRateRatio;
}

View File

@ -0,0 +1,135 @@
/**********************************************************************************************************************************
*
* OpenAL cross platform audio library
* Copyright (c) 2005, Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************************************************************************/
#ifndef __OAL_CAPTURE_DEVICE__
#define __OAL_CAPTURE_DEVICE__
#include <CoreAudio/AudioHardware.h>
#include <AudioToolbox/AudioToolbox.h>
#include <AudioUnit/AudioUnit.h>
#include <map>
#include <libkern/OSAtomic.h>
#include "oalImp.h"
#include "oalRingBuffer.h"
#include "CAStreamBasicDescription.h"
#include "CABufferList.h"
#define LOG_CAPTUREDEVICE_VERBOSE 0
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// OALCaptureDevices
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark _____OALCaptureDevice_____
class OALCaptureDevice
{
#pragma mark __________ Public_Class_Members
public:
OALCaptureDevice(const char* inDeviceName, uintptr_t inSelfToken, UInt32 inSampleRate, UInt32 inFormat, UInt32 inBufferSize);
~OALCaptureDevice();
void StartCapture();
void StopCapture();
OSStatus GetFrames(UInt32 inFrameCount, UInt8* inBuffer);
UInt32 AvailableFrames();
void SetError(ALenum errorCode);
ALenum GetError();
// we need to mark the capture device if it is being used to prevent deletion from another thread
void SetInUseFlag() { OSAtomicIncrement32Barrier(&mInUseFlag); }
void ClearInUseFlag() { OSAtomicDecrement32Barrier(&mInUseFlag); }
volatile int32_t IsInUse() { return mInUseFlag; }
#pragma mark __________ Private_Class_Members
private:
#if LOG_CAPTUREDEVICE_VERBOSE
uintptr_t mSelfToken;
#endif
ALenum mCurrentError;
bool mCaptureOn;
SInt64 mStoreSampleTime; // increment on each read in the input proc, and pass to the ring buffer class when writing, reset on each stop
SInt64 mFetchSampleTime; // increment on each read in the input proc, and pass to the ring buffer class when writing, reset on each stop
AudioUnit mInputUnit;
CAStreamBasicDescription mNativeFormat;
CAStreamBasicDescription mRequestedFormat;
CAStreamBasicDescription mOutputFormat;
OALRingBuffer* mRingBuffer; // the ring buffer
UInt8* mBufferData;
AudioConverterRef mAudioConverter;
Float64 mSampleRateRatio;
UInt32 mRequestedRingFrames;
CABufferList* mAudioInputPtrs;
volatile int32_t mInUseFlag; // flag to indicate the device is currently being used by one or more threads
void InitializeAU (const char* inDeviceName);
static OSStatus InputProc( void * inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * ioData);
static OSStatus ACComplexInputDataProc (AudioConverterRef inAudioConverter,
UInt32 *ioNumberDataPackets,
AudioBufferList *ioData,
AudioStreamPacketDescription **outDataPacketDescription,
void* inUserData);
};
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark _____OALCaptureDeviceMap_____
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class OALCaptureDeviceMap : std::multimap<uintptr_t, OALCaptureDevice*, std::less<uintptr_t> > {
public:
void Add (const uintptr_t inDeviceToken, OALCaptureDevice **inDevice) {
iterator it = upper_bound(inDeviceToken);
insert(it, value_type (inDeviceToken, *inDevice));
}
OALCaptureDevice* Get(uintptr_t inDeviceToken) {
iterator it = find(inDeviceToken);
if (it != end())
return ((*it).second);
return (NULL);
}
void Remove (const uintptr_t inDeviceToken) {
iterator it = find(inDeviceToken);
if (it != end())
erase(it);
}
UInt32 Size () const { return size(); }
bool Empty () const { return empty(); }
};
#endif

View File

@ -0,0 +1,254 @@
/**********************************************************************************************************************************
*
* OpenAL cross platform audio library
* Copyright (c) 2004, Apple Computer, Inc., Copyright (c) 2012, Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Inc. ("Apple") nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************************************************************************/
#include <libkern/OSAtomic.h>
// Local includes
#include "oalImp.h"
#include "oalCaptureMixer.h"
// Public Utility includes
#include "CAXException.h"
const UInt32 kMaxFramesPerSlice = 4096;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark ***** OALCaptureMixers *****
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OALCaptureMixer::OALCaptureMixer (AudioUnit inMixerUnit, Float64 inSampleRate, UInt32 inOALFormat, UInt32 inBufferSize)
: mMixerUnit(inMixerUnit),
mRingBuffer(NULL),
mRequestedRingFrames(inBufferSize),
mStoreSampleTime(0),
mFetchSampleTime(0),
mCaptureOn(false),
mAudioConverter(0),
mConvertedDataABL(NULL)
{
try {
// translate the sample rate and data format parameters into an ASBD - this method throws
FillInASBD(mRequestedFormat, inOALFormat, inSampleRate);
// inBufferSize must be at least as big as one packet of the requested output format
if (inBufferSize < mRequestedFormat.mBytesPerPacket)
throw ((OSStatus) AL_INVALID_VALUE);
// get the output format of the 3DMixer
CAStreamBasicDescription mixerOutFormat;
UInt32 propSize = sizeof(mixerOutFormat);
XThrowIfErr(AudioUnitGetProperty(mMixerUnit, kAudioUnitProperty_StreamFormat, 0, 0, &mixerOutFormat, &propSize));
mRingBuffer = new OALRingBuffer();
mRingBuffer->Allocate(mRequestedFormat.mBytesPerFrame, kMaxFramesPerSlice);
//create a new converter to convert the mixer output data to the requested format
XThrowIfErr(AudioConverterNew(&mixerOutFormat, &mRequestedFormat, &mAudioConverter));
mConvertedDataABL = CABufferList::New("converted data", mRequestedFormat);
mConvertedDataABL->AllocateBuffers(mRequestedFormat.mBytesPerFrame * kMaxFramesPerSlice);
}
catch (OSStatus result) {
if (mRingBuffer) {
delete (mRingBuffer);
mRingBuffer = NULL;
}
throw result;
}
catch (...) {
if (mRingBuffer) {
delete (mRingBuffer);
mRingBuffer = NULL;
}
throw static_cast<OSStatus>(-1);
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OALCaptureMixer::~OALCaptureMixer()
{
if (mCaptureOn)
StopCapture();
if (mRingBuffer) {
delete (mRingBuffer);
mRingBuffer = NULL;
}
if (mConvertedDataABL) {
delete (mConvertedDataABL);
mConvertedDataABL = NULL;
}
if (mAudioConverter) {
AudioConverterDispose(mAudioConverter);
mAudioConverter = NULL;
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void OALCaptureMixer::StartCapture()
{
if (!mCaptureOn)
{
SetCaptureFlag();
AudioUnitAddRenderNotify(mMixerUnit, RenderCallback, this);
mRingBuffer->Clear();
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void OALCaptureMixer::StopCapture()
{
if (mCaptureOn)
{
ClearCaptureFlag();
AudioUnitRemoveRenderNotify(mMixerUnit, RenderCallback, this);
mRingBuffer->Clear();
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OSStatus OALCaptureMixer::RenderCallback( void * inRefCon,
AudioUnitRenderActionFlags * ioActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * ioData)
{
OALCaptureMixer* THIS = (OALCaptureMixer*) inRefCon;
if (!THIS->mCaptureOn)
return noErr;
try {
if (*ioActionFlags & kAudioUnitRenderAction_PostRender)
{
static int TEMP_kAudioUnitRenderAction_PostRenderError = (1 << 8);
if (inBusNumber == 0 && !(*ioActionFlags & TEMP_kAudioUnitRenderAction_PostRenderError))
{
// convert the data from the mixer to the requested format
UInt32 packetCount = inNumberFrames;
AudioBufferList* abl = &THIS->mConvertedDataABL->GetModifiableBufferList();
XThrowIfErr(AudioConverterFillComplexBuffer(THIS->mAudioConverter, ConverterProc, ioData, &packetCount, abl, NULL));
// store the converted data in the ring buffer
if(THIS->mRingBuffer->Store((const Byte*)abl->mBuffers[0].mData, inNumberFrames, THIS->mStoreSampleTime))
THIS->mStoreSampleTime += inNumberFrames;
}
}
}
catch (OSStatus result) {
return result;
}
catch (...) {
return -1;
}
return noErr;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OSStatus OALCaptureMixer::ConverterProc( AudioConverterRef /*inAudioConverter*/,
UInt32* ioNumberDataPackets,
AudioBufferList* ioData,
AudioStreamPacketDescription** /*outDataPacketDescription*/,
void* inUserData)
{
AudioBufferList* inputData = (AudioBufferList*) inUserData;
for (int i=0; i<inputData->mNumberBuffers; ++i)
{
//tell the converter where the data is and how much there is
ioData->mBuffers[i].mData = inputData->mBuffers[i].mData;
ioData->mBuffers[i].mDataByteSize = inputData->mBuffers[i].mDataByteSize;
}
return noErr;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OSStatus OALCaptureMixer::GetFrames(UInt32 inFrameCount, UInt8* inBuffer)
{
OSStatus result = noErr;
if (!mCaptureOn)
{
throw ((OSStatus) AL_INVALID_OPERATION); // error condition, device not currently capturing
}
if (inFrameCount > AvailableFrames())
{
return -1; // error condition, there aren't enough valid frames to satisfy request
}
result = mRingBuffer->Fetch((Byte*)inBuffer, inFrameCount, mFetchSampleTime);
if (result)
{
return result;
}
if (result == noErr)
mFetchSampleTime += inFrameCount;
return result;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UInt32 OALCaptureMixer::AvailableFrames()
{
SInt64 start, end;
mRingBuffer->GetTimeBounds(start, end);
if (mFetchSampleTime < start)
mFetchSampleTime = start; // move up our fetch starting point, we have fallen too far behind
UInt32 availableFrames = static_cast<UInt32>(end - mFetchSampleTime);
if (availableFrames > mRequestedRingFrames)
availableFrames = mRequestedRingFrames;
return availableFrames;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void OALCaptureMixer::SetCaptureFlag()
{
int32_t one = 1; int32_t zero = 0;
OSAtomicCompareAndSwap32Barrier(zero, one, &mCaptureOn);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void OALCaptureMixer::ClearCaptureFlag()
{
int32_t one = 1; int32_t zero = 0;
OSAtomicCompareAndSwap32Barrier(one, zero, &mCaptureOn);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -0,0 +1,86 @@
/**********************************************************************************************************************************
*
* OpenAL cross platform audio library
* Copyright (c) 2004, Apple Computer, Inc., Copyright (c) 2012, Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Inc. ("Apple") nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************************************************************************/
#ifndef __OpenAL__oalCaptureMixer__
#define __OpenAL__oalCaptureMixer__
//local includes
#include "oalRingBuffer.h"
// System includes
#include <AudioToolbox/AudioToolbox.h>
// Public Utility includes
#include "CAStreamBasicDescription.h"
#include "CABufferList.h"
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// OALCaptureMixer
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark _____OALCaptureMixer_____
class OALCaptureMixer
{
public:
OALCaptureMixer(AudioUnit inMixer, Float64 inSampleRate, UInt32 inOALFormat, UInt32 inBufferSize);
~OALCaptureMixer();
void StartCapture();
void StopCapture();
OSStatus GetFrames(UInt32 inFrameCount, UInt8* inBuffer);
UInt32 AvailableFrames();
CAStreamBasicDescription GetOutputFormat() { return mRequestedFormat; }
static OSStatus RenderCallback( void * inRefCon,
AudioUnitRenderActionFlags * ioActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * ioData);
static OSStatus ConverterProc( AudioConverterRef inAudioConverter,
UInt32* ioNumberDataPackets,
AudioBufferList* ioData,
AudioStreamPacketDescription** outDataPacketDescription,
void* inUserData);
void SetCaptureFlag();
void ClearCaptureFlag();
bool IsCapturing() { return static_cast<bool>(mCaptureOn); }
private:
AudioUnit mMixerUnit;
CAStreamBasicDescription mRequestedFormat;
OALRingBuffer* mRingBuffer;
UInt32 mRequestedRingFrames;
SInt64 mStoreSampleTime;
SInt64 mFetchSampleTime;
volatile int32_t mCaptureOn;
AudioConverterRef mAudioConverter;
CABufferList* mConvertedDataABL;
};
#endif /* defined(__OpenAL__oalCaptureMixer__) */

1695
Source/OpenAL/oalContext.cpp Normal file

File diff suppressed because it is too large Load Diff

324
Source/OpenAL/oalContext.h Normal file
View File

@ -0,0 +1,324 @@
/**********************************************************************************************************************************
*
* OpenAL cross platform audio library
* Copyright (c) 2004, Apple Computer, Inc., Copyright (c) 2012, Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Inc. ("Apple") nor the names of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************************************************************************/
#ifndef __OAL_CONTEXT__
#define __OAL_CONTEXT__
#include "oalDevice.h"
#include "alc.h"
#include "MacOSX_OALExtensions.h"
#include "oalCaptureMixer.h"
#include "CAGuard.h"
#include <Carbon/Carbon.h>
#include <map>
#include <libkern/OSAtomic.h>
#define CAPTURE_AUDIO_TO_FILE 0
#if CAPTURE_AUDIO_TO_FILE
#include "CAAudioUnitOutputCapturer.h"
#endif
#define LOG_BUS_CONNECTIONS 0
#define LOG_CONTEXT_VERBOSE 0
#define kDefaultReferenceDistance 1.0
#define kDefaultMaximumDistance 1000000.0
#define kDefaultRolloff 1.0
#define kPreferredMixerVersion 0x21000
#define kMinimumMixerVersion 0x10300
// Default Low Quality Stereo Spatial Setting:
#define kDefaultLowQuality kSpatializationAlgorithm_EqualPowerPanning
// Default High Quality Stereo Spatial Setting:
#define kDefaultHighQuality kSpatializationAlgorithm_HRTF
// Default MultiChannel Spatial Setting:
#define kDefaultMultiChannelQuality kSpatializationAlgorithm_SoundField
/*
An OALContext is basically the equivalent of a 'room' or 'scene'. It is attached to an OALDevice which
is a piece of hardware and contains a single 3DMixer. Each context has it's own source objects
and a single listener. It also has it's own settings for the 3DMixer, such as Reverb, Doppler, etc.
*/
enum { kNoSourceAttached = (ALuint)-1 };
struct BusInfo {
ALuint mSourceAttached; // the token of the source attached
UInt32 mNumberChannels; // mono/stereo setting of the bus
UInt32 mReverbState; // unused until Reverb extension is added to the implementation
};
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class OALSource; // forward declaration
class OALSourceMap; // forward declaration
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// OALContexts
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark _____OALContext_____
class OALContext
{
public:
OALContext(const uintptr_t inSelfToken, OALDevice *inOALDevice, const ALCint *inAttributeList, UInt32 &inBusCount, Float64 &inMixerRate);
~OALContext();
bool DoSetDistance() { return mCalculateDistance;}
UInt32 GetDesiredRenderChannels(UInt32 inDeviceChannels);
AudioUnit GetMixerUnit() { return mMixerUnit;}
AUNode GetMixerNode() { return mMixerNode;}
AUGraph GetGraph() { return mOwningDevice->GetGraph(); }
UInt32 GetRenderQuality() {return mRenderQuality;}
Float32 GetFramesPerSlice() { return mOwningDevice->GetFramesPerSlice();}
Float64 GetMixerRate () const { return mMixerOutputRate; }
Float32 GetDefaultReferenceDistance() { return mDefaultReferenceDistance;}
Float32 GetDefaultMaxDistance() { return mDefaultMaxDistance;}
bool IsDistanceScalingRequired() { return mDistanceScalingRequired;}
UInt32 GetAvailableMonoBus (ALuint inSourceToken);
UInt32 GetAvailableStereoBus (ALuint inSourceToken);
UInt32 GetBusCount () { return mBusCount;}
uintptr_t GetDeviceToken () { return mOwningDevice->GetDeviceToken();}
UInt32 GetDistanceModel() { return mDistanceModel;}
Float32 GetSpeedOfSound() {return (mSpeedOfSound);}
Float32 GetDopplerFactor() {return (mDopplerFactor);}
Float32 GetDopplerVelocity() {return (mDopplerVelocity);}
Float32 GetListenerGain() {return (mListenerGain);}
void GetListenerPosition(Float32 *posX, Float32 *posY, Float32 *posZ) {*posX = mListenerPosition[0];
*posY = mListenerPosition[1];
*posZ = mListenerPosition[2];}
void GetListenerVelocity(Float32 *posX, Float32 *posY, Float32 *posZ) { *posX = mListenerVelocity[0];
*posY = mListenerVelocity[1];
*posZ = mListenerVelocity[2];}
void GetListenerOrientation( Float32 *forwardX, Float32 *forwardY, Float32 *forwardZ,
Float32 *upX, Float32 *upY, Float32 *upZ) { *forwardX = mListenerOrientationForward[0];
*forwardY = mListenerOrientationForward[1];
*forwardZ = mListenerOrientationForward[2];
*upX = mListenerOrientationUp[0];
*upY = mListenerOrientationUp[1];
*upZ = mListenerOrientationUp[2]; }
UInt32 GetAttributeListSize(){return mAttributeListSize;}
void CopyAttributeList( ALCint* outAttrList);
void SetReverbQuality(UInt32 inQuality);
void SetReverbEQGain(Float32 inLevel);
void SetReverbEQBandwidth(Float32 inBandwidth);
void SetReverbEQFrequency(Float32 inFrequency);
UInt32 GetReverbQuality();
Float32 GetReverbEQGain();
Float32 GetReverbEQBandwidth();
Float32 GetReverbEQFrequency();
// set info methods
void SetBusAsAvailable (UInt32 inBusIndex);
void SetDistanceAttenuation(UInt32 inBusIndex, Float64 inRefDist, Float64 inMaxDist, Float64 inRolloff);
void SetRenderQuality (UInt32 inRenderQuality);
void SetSourceDesiredRenderQualityOnBus (UInt32 inRenderQuality, int inBus);
UInt32 GetRenderQualityForBus (int inBus);
void SetDistanceModel(UInt32 inDistanceModel);
void SetDopplerFactor(Float32 inDopplerFactor);
void SetDopplerVelocity(Float32 inDopplerVelocity);
void SetSpeedOfSound(Float32 inSpeedOfSound);
void SetListenerPosition(Float32 posX, Float32 posY, Float32 posZ);
void SetListenerVelocity(Float32 posX, Float32 posY, Float32 posZ);
void SetListenerGain(Float32 inGain);
void SetListenerOrientation( Float32 forwardX, Float32 forwardY, Float32 forwardZ,
Float32 upX, Float32 upY, Float32 upZ);
void SetReverbPreset (FSRef* inRef);
// ASA Support: Reverb, Occlusion
void SetReverbState(UInt32 inReverbState);
UInt32 GetReverbState() {return mASAReverbState;}
void SetReverbRoomType(UInt32 inRoomType);
void SetReverbLevel(Float32 inReverbLevel);
UInt32 GetReverbRoomType() {return mASAReverbRoomType;}
Float32 GetReverbLevel() {return mASAReverbGlobalLevel;}
// Context Output Capturer Methods
OSStatus OutputCapturerCreate(Float64 inSampleRate, UInt32 inOALFormat, UInt32 inBufferSize);
OSStatus OutputCapturerStart();
OSStatus OutputCapturerStop();
OSStatus OutputCapturerGetFrames(UInt32 inFrameCount, UInt8* inBuffer);
UInt32 OutputCapturerAvailableFrames();
// notification proc methods
OSStatus DoPostRender ();
OSStatus DoPreRender ();
static OSStatus ContextNotificationProc ( void *inRefCon,
AudioUnitRenderActionFlags *inActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData);
// threading protection methods
bool CallingInRenderThread () const { return (pthread_self() == mRenderThreadID); }
volatile int32_t IsInUse() { return mInUseFlag; }
void SetInUseFlag() { OSAtomicIncrement32Barrier(&mInUseFlag); }
void ClearInUseFlag() { OSAtomicDecrement32Barrier(&mInUseFlag); }
// context activity methods
void ProcessContext();
void SuspendContext();
// source methods
void AddSource(ALuint inSourceToken);
void RemoveSource(ALuint inSourceToken);
OALSource* ProtectSource(ALuint inSourceToken);
OALSource* GetSourceForRender(ALuint inSourceToken);
OALSource* GetDeadSourceForRender(ALuint inSourceToken);
void ReleaseSource(OALSource* inSource);
UInt32 GetSourceCount();
void CleanUpDeadSourceList();
// device methods
void ConnectMixerToDevice();
void DisconnectMixerFromDevice();
void InitRenderQualityOnBusses();
void InitRenderQualityOnSources();
void ConfigureMixerFormat();
private:
#if LOG_CONTEXT_VERBOSE
uintptr_t mSelfToken;
#endif
// bool mProcessingActive;
OALDevice *mOwningDevice;
AUNode mMixerNode;
AudioUnit mMixerUnit;
OALSourceMap *mSourceMap;
CAGuard mSourceMapLock; // the map is not thread-safe. We need a mutex to serialize operations on it
OALSourceMap *mDeadSourceMap;
CAGuard mDeadSourceMapLock; // the map is not thread-safe. We need a mutex to serialize operations on it
UInt32 mDistanceModel;
Float32 mSpeedOfSound;
Float32 mDopplerFactor;
Float32 mDopplerVelocity;
Float32 mListenerPosition[3];
Float32 mListenerVelocity[3];
Float32 mListenerGain;
Float32 mListenerOrientationForward[3];
Float32 mListenerOrientationUp[3];
UInt32 mAttributeListSize;
ALCint* mAttributeList;
bool mDistanceScalingRequired;
bool mCalculateDistance; // true except: for 1.3 mixer Inverse curve, OR pre 2.2 mixer and either Exponential or Linear curves
UInt32 mRenderQuality; // Hi or Lo for now
UInt32 mSpatialSetting;
UInt32 mBusCount;
volatile int32_t mInUseFlag;
Float64 mMixerOutputRate;
Float32 mDefaultReferenceDistance;
Float32 mDefaultMaxDistance;
bool mUserSpecifiedBusCounts;
BusInfo *mBusInfo;
pthread_t mRenderThreadID;
bool mSettableMixerAttenuationCurves;
UInt32 mASAReverbState;
UInt32 mASAReverbRoomType;
Float32 mASAReverbGlobalLevel;
UInt32 mASAReverbQuality;
Float32 mASAReverbEQGain;
Float32 mASAReverbEQBandwidth;
Float32 mASAReverbEQFrequency;
OALCaptureMixer* mOutputCapturer;
#if LOG_BUS_CONNECTIONS
UInt32 mMonoSourcesConnected;
UInt32 mStereoSourcesConnected;
#endif
#if CAPTURE_AUDIO_TO_FILE
CAAudioUnitOutputCapturer *gTheCapturer;
CFURLRef gFileURL;
AudioStreamBasicDescription gCapturerDataFormat;
#endif
void InitializeMixer(UInt32 inStereoBusCount);
};
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// OALDevices contain a single OALContextMap to keep track of the contexts that belong to it.
#pragma mark _____OALContextMap_____
class OALContextMap : std::multimap<uintptr_t, OALContext*, std::less<uintptr_t> > {
public:
void Add (const uintptr_t inContextToken, OALContext **inContext) {
iterator it = upper_bound(inContextToken);
insert(it, value_type (inContextToken, *inContext));
}
OALContext* Get (uintptr_t inContextToken) {
iterator it = find(inContextToken);
if (it != end())
return ((*it).second);
return (NULL);
}
bool Remove (const uintptr_t inContextToken) {
iterator it = find(inContextToken);
if (it != end()) {
erase(it);
return true; // success
}
return false;
}
OALContext* GetContextByIndex(UInt32 inIndex, uintptr_t &outContextToken) {
iterator it = begin();
std::advance(it, inIndex);
if (it != end())
{
outContextToken = (*it).first;
return (*it).second;
}
return (NULL);
}
uintptr_t GetDeviceTokenForContext(uintptr_t inContextToken) {
OALContext *context = Get(inContextToken);
if (context != NULL)
return (context->GetDeviceToken());
else
return (0);
}
UInt32 Size() const { return size(); }
bool Empty() const { return empty(); }
};
#endif

686
Source/OpenAL/oalDevice.cpp Normal file
View File

@ -0,0 +1,686 @@
/**********************************************************************************************************************************
*
* OpenAL cross platform audio library
* Copyright (c) 2004, Apple Computer, Inc., Copyright (c) 2012, Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Inc. ("Apple") nor the names of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************************************************************************/
#include "oalDevice.h"
#include "oalContext.h"
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#define LOG_DEVICE_CHANGES 0
#define PROFILE_IO_USAGE 0
#define LOG_VERBOSE 0
#if PROFILE_IO_USAGE
static int debugCounter = -1;
static int numCyclesToPrint = 1000;
static UInt64 lastHostTime;
static UInt64 totalHostTime;
static UInt64 minUsage;
static UInt64 maxUsage;
static UInt64 totalUsage;
#define PROFILE_IO_CYCLE 0
#if PROFILE_IO_CYCLE
static UInt64 maxHT;
static UInt64 minHT;
#endif
#include <CoreAudio/HostTime.h>
#endif
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#if GET_OVERLOAD_NOTIFICATIONS
OSStatus PrintTheOverloadMessage( AudioDeviceID inDevice,
UInt32 inChannel,
Boolean isInput,
AudioDevicePropertyID inPropertyID,
void* inClientData)
{
DebugMessage("OVERLOAD OCCURRED");
}
#endif
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// OALDevices
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark ***** OALDevices *****
/*
If caller wants a specific HAL device (instead of the default output device), a NULL terminated
C-String representation of the CFStringRef returned from the HAL APIs for the
kAudioDevicePropertyDeviceUID property
*/
OALDevice::OALDevice (const char* inDeviceName, uintptr_t inSelfToken, UInt32 inRenderChannelSetting)
: mSelfToken (inSelfToken),
mCurrentError(ALC_NO_ERROR),
mHALDevice (0),
mDistanceScalingRequired(false),
mGraphInitialized(false),
mAUGraph(0),
mOutputNode(0),
mOutputUnit(0),
mMixerNode(0),
mChannelLayoutTag(0),
mConnectedContext(NULL),
mDeviceSampleRate(kDefaultMixerRate),
mRenderChannelCount(0),
mRenderChannelSetting(inRenderChannelSetting),
mFramesPerSlice(512),
mInUseFlag(0)
{
#if LOG_VERBOSE
DebugMessageN1("OALDevice::OALDevice() - OALDevice = %ld", (long int) mSelfToken);
#endif
OSStatus result = noErr;
UInt32 size = 0;
CFStringRef cfString = NULL;
char *useThisDevice = (char *) inDeviceName;
try {
// make sure a proper render channel setting was passed to teh constructor
if ((inRenderChannelSetting != ALC_MAC_OSX_RENDER_CHANNEL_COUNT_MULTICHANNEL) && (inRenderChannelSetting != ALC_MAC_OSX_RENDER_CHANNEL_COUNT_STEREO))
throw (OSStatus) AL_INVALID_VALUE;
// until the ALC_ENUMERATION_EXT extension is supported only use the default output device
useThisDevice = NULL;
// first, get the requested HAL device's ID
if (useThisDevice)
{
// turn the inDeviceName into a CFString
cfString = CFStringCreateWithCString(NULL, useThisDevice, kCFStringEncodingUTF8);
if (cfString)
{
AudioValueTranslation translation;
translation.mInputData = &cfString;
translation.mInputDataSize = sizeof(cfString);
translation.mOutputData = &mHALDevice;
translation.mOutputDataSize = sizeof(mHALDevice);
size = sizeof(AudioValueTranslation);
result = AudioHardwareGetProperty(kAudioHardwarePropertyDeviceForUID, &size, &translation);
CFRelease (cfString);
}
else
result = -1; // couldn't get string ref
THROW_RESULT
}
else
{
size = sizeof(AudioDeviceID);
result = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &size, &mHALDevice);
THROW_RESULT
}
InitializeGraph(useThisDevice);
mRenderChannelCount = GetDesiredRenderChannelCount();
#if PROFILE_IO_USAGE
debugCounter = -1;
#endif
}
catch (...) {
throw;
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OALDevice::~OALDevice()
{
#if LOG_VERBOSE
DebugMessageN1("OALDevice::~OALDevice() - OALDevice = %ld", (long int) mSelfToken);
#endif
TeardownGraph();
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void OALDevice::SetError(ALenum errorCode)
{
#if LOG_VERBOSE
DebugMessageN2("OALDevice::SetError() - OALDevice:errorCode = %ld:%d", (long int) mSelfToken, errorCode);
#endif
if (mCurrentError == ALC_NO_ERROR)
return;
mCurrentError = errorCode;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ALenum OALDevice::GetError()
{
#if LOG_VERBOSE
DebugMessageN1("OALDevice::GetError() - OALDevice = %ld", (long int) mSelfToken);
#endif
ALenum latestError = mCurrentError;
mCurrentError = ALC_NO_ERROR;
return latestError;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void OALDevice::TeardownGraph()
{
#if LOG_VERBOSE || LOG_DEVICE_CHANGES
DebugMessageN1("OALDevice::TeardownGraph() - OALDevice = %ld", (long int) mSelfToken);
#endif
#if GET_OVERLOAD_NOTIFICATIONS
AudioDeviceID device = 0;
UInt32 size = sizeof(device);
AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &size, &device);
if (device != 0)
{
DebugMessage("********** Removing Overload Notification ***********");
AudioDeviceRemovePropertyListener( device, 0, false, kAudioDeviceProcessorOverload, PrintTheOverloadMessage);
}
#endif
if (mAUGraph)
{
StopGraph();
DisposeAUGraph (mAUGraph);
mAUGraph = 0;
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// also resets the audio channel layout if necessary
void OALDevice::ResetRenderChannelSettings()
{
#if LOG_VERBOSE || LOG_DEVICE_CHANGES
DebugMessageN1("OALDevice::ResetRenderChannelSettings() - OALDevice = %ld", (long int) mSelfToken);
#endif
// verify that the channel count has actually changed before doing all this work...
UInt32 channelCount = GetDesiredRenderChannelCount();
if (mRenderChannelCount == channelCount)
return; // only reset the graph if the channel count has changed
mRenderChannelCount = channelCount;
Boolean wasRunning = false;
AUGraphIsRunning (mAUGraph, &wasRunning);
if (wasRunning)
StopGraph();
// disconnect the mixer (mMixerNode) from the output au if necessary
OSStatus result = noErr;
if (mMixerNode)
{
// mixer is currently connected
result = AUGraphDisconnectNodeInput (mAUGraph, mOutputNode, 0);
THROW_RESULT
// update the graph
result = AUGraphUpdate (mAUGraph, NULL);
THROW_RESULT
}
// set AU properties
{
CAStreamBasicDescription format;
UInt32 propSize = sizeof(format);
// get the current input scope format of the output device, so we can just change the channel count
result = AudioUnitGetProperty(mOutputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &format, &propSize);
THROW_RESULT
format.SetCanonical (mRenderChannelCount, false); // not interleaved
result = AudioUnitSetProperty (mOutputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &format, sizeof(format));
THROW_RESULT
// The Output Format of the Contexts that use this device will be set later by ReconfigureContextsOfThisDevice()
// channel layout may have changed do to a different render channel count
AudioChannelLayout layout;
layout.mChannelLayoutTag = GetChannelLayoutTag();
layout.mChannelBitmap = 0;
layout.mNumberChannelDescriptions = 0;
result = AudioUnitSetProperty (mOutputUnit, kAudioUnitProperty_AudioChannelLayout, kAudioUnitScope_Input, 0, &layout, sizeof(layout));
THROW_RESULT
}
// tell the contexts using this device to change their mixer output format - so when they are reconnected to the output au - formats will be reset
ReconfigureContextsOfThisDevice(mSelfToken);
// reconnect mixer to output unit if it was previously connected
if (mMixerNode)
{
result = AUGraphConnectNodeInput (mAUGraph, mMixerNode, 0, mOutputNode, 0);
THROW_RESULT
// update the graph
result = AUGraphUpdate (mAUGraph, NULL);
THROW_RESULT
}
if (wasRunning)
AUGraphStart(mAUGraph); // restart the graph if it was already running
return;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void OALDevice::GraphFormatPropertyListener ( void *inRefCon,
AudioUnit ci,
AudioUnitPropertyID inID,
AudioUnitScope inScope,
AudioUnitElement inElement)
{
#if LOG_VERBOSE || LOG_DEVICE_CHANGES
DebugMessageN1("OALDevice::GraphFormatPropertyListener - OALDevice: %ld", ((OALDevice*)inRefCon)->mSelfToken);
#endif
try {
if (inScope == kAudioUnitScope_Output)
{
((OALDevice*)inRefCon)->ResetRenderChannelSettings ();
}
}
catch (...) {
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void OALDevice::SetRenderChannelSetting (UInt32 inRenderChannelSetting)
{
#if LOG_VERBOSE || LOG_DEVICE_CHANGES
DebugMessageN1("OALDevice::SetRenderChannelSetting() - OALDevice = %ld", (long int) mSelfToken);
#endif
try {
if ((inRenderChannelSetting != ALC_MAC_OSX_RENDER_CHANNEL_COUNT_MULTICHANNEL) && (inRenderChannelSetting != ALC_MAC_OSX_RENDER_CHANNEL_COUNT_STEREO))
throw (OSStatus) AL_INVALID_VALUE;
if (inRenderChannelSetting == mRenderChannelSetting)
return; //nothing to do
mRenderChannelSetting = inRenderChannelSetting;
if (inRenderChannelSetting == ALC_MAC_OSX_RENDER_CHANNEL_COUNT_STEREO)
{
// clamping to stereo
if (mRenderChannelCount == 2)
return; // already rendering to stereo, so there's nothing to do
}
else
{
// allowing multi channel now
if (mRenderChannelCount > 2)
return; // already rendering to mc, so there's nothing to do
}
// work to be done now, it is necessary to change the channel layout and stream format from multi channel to stereo
// this requires the graph to be stopped and reconfigured
ResetRenderChannelSettings ();
}
catch (OSStatus result) {
DebugMessageN2("OALDevice::SetRenderChannelSetting - OALDevice: %ld:%ld", mSelfToken, (long int) result);
}
catch (...) {
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void OALDevice::InitializeGraph (const char* inDeviceName)
{
#if LOG_VERBOSE || LOG_DEVICE_CHANGES
DebugMessageN1("OALDevice::InitializeGraph() - OALDevice = %ld", (long int) mSelfToken);
#endif
if (mAUGraph)
throw static_cast<OSStatus>('init');
OSStatus result = noErr;
// ~~~~~~~~~~~~~~~~~~~~ CREATE GRAPH
result = NewAUGraph(&mAUGraph);
THROW_RESULT
// ~~~~~~~~~~~~~~~~~~~~ SET UP OUTPUT NODE
ComponentDescription cd;
cd.componentFlags = 0;
cd.componentFlagsMask = 0;
// At this time, only allow the default output device to be used and ignore the inDeviceName parameter
cd.componentType = kAudioUnitType_Output;
cd.componentSubType = kAudioUnitSubType_DefaultOutput;
cd.componentManufacturer = kAudioUnitManufacturer_Apple;
result = AUGraphNewNode (mAUGraph, &cd, 0, NULL, &mOutputNode);
THROW_RESULT
// ~~~~~~~~~~~~~~~~~~~~ OPEN GRAPH
result = AUGraphOpen (mAUGraph);
THROW_RESULT
result = AUGraphGetNodeInfo (mAUGraph, mOutputNode, 0, 0, 0, &mOutputUnit);
THROW_RESULT
result = AudioUnitInitialize (mOutputUnit);
THROW_RESULT
result = AudioUnitAddPropertyListener (mOutputUnit, kAudioUnitProperty_StreamFormat, GraphFormatPropertyListener, this);
THROW_RESULT
// Frame Per Slice
// get the device's frame count and set the AUs to match, will be set to 512 if this fails
AudioDeviceID device = 0;
UInt32 dataSize = sizeof(device);
result = AudioUnitGetProperty(mOutputUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &device, &dataSize);
if (result == noErr)
{
dataSize = sizeof(mFramesPerSlice);
result = AudioDeviceGetProperty(device, 0, false, kAudioDevicePropertyBufferFrameSize, &dataSize, &mFramesPerSlice);
if (result == noErr)
{
/*result =*/ AudioUnitSetProperty( mOutputUnit, kAudioUnitProperty_MaximumFramesPerSlice,
kAudioUnitScope_Global, 0, &mFramesPerSlice, sizeof(mFramesPerSlice));
}
}
// get the device's outputRate
CAStreamBasicDescription format;
UInt32 propSize = sizeof(format);
result = AudioUnitGetProperty(mOutputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &format, &propSize);
if (result == noErr)
mDeviceSampleRate = format.mSampleRate;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UInt32 OALDevice::GetDesiredRenderChannelCount ()
{
#if LOG_VERBOSE
DebugMessageN1("OALDevice::GetDesiredRenderChannelCount - OALDevice: %ld", mSelfToken);
#endif
UInt32 returnValue = 2; // return stereo by default
// observe the mRenderChannelSetting flag and clamp to stereo if necessary
// This allows the user to request the libary to render to stereo in the case where only 2 speakers
// are connected to multichannel hardware
if (mRenderChannelSetting == ALC_MAC_OSX_RENDER_CHANNEL_COUNT_STEREO)
return (returnValue);
// get the HAL device id form the output AU
AudioDeviceID deviceID;
UInt32 propSize = sizeof(deviceID);
OSStatus result = AudioUnitGetProperty(mOutputUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Output, 1, &deviceID, &propSize);
THROW_RESULT
// get the channel layout set by the user in AMS
result = AudioDeviceGetPropertyInfo(deviceID, 0, false, kAudioDevicePropertyPreferredChannelLayout, &propSize, NULL);
if (result == noErr)
{
AudioChannelLayout* layout = (AudioChannelLayout *) calloc(1, propSize);
if (layout != NULL)
{
/*result =*/ AudioDeviceGetProperty(deviceID, 0, false, kAudioDevicePropertyPreferredChannelLayout, &propSize, layout);
if (layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions)
{
// no channel layout tag is returned, so walk through the channel descriptions and count
// the channels that are associated with a speaker
if (layout->mNumberChannelDescriptions == 2)
{
returnValue = 2; // there is no channel info for stereo
}
else
{
returnValue = 0;
for (UInt32 i = 0; i < layout->mNumberChannelDescriptions; i++)
{
if ((layout->mChannelDescriptions[i].mChannelLabel != kAudioChannelLabel_Unknown) && (layout->mChannelDescriptions[i].mChannelLabel != kAudioChannelLabel_LFEScreen))
returnValue++;
}
}
mChannelLayoutTag = GetLayoutTagForLayout(layout, returnValue);
}
else
{
mChannelLayoutTag = layout->mChannelLayoutTag;
switch (layout->mChannelLayoutTag)
{
case kAudioChannelLayoutTag_AudioUnit_5_0:
case kAudioChannelLayoutTag_AudioUnit_5_1:
returnValue = 5;
break;
case kAudioChannelLayoutTag_AudioUnit_6_0:
case kAudioChannelLayoutTag_AudioUnit_6_1:
returnValue = 6;
break;
case kAudioChannelLayoutTag_AudioUnit_7_0:
case kAudioChannelLayoutTag_AudioUnit_7_1:
case kAudioChannelLayoutTag_AudioUnit_7_0_Front:
returnValue = 7;
break;
case kAudioChannelLayoutTag_AudioUnit_8:
returnValue = 8;
break;
case kAudioChannelLayoutTag_AudioUnit_4:
returnValue = 4;
break;
default:
returnValue = 2;
break;
}
}
free(layout);
}
}
// pass in num channels on the hw,
// how many channels the user has requested, and which 3DMixer is present
returnValue = GetDesiredRenderChannelsFor3DMixer(returnValue);
return (returnValue);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// called from alcDestroyContext(), when all context's that use this device are gone
void OALDevice::StopGraph()
{
#if LOG_VERBOSE
DebugMessageN1("OALDevice::StopGraph() - OALDevice = %ld", (long int) mSelfToken);
#endif
AUGraphStop (mAUGraph);
Boolean flag;
do {
AUGraphIsRunning (mAUGraph, &flag);
} while (flag);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*
When a Context is connected for the first time, the graph is initialized & started.
It will not be explicitly stopped until all the contexts that use this device have been destroyed.
*/
void OALDevice::ConnectContext (OALContext* inContext)
{
#if LOG_VERBOSE || LOG_DEVICE_CHANGES
DebugMessageN1("OALDevice::ConnectContext() - OALDevice = %ld", (long int) mSelfToken);
#endif
OSStatus result = noErr;
OALContext* oldContext = mConnectedContext; // save in case it needs to be restored
if (inContext == mConnectedContext)
return; // already connected
try {
// we only have to disconnect when the 3DMixer node has changed
if (mConnectedContext && (inContext->GetMixerNode() != mMixerNode)){
result = AUGraphDisconnectNodeInput(mAUGraph, mOutputNode, 0);
THROW_RESULT
mMixerNode = 0;
mConnectedContext = 0;
}
// set AU properties
{
CAStreamBasicDescription format;
UInt32 propSize = sizeof(format);
result = AudioUnitGetProperty(mOutputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &format, &propSize);
THROW_RESULT
format.SetCanonical (mRenderChannelCount, false); // not interleaved
format.mSampleRate = inContext->GetMixerRate();
result = AudioUnitSetProperty (mOutputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &format, sizeof(format));
THROW_RESULT
result = AudioUnitSetProperty (inContext->GetMixerUnit(), kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &format, sizeof(format));
THROW_RESULT
// used to be a configure graph AUs (outout AU and mixerAU to be connected)
AudioChannelLayout layout;
layout.mChannelLayoutTag = GetChannelLayoutTag();
layout.mChannelBitmap = 0;
layout.mNumberChannelDescriptions = 0;
result = AudioUnitSetProperty (mOutputUnit, kAudioUnitProperty_AudioChannelLayout, kAudioUnitScope_Input, 0, &layout, sizeof(layout));
THROW_RESULT
}
// connect new mixer to output unit
result = AUGraphConnectNodeInput (mAUGraph, inContext->GetMixerNode(), 0, mOutputNode, 0);
THROW_RESULT
mMixerNode = inContext->GetMixerNode();
mConnectedContext = inContext;
// initialize the graph on the 1st connection of a mixer to the graph
if (!mGraphInitialized) {
AUGraphInitialize(mAUGraph);
mGraphInitialized = true;
}
else
{
// if graph in uninitialized or not running , where should this go
result = AUGraphUpdate (mAUGraph, NULL);
THROW_RESULT
}
// the graph may not be running yet
if (!IsGraphStillRunning ())
AUGraphStart (mAUGraph);
}
catch (OSStatus result) {
mConnectedContext = oldContext;
throw result;
}
catch (...) {
mConnectedContext = oldContext;
throw -1;
}
return;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void OALDevice::DisconnectContext(OALContext* inContext)
{
#if LOG_VERBOSE || LOG_DEVICE_CHANGES
DebugMessageN1("OALDevice::DisconnectContext() - OALDevice = %ld", (long int) mSelfToken);
#endif
if (inContext == mConnectedContext)
mConnectedContext = NULL;
AUGraphDisconnectNodeInput(mAUGraph, mOutputNode, 0);
// AUGraphUpdate will block here, until the node is removed
AUGraphUpdate(mAUGraph, NULL);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void OALDevice::RemoveContext(OALContext* inContext)
{
#if LOG_VERBOSE || LOG_DEVICE_CHANGES
DebugMessageN1("OALDevice::RemoveContext() - OALDevice = %ld", (long int) mSelfToken);
#endif
if(inContext == mConnectedContext)
mConnectedContext = NULL;
// now remove the remove the mixer node for the context
AUGraphRemoveNode(mAUGraph, inContext->GetMixerNode());
// AUGraphUpdate will block here, until the node is removed
AUGraphUpdate(mAUGraph, NULL);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AudioChannelLayoutTag OALDevice::GetLayoutTagForLayout(AudioChannelLayout *inLayout, UInt32 inNumChannels)
{
#if LOG_VERBOSE
DebugMessageN1("OALDevice::GetLayoutTagForLayout() - OALDevice = %ld", (long int) mSelfToken);
#endif
if (inNumChannels == 5)
return kAudioChannelLayoutTag_AudioUnit_5_0;
// Quad not supported prior to 3d mixer ver. 2.0
else if ((inNumChannels == 4) && (Get3DMixerVersion() >= k3DMixerVersion_2_0))
return kAudioChannelLayoutTag_AudioUnit_4;
// now check for new multichannel formats in the 3d mixer v. 2.3 and higher
else if (inNumChannels == 6 && (Get3DMixerVersion() >= k3DMixerVersion_2_3))
return kAudioChannelLayoutTag_AudioUnit_6_0;
else if (inNumChannels == 7 && (Get3DMixerVersion() >= k3DMixerVersion_2_3))
{
//return kAudioChannelLayoutTag_AudioUnit_7_0;
for (UInt32 i=0; i< inLayout->mNumberChannelDescriptions; i++)
{
if((inLayout->mChannelDescriptions[i].mChannelLabel == kAudioChannelLabel_RearSurroundLeft) ||
(inLayout->mChannelDescriptions[i].mChannelLabel == kAudioChannelLabel_RearSurroundRight))
{
//if we have rear channels, we need kAudioChannelLayoutTag_AudioUnit_7_0
return kAudioChannelLayoutTag_AudioUnit_7_0;
}
}
//if we didn't find rear channels, default 7.0 front
return kAudioChannelLayoutTag_AudioUnit_7_0_Front;
}
else if (inNumChannels == 8 && (Get3DMixerVersion() >= k3DMixerVersion_2_3))
return kAudioChannelLayoutTag_AudioUnit_8;
return kAudioChannelLayoutTag_Stereo; // default case
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UInt32 OALDevice::GetChannelLayoutTag()
{
#if LOG_VERBOSE
DebugMessageN1("OALDevice::GetChannelLayoutTag() - OALDevice = %ld", (long int) mSelfToken);
#endif
return mChannelLayoutTag;
}

195
Source/OpenAL/oalDevice.h Normal file
View File

@ -0,0 +1,195 @@
/**********************************************************************************************************************************
*
* OpenAL cross platform audio library
* Copyright (c) 2004, Apple Computer, Inc., Copyright (c) 2012, Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Inc. ("Apple") nor the names of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************************************************************************/
#ifndef __OAL_DEVICE__
#define __OAL_DEVICE__
#include <Carbon/Carbon.h>
#include <CoreAudio/AudioHardware.h>
#include <AudioToolbox/AudioToolbox.h>
#include <AudioUnit/AudioUnit.h>
#include <libkern/OSAtomic.h>
#include <map>
#include "oalImp.h"
#include "CAStreamBasicDescription.h"
class OALContext; // forward declaration
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Some build flags for gathering performance and data flow information
#if USE_AU_TRACER
#include "AUTracer.h"
#endif
#if DEBUG
#define AUHAL_LOG_OUTPUT 0
#endif
#if AUHAL_LOG_OUTPUT
#include "AudioLogger.h"
#endif
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Device Constants
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Default Mixer Output Sample Rate Setting:
#define kDefaultMixerRate 44100.0
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// OALDevices
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark _____OALDevice_____
class OALDevice
{
public:
OALDevice(const char* inDeviceName, uintptr_t inSelfToken, UInt32 inRenderChannelSetting);
~OALDevice();
void ConnectContext (OALContext* inContext);
void DisconnectContext (OALContext* inContext);
void RemoveContext (OALContext* inContext);
void StopGraph();
// thread safety
volatile int32_t IsInUse() { return mInUseFlag; }
void SetInUseFlag() { OSAtomicIncrement32Barrier(&mInUseFlag); }
void ClearInUseFlag() { OSAtomicDecrement32Barrier(&mInUseFlag); }
// set info
void SetRenderChannelSetting (UInt32 inRenderChannelSetting);
void SetError(ALenum errorCode);
// get info
uintptr_t GetDeviceToken () const { return mSelfToken; }
Float64 GetDeviceSampleRate () const { return mDeviceSampleRate; }
UInt32 GetRenderChannelSetting() { return mRenderChannelSetting; }
ALenum GetError();
UInt32 GetFramesPerSlice() { return mFramesPerSlice;}
AUGraph GetGraph () {return mAUGraph;}
AudioUnit GetOutputAU(){return mOutputUnit;}
OSStatus UpdateDeviceChannelLayout();
UInt32 GetDesiredRenderChannelCount ();
// misc.
bool IsValidRenderQuality (UInt32 inRenderQuality);
static void GraphFormatPropertyListener ( void *inRefCon,
AudioUnit ci,
AudioUnitPropertyID inID,
AudioUnitScope inScope,
AudioUnitElement inElement);
bool IsGraphStillRunning ()
{
Boolean running;
OSStatus result = AUGraphIsRunning (mAUGraph, &running);
THROW_RESULT
return bool(running);
}
void Print () const
{
#if DEBUG || CoreAudio_Debug
CAShow (mAUGraph);
#endif
}
private:
uintptr_t mSelfToken;
ALenum mCurrentError;
AudioDeviceID mHALDevice; // the HAL device used to render audio to the user
bool mDistanceScalingRequired;
bool mGraphInitialized;
AUGraph mAUGraph;
AUNode mOutputNode;
AudioUnit mOutputUnit;
AUNode mMixerNode;
AudioChannelLayoutTag mChannelLayoutTag;
OALContext* mConnectedContext;
Float64 mDeviceSampleRate;
UInt32 mRenderChannelCount;
UInt32 mRenderChannelSetting; // currently either stereo or multichannel
UInt32 mFramesPerSlice;
volatile int32_t mInUseFlag; // flag to indicate if the device is currently being edited by one or more threads
#if AUHAL_LOG_OUTPUT
AudioLogger mLogger;
#endif
#if USE_AU_TRACER
AUTracer mAUTracer;
#endif
void InitializeGraph (const char* inDeviceName);
void TeardownGraph();
void ResetRenderChannelSettings();
AudioChannelLayoutTag GetLayoutTagForLayout(AudioChannelLayout *inLayout, UInt32 inNumChannels);
UInt32 GetChannelLayoutTag();
};
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark _____OALDeviceMap_____
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class OALDeviceMap : std::multimap<uintptr_t, OALDevice*, std::less<uintptr_t> > {
public:
void Add (const uintptr_t inDeviceToken, OALDevice **inDevice) {
iterator it = upper_bound(inDeviceToken);
insert(it, value_type (inDeviceToken, *inDevice));
}
OALDevice* Get(uintptr_t inDeviceToken) {
iterator it = find(inDeviceToken);
if (it != end())
return ((*it).second);
return (NULL);
}
OALDevice* GetDeviceByIndex(UInt32 inIndex, uintptr_t &outDeviceToken) {
iterator it = begin();
std::advance(it, inIndex);
if (it != end())
{
outDeviceToken = (*it).first;
return (*it).second;
}
return (NULL);
}
void Remove (const uintptr_t inDeviceToken) {
iterator it = find(inDeviceToken);
if (it != end())
erase(it);
}
UInt32 Size () const { return size(); }
bool Empty () const { return empty(); }
};
#endif

5704
Source/OpenAL/oalImp.cpp Normal file

File diff suppressed because it is too large Load Diff

161
Source/OpenAL/oalImp.h Normal file
View File

@ -0,0 +1,161 @@
/**********************************************************************************************************************************
*
* OpenAL cross platform audio library
* Copyright (c) 2004, Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************************************************************************/
#ifndef __OAL_IMP__
#define __OAL_IMP__
#include "al.h"
#include "alc.h"
#include "oalOSX.h"
#include <Carbon/Carbon.h>
#include <map>
typedef ALvoid (*alSourceNotificationProc) (ALuint sid, ALuint notificationID, ALvoid* userData);
#ifdef __cplusplus
extern "C" {
#endif
// added for OSX Extension
ALC_API ALvoid alcMacOSXRenderingQuality (ALint value);
ALC_API ALvoid alMacOSXRenderChannelCount (ALint value);
ALC_API ALvoid alcMacOSXMixerMaxiumumBusses (ALint value);
ALC_API ALvoid alcMacOSXMixerOutputRate(ALdouble value);
ALC_API ALint alcMacOSXGetRenderingQuality ();
ALC_API ALint alMacOSXGetRenderChannelCount ();
ALC_API ALint alcMacOSXGetMixerMaxiumumBusses ();
ALC_API ALdouble alcMacOSXGetMixerOutputRate();
AL_API ALvoid AL_APIENTRY alSetInteger (ALenum pname, ALint value);
AL_API ALvoid AL_APIENTRY alSetDouble (ALenum pname, ALdouble value);
AL_API ALvoid AL_APIENTRY alBufferDataStatic (ALint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq);
// source notifications
AL_API ALenum alSourceAddNotification (ALuint sid, ALuint notificationID, alSourceNotificationProc notifyProc, ALvoid* userData);
AL_API ALvoid alSourceRemoveNotification (ALuint sid, ALuint notificationID, alSourceNotificationProc notifyProc, ALvoid* userData);
// source spatialization
AL_API ALvoid alSourceRenderingQuality (ALuint sid, ALint value);
AL_API ALint alSourceGetRenderingQuality (ALuint sid);
// added for ASA (Apple Environmental Audio)
ALC_API ALenum alcASAGetSource(ALuint property, ALuint source, ALvoid *data, ALuint* dataSize);
ALC_API ALenum alcASASetSource(ALuint property, ALuint source, ALvoid *data, ALuint dataSize);
ALC_API ALenum alcASAGetListener(ALuint property, ALvoid *data, ALuint* dataSize);
ALC_API ALenum alcASASetListener(ALuint property, ALvoid *data, ALuint dataSize);
// 3DMixer output capturer
ALC_API ALvoid alcOutputCapturerPrepare( ALCuint frequency, ALCenum format, ALCsizei buffersize );
ALC_API ALvoid alcOutputCapturerStart();
ALC_API ALvoid alcOutputCapturerStop();
ALC_API ALint alcOutputCapturerAvailableSamples();
ALC_API ALvoid alcOutputCapturerSamples( ALCvoid *buffer, ALCsizei samples );
// Used internally but no longer available via a header file. Some OpenAL applications may have been built with a header
// that defined these constants so keep defining them.
#define ALC_SPATIAL_RENDERING_QUALITY 0xF002
#define ALC_MIXER_OUTPUT_RATE 0xF003
#define ALC_MIXER_MAXIMUM_BUSSES 0xF004
#define ALC_RENDER_CHANNEL_COUNT 0xF005
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#define AL_FORMAT_MONO_FLOAT32 0x10010
#define AL_FORMAT_STEREO_FLOAT32 0x10011
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Continue exporting these deprectaed APIs to prevent runtime link errors
#ifdef TARGET_OS_MAC
#if TARGET_OS_MAC
#pragma export on
#endif
#endif
AL_API ALvoid AL_APIENTRY alHint( ALenum target, ALenum mode );
#ifdef TARGET_OS_MAC
#if TARGET_OS_MAC
#pragma export off
#endif
#endif
#ifdef __cplusplus
}
#endif
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// development build flags
#define USE_AU_TRACER 0
#define LOG_GRAPH_AND_MIXER_CHANGES 0
#define GET_OVERLOAD_NOTIFICATIONS 0
#define LOG_IO 0
#if LOG_IO
#include "AudioLogger.h"
#endif
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#define AL_MAXBUFFERS 1024
#define AL_MAXSOURCES 256
#define kDefaultMaximumMixerBusCount 64
#define kDopplerDefault 0
enum {
kRogerBeepType = 'rogr',
kDistortionType = 'dist'
};
#define THROW_RESULT if(result != noErr) throw static_cast<OSStatus>(result);
enum {
kUnknown3DMixerVersion = 0,
kUnsupported3DMixer = 1,
k3DMixerVersion_1_3 = 13,
k3DMixerVersion_2_0,
k3DMixerVersion_2_1,
k3DMixerVersion_2_2,
k3DMixerVersion_2_3
};
enum {
kUnknownAUState = -1,
kAUIsNotPresent = 0,
kAUIsPresent = 1
};
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void alSetError (ALenum errorCode);
UInt32 Get3DMixerVersion ();
ALCint IsDistortionPresent();
ALCint IsRogerBeepPresent();
#endif

823
Source/OpenAL/oalOSX.cpp Normal file
View File

@ -0,0 +1,823 @@
/**********************************************************************************************************************************
* OpenAL cross platform audio library
* Copyright (C) 1999-2000 by authors.
* Portions Copyright (C) 2004 by Apple Computer Inc., Copyright (C) 2012 by Apple Inc.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* Or go to http://www.gnu.org/copyleft/lgpl.html
**********************************************************************************************************************************/
#include "oalOSX.h"
#define LOG_RING_BUFFER 0
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark ***** UTILITY *****
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Use this for getting a unique token when creating new contexts and devices
uintptr_t GetNewPtrToken (void)
{
static uintptr_t currentToken = 24;
uintptr_t returnedToken;
returnedToken = currentToken;
currentToken++;
return (returnedToken);
}
// Use this for getting a unique integer token
ALuint GetNewToken (void)
{
static ALuint currentToken = 2400;
ALuint returnedToken;
returnedToken = currentToken;
currentToken++;
return (returnedToken);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const char kPathDelimiter[] = "/";
const UInt32 kPathDelimiterLength = 1;
bool IsRelativePath(const char* inPath)
{
return inPath[0] != kPathDelimiter[0];
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void MakeAbsolutePath(const char* inRelativePath, char* outAbsolutePath, UInt32 inMaxAbsolutePathLength)
{
// get the path to the current working directory
getcwd(outAbsolutePath, inMaxAbsolutePathLength);
if ((strlen(outAbsolutePath) + kPathDelimiterLength) <= inMaxAbsolutePathLength - 1)
{
strcat(outAbsolutePath, kPathDelimiter);
if ((strlen(outAbsolutePath) + strlen(inRelativePath)) <= inMaxAbsolutePathLength - 1)
{
strcat(outAbsolutePath, inRelativePath);
}
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UInt32 GetOALFormatFromASBD(CAStreamBasicDescription &inASBD)
{
switch (inASBD.mFormatID)
{
case kAudioFormatLinearPCM:
// NOTE: if float: check for extension
if (inASBD.mFormatFlags & kAudioFormatFlagIsFloat)
{
if (inASBD.NumberChannels() == 1 && inASBD.mBitsPerChannel == 32)
{
if(alIsExtensionPresent("AL_EXT_float32"))
return alGetEnumValue("AL_FORMAT_MONO_FLOAT32");
}
if (inASBD.NumberChannels() == 2 && inASBD.mBitsPerChannel == 32)
{
if(alIsExtensionPresent("AL_EXT_float32"))
return alGetEnumValue("AL_FORMAT_STEREO_FLOAT32");
}
}
else
{
if (inASBD.NumberChannels() == 1 && inASBD.mBitsPerChannel == 16)
return AL_FORMAT_MONO16;
else if (inASBD.NumberChannels() == 2 && inASBD.mBitsPerChannel == 16)
return AL_FORMAT_STEREO16;
else if (inASBD.NumberChannels() == 1 && inASBD.mBitsPerChannel == 8)
return AL_FORMAT_MONO8;
else if (inASBD.NumberChannels() == 2 && inASBD.mBitsPerChannel == 8)
return AL_FORMAT_STEREO8;
}
break;
default:
return (0);
break;
}
return (0);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const char* GetFormatString(UInt32 inToken)
{
switch(inToken)
{
case AL_FORMAT_MONO16:
return "16-Bit/Mono";
break;
case AL_FORMAT_STEREO16:
return "16-Bit/Stereo";
break;
case AL_FORMAT_MONO8:
return "8-Bit/Mono";
break;
case AL_FORMAT_STEREO8:
return "8-Bit/Stereo";
break;
}
return "UNKNOWN FORMAT";
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// For use with DebugMessages so errors are more readable
const char* GetALAttributeString(UInt32 inToken)
{
switch(inToken)
{
case AL_SOURCE_RELATIVE: return "AL_SOURCE_RELATIVE"; break;
case AL_CONE_INNER_ANGLE: return "AL_CONE_INNER_ANGLE"; break;
case AL_CONE_OUTER_ANGLE: return "AL_CONE_OUTER_ANGLE"; break;
case AL_CONE_OUTER_GAIN: return "AL_CONE_OUTER_GAIN"; break;
case AL_PITCH: return "AL_PITCH"; break;
case AL_POSITION: return "AL_POSITION"; break;
case AL_DIRECTION: return "AL_DIRECTION"; break;
case AL_VELOCITY: return "AL_VELOCITY"; break;
case AL_LOOPING: return "AL_LOOPING"; break;
case AL_BUFFER: return "AL_BUFFER"; break;
case AL_GAIN: return "AL_GAIN"; break;
case AL_MIN_GAIN: return "AL_MIN_GAIN"; break;
case AL_MAX_GAIN: return "AL_MAX_GAIN"; break;
case AL_ORIENTATION: return "AL_ORIENTATION"; break;
case AL_REFERENCE_DISTANCE: return "AL_REFERENCE_DISTANCE"; break;
case AL_ROLLOFF_FACTOR: return "AL_ROLLOFF_FACTOR"; break;
case AL_MAX_DISTANCE: return "AL_MAX_DISTANCE"; break;
case AL_SOURCE_STATE: return "AL_SOURCE_STATE"; break;
case AL_BUFFERS_QUEUED: return "AL_BUFFERS_QUEUED"; break;
case AL_BUFFERS_PROCESSED: return "AL_BUFFERS_PROCESSED"; break;
case AL_SEC_OFFSET: return "AL_SEC_OFFSET"; break;
case AL_SAMPLE_OFFSET: return "AL_SAMPLE_OFFSET"; break;
case AL_BYTE_OFFSET: return "AL_BYTE_OFFSET"; break;
case AL_SOURCE_TYPE: return "AL_SOURCE_TYPE"; break;
case AL_NONE: return "AL_NONE"; break;
case AL_INVERSE_DISTANCE: return "AL_INVERSE_DISTANCE"; break;
case AL_INVERSE_DISTANCE_CLAMPED: return "AL_INVERSE_DISTANCE_CLAMPED"; break;
case AL_LINEAR_DISTANCE: return "AL_LINEAR_DISTANCE"; break;
case AL_LINEAR_DISTANCE_CLAMPED: return "AL_LINEAR_DISTANCE_CLAMPED"; break;
case AL_EXPONENT_DISTANCE: return "AL_EXPONENT_DISTANCE"; break;
case AL_EXPONENT_DISTANCE_CLAMPED: return "AL_EXPONENT_DISTANCE_CLAMPED"; break;
case AL_INVALID_NAME: return "AL_INVALID_NAME"; break;
}
return "UNKNOWN ATTRIBUTE - WARNING WARNING WARNING";
}
const char* GetALCAttributeString(UInt32 inToken)
{
switch(inToken)
{
case ALC_DEFAULT_DEVICE_SPECIFIER: return "ALC_DEFAULT_DEVICE_SPECIFIER"; break;
case ALC_DEVICE_SPECIFIER: return "ALC_DEVICE_SPECIFIER"; break;
case ALC_EXTENSIONS: return "ALC_EXTENSIONS"; break;
case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER: return "ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER"; break;
case ALC_CAPTURE_DEVICE_SPECIFIER: return "ALC_CAPTURE_DEVICE_SPECIFIER"; break;
case ALC_NO_ERROR: return "ALC_NO_ERROR"; break;
case ALC_INVALID_DEVICE: return "ALC_INVALID_DEVICE"; break;
case ALC_INVALID_CONTEXT: return "ALC_INVALID_CONTEXT"; break;
case ALC_INVALID_ENUM: return "ALC_INVALID_ENUM"; break;
case ALC_INVALID_VALUE: return "ALC_INVALID_VALUE"; break;
case ALC_ASA_REVERB_ON: return "ALC_ASA_REVERB_ON"; break;
case ALC_ASA_REVERB_ROOM_TYPE: return "ALC_ASA_REVERB_ROOM_TYPE"; break;
case ALC_ASA_REVERB_SEND_LEVEL: return "ALC_ASA_REVERB_SEND_LEVEL"; break;
case ALC_ASA_REVERB_GLOBAL_LEVEL: return "ALC_ASA_REVERB_GLOBAL_LEVEL"; break;
case ALC_ASA_OCCLUSION: return "ALC_ASA_OCCLUSION"; break;
case ALC_ASA_ROGER_BEEP_ENABLE: return "ALC_ASA_ROGER_BEEP_ENABLE"; break;
case ALC_ASA_ROGER_BEEP_ON: return "ALC_ASA_ROGER_BEEP_ON"; break;
case ALC_ASA_ROGER_BEEP_GAIN: return "ALC_ASA_ROGER_BEEP_GAIN"; break;
case ALC_ASA_ROGER_BEEP_SENSITIVITY: return "ALC_ASA_ROGER_BEEP_SENSITIVITY"; break;
case ALC_ASA_ROGER_BEEP_TYPE: return "ALC_ASA_ROGER_BEEP_TYPE"; break;
case ALC_ASA_ROGER_BEEP_PRESET: return "ALC_ASA_ROGER_BEEP_PRESET"; break;
case ALC_ASA_DISTORTION_ENABLE: return "ALC_ASA_DISTORTION_ENABLE"; break;
case ALC_ASA_DISTORTION_ON: return "ALC_ASA_DISTORTION_ON"; break;
case ALC_ASA_DISTORTION_MIX: return "ALC_ASA_DISTORTION_MIX"; break;
case ALC_ASA_DISTORTION_TYPE: return "ALC_ASA_DISTORTION_TYPE"; break;
case ALC_ASA_DISTORTION_PRESET: return "ALC_ASA_DISTORTION_PRESET"; break;
}
return "UNKNOWN ATTRIBUTE - WARNING WARNING WARNING";
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool IsValidRenderQuality (UInt32 inRenderQuality)
{
switch (inRenderQuality)
{
case ALC_MAC_OSX_SPATIAL_RENDERING_QUALITY_HIGH:
case ALC_MAC_OSX_SPATIAL_RENDERING_QUALITY_LOW:
return (true);
break;
default:
return (false);
break;
}
return (false);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool IsFormatSupported(UInt32 inFormatID)
{
switch(inFormatID)
{
case AL_FORMAT_MONO16:
case AL_FORMAT_STEREO16:
case AL_FORMAT_MONO8:
case AL_FORMAT_STEREO8:
return true;
break;
case AL_FORMAT_MONO_FLOAT32:
case AL_FORMAT_STEREO_FLOAT32:
return alIsExtensionPresent("AL_EXT_float32");
break;
default:
return false;
break;
}
return false;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OSStatus FillInASBD(CAStreamBasicDescription &inASBD, UInt32 inFormatID, UInt32 inSampleRate)
{
OSStatus err = noErr;
switch (inFormatID)
{
case AL_FORMAT_STEREO16:
inASBD.mSampleRate = inSampleRate * 1.0;
inASBD.mFormatID = kAudioFormatLinearPCM;
inASBD.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
inASBD.mBytesPerPacket = 4;
inASBD.mBytesPerFrame = 4;
inASBD.mFramesPerPacket = 1;
inASBD.mBitsPerChannel = 16;
inASBD.mChannelsPerFrame = 2;
inASBD.mReserved = 0;
break;
case AL_FORMAT_MONO16:
inASBD.mSampleRate = inSampleRate * 1.0;
inASBD.mFormatID = kAudioFormatLinearPCM;
inASBD.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
inASBD.mBytesPerPacket = 2;
inASBD.mBytesPerFrame = 2;
inASBD.mFramesPerPacket = 1;
inASBD.mBitsPerChannel = 16;
inASBD.mChannelsPerFrame = 1;
inASBD.mReserved = 0;
break;
case AL_FORMAT_STEREO8:
inASBD.mSampleRate = inSampleRate * 1.0;
inASBD.mFormatID = kAudioFormatLinearPCM;
inASBD.mFormatFlags = kAudioFormatFlagIsPacked;
inASBD.mBytesPerPacket = 2;
inASBD.mBytesPerFrame = 2;
inASBD.mFramesPerPacket = 1;
inASBD.mBitsPerChannel = 8;
inASBD.mChannelsPerFrame = 2;
inASBD.mReserved = 0;
break;
case AL_FORMAT_MONO8 :
inASBD.mSampleRate = inSampleRate * 1.0;
inASBD.mFormatID = kAudioFormatLinearPCM;
inASBD.mFormatFlags = kAudioFormatFlagIsPacked;
inASBD.mBytesPerPacket = 1;
inASBD.mBytesPerFrame = 1;
inASBD.mFramesPerPacket = 1;
inASBD.mBitsPerChannel = 8;
inASBD.mChannelsPerFrame = 1;
inASBD.mReserved = 0;
break;
case AL_FORMAT_STEREO_FLOAT32 :
inASBD.mSampleRate = inSampleRate * 1.0;
inASBD.mFormatID = kAudioFormatLinearPCM;
inASBD.mFormatFlags = kLinearPCMFormatFlagIsFloat;
inASBD.mBytesPerPacket = 8;
inASBD.mBytesPerFrame = 8;
inASBD.mFramesPerPacket = 1;
inASBD.mBitsPerChannel = 32;
inASBD.mChannelsPerFrame = 2;
inASBD.mReserved = 0;
break;
case AL_FORMAT_MONO_FLOAT32 :
inASBD.mSampleRate = inSampleRate * 1.0;
inASBD.mFormatID = kAudioFormatLinearPCM;
inASBD.mFormatFlags = kLinearPCMFormatFlagIsFloat;
inASBD.mBytesPerPacket = 4;
inASBD.mBytesPerFrame = 4;
inASBD.mFramesPerPacket = 1;
inASBD.mBitsPerChannel = 32;
inASBD.mChannelsPerFrame = 1;
inASBD.mReserved = 0;
break;
default:
err = AL_INVALID_VALUE;
break;
}
return (err);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void GetDefaultDeviceName(ALCchar* outDeviceName, bool isInput)
{
UInt32 size = 0;
OSStatus result = noErr;
UInt32 deviceProperty = isInput ? kAudioHardwarePropertyDefaultInputDevice : kAudioHardwarePropertyDefaultOutputDevice;
try {
AudioDeviceID defaultDevice = 0;
// Get the default output device
size = sizeof(defaultDevice);
result = AudioHardwareGetProperty(deviceProperty, &size, &defaultDevice);
THROW_RESULT
result = AudioDeviceGetPropertyInfo( defaultDevice, 0, false, kAudioDevicePropertyDeviceName, &size, NULL);
THROW_RESULT
if (size > maxLen)
throw -1;
size = maxLen;
result = AudioDeviceGetProperty(defaultDevice, 0, false, kAudioDevicePropertyDeviceName, &size, outDeviceName);
THROW_RESULT
} catch (...) {
outDeviceName[0] = '\0'; // failure case, make it a zero length string
}
return;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UInt32 CalculateNeededMixerBusses(const ALCint *attrList, UInt32 inDefaultBusCount)
{
UInt32 monoSources = 0;
UInt32 stereoSources = 0;
UInt32 returnValue = inDefaultBusCount; // default case
ALCint* currentAttribute = ( ALCint*) attrList;
// ATTRIBUTE LIST
if (attrList)
{
while (*currentAttribute != 0)
{
switch (*currentAttribute)
{
case ALC_MONO_SOURCES:
monoSources = currentAttribute[1];
break;
case ALC_STEREO_SOURCES:
stereoSources = currentAttribute[1];
break;
default:
break;
}
currentAttribute += 2;
}
if (monoSources == 0 && stereoSources == 0)
returnValue = inDefaultBusCount;
else if ((monoSources + stereoSources > kDefaultMaximumMixerBusCount) || (monoSources + stereoSources > inDefaultBusCount))
returnValue = monoSources + stereoSources;
}
return returnValue;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UInt32 GetDesiredRenderChannelsFor3DMixer(UInt32 inDeviceChannels)
{
UInt32 returnValue = inDeviceChannels;
if ((Get3DMixerVersion() < k3DMixerVersion_2_0) && (returnValue == 4))
{
// quad did not work properly before version 2.0 of the 3DMixer, so just render to stereo
returnValue = 2;
}
else if (inDeviceChannels < 4)
{
// guard against the possibility of multi channel hw that has never been given a preferred channel layout
// Or, that a 3 channel layout was returned (which is unsupported by the 3DMixer)
returnValue = 2;
}
else if ((inDeviceChannels > 5) && (Get3DMixerVersion() < k3DMixerVersion_2_3))
{
// 3DMixer ver. 2.2 and below does not render to more than 5 channels
returnValue = 5;
}
else if (inDeviceChannels > 8)
{
// Current 3DMixer renders to maximum 8 channels
returnValue = 8;
}
return returnValue;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark ***** DEPRECATED ALUT *****
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#ifdef __cplusplus
extern "C" {
#endif
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// alutLoadWAVMemory()
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#define ALUTAPI
#define ALUTAPIENTRY
ALUTAPI ALvoid ALUTAPIENTRY alutInit(ALint *argc,ALbyte **argv);
ALUTAPI ALvoid ALUTAPIENTRY alutExit(void);
ALUTAPI ALvoid ALUTAPIENTRY alutLoadWAVFile(ALbyte *file,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq);
ALUTAPI ALvoid ALUTAPIENTRY alutLoadWAVMemory(ALbyte *memory,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq);
ALUTAPI ALvoid ALUTAPIENTRY alutUnloadWAV(ALenum format,ALvoid *data,ALsizei size,ALsizei freq);
/*
alutLoadWAVMemory() existed in previous OAL implementations, and is provided for legacy purposes.
This is the same implementation already existing in the Open Source repository.
*/
typedef struct /* WAV File-header */
{
ALubyte Id[4];
ALsizei Size;
ALubyte Type[4];
} WAVFileHdr_Struct;
typedef struct /* WAV Fmt-header */
{
ALushort Format;
ALushort Channels;
ALuint SamplesPerSec;
ALuint BytesPerSec;
ALushort BlockAlign;
ALushort BitsPerSample;
} WAVFmtHdr_Struct;
typedef struct /* WAV FmtEx-header */
{
ALushort Size;
ALushort SamplesPerBlock;
} WAVFmtExHdr_Struct;
typedef struct /* WAV Smpl-header */
{
ALuint Manufacturer;
ALuint Product;
ALuint SamplePeriod;
ALuint Note;
ALuint FineTune;
ALuint SMPTEFormat;
ALuint SMPTEOffest;
ALuint Loops;
ALuint SamplerData;
struct
{
ALuint Identifier;
ALuint Type;
ALuint Start;
ALuint End;
ALuint Fraction;
ALuint Count;
} Loop[1];
} WAVSmplHdr_Struct;
typedef struct /* WAV Chunk-header */
{
ALubyte Id[4];
ALuint Size;
} WAVChunkHdr_Struct;
void SwapWords(unsigned int *puint);
void SwapBytes(unsigned short *pshort);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void SwapWords(unsigned int *puint)
{
unsigned int tempint;
char *pChar1, *pChar2;
tempint = *puint;
pChar2 = (char *)&tempint;
pChar1 = (char *)puint;
pChar1[0]=pChar2[3];
pChar1[1]=pChar2[2];
pChar1[2]=pChar2[1];
pChar1[3]=pChar2[0];
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void SwapBytes(unsigned short *pshort)
{
unsigned short tempshort;
char *pChar1, *pChar2;
tempshort = *pshort;
pChar2 = (char *)&tempshort;
pChar1 = (char *)pshort;
pChar1[0]=pChar2[1];
pChar1[1]=pChar2[0];
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ALUTAPI ALvoid ALUTAPIENTRY alutLoadWAVMemory(ALbyte *memory,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq)
{
WAVChunkHdr_Struct ChunkHdr;
WAVFmtExHdr_Struct FmtExHdr;
WAVFileHdr_Struct FileHdr;
WAVSmplHdr_Struct SmplHdr;
WAVFmtHdr_Struct FmtHdr;
ALbyte *Stream;
*format=AL_FORMAT_MONO16;
*data=NULL;
*size=0;
*freq=22050;
if (memory)
{
Stream=memory;
if (Stream)
{
memcpy(&FileHdr,Stream,sizeof(WAVFileHdr_Struct));
Stream+=sizeof(WAVFileHdr_Struct);
SwapWords((unsigned int*) &FileHdr.Size);
FileHdr.Size=((FileHdr.Size+1)&~1)-4;
while ((FileHdr.Size!=0)&&(memcpy(&ChunkHdr,Stream,sizeof(WAVChunkHdr_Struct))))
{
Stream+=sizeof(WAVChunkHdr_Struct);
SwapWords(&ChunkHdr.Size);
if ((ChunkHdr.Id[0] == 'f') && (ChunkHdr.Id[1] == 'm') && (ChunkHdr.Id[2] == 't') && (ChunkHdr.Id[3] == ' '))
{
memcpy(&FmtHdr,Stream,sizeof(WAVFmtHdr_Struct));
SwapBytes(&FmtHdr.Format);
if (FmtHdr.Format==0x0001)
{
SwapBytes(&FmtHdr.Channels);
SwapBytes(&FmtHdr.BitsPerSample);
SwapWords(&FmtHdr.SamplesPerSec);
SwapBytes(&FmtHdr.BlockAlign);
*format=(FmtHdr.Channels==1?
(FmtHdr.BitsPerSample==8?AL_FORMAT_MONO8:AL_FORMAT_MONO16):
(FmtHdr.BitsPerSample==8?AL_FORMAT_STEREO8:AL_FORMAT_STEREO16));
*freq=FmtHdr.SamplesPerSec;
Stream+=ChunkHdr.Size;
}
else
{
memcpy(&FmtExHdr,Stream,sizeof(WAVFmtExHdr_Struct));
Stream+=ChunkHdr.Size;
}
}
else if ((ChunkHdr.Id[0] == 'd') && (ChunkHdr.Id[1] == 'a') && (ChunkHdr.Id[2] == 't') && (ChunkHdr.Id[3] == 'a'))
{
if (FmtHdr.Format==0x0001)
{
*size=ChunkHdr.Size;
if(*data == NULL){
*data=malloc(ChunkHdr.Size + 31);
memset(*data,0,ChunkHdr.Size+31);
}
else{
realloc(*data,ChunkHdr.Size + 31);
memset(*data,0,ChunkHdr.Size+31);
}
if (*data)
{
memcpy(*data,Stream,ChunkHdr.Size);
memset(((char *)*data)+ChunkHdr.Size,0,31);
Stream+=ChunkHdr.Size;
if (FmtHdr.BitsPerSample == 16)
{
for (UInt32 i = 0; i < (ChunkHdr.Size / 2); i++)
{
SwapBytes(&(*(unsigned short **)data)[i]);
}
}
}
}
else if (FmtHdr.Format==0x0011)
{
//IMA ADPCM
}
else if (FmtHdr.Format==0x0055)
{
//MP3 WAVE
}
}
else if ((ChunkHdr.Id[0] == 's') && (ChunkHdr.Id[1] == 'm') && (ChunkHdr.Id[2] == 'p') && (ChunkHdr.Id[3] == 'l'))
{
memcpy(&SmplHdr,Stream,sizeof(WAVSmplHdr_Struct));
Stream+=ChunkHdr.Size;
}
else Stream+=ChunkHdr.Size;
Stream+=ChunkHdr.Size&1;
FileHdr.Size-=(((ChunkHdr.Size+1)&~1)+8);
}
}
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ALUTAPI ALvoid ALUTAPIENTRY alutInit(ALint *argc,ALbyte **argv)
{
ALCcontext *Context;
ALCdevice *Device;
Device=alcOpenDevice(NULL); //Open device
if (Device != NULL) {
Context=alcCreateContext(Device,0); //Create context
if (Context != NULL) {
alcMakeContextCurrent(Context); //Set active context
}
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ALUTAPI ALvoid ALUTAPIENTRY alutExit(void)
{
ALCcontext *Context;
ALCdevice *Device;
//Get active context
Context=alcGetCurrentContext();
//Get device for active context
Device=alcGetContextsDevice(Context);
//Release context
alcDestroyContext(Context);
//Close device
alcCloseDevice(Device);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ALUTAPI ALvoid ALUTAPIENTRY alutLoadWAVFile(ALbyte *file,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq)
{
OSStatus err = noErr;
AudioFileID audioFile = 0;
FSRef fsRef;
*data = NULL; // in case of failure, do not return some unitialized value as a bogus address
if (IsRelativePath(file))
{
char absolutePath[256];
// we need to make a full path here so FSPathMakeRef() works properly
MakeAbsolutePath(file, absolutePath, 256);
// create an fsref from the file parameter
err = FSPathMakeRef ((const UInt8 *) absolutePath, &fsRef, NULL);
}
else
err = FSPathMakeRef ((const UInt8 *) file, &fsRef, NULL);
if (err == noErr)
{
err = AudioFileOpen(&fsRef, kAudioFileReadPermission, 0, &audioFile);
if (err == noErr)
{
UInt32 dataSize;
CAStreamBasicDescription asbd;
dataSize = sizeof(CAStreamBasicDescription);
AudioFileGetProperty(audioFile, kAudioFilePropertyDataFormat, &dataSize, &asbd);
*format = GetOALFormatFromASBD(asbd);
if (IsFormatSupported(*format))
{
*freq = (UInt32) asbd.mSampleRate;
SInt64 audioDataSize = 0;
dataSize = sizeof(audioDataSize);
err = AudioFileGetProperty(audioFile, kAudioFilePropertyAudioDataByteCount, &dataSize, &audioDataSize);
if (err == noErr)
{
*size = audioDataSize;
*data = NULL;
*data = calloc(1, audioDataSize);
if (*data)
{
dataSize = audioDataSize;
/*err =*/ AudioFileReadBytes(audioFile, false, 0, &dataSize, *data);
#if TARGET_RT_BIG_ENDIAN
// Only swap to big endian if running on a ppc mac
if ((asbd.mFormatID == kAudioFormatLinearPCM) && (asbd.mBitsPerChannel > 8))
{
// we just got 16 bit pcm data out of a WAVE file on a big endian platform, so endian swap the data
AudioConverterRef converter;
CAStreamBasicDescription outFormat = asbd;
void * tempData = NULL;
// ste format to big endian
outFormat.mFormatFlags = kAudioFormatFlagIsBigEndian | kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
// make some place for converted data
tempData = calloc(1 , audioDataSize);
err = AudioConverterNew(&asbd, &outFormat, &converter);
if ((err == noErr) && (tempData != NULL))
{
UInt32 bufferSize = audioDataSize;
err = AudioConverterConvertBuffer(converter, audioDataSize, *data, &bufferSize, tempData);
if (err == noErr)
memcpy(*data, tempData, audioDataSize);
AudioConverterDispose(converter);
}
if (tempData) free (tempData);
}
#endif // TARGET_RT_BIG_ENDIAN
}
}
}
/*err =*/ AudioFileClose(audioFile);
}
}
else
alSetError(err);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ALUTAPI ALvoid ALUTAPIENTRY alutUnloadWAV(ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
{
if (data)
free(data);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// AL_MAIN functions
AL_API ALvoid AL_APIENTRY alInit(ALint *argc, ALubyte **argv)
{
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AL_API ALvoid AL_APIENTRY alExit(void)
{
}
#ifdef __cplusplus
}
#endif
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark ***** OALRingBuffer *****
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// count the leading zeroes in a word
static __inline__ int CountLeadingZeroes(int arg) {
#if TARGET_CPU_X86 || TARGET_CPU_X86_64
__asm__ volatile(
"bsrl %0, %0\n\t"
"movl $63, %%ecx\n\t"
"cmove %%ecx, %0\n\t"
"xorl $31, %0"
: "=r" (arg)
: "0" (arg)
);
#elif TARGET_CPU_PPC || TARGET_CPU_PPC64
__asm__ volatile("cntlzw %0, %1" : "=r" (arg) : "r" (arg));
#else
#error "ERROR - assembly instructions for counting leading zeroes not present"
#endif
return arg;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// base 2 log of next power of two greater or equal to x
inline UInt32 Log2Ceil(UInt32 x)
{
return 32 - CountLeadingZeroes(x - 1);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// next power of two greater or equal to x
inline UInt32 NextPowerOfTwo(UInt32 x)
{
return 1L << Log2Ceil(x);
}

53
Source/OpenAL/oalOSX.h Normal file
View File

@ -0,0 +1,53 @@
/**********************************************************************************************************************************
*
* OpenAL cross platform audio library
* Copyright (c) 2004, Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************************************************************************/
#ifndef __OAL_OSX__
#define __OAL_OSX__
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <Carbon/Carbon.h>
#include <AudioToolbox/AudioToolbox.h>
#include "CAStreamBasicDescription.h"
#include "oalImp.h"
#include "MacOSX_OALExtensions.h"
#define maxLen 256
bool IsFormatSupported(UInt32 inFormatID);
OSStatus FillInASBD(CAStreamBasicDescription &inASBD, UInt32 inFormatID, UInt32 inSampleRate);
bool IsValidRenderQuality (UInt32 inRenderQuality);
UInt32 GetDesiredRenderChannelsFor3DMixer(UInt32 inDeviceChannels);
void GetDefaultDeviceName(ALCchar* outDeviceName, bool isInput);
uintptr_t GetNewPtrToken (void);
ALuint GetNewToken (void);
UInt32 CalculateNeededMixerBusses(const ALCint *attrList, UInt32 inDefaultBusCount);
const char* GetFormatString(UInt32 inToken);
const char* GetALAttributeString(UInt32 inToken);
const char* GetALCAttributeString(UInt32 inToken);
void WaitOneRenderCycle();
void ReconfigureContextsOfThisDevice(uintptr_t inDeviceToken);
#endif

View File

@ -0,0 +1,167 @@
/**********************************************************************************************************************************
*
* OpenAL cross platform audio library
* Copyright (c) 2004, Apple Computer, Inc., Copyright (c) 2012, Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Inc. ("Apple") nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************************************************************************/
#include "oalRingBuffer.h"
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark ***** OALRingBuffer *****
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OALRingBuffer::OALRingBuffer() : mBuffer(NULL), mCapacityFrames(0), mCapacityBytes(0)
{
}
OALRingBuffer::OALRingBuffer(UInt32 bytesPerFrame, UInt32 capacityFrames) :
mBuffer(NULL)
{
Allocate(bytesPerFrame, capacityFrames);
}
OALRingBuffer::~OALRingBuffer()
{
Deallocate();
}
void OALRingBuffer::Allocate(UInt32 bytesPerFrame, UInt32 capacityFrames)
{
Deallocate();
mBytesPerFrame = bytesPerFrame;
mCapacityFrames = capacityFrames;
mCapacityBytes = bytesPerFrame * capacityFrames;
mBuffer = (Byte *)malloc(mCapacityBytes);
Clear();
}
void OALRingBuffer::Deallocate()
{
if (mBuffer) {
free(mBuffer);
mBuffer = NULL;
}
mCapacityBytes = 0;
mCapacityFrames = 0;
Clear();
}
void OALRingBuffer::Clear()
{
if (mBuffer)
memset(mBuffer, 0, mCapacityBytes);
mStartOffset = 0;
mStartFrame = 0;
mEndFrame = 0;
}
bool OALRingBuffer::Store(const Byte *data, UInt32 nFrames, SInt64 startFrame)
{
if (nFrames > mCapacityFrames) return false;
// reading and writing could well be in separate threads
SInt64 endFrame = startFrame + nFrames;
if (startFrame >= mEndFrame + mCapacityFrames)
// writing more than one buffer ahead -- fine but that means that everything we have is now too far in the past
Clear();
if (mStartFrame == 0) {
// empty buffer
mStartOffset = 0;
mStartFrame = startFrame;
mEndFrame = endFrame;
memcpy(mBuffer, data, nFrames * mBytesPerFrame);
} else {
UInt32 offset0, offset1, nBytes;
if (endFrame > mEndFrame) {
// advancing (as will be usual with sequential stores)
if (startFrame > mEndFrame) {
// we are skipping some samples, so zero the range we are skipping
offset0 = FrameOffset(mEndFrame);
offset1 = FrameOffset(startFrame);
if (offset0 < offset1)
memset(mBuffer + offset0, 0, offset1 - offset0);
else {
nBytes = mCapacityBytes - offset0;
memset(mBuffer + offset0, 0, nBytes);
memset(mBuffer, 0, offset1);
}
}
mEndFrame = endFrame;
// except for the case of not having wrapped yet, we will normally
// have to advance the start
SInt64 newStart = mEndFrame - mCapacityFrames;
if (newStart > mStartFrame) {
mStartOffset = (mStartOffset + (newStart - mStartFrame) * mBytesPerFrame) % mCapacityBytes;
mStartFrame = newStart;
}
}
// now everything is lined up and we can just write the new data
offset0 = FrameOffset(startFrame);
offset1 = FrameOffset(endFrame);
if (offset0 < offset1)
memcpy(mBuffer + offset0, data, offset1 - offset0);
else {
nBytes = mCapacityBytes - offset0;
memcpy(mBuffer + offset0, data, nBytes);
memcpy(mBuffer, data + nBytes, offset1);
}
}
return true;
}
OSStatus OALRingBuffer::Fetch(Byte *data, UInt32 nFrames, SInt64 startFrame)
{
SInt64 endFrame = startFrame + nFrames;
if (startFrame < mStartFrame || endFrame > mEndFrame) {
return -1;
}
UInt32 offset0 = FrameOffset(startFrame);
UInt32 offset1 = FrameOffset(endFrame);
if (offset0 < offset1)
memcpy(data, mBuffer + offset0, offset1 - offset0);
else {
UInt32 nBytes = mCapacityBytes - offset0;
memcpy(data, mBuffer + offset0, nBytes);
memcpy(data + nBytes, mBuffer, offset1);
}
return noErr;
}
Byte * OALRingBuffer::GetFramePtr(SInt64 frameNumber, UInt32 &outNFrames)
{
if (frameNumber < mStartFrame || frameNumber >= mEndFrame) {
outNFrames = 0;
return NULL;
}
UInt32 offset0 = FrameOffset(frameNumber);
UInt32 offset1 = FrameOffset(mEndFrame);
if (offset0 < offset1) {
outNFrames = static_cast<UInt32>(mEndFrame - frameNumber);
} else {
outNFrames = (mCapacityBytes - offset0) / mBytesPerFrame;
}
return mBuffer + offset0;
}

View File

@ -0,0 +1,84 @@
/**********************************************************************************************************************************
*
* OpenAL cross platform audio library
* Copyright (c) 2004, Apple Computer, Inc., Copyright (c) 2012, Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Inc. ("Apple") nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************************************************************************/
#include <AudioToolbox/AudioToolbox.h>
#ifndef __OpenAL_Aspen__oalRingBuffer__
#define __OpenAL_Aspen__oalRingBuffer__
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark _____OALRingBuffer_____
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// OALRingBuffer:
// This class implements an audio ring buffer. Multi-channel data can be either
// interleaved or deinterleaved.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
enum {
kOALRingBufferError_WayBehind = -2, // both fetch times are earlier than buffer start time
kOALRingBufferError_SlightlyBehind = -1, // fetch start time is earlier than buffer start time (fetch end time OK)
kOALRingBufferError_OK = 0,
kOALRingBufferError_SlightlyAhead = 1, // fetch end time is later than buffer end time (fetch start time OK)
kOALRingBufferError_WayAhead = 2, // both fetch times are later than buffer end time
kOALRingBufferError_TooMuch = 3, // fetch start time is earlier than buffer start time and fetch end time is later than buffer end time
kOALRingBufferError_CPUOverload = 4 // the reader is unable to get enough CPU cycles to capture a consistent snapshot of the time bounds
};
typedef SInt32 OALRingBufferError;
typedef SInt64 SampleTime;
const UInt32 kGeneralRingTimeBoundsQueueSize = 32;
const UInt32 kGeneralRingTimeBoundsQueueMask = kGeneralRingTimeBoundsQueueSize - 1;
class OALRingBuffer {
public:
OALRingBuffer();
OALRingBuffer(UInt32 bytesPerFrame, UInt32 capacityFrames);
~OALRingBuffer();
void Allocate(UInt32 bytesPerFrame, UInt32 capacityFrames);
void Deallocate();
void Clear();
bool Store(const Byte *data, UInt32 nFrames, SInt64 frameNumber);
OSStatus Fetch(Byte *data, UInt32 nFrames, SInt64 frameNumber);
Byte* GetFramePtr(SInt64 frameNumber, UInt32 &outNFrames);
void GetTimeBounds(SInt64 &start, SInt64&end) { start = mStartFrame; end = mEndFrame; }
protected:
UInt32 FrameOffset(SInt64 frameNumber) { return (mStartOffset + UInt32(frameNumber - mStartFrame) * mBytesPerFrame) % mCapacityBytes; }
protected:
Byte * mBuffer;
UInt32 mBytesPerFrame;
UInt32 mCapacityFrames;
UInt32 mCapacityBytes;
UInt32 mStartOffset;
SInt64 mStartFrame;
SInt64 mEndFrame;
};
#endif /* defined(__OpenAL_Aspen__oalRingBuffer__) */

4749
Source/OpenAL/oalSource.cpp Normal file

File diff suppressed because it is too large Load Diff

835
Source/OpenAL/oalSource.h Normal file
View File

@ -0,0 +1,835 @@
/**********************************************************************************************************************************
*
* OpenAL cross platform audio library
* Copyright (c) 2004, Apple Computer, Inc., Copyright (c) 2012, Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Inc. ("Apple") nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************************************************************************/
#ifndef __OAL_SOURCE__
#define __OAL_SOURCE__
#include "oalImp.h"
#include "oalDevice.h"
#include "oalContext.h"
#include "al.h"
#include <Carbon/Carbon.h>
#include <AudioToolbox/AudioConverter.h>
#include <list>
#include <libkern/OSAtomic.h>
#include <vector>
#include <queue>
#include <dispatch/dispatch.h>
#include "CAStreamBasicDescription.h"
#include "CAAtomicStack.h"
#include "CAGuard.h"
class OALBuffer; // forward declaration
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// buffer info state constants
enum {
kSecondsOffset = 1,
kSampleOffset = 2,
kByteOffset = 3
};
enum {
kPendingProcessing = 0,
kInProgress = 1,
kProcessed = 2
};
enum {
kRampingComplete = -2,
kRampDown = -1,
kNoRamping = 0,
kRampUp = 1
};
enum {
kMQ_NoMessage = 0,
kMQ_Stop = 1,
kMQ_Rewind = 2,
kMQ_SetBuffer = 3,
kMQ_Play = 4,
kMQ_Pause = 5,
kMQ_Resume = 6,
kMQ_SetFramePosition = 7,
kMQ_ClearBuffersFromQueue = 8,
kMQ_DeconstructionStop = 9,
kMQ_Retrigger = 10,
kMQ_AddBuffersToQueue = 11
};
#define OALSourceError_CallConverterAgain 'agan'
#define kSourceNeedsBus -1
// do not change kDistanceScalar from 10.0 - it is used to compensate for a reverb related problem in the 3DMixer
#define kDistanceScalar 10.0
#define kTransitionToStop 0XDD01
#define kTransitionToPlay 0XDD02
#define kTransitionToPause 0XDD03
#define kTransitionToRewind 0XDD04
#define kTransitionToRetrigger 0XDD05
#define kTransitionToResume 0XDD06
#pragma mark _____PlaybackMessage_____
class PlaybackMessage {
public:
PlaybackMessage(UInt32 inMessage, OALBuffer* inBuffer, UInt32 inNumBuffers) :
mMessageID(inMessage),
mBuffer(inBuffer),
mNumBuffers(inNumBuffers)
{ };
~PlaybackMessage(){};
PlaybackMessage* mNext;
UInt32 mMessageID;
OALBuffer* mBuffer;
UInt32 mNumBuffers;
PlaybackMessage *& next() { return mNext; }
void set_next(PlaybackMessage *next) { mNext = next; }
};
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark _____BufferQueue_____
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// This struct is used by OAL source to store info about the buffers in it's queue
struct BufferInfo {
ALuint mBufferToken; // the buffer name that the user was returned when the buffer was created
OALBuffer *mBuffer; // buffer object
UInt32 mOffset; // current read position offset of this data
UInt32 mProcessedState; // mark as true when data of this buffer is finished playing and looping is off
ALuint mACToken; // use this AC from the ACMap for converting the data to the mixer format, when
// set to zero, then NO AC is needed, the data has already been converted
};
class BufferQueue : std::vector<BufferInfo> {
public:
BufferQueue() { mBufferQueueSize = 0;}
void AppendBuffer(OALSource* thisSource, ALuint inBufferToken, OALBuffer *inBuffer, ALuint inACToken);
ALuint RemoveQueueEntryByIndex(OALSource* thisSource, UInt32 inIndex, bool inReleaseIt);
UInt32 GetQueueSizeInFrames() ;
UInt32 GetBufferFrameCount(UInt32 inBufferIndex);
void SetFirstBufferOffset(UInt32 inFrameOffset) ;
ALuint GetBufferTokenByIndex(UInt32 inBufferIndex);
UInt32 GetCurrentFrame(UInt32 inBufferIndex);
BufferInfo* Get(short inBufferIndex) {
iterator it = begin();
std::advance(it, inBufferIndex);
if (it != end())
return(&(*it));
return (NULL);
}
void SetBufferAsProcessed(UInt32 inBufferIndex) {
iterator it = begin();
std::advance(it, inBufferIndex);
if (it != end())
it->mProcessedState = kProcessed;
}
// mark all the buffers in the queue as unprocessed and offset 0
void ResetBuffers() {
iterator it = begin();
while (it != end())
{
it->mProcessedState = kPendingProcessing;
it->mOffset = 0;
++it;
}
}
UInt32 GetQueueSize () { return mBufferQueueSize; }
void SetQueueSize () { mBufferQueueSize = Size(); }
bool Empty () const { return empty(); }
void Reserve(UInt32 reserveSize) {return reserve(reserveSize); }
private:
UInt32 GetPacketSize() ;
UInt32 FrameOffsetToPacketOffset(UInt32 inFrameOffset);
UInt32 Size () const { return size(); }
volatile int32_t mBufferQueueSize; // shadow variable to store the size of the queue
};
typedef BufferQueue BufferQueue;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark _____ACMap_____
// ACMap - map the AudioConverters for the sources queue
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// This struct is used by OAL source to store info about the ACs used by it's queue
struct ACInfo {
AudioConverterRef mConverter;
CAStreamBasicDescription mInputFormat;
};
class ACMap : std::multimap<ALuint, ACInfo, std::less<ALuint> > {
public:
// add a new context to the map
void Add (const ALuint inACToken, ACInfo *inACInfo) {
iterator it = upper_bound(inACToken);
insert(it, value_type (inACToken, *inACInfo));
}
AudioConverterRef Get(ALuint inACToken) {
const_iterator it = find(inACToken);
iterator theEnd = end();
if (it != theEnd)
return ((*it).second.mConverter);
return (NULL);
}
void GetACForFormat (CAStreamBasicDescription* inFormat, ALuint &outToken) {
iterator it = begin();
outToken = 0; // 0 means there is none yet
while (it != end()) {
if( (*it).second.mInputFormat == *inFormat) {
outToken = (*it).first;
it = end();
}
else
++it;
}
return;
}
void Remove (const ALuint inACToken) {
iterator it = find(inACToken);
if (it != end()) {
AudioConverterDispose((*it).second.mConverter);
erase(it);
}
}
// the map should be disposed after making this call
void RemoveAllConverters () {
iterator it = begin();
iterator theEnd = end();
while (it != theEnd) {
AudioConverterDispose((*it).second.mConverter);
++it;
}
}
UInt32 Size () const { return size(); }
bool Empty () const { return empty(); }
};
typedef ACMap ACMap;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark _____SourceNotifyInfo_____
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class SourceNotifyInfo
{
public:
SourceNotifyInfo()
: mID(0),
mProc(0),
mUserData(0)
{}
friend class SourceNotifications;
private:
ALuint mID;
alSourceNotificationProc mProc;
void *mUserData;
};
class SourceNotifications : public std::vector<SourceNotifyInfo>
{
public:
SourceNotifications(ALuint inSourceID)
: mSourceToken(inSourceID)
{
mNotifyMutex = new CAMutex("Notifcation Mutex");
}
~SourceNotifications()
{
delete mNotifyMutex;
}
OSStatus AddSourceNotification(ALuint inID, alSourceNotificationProc inProc, void *inUserData)
{
CAMutex::Locker lock(*mNotifyMutex);
return AddSourceNotificationImp(inID, inProc, inUserData);
}
OSStatus RemoveSourceNotification(ALuint inID, alSourceNotificationProc inProc, void *inUserData)
{
CAMutex::Locker lock(*mNotifyMutex);
return RemoveSourceNotificationImp(inID, inProc, inUserData);
}
OSStatus RemoveAllSourceNotifications(ALuint inID)
{
CAMutex::Locker lock(*mNotifyMutex);
return RemoveAllSourceNotificationsImp(inID);
}
void CallSourceNotifications(ALuint inID)
{
if (mNotifyMutex != NULL) {
CAMutex::Locker lock(*mNotifyMutex);
return CallSourceNotificationsImp(inID);
}
}
private:
const SourceNotifications::iterator FindNotificationInfo(ALuint inID, alSourceNotificationProc inProc, void *inUserData)
{
SourceNotifications::iterator it;
for (it = begin(); it != end(); ++it) {
if ((it->mID == inID) && (it->mProc == inProc) && (it->mUserData == inUserData))
return it;
}
return it; // end()
}
OSStatus AddSourceNotificationImp(ALuint inID, alSourceNotificationProc inProc, void *inUserData)
{
OSStatus status = noErr;
SourceNotifications::iterator it = FindNotificationInfo(inID, inProc, inUserData);
if (it == end()) {
SourceNotifyInfo info;
info.mID = inID;
info.mProc = inProc;
info.mUserData = inUserData;
push_back(info);
}
else {
status = -50;
}
return status;
}
OSStatus RemoveSourceNotificationImp(ALuint inID, alSourceNotificationProc inProc, void *inUserData)
{
OSStatus status = noErr;
SourceNotifications::iterator it = FindNotificationInfo(inID, inProc, inUserData);
if (it != end())
{
erase(it);
for (it = begin(); it != end(); ++it) {
if (it->mID == inID)
break;
}
}
else {
status = -50;
}
return status;
}
OSStatus RemoveAllSourceNotificationsImp(ALuint inID)
{
SourceNotifications::iterator it;
for (int index = size() - 1; index >= 0; index--)
{
it = begin() + index;
if (it->mID == inID)
erase(it);
}
OSStatus status = noErr;
return status;
}
void CallSourceNotificationsImp(ALuint inID)
{
SourceNotifications::iterator it;
for (it = begin(); it != end(); ++it)
if (it->mID == inID)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
it->mProc(mSourceToken, inID, it->mUserData);
});
}
}
CAMutex* mNotifyMutex;
ALuint mSourceToken;
};
#pragma mark _____OALRenderLocker_____
class OALRenderLocker {
int mAcquireFlag, mTryFlag;
OALRenderLocker& operator= (const OALRenderLocker& as) { return *this; }
OALRenderLocker (const OALRenderLocker& as) {}
public:
OALRenderLocker () : mAcquireFlag(0), mTryFlag (0) {}
class RenderLocker {
OALRenderLocker &mEditor;
bool mInRenderThread;
public:
RenderLocker (OALRenderLocker &editor, bool inRenderThread)
: mEditor(editor),
mInRenderThread(inRenderThread)
{
if (!mInRenderThread)
{
OSAtomicIncrement32Barrier(&mEditor.mAcquireFlag);
while (mEditor.mTryFlag) { usleep(500); }
}
}
~RenderLocker ()
{
if (!mInRenderThread)
{
OSAtomicDecrement32Barrier (&mEditor.mAcquireFlag);
}
}
};
class RenderTryer {
OALRenderLocker &mTrier;
public:
RenderTryer (OALRenderLocker & trier)
: mTrier (trier)
{
OSAtomicIncrement32Barrier(&mTrier.mTryFlag);
}
~RenderTryer ()
{
OSAtomicDecrement32Barrier (&mTrier.mTryFlag);
}
bool Acquired () const { return !mTrier.mAcquireFlag; }
};
};
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// OALSources
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark _____OALSource_____
class OALSource
{
#pragma mark __________ PRIVATE __________
private:
ALuint mSelfToken; // the token returned to the caller upon alGenSources()
bool mSafeForDeletion;
OALContext *mOwningContext;
bool mIsSuspended;
bool mCalculateDistance;
bool mResetBusFormat;
bool mResetBus;
bool mResetPitch;
BufferQueue *mBufferQueueActive; // map of buffers for queueing
BufferQueue *mBufferQueueInactive; // map of buffers already queued
BufferQueue *mBufferQueueTemp; // map of buffers for temporary queueing
volatile int32_t mQueueLength; // snapshot of the queue length (mBufferQueueActive + mBufferQueueInactive)
volatile int32_t mTempQueueLength; // queue length returned when source is transitioning to flush Qs
UInt32 mBuffersQueuedForClear; // number of buffers pending removal from the inactive queue
ALuint mCurrentBufferIndex; // index of the current buffer being played
bool mQueueIsProcessed; // state of the entire buffer queue
volatile int32_t mInUseFlag; // flag to indicate a source is currently being used by one or more threads
CAGuard mSourceLock;
AURenderCallbackStruct mPlayCallback;
int mCurrentPlayBus; // the mixer bus currently used by this source
ACMap *mACMap;
bool mOutputSilence;
Float32 mPosition[3];
Float32 mVelocity[3];
Float32 mConeDirection[3];
UInt32 mLooping;
UInt32 mSourceRelative;
UInt32 mSourceType;
Float32 mConeInnerAngle;
Float32 mConeOuterAngle;
Float32 mConeOuterGain;
// Gain Scalers
Float32 mConeGainScaler;
Float32 mAttenuationGainScaler;
// support for pre 2.0 3DMixer
float mReadIndex;
float mCachedInputL1;
float mCachedInputL2;
float mCachedInputR1;
float mCachedInputR2;
UInt32 mTempSourceStorageBufferSize;
AudioBufferList *mTempSourceStorage;
UInt32 mState; // playback state: Playing, Stopped, Paused, Initial, Transitioning (to stop)
float mGain;
Float32 mPitch;
Float32 mDopplerScaler;
Float32 mRollOffFactor;
Float32 mReferenceDistance;
Float32 mMaxDistance;
Float32 mMinGain;
Float32 mMaxGain;
SInt32 mRampState;
UInt32 mBufferCountToUnqueueInPostRender;
bool mTransitioningToFlushQ;
UInt32 mPlaybackHeadPosition; // stored for a deferred repositioning of playbackHead as a frame index
Float32 mASAReverbSendLevel;
Float32 mASAOcclusion;
Float32 mASAObstruction;
UInt32 mRenderQuality;
// thread protection
OALRenderLocker mRenderLocker;
// Audio Units and properties for RogerBeep and Distortion
AUNode mRogerBeepNode;
AudioUnit mRogerBeepAU;
Boolean mASARogerBeepEnable;
Boolean mASARogerBeepOn;
Float32 mASARogerBeepGain;
SInt32 mASARogerBeepSensitivity;
SInt32 mASARogerBeepType;
char* mASARogerBeepPreset;
AUNode mDistortionNode;
AudioUnit mDistortionAU;
Boolean mASADistortionEnable;
Boolean mASADistortionOn;
Float32 mASADistortionMix;
SInt32 mASADistortionType;
char* mASADistortionPreset;
AudioUnit mRenderUnit;
UInt32 mRenderElement;
SourceNotifications* mSourceNotifications;
typedef TAtomicStack<PlaybackMessage> PlaybackMessageList;
PlaybackMessageList mMessageQueue;
void JoinBufferLists();
void LoopToBeginning();
void ChangeChannelSettings();
void InitSource();
void SetState(UInt32 inState);
OSStatus DoRender (AudioBufferList *ioData);
OSStatus DoSRCRender (AudioBufferList *ioData); // support for pre 2.0 3DMixer
bool ConeAttenuation();
void CalculateDistanceAndAzimuth(Float32 *outDistance, Float32 *outAzimuth, Float32 *outElevation, Float32 *outDopplerShift);
void UpdateBusGain ();
void UpdateMinBusGain ();
void UpdateMaxBusGain ();
void UpdateBusFormat ();
void UpdateBusRenderQuality ();
void UpdateBusReverb ();
void UpdateBusOcclusion ();
void UpdateBusObstruction ();
void UpdateQueue ();
void RampDown (AudioBufferList *ioData);
void RampUp (AudioBufferList *ioData);
void ClearActiveQueue();
void AddNotifyAndRenderProcs();
void ReleaseNotifyAndRenderProcs();
void DisconnectFromBus();
void SetupMixerBus();
void ResetMixerBus();
void SetupDistortionAU();
void SetupRogerBeepAU();
bool PrepBufferQueueForPlayback();
UInt32 SecondsToFrames(Float32 inSeconds);
UInt32 BytesToFrames(Float32 inBytes);
void AppendBufferToQueue(ALuint inBufferToken, OALBuffer *inBuffer);
UInt32 FramesToSecondsInt(UInt32 inFrames);
Float32 FramesToSecondsFloat(UInt32 inFrames);
UInt32 FramesToBytes(UInt32 inFrames);
void PostRenderSetBuffer(ALuint inBufferToken, OALBuffer *inBuffer);
void PostRenderAddBuffersToQueue(UInt32 inNumBuffersToQueue);
void PostRenderRemoveBuffersFromQueue(UInt32 inBuffersToUnqueue);
void FlushBufferQueue();
void FlushTempBufferQueue();
void AdvanceQueueToFrameIndex(UInt32 inFrameOffset);
OSStatus SetDistanceParams(bool inChangeReferenceDistance, bool inChangeMaxDistance);
Float32 GetMaxAttenuation(Float32 inRefDistance, Float32 inMaxDistance, Float32 inRolloff);
BufferInfo* NextPlayableBufferInActiveQ();
inline bool InRenderThread() { return mOwningContext->CallingInRenderThread(); }
void SetQueueLength() { mQueueLength = mBufferQueueActive->GetQueueSize() + mBufferQueueInactive->GetQueueSize() - mBuffersQueuedForClear; }
/*
OSStatus MuteCurrentPlayBus () const
{
return AudioUnitSetParameter ( mOwningContext->GetMixerUnit(), k3DMixerParam_Gain, kAudioUnitScope_Input, mCurrentPlayBus, 0.0, 0);
}
*/
static OSStatus SourceNotificationProc (void *inRefCon,
AudioUnitRenderActionFlags *inActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData);
static OSStatus SourceInputProc ( void *inRefCon,
AudioUnitRenderActionFlags *inActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData);
static OSStatus ACComplexInputDataProc ( AudioConverterRef inAudioConverter,
UInt32 *ioNumberDataPackets,
AudioBufferList *ioData,
AudioStreamPacketDescription **outDataPacketDescription,
void* inUserData);
#pragma mark __________ PUBLIC __________
public:
OALSource(ALuint inSelfToken, OALContext *inOwningContext);
~OALSource();
// set info methods - these may be called from either the render thread or the API caller
void SetPitch (Float32 inPitch);
void SetGain (Float32 inGain);
void SetMinGain (Float32 inMinGain);
void SetMaxGain (Float32 inMaxGain);
void SetReferenceDistance (Float32 inReferenceDistance);
void SetMaxDistance (Float32 inMaxDistance);
void SetRollOffFactor (Float32 inRollOffFactor);
void SetLooping (UInt32 inLooping);
void SetPosition (Float32 inX, Float32 inY, Float32 inZ);
void SetVelocity (Float32 inX, Float32 inY, Float32 inZ);
void SetDirection (Float32 inX, Float32 inY, Float32 inZ);
void SetSourceRelative (UInt32 inSourceRelative);
void SetChannelParameters ();
void SetConeInnerAngle (Float32 inConeInnerAngle);
void SetConeOuterAngle (Float32 inConeOuterAngle);
void SetConeOuterGain (Float32 inConeOuterGain);
void SetQueueOffset(UInt32 inOffsetType, Float32 inSecondOffset);
void SetUpDeconstruction();
// get info methods
Float32 GetPitch ();
Float32 GetDopplerScaler ();
Float32 GetGain ();
Float32 GetMinGain ();
Float32 GetMaxGain ();
Float32 GetReferenceDistance ();
Float32 GetMaxDistance ();
Float32 GetRollOffFactor ();
UInt32 GetLooping ();
void GetPosition (Float32 &inX, Float32 &inY, Float32 &inZ);
void GetVelocity (Float32 &inX, Float32 &inY, Float32 &inZ);
void GetDirection (Float32 &inX, Float32 &inY, Float32 &inZ);
UInt32 GetSourceRelative ();
UInt32 GetSourceType ();
Float32 GetConeInnerAngle ();
Float32 GetConeOuterAngle ();
Float32 GetConeOuterGain ();
UInt32 GetState();
ALuint GetToken();
UInt32 GetQueueFrameOffset();
UInt32 GetQueueOffset(UInt32 inOffsetType);
Float32 GetQueueOffsetSecondsFloat();
// thread safety
void SetInUseFlag() { OSAtomicIncrement32Barrier(&mInUseFlag); }
void ClearInUseFlag() { OSAtomicDecrement32Barrier(&mInUseFlag); }
// buffer queue
UInt32 GetQLengthPriv();
UInt32 GetQLength();
UInt32 GetBuffersProcessed();
void SetBuffer (ALuint inBufferToken, OALBuffer *inBuffer);
ALuint GetBuffer ();
void AddToQueue(ALuint inBufferToken, OALBuffer *inBuffer);
void AddToTempQueue(ALuint inBufferToken, OALBuffer *inBuffer);
void RemoveBuffersFromQueue(UInt32 inCount, ALuint *outBufferTokens);
bool IsSourceTransitioningToFlushQ();
bool IsSafeForDeletion () { return (mSafeForDeletion && (mInUseFlag <= 0) && mSourceLock.IsFree()); }
// source notification methods
ALenum AddNotification(ALuint notificationID, alSourceNotificationProc notifyProc, ALvoid* userData);
void RemoveNotification(ALuint notificationID, alSourceNotificationProc notifyProc, ALvoid* userData);
// source spatialization methods
OSStatus SetRenderQuality(ALuint inValue);
ALint GetRenderQuality();
// notification methods
void ClearMessageQueue();
void SwapBufferQueues();
void AddPlaybackMessage(UInt32 inMessage, OALBuffer* inBuffer, UInt32 inNumBuffers);
void SetPlaybackState(ALuint inState, bool sendSourceStateChangeNotification=false);
OSStatus DoPreRender ();
OSStatus DoPostRender ();
// playback methods
void Play();
void Pause();
void Resume();
void Rewind();
void Stop();
void Suspend();
void Unsuspend();
// ASA methods
void SetReverbSendLevel(Float32 inReverbLevel);
void SetOcclusion(Float32 inOcclusion);
void SetObstruction(Float32 inObstruction);
void SetRogerBeepEnable(Boolean inEnable);
void SetRogerBeepOn(Boolean inOn);
void SetRogerBeepGain(Float32 inGain);
void SetRogerBeepSensitivity(SInt32 inSensitivity);
void SetRogerBeepType(SInt32 inType);
void SetRogerBeepPreset(FSRef* inRef);
void SetDistortionEnable(Boolean inEnable);
void SetDistortionOn(Boolean inOn);
void SetDistortionMix(Float32 inMix);
void SetDistortionType(SInt32 inType);
void SetDistortionPreset(FSRef* inRef);
Float32 GetReverbSendLevel() {return mASAReverbSendLevel;}
Float32 GetOcclusion() {return mASAOcclusion;}
Float32 GetObstruction() {return mASAObstruction;}
Boolean GetRogerBeepEnable() {return mASARogerBeepEnable;}
Boolean GetRogerBeepOn() {return mASARogerBeepOn;}
Float32 GetRogerBeepGain() {return mASARogerBeepGain;}
UInt32 GetRogerBeepSensitivity() {return mASARogerBeepSensitivity;}
UInt32 GetRogerBeepType() {return mASARogerBeepType;}
Boolean GetDistortionEnable() {return mASADistortionEnable;}
Boolean GetDistortionOn() {return mASADistortionOn;}
Float32 GetDistortionMix() {return mASADistortionMix;}
SInt32 GetDistortionType() {return mASADistortionType;}
};
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark _____OALSourceMap_____
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class OALSourceMap : std::multimap<ALuint, OALSource*, std::less<ALuint> > {
public:
// add a new context to the map
void Add (const ALuint inSourceToken, OALSource **inSource) {
iterator it = upper_bound(inSourceToken);
insert(it, value_type (inSourceToken, *inSource));
}
OALSource* GetSourceByIndex(UInt32 inIndex) {
iterator it = begin();
for (UInt32 i = 0; i < inIndex; i++) {
if (it != end())
++it;
else
i = inIndex;
}
if (it != end())
return ((*it).second);
return (NULL);
}
OALSource* Get(ALuint inSourceToken) {
iterator it = find(inSourceToken);
if (it != end())
return ((*it).second);
return (NULL);
}
void MarkAllSourcesForRecalculation() {
iterator it = begin();
while (it != end()) {
(*it).second->SetChannelParameters();
++it;
}
return;
}
void SuspendAllSources() {
iterator it = begin();
while (it != end())
{
(*it).second->Suspend();
++it;
}
return;
}
void UnsuspendAllSources() {
iterator it = begin();
while (it != end())
{
(*it).second->Unsuspend();
++it;
}
return;
}
void Remove (const ALuint inSourceToken) {
iterator it = find(inSourceToken);
if (it != end())
erase(it);
}
UInt32 Size () const { return size(); }
bool Empty () const { return empty(); }
};
#endif

9
notifications.json Normal file
View File

@ -0,0 +1,9 @@
{
"rules": [{
"notifications": [{
"address" : "img-audio-checkins@group.apple.com",
"prefix" : "[OpenAL]",
"includeDiff" : true
}]
}]
}