diff options
author | Marcelo Fernandez <marcelofg55@gmail.com> | 2018-07-03 22:08:43 -0300 |
---|---|---|
committer | Saracen <SaracenOne@gmail.com> | 2018-07-27 16:50:10 +0100 |
commit | 061358d8385a78a32a30ac5acf5443c465c8ec61 (patch) | |
tree | 9956b66bde27fa25ef97095b8b5f2422495783b1 /drivers/coreaudio | |
parent | 76fd9d215c25874b1c5d33355de0ed983922c32d (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.cpp | 81 | ||||
-rw-r--r-- | drivers/coreaudio/audio_driver_coreaudio.h | 14 |
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(); |