apple: Add primitive core audio support
Also made the project xcode 7 friendly
This commit is contained in:
parent
72f51f4f0e
commit
4282395528
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
Simple Core Audio backend for osx (and maybe ios?)
|
||||
Based off various audio core samples and dolphin's code
|
||||
|
||||
This is part of the Reicast project, please consult the
|
||||
LICENSE file for licensing & related information
|
||||
|
||||
This could do with some locking logic to avoid
|
||||
race conditions, and some variable length buffer
|
||||
logic to support chunk sizes other than 512 bytes
|
||||
|
||||
It does work on my macmini though
|
||||
*/
|
||||
|
||||
#include "oslib/audiobackend_coreaudio.h"
|
||||
|
||||
#if HOST_OS == OS_DARWIN
|
||||
|
||||
//#include <CoreAudio/CoreAudio.h>
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
|
||||
AudioUnit audioUnit;
|
||||
|
||||
u8 samples_temp[1024 * 4];
|
||||
|
||||
volatile int samples_ptr = 0;
|
||||
|
||||
OSStatus coreaudio_callback(void* ctx, AudioUnitRenderActionFlags* flags, const AudioTimeStamp* ts,
|
||||
UInt32 bus, UInt32 frames, AudioBufferList* abl)
|
||||
{
|
||||
verify(frames <= 1024);
|
||||
|
||||
u8* src = samples_temp;
|
||||
|
||||
for (int i = 0; i < abl->mNumberBuffers; i++) {
|
||||
memcpy(abl->mBuffers[i].mData, src, abl->mBuffers[i].mDataByteSize);
|
||||
src += abl->mBuffers[i].mDataByteSize;
|
||||
}
|
||||
|
||||
samples_ptr -= frames * 2 * 2;
|
||||
|
||||
if (samples_ptr < 0)
|
||||
samples_ptr = 0;
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
// We're making these functions static - there's no need to pollute the global namespace
|
||||
static void coreaudio_init()
|
||||
{
|
||||
OSStatus err;
|
||||
AURenderCallbackStruct callback_struct;
|
||||
AudioStreamBasicDescription format;
|
||||
AudioComponentDescription desc;
|
||||
AudioComponent component;
|
||||
|
||||
desc.componentType = kAudioUnitType_Output;
|
||||
#if !defined(TARGET_IPHONE)
|
||||
desc.componentSubType = kAudioUnitSubType_DefaultOutput;
|
||||
#else
|
||||
desc.componentSubType = kAudioUnitSubType_RemoteIO;
|
||||
#endif
|
||||
//desc.componentSubType = kAudioUnitSubType_GenericOutput;
|
||||
desc.componentFlags = 0;
|
||||
desc.componentFlagsMask = 0;
|
||||
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||
component = AudioComponentFindNext(nullptr, &desc);
|
||||
|
||||
verify(component != nullptr);
|
||||
|
||||
err = AudioComponentInstanceNew(component, &audioUnit);
|
||||
verify(err == noErr);
|
||||
|
||||
FillOutASBDForLPCM(format, 44100,
|
||||
2, 16, 16, false, false, false);
|
||||
err = AudioUnitSetProperty(audioUnit,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input, 0, &format,
|
||||
sizeof(AudioStreamBasicDescription));
|
||||
verify(err == noErr);
|
||||
|
||||
callback_struct.inputProc = coreaudio_callback;
|
||||
callback_struct.inputProcRefCon = 0;
|
||||
err = AudioUnitSetProperty(audioUnit,
|
||||
kAudioUnitProperty_SetRenderCallback,
|
||||
kAudioUnitScope_Input, 0, &callback_struct,
|
||||
sizeof callback_struct);
|
||||
verify(err == noErr);
|
||||
|
||||
/*
|
||||
err = AudioUnitSetParameter(audioUnit,
|
||||
kHALOutputParam_Volume,
|
||||
kAudioUnitParameterFlag_Output, 0,
|
||||
1, 0);
|
||||
verify(err == noErr);
|
||||
|
||||
*/
|
||||
|
||||
err = AudioUnitInitialize(audioUnit);
|
||||
|
||||
verify(err == noErr);
|
||||
|
||||
err = AudioOutputUnitStart(audioUnit);
|
||||
|
||||
verify(err == noErr);
|
||||
}
|
||||
|
||||
static u32 coreaudio_push(void* frame, u32 samples, bool wait)
|
||||
{
|
||||
/* Yeah, right */
|
||||
while (samples_ptr != 0 && wait) ;
|
||||
|
||||
if (samples_ptr == 0) {
|
||||
memcpy(&samples_temp[samples_ptr], frame, samples * 4);
|
||||
samples_ptr += samples * 4;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void coreaudio_term()
|
||||
{
|
||||
OSStatus err;
|
||||
|
||||
err = AudioOutputUnitStop(audioUnit);
|
||||
verify(err == noErr);
|
||||
|
||||
err = AudioUnitUninitialize(audioUnit);
|
||||
verify(err == noErr);
|
||||
|
||||
err = AudioComponentInstanceDispose(audioUnit);
|
||||
verify(err == noErr);
|
||||
}
|
||||
|
||||
audiobackend_t audiobackend_coreaudio = {
|
||||
"coreaudio", // Slug
|
||||
"Core Audio", // Name
|
||||
&coreaudio_init,
|
||||
&coreaudio_push,
|
||||
&coreaudio_term
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
#include "oslib/audiostream.h"
|
||||
|
||||
extern audiobackend_t audiobackend_coreaudio;
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
#include "oslib/audiobackend_alsa.h"
|
||||
#include "oslib/audiobackend_oss.h"
|
||||
#include "oslib/audiobackend_pulseaudio.h"
|
||||
#include "oslib/audiobackend_coreaudio.h"
|
||||
|
||||
struct SoundFrame { s16 l;s16 r; };
|
||||
#define SAMPLE_COUNT 512
|
||||
|
@ -85,6 +86,9 @@ void RegisterAllAudioBackends() {
|
|||
#if USE_PULSEAUDIO
|
||||
RegisterAudioBackend(&audiobackend_pulseaudio);
|
||||
#endif
|
||||
#if HOST_OS == OS_DARWIN
|
||||
RegisterAudioBackend(&audiobackend_coreaudio);
|
||||
#endif
|
||||
audiobackends_registered = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -237,6 +237,8 @@
|
|||
9C7A3B4E18C806E00070BB5F /* stdclass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A3A9918C806E00070BB5F /* stdclass.cpp */; };
|
||||
9C7A3B5918C81A4F0070BB5F /* SWRevealViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A3B5818C81A4F0070BB5F /* SWRevealViewController.m */; };
|
||||
9C7A3BC418C84EA10070BB5F /* MainStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C7A3BC318C84EA10070BB5F /* MainStoryboard.storyboard */; };
|
||||
EBDF37561BB96E1B001191B5 /* audiobackend_coreaudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EBDF37541BB96E1B001191B5 /* audiobackend_coreaudio.cpp */; settings = {ASSET_TAGS = (); }; };
|
||||
EBDF375A1BB96ECD001191B5 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBDF37591BB96ECD001191B5 /* AudioToolbox.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
|
@ -635,6 +637,10 @@
|
|||
9C7A3B5718C81A4F0070BB5F /* SWRevealViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWRevealViewController.h; sourceTree = "<group>"; };
|
||||
9C7A3B5818C81A4F0070BB5F /* SWRevealViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWRevealViewController.m; sourceTree = "<group>"; };
|
||||
9C7A3BC318C84EA10070BB5F /* MainStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = MainStoryboard.storyboard; sourceTree = "<group>"; };
|
||||
EBDF37541BB96E1B001191B5 /* audiobackend_coreaudio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audiobackend_coreaudio.cpp; sourceTree = "<group>"; };
|
||||
EBDF37551BB96E1B001191B5 /* audiobackend_coreaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audiobackend_coreaudio.h; sourceTree = "<group>"; };
|
||||
EBDF37571BB96E75001191B5 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; };
|
||||
EBDF37591BB96ECD001191B5 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
@ -642,6 +648,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
EBDF375A1BB96ECD001191B5 /* AudioToolbox.framework in Frameworks */,
|
||||
87D92F4E1B7A1B5700D8FD9E /* GameController.framework in Frameworks */,
|
||||
87C4AA561A4414070048DBF4 /* AssetsLibrary.framework in Frameworks */,
|
||||
87C4AA541A440BEB0048DBF4 /* libz.dylib in Frameworks */,
|
||||
|
@ -681,6 +688,8 @@
|
|||
8497BCC31A41BFBA00EFB9ED /* oslib */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EBDF37541BB96E1B001191B5 /* audiobackend_coreaudio.cpp */,
|
||||
EBDF37551BB96E1B001191B5 /* audiobackend_coreaudio.h */,
|
||||
877652B61B6157BD00437F10 /* audiobackend_alsa.cpp */,
|
||||
877652B71B6157BD00437F10 /* audiobackend_alsa.h */,
|
||||
877652B81B6157BD00437F10 /* audiobackend_android.h */,
|
||||
|
@ -753,6 +762,8 @@
|
|||
87078A8518A47FE90034C7A0 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EBDF37591BB96ECD001191B5 /* AudioToolbox.framework */,
|
||||
EBDF37571BB96E75001191B5 /* AudioUnit.framework */,
|
||||
87D92F4D1B7A1B5700D8FD9E /* GameController.framework */,
|
||||
87C4AA551A4414070048DBF4 /* AssetsLibrary.framework */,
|
||||
87C4AA531A440BEB0048DBF4 /* libz.dylib */,
|
||||
|
@ -1642,6 +1653,7 @@
|
|||
84967C901B8F492C005F1140 /* filter_neon.S in Sources */,
|
||||
876AA3771B818A4000617242 /* ini.cpp in Sources */,
|
||||
84967C9B1B8F492C005F1140 /* pngset.c in Sources */,
|
||||
EBDF37561BB96E1B001191B5 /* audiobackend_coreaudio.cpp in Sources */,
|
||||
9C7A3B3618C806E00070BB5F /* chd.cpp in Sources */,
|
||||
9C7A3B2118C806E00070BB5F /* sh4_fpu.cpp in Sources */,
|
||||
9C7A3B3218C806E00070BB5F /* sh4_opcode_list.cpp in Sources */,
|
||||
|
|
|
@ -24,11 +24,11 @@ class EmuGLView: NSOpenGLView {
|
|||
//glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
|
||||
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
openGLContext.makeCurrentContext()
|
||||
openGLContext!.makeCurrentContext()
|
||||
|
||||
while !emu_single_frame(Int32(dirtyRect.width), Int32(dirtyRect.height)) { }
|
||||
|
||||
openGLContext.flushBuffer()
|
||||
openGLContext!.flushBuffer()
|
||||
}
|
||||
|
||||
override func awakeFromNib() {
|
||||
|
@ -49,12 +49,12 @@ class EmuGLView: NSOpenGLView {
|
|||
|
||||
let pf = NSOpenGLPixelFormat(attributes:attrs)
|
||||
|
||||
let context = NSOpenGLContext(format: pf, shareContext: nil);
|
||||
let context = NSOpenGLContext(format: pf!, shareContext: nil);
|
||||
|
||||
self.pixelFormat = pf;
|
||||
self.openGLContext = context;
|
||||
|
||||
openGLContext.makeCurrentContext()
|
||||
openGLContext!.makeCurrentContext()
|
||||
emu_gles_init();
|
||||
}
|
||||
|
||||
|
|
|
@ -192,6 +192,9 @@
|
|||
84B7BF7F1B72720200F9733F /* stdclass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84B7BEA71B72720200F9733F /* stdclass.cpp */; };
|
||||
84B7BF831B727AD700F9733F /* osx-main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84B7BF821B727AD700F9733F /* osx-main.mm */; };
|
||||
84B7BF861B72871600F9733F /* EmuGLView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B7BF851B72871600F9733F /* EmuGLView.swift */; };
|
||||
EBDF374F1BB96581001191B5 /* audiobackend_coreaudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EBDF374D1BB96581001191B5 /* audiobackend_coreaudio.cpp */; settings = {ASSET_TAGS = (); }; };
|
||||
EBDF37511BB969EE001191B5 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBDF37501BB969EE001191B5 /* CoreAudio.framework */; };
|
||||
EBDF37531BB969F8001191B5 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBDF37521BB969F8001191B5 /* AudioUnit.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
|
@ -536,6 +539,10 @@
|
|||
84B7BF821B727AD700F9733F /* osx-main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "osx-main.mm"; sourceTree = "<group>"; };
|
||||
84B7BF841B72821900F9733F /* emulator-osx-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "emulator-osx-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
84B7BF851B72871600F9733F /* EmuGLView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmuGLView.swift; sourceTree = "<group>"; };
|
||||
EBDF374D1BB96581001191B5 /* audiobackend_coreaudio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audiobackend_coreaudio.cpp; sourceTree = "<group>"; };
|
||||
EBDF374E1BB96581001191B5 /* audiobackend_coreaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audiobackend_coreaudio.h; sourceTree = "<group>"; };
|
||||
EBDF37501BB969EE001191B5 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
|
||||
EBDF37521BB969F8001191B5 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
@ -543,6 +550,8 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
EBDF37531BB969F8001191B5 /* AudioUnit.framework in Frameworks */,
|
||||
EBDF37511BB969EE001191B5 /* CoreAudio.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -569,6 +578,8 @@
|
|||
84A388AA1B1CDD3E000166C0 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EBDF37521BB969F8001191B5 /* AudioUnit.framework */,
|
||||
EBDF37501BB969EE001191B5 /* CoreAudio.framework */,
|
||||
84B7BD111B7271CF00F9733F /* core */,
|
||||
84A388B51B1CDD3E000166C0 /* reicast-osx */,
|
||||
84A388C61B1CDD3F000166C0 /* reicast-osxTests */,
|
||||
|
@ -1212,6 +1223,8 @@
|
|||
84B7BE791B72720200F9733F /* audiostream.cpp */,
|
||||
84B7BE7A1B72720200F9733F /* audiostream.h */,
|
||||
84B7BE7B1B72720200F9733F /* oslib.h */,
|
||||
EBDF374D1BB96581001191B5 /* audiobackend_coreaudio.cpp */,
|
||||
EBDF374E1BB96581001191B5 /* audiobackend_coreaudio.h */,
|
||||
);
|
||||
name = oslib;
|
||||
path = ../../../core/oslib;
|
||||
|
@ -1319,6 +1332,7 @@
|
|||
84A388AB1B1CDD3E000166C0 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0700;
|
||||
LastUpgradeCheck = 0610;
|
||||
ORGANIZATIONNAME = reicast;
|
||||
TargetAttributes = {
|
||||
|
@ -1401,6 +1415,7 @@
|
|||
84B7BF431B72720200F9733F /* decoder.cpp in Sources */,
|
||||
84B7BEBB1B72720200F9733F /* elf64.cpp in Sources */,
|
||||
84B7BF1B1B72720200F9733F /* inffast.c in Sources */,
|
||||
EBDF374F1BB96581001191B5 /* audiobackend_coreaudio.cpp in Sources */,
|
||||
84967CC31B8F49EE005F1140 /* pngmem.c in Sources */,
|
||||
84B7BF581B72720200F9733F /* sh4_rom.cpp in Sources */,
|
||||
84B7BF441B72720200F9733F /* driver.cpp in Sources */,
|
||||
|
|
Loading…
Reference in New Issue