summaryrefslogtreecommitdiff
path: root/drivers/coreaudio
diff options
context:
space:
mode:
authorMarcelo Fernandez <marcelofg55@gmail.com>2018-07-03 22:08:43 -0300
committerSaracen <SaracenOne@gmail.com>2018-07-27 16:50:10 +0100
commit061358d8385a78a32a30ac5acf5443c465c8ec61 (patch)
tree9956b66bde27fa25ef97095b8b5f2422495783b1 /drivers/coreaudio
parent76fd9d215c25874b1c5d33355de0ed983922c32d (diff)
Modified Microphone implementation to handle only one device at a time (WIP)
Diffstat (limited to 'drivers/coreaudio')
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.cpp81
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.h14
2 files changed, 74 insertions, 21 deletions
diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp
index e13b81ddab..261ba7809c 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.cpp
+++ b/drivers/coreaudio/audio_driver_coreaudio.cpp
@@ -35,6 +35,7 @@
#include "os/os.h"
#define kOutputBus 0
+#define kInputBus 1
#ifdef OSX_ENABLED
OSStatus AudioDriverCoreAudio::output_device_address_cb(AudioObjectID inObjectID,
@@ -117,6 +118,11 @@ Error AudioDriverCoreAudio::init() {
result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &strdesc, sizeof(strdesc));
ERR_FAIL_COND_V(result != noErr, FAILED);
+ strdesc.mChannelsPerFrame = 2;
+
+ result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &strdesc, sizeof(strdesc));
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+
int latency = GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
// Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
@@ -126,8 +132,14 @@ Error AudioDriverCoreAudio::init() {
ERR_FAIL_COND_V(result != noErr, FAILED);
#endif
- buffer_size = buffer_frames * channels;
+ unsigned int buffer_size = buffer_frames * channels;
samples_in.resize(buffer_size);
+ input_buf.resize(buffer_size);
+ audio_input_buffer.resize(buffer_size * 8);
+ for (int i = 0; i < audio_input_buffer.size(); i++) {
+ audio_input_buffer.write[i] = 0;
+ }
+ audio_input_position = 0;
if (OS::get_singleton()->is_stdout_verbose()) {
print_line("CoreAudio: detected " + itos(channels) + " channels");
@@ -141,6 +153,12 @@ Error AudioDriverCoreAudio::init() {
result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callback, sizeof(callback));
ERR_FAIL_COND_V(result != noErr, FAILED);
+ zeromem(&callback, sizeof(AURenderCallbackStruct));
+ callback.inputProc = &AudioDriverCoreAudio::input_callback;
+ callback.inputProcRefCon = this;
+ result = AudioUnitSetProperty(audio_unit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &callback, sizeof(callback));
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+
result = AudioUnitInitialize(audio_unit);
ERR_FAIL_COND_V(result != noErr, FAILED);
@@ -192,6 +210,42 @@ OSStatus AudioDriverCoreAudio::output_callback(void *inRefCon,
return 0;
};
+OSStatus AudioDriverCoreAudio::input_callback(void *inRefCon,
+ AudioUnitRenderActionFlags *ioActionFlags,
+ const AudioTimeStamp *inTimeStamp,
+ UInt32 inBusNumber, UInt32 inNumberFrames,
+ AudioBufferList *ioData) {
+
+ AudioDriverCoreAudio *ad = (AudioDriverCoreAudio *)inRefCon;
+ if (!ad->active) {
+ return 0;
+ }
+
+ ad->lock();
+
+ AudioBufferList bufferList;
+ bufferList.mNumberBuffers = 1;
+ bufferList.mBuffers[0].mData = ad->input_buf.ptrw();
+ bufferList.mBuffers[0].mNumberChannels = 2;
+ bufferList.mBuffers[0].mDataByteSize = ad->input_buf.size() * sizeof(int16_t);
+
+ OSStatus result = AudioUnitRender(ad->audio_unit, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, &bufferList);
+ if (result == noErr) {
+ for (int i = 0; i < inNumberFrames * 2; i++) {
+ ad->audio_input_buffer.write[ad->audio_input_position++] = ad->input_buf[i] << 16;
+ if (ad->audio_input_position >= ad->audio_input_buffer.size()) {
+ ad->audio_input_position = 0;
+ }
+ }
+ } else {
+ ERR_PRINT(("AudioUnitRender failed, code: " + itos(result)).utf8().get_data());
+ }
+
+ ad->unlock();
+
+ return result;
+}
+
void AudioDriverCoreAudio::start() {
if (!active) {
OSStatus result = AudioOutputUnitStart(audio_unit);
@@ -434,26 +488,22 @@ void AudioDriverCoreAudio::finish() {
}
};
-bool AudioDriverCoreAudio::capture_device_start(StringName p_name) {
+Error AudioDriverCoreAudio::capture_start() {
- return false;
-}
-
-bool AudioDriverCoreAudio::capture_device_stop(StringName p_name) {
+ UInt32 flag = 1;
+ OSStatus result = AudioUnitSetProperty(audio_unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, sizeof(flag));
+ ERR_FAIL_COND_V(result != noErr, FAILED);
- return false;
+ return OK;
}
-PoolStringArray AudioDriverCoreAudio::capture_device_get_names() {
-
- PoolStringArray names;
+Error AudioDriverCoreAudio::capture_stop() {
- return names;
-}
-
-StringName AudioDriverCoreAudio::capture_device_get_default_name() {
+ UInt32 flag = 0;
+ OSStatus result = AudioUnitSetProperty(audio_unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, sizeof(flag));
+ ERR_FAIL_COND_V(result != noErr, FAILED);
- return "";
+ return OK;
}
AudioDriverCoreAudio::AudioDriverCoreAudio() {
@@ -463,7 +513,6 @@ AudioDriverCoreAudio::AudioDriverCoreAudio() {
mix_rate = 0;
channels = 2;
- buffer_size = 0;
buffer_frames = 0;
samples_in.clear();
diff --git a/drivers/coreaudio/audio_driver_coreaudio.h b/drivers/coreaudio/audio_driver_coreaudio.h
index 0d3efca28d..7629e56686 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.h
+++ b/drivers/coreaudio/audio_driver_coreaudio.h
@@ -52,9 +52,9 @@ class AudioDriverCoreAudio : public AudioDriver {
int mix_rate;
unsigned int channels;
unsigned int buffer_frames;
- unsigned int buffer_size;
Vector<int32_t> samples_in;
+ Vector<int16_t> input_buf;
#ifdef OSX_ENABLED
static OSStatus output_device_address_cb(AudioObjectID inObjectID,
@@ -68,6 +68,12 @@ class AudioDriverCoreAudio : public AudioDriver {
UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList *ioData);
+ static OSStatus input_callback(void *inRefCon,
+ AudioUnitRenderActionFlags *ioActionFlags,
+ const AudioTimeStamp *inTimeStamp,
+ UInt32 inBusNumber, UInt32 inNumberFrames,
+ AudioBufferList *ioData);
+
public:
const char *get_name() const {
return "CoreAudio";
@@ -86,10 +92,8 @@ public:
virtual void unlock();
virtual void finish();
- virtual bool capture_device_start(StringName p_name);
- virtual bool capture_device_stop(StringName p_name);
- virtual PoolStringArray capture_device_get_names();
- virtual StringName capture_device_get_default_name();
+ virtual Error capture_start();
+ virtual Error capture_stop();
bool try_lock();
void stop();