apple: Add primitive core audio support

Also made the project xcode 7 friendly
This commit is contained in:
Stefanos Kornilios Mitsis Poiitidis 2015-09-28 14:59:42 +02:00
parent 72f51f4f0e
commit 4282395528
6 changed files with 182 additions and 4 deletions

View File

@ -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

View File

@ -0,0 +1,5 @@
#pragma once
#include "oslib/audiostream.h"
extern audiobackend_t audiobackend_coreaudio;

View File

@ -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;
}

View File

@ -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 */,

View File

@ -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();
}

View File

@ -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 */,