From 24c48a1782b29f96f93c06ea479bedcec6869a43 Mon Sep 17 00:00:00 2001 From: Loic Nageleisen Date: Mon, 21 Mar 2016 12:23:11 +0100 Subject: [PATCH] make it work (1s, 440Hz tone) --- Makefile | 2 +- coreaudio_example.cc | 4 +-- coreaudio_example_main.cc | 59 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 61 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 28e2037..0c78147 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ all: example -example: +example: *.h *.cc clang++ -std=c++11 -stdlib=libc++ -Wl,-framework,CoreAudio -Wl,-framework,AudioUnit coreaudio_example.cc coreaudio_example_main.cc -o example clean: diff --git a/coreaudio_example.cc b/coreaudio_example.cc index f688bd4..866f875 100644 --- a/coreaudio_example.cc +++ b/coreaudio_example.cc @@ -53,7 +53,7 @@ static struct CoreAudioFormatDescriptionMap format_map[] = { {FMT_S16_BE, 16, sizeof (int16_t), kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsBigEndian}, {FMT_S32_LE, 32, sizeof (int32_t), kAudioFormatFlagIsSignedInteger}, {FMT_S32_BE, 32, sizeof (int32_t), kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsBigEndian}, - {FMT_FLOAT, 32, sizeof (float), kAudioFormatFlagIsFloat}, + {FMT_FLOAT, 32, sizeof (float), kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved}, }; /* @@ -118,7 +118,7 @@ This gives you an output unit you can send data to using a callback. Now we should actually set up the unit for playback... */ -bool open_audio (int format, int rate, int chan, AURenderCallbackStruct * callback) +bool open_audio (enum format_type format, int rate, int chan, AURenderCallbackStruct * callback) { struct CoreAudioFormatDescriptionMap * m = nullptr; diff --git a/coreaudio_example_main.cc b/coreaudio_example_main.cc index 76e8197..d637d1a 100644 --- a/coreaudio_example_main.cc +++ b/coreaudio_example_main.cc @@ -1 +1,58 @@ -int main() { return 0; } +#include "coreaudio_example.h" + +static double gtheta = 0; + +OSStatus tone(void *inRef, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) { + // Fixed amplitude is good enough for our purposes + const double amplitude = 0.25; + + // Get the tone parameters out of the static var + // could be stored in inRef + double theta = gtheta; + double theta_increment = 2.0 * M_PI * 440 / 44100; + + // This is a mono tone generator so we only need the first buffer + const int channel = 0; + Float32 *buffer = (Float32 *)ioData->mBuffers[channel].mData; + + // Generate the samples + for (UInt32 frame = 0; frame < inNumberFrames; frame++) + { + buffer[frame] = sin(theta) * amplitude; + + theta += theta_increment; + if (theta > 2.0 * M_PI) + { + theta -= 2.0 * M_PI; + } + } + + printf("%f\n", theta); + gtheta = theta; + + return noErr; +} + +int main() { + coreaudio_example::init(); + + AURenderCallbackStruct callback; + callback.inputProc = tone; + callback.inputProcRefCon = nullptr; // could pass a struct to store state like theta + + bool ok = coreaudio_example::open_audio(coreaudio_example::FMT_FLOAT, 44100, 1, &callback); + if (!ok) { + coreaudio_example::cleanup(); + fprintf(stderr, "failed to open\n"); + return 1; + } + + coreaudio_example::set_volume(100); + + // sleep 1s, rendering via callback happens in another thread + usleep(1000000); + + coreaudio_example::close_audio(); + coreaudio_example::cleanup(); + return 0; +}