5
// Created by rock88 on 15/03/2013.
6
// Copyright (c) 2013 Homebrew. All rights reserved.
9
#import "AudioEngine.h"
11
#import <OpenAL/alc.h>
12
#import <AudioToolbox/AudioToolbox.h>
13
#import <AVFoundation/AVFoundation.h>
17
static volatile BOOL done = 0;
19
#define SAMPLE_SIZE 44100
20
static short stream[SAMPLE_SIZE];
22
int NativeMix(short *audio, int num_samples);
24
@interface AudioEngine ()
26
@property (nonatomic,assign) ALCdevice *alcDevice;
27
@property (nonatomic,assign) ALCcontext *alContext;
28
@property (nonatomic,assign) ALuint buffer;
29
@property (nonatomic,assign) ALuint source;
33
@implementation AudioEngine
34
@synthesize alcDevice,alContext,buffer,source;
56
std::string Err = "OpenAL error: ";
57
if ((ErrCode = alGetError()) != AL_NO_ERROR)
59
Err += (char *)alGetString(ErrCode);
60
printf("%s\n",Err.c_str());
67
alcDevice = alcOpenDevice(NULL);
71
NSLog(@"OpenAL device opened: %s",alcGetString(alcDevice, ALC_DEVICE_SPECIFIER));
75
NSLog(@"WARNING: could not open OpenAL device");
79
alContext = alcCreateContext(alcDevice, NULL);
83
alcMakeContextCurrent(alContext);
87
NSLog(@"ERROR: no OpenAL context");
91
alGenSources(1, &source);
92
alGenBuffers(1, &buffer);
98
alcMakeContextCurrent(NULL);
102
alcDestroyContext(alContext);
108
alcCloseDevice(alcDevice);
116
alGetSourcei(source, AL_SOURCE_STATE, &state);
117
return (state == AL_PLAYING);
122
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
127
frames_ready = NativeMix(stream, SAMPLE_SIZE / 2);
131
if (frames_ready > 0)
133
const size_t bytes_ready = frames_ready * sizeof(short) * 2;
134
alSourcei(source, AL_BUFFER, 0);
135
alBufferData(buffer, AL_FORMAT_STEREO16, stream, bytes_ready, 44100);
136
alSourcei(source, AL_BUFFER, buffer);
137
alSourcePlay(source);
139
// TODO: Maybe this could get behind?
140
usleep((1000000 * frames_ready) / 44100);