git.y1.nz

SameBoy

Accurate GB/GBC emulator
download: https://git.y1.nz/archives/sameboy.tar.gz
README | Files | Log | Refs | LICENSE

AppleCommon/GBAudioClient.m

      1 #import <Foundation/Foundation.h>
      2 #import <AudioToolbox/AudioToolbox.h>
      3 #import "GBAudioClient.h"
      4 
      5 static OSStatus render(
      6                     GBAudioClient *self,
      7                     AudioUnitRenderActionFlags *ioActionFlags,
      8                     const AudioTimeStamp *inTimeStamp,
      9                     UInt32 inBusNumber,
     10                     UInt32 inNumberFrames,
     11                     AudioBufferList *ioData)
     12 
     13 {
     14     GB_sample_t *buffer = (GB_sample_t *)ioData->mBuffers[0].mData;
     15 
     16     self.renderBlock(self.rate, inNumberFrames, buffer);
     17     
     18     return noErr;
     19 }
     20 
     21 @implementation GBAudioClient
     22 {
     23     AudioComponentInstance audioUnit;
     24 }
     25 
     26 - (id)initWithRendererBlock:(void (^)(UInt32 sampleRate, UInt32 nFrames, GB_sample_t *buffer)) block
     27               andSampleRate:(UInt32) rate
     28 {
     29     if (!(self = [super init])) { 
     30         return nil;
     31     }
     32 
     33     // Configure the search parameters to find the default playback output unit
     34     // (called the kAudioUnitSubType_RemoteIO on iOS but
     35     // kAudioUnitSubType_DefaultOutput on Mac OS X)
     36     AudioComponentDescription defaultOutputDescription;
     37     defaultOutputDescription.componentType = kAudioUnitType_Output;
     38 #if TARGET_OS_IPHONE
     39     defaultOutputDescription.componentSubType = kAudioUnitSubType_RemoteIO;
     40 #else
     41     defaultOutputDescription.componentSubType = kAudioUnitSubType_DefaultOutput;
     42 #endif
     43     defaultOutputDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
     44     defaultOutputDescription.componentFlags = 0;
     45     defaultOutputDescription.componentFlagsMask = 0;
     46 
     47     // Get the default playback output unit
     48     AudioComponent defaultOutput = AudioComponentFindNext(NULL, &defaultOutputDescription);
     49     if (!defaultOutput) {
     50         NSLog(@"Can't find default output");
     51         return nil;
     52     }
     53 
     54     // Create a new unit based on this that we'll use for output
     55     OSErr err = AudioComponentInstanceNew(defaultOutput, &audioUnit);
     56     if (!audioUnit) {
     57         NSLog(@"Error creating unit: %hd", err);
     58         return nil;
     59     }
     60 
     61     // Set our tone rendering function on the unit
     62     AURenderCallbackStruct input;
     63     input.inputProc = (void*)render;
     64     input.inputProcRefCon = (__bridge void *)(self);
     65     err = AudioUnitSetProperty(audioUnit,
     66                                kAudioUnitProperty_SetRenderCallback,
     67                                kAudioUnitScope_Input,
     68                                0,
     69                                &input,
     70                                sizeof(input));
     71     if (err) {
     72         NSLog(@"Error setting callback: %hd", err);
     73         return nil;
     74     }
     75 
     76     AudioStreamBasicDescription streamFormat;
     77     streamFormat.mSampleRate = rate;
     78     streamFormat.mFormatID = kAudioFormatLinearPCM;
     79     streamFormat.mFormatFlags =
     80     kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked | kAudioFormatFlagsNativeEndian;
     81     streamFormat.mBytesPerPacket = 4;
     82     streamFormat.mFramesPerPacket = 1;
     83     streamFormat.mBytesPerFrame = 4;
     84     streamFormat.mChannelsPerFrame = 2;
     85     streamFormat.mBitsPerChannel = 2 * 8;
     86     err = AudioUnitSetProperty (audioUnit,
     87                                 kAudioUnitProperty_StreamFormat,
     88                                 kAudioUnitScope_Input,
     89                                 0,
     90                                 &streamFormat,
     91                                 sizeof(AudioStreamBasicDescription));
     92     
     93     if (err) {
     94         NSLog(@"Error setting stream format: %hd", err);
     95         return nil;
     96     }
     97     err = AudioUnitInitialize(audioUnit);
     98     if (err) {
     99         NSLog(@"Error initializing unit: %hd", err);
    100         return nil;
    101     }
    102 
    103     self.renderBlock = block;
    104     _rate = rate;
    105 
    106     return self;
    107 }
    108 
    109 -(void) start
    110 {
    111     OSErr err = AudioOutputUnitStart(audioUnit);
    112     if (err) {
    113         NSLog(@"Error starting unit: %hd", err);
    114         return;
    115     }
    116     _playing = true;
    117 
    118 }
    119 
    120 
    121 -(void) stop
    122 {
    123     AudioOutputUnitStop(audioUnit);
    124     _playing = false;
    125 }
    126 
    127 -(void) dealloc 
    128 {
    129     [self stop];
    130     AudioUnitUninitialize(audioUnit);
    131     AudioComponentInstanceDispose(audioUnit);
    132 }
    133 
    134 @end

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.