void FIOSAudioDevice::ResumeContext() { int32& SuspendCounter = GetSuspendCounter(); FPlatformAtomics::InterlockedDecrement(&SuspendCounter); AUGraphStart(AudioUnitGraph); }
void midi_reset(void) { if (s_graph == 0) return; AUGraphStop(s_graph); AUGraphStart(s_graph); }
bool CCoreAudioGraph::Start() { if (!m_audioGraph) return false; OSStatus ret; Boolean isRunning = false; ret = AUGraphIsRunning(m_audioGraph, &isRunning); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Start: Audio graph not running. Error = %s", GetError(ret).c_str()); return false; } if (!isRunning) { if (m_audioUnit) m_audioUnit->Start(); if (m_mixerUnit) m_mixerUnit->Start(); if (m_inputUnit) m_inputUnit->Start(); ret = AUGraphStart(m_audioGraph); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Start: Error starting audio graph. Error = %s", GetError(ret).c_str()); } ShowGraph(); } return true; }
int main (int argc, const char * argv[]) { MyAUGraphPlayer player = {0}; // create the input unit CreateInputUnit(&player); // build a graph with output unit CreateMyAUGraph(&player); #ifdef PART_II // configure the speech synthesizer PrepareSpeechAU(&player); #endif // start playing CheckError (AudioOutputUnitStart(player.inputUnit), "AudioOutputUnitStart failed"); CheckError(AUGraphStart(player.graph), "AUGraphStart failed"); // and wait printf("Capturing, press <return> to stop:\n"); getchar(); cleanup: AUGraphStop (player.graph); AUGraphUninitialize (player.graph); AUGraphClose(player.graph); }
int main (int argc, char * const argv[]) { char inputFile[]="blip.mp3"; static const double threshold=0.50; int hardware=macbookpro; double x,y,z,prev_x,prev_y,prev_z; AudioFileID audioFile; CFURLRef theURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8*)inputFile, strlen(inputFile), false); XThrowIfError (AudioFileOpenURL (theURL, kAudioFileReadPermission, 0, &audioFile), "AudioFileOpenURL"); // get the number of channels of the file CAStreamBasicDescription fileFormat; UInt32 propsize = sizeof(CAStreamBasicDescription); XThrowIfError (AudioFileGetProperty(audioFile, kAudioFilePropertyDataFormat, &propsize, &fileFormat), "AudioFileGetProperty"); // lets set up our playing state now AUGraph theGraph; CAAudioUnit fileAU; // this makes the graph, the file AU and sets it all up for playing MakeSimpleGraph (theGraph, fileAU, fileFormat, audioFile); // now we load the file contents up for playback before we start playing // this has to be done the AU is initialized and anytime it is reset or uninitialized Float64 fileDuration = PrepareFileAU (fileAU, fileFormat, audioFile); printf ("file duration: %f secs\n", fileDuration); read_sms_real(hardware,&x,&y,&z); prev_x=x; prev_y=y; prev_z=z; for(;;) { read_sms_real(hardware,&x,&y,&z); //printf("x: %f y: %f z: %f\n",x,y,z); if(isDelta(threshold,x,y,z,prev_x,prev_y,prev_z)) XThrowIfError (AUGraphStart (theGraph), "AUGraphStart"); prev_x=x; prev_y=y; prev_z=z; } // sleep until the file is finished //usleep ((int)(fileDuration * 1000. * 1000.)); // lets clean up XThrowIfError (AUGraphStop (theGraph), "AUGraphStop"); XThrowIfError (AUGraphUninitialize (theGraph), "AUGraphUninitialize"); XThrowIfError (AudioFileClose (audioFile), "AudioFileClose"); XThrowIfError (AUGraphClose (theGraph), "AUGraphClose"); return 0; }
bool midi_init(void) { OSStatus result; result = CreateAUGraph(); if (result != 0) return false; result = AUGraphInitialize(s_graph); if (result != 0) return false; result = AUGraphStart(s_graph); if (result != 0) return false; return true; }
void CoreAudio_PlayFile_Thread(void *auGraph) { /* Start playing the sound file, and wait for it to complete */ AUGraphStart(theGraph); usleep((int) (1000.0 * 1000.0 * fileDuration)); CoreAudio_ShutDown(); /* Shutdown the audio stream */ pthread_mutex_unlock(&mutexCAAccess); }
void QBSoundMac::startAUGraph() { //printf("startAUGraph\n"); if (!mOpenGraph) { if (!mInitGraph) { initGraph(); mInitGraph = true; } AUGraphStop(mGraph); AUGraphStart(mGraph); } mOpenGraph = true; }
int main (int argc, const char * argv[]) { MyMIDIPlayer player; setupAUGraph(&player); setupMIDI(&player); CheckError (AUGraphStart(player.graph), "couldn't start graph"); CFRunLoopRun(); // run until aborted with control-C return 0; }
OSStatus CAPlayThrough::Start() { OSStatus err = noErr; if(!IsRunning()){ //Start pulling for audio data err = AudioOutputUnitStart(mInputUnit); checkErr(err); err = AUGraphStart(mGraph); checkErr(err); //reset sample times mFirstInputTime = -1; mFirstOutputTime = -1; } return err; }
int main(int argc, const char *argv[]) { MyAUGraphPlayer player = {0}; // build a basic speech->speakers graph CreateMyAUGraph(&player); // configure the speech synthesizer PrepareSpeechAU(&player); // start playing CheckError(AUGraphStart(player.graph), "AUGraphStart failed"); // sleep a while so the speech can play out usleep ((int)(10 * 1000. * 1000.)); cleanup: AUGraphStop (player.graph); AUGraphUninitialize (player.graph); AUGraphClose(player.graph); DisposeAUGraph(player.graph); return 0; }
int main(int argc, char *argv[]) { WindowRef window; HIViewRef content; HIViewRef combo; HIViewRef group; HIViewRef check; HIViewRef text; HIViewRef slider; HIViewRef quit; MenuRef menu; HIRect rect; // Window bounds Rect bounds = {0, 0, 436, 590}; // Create window CreateNewWindow(kDocumentWindowClass, kWindowStandardFloatingAttributes | kWindowStandardHandlerAttribute | kWindowInWindowMenuAttribute | kWindowCompositingAttribute, &bounds, &window); // Set the title SetWindowTitleWithCFString(window, CFSTR("Accordion")); // Create an application menu CreateNewMenu(0, 0, &menu); // Set menu title SetMenuTitleWithCFString(menu, CFStringCreateWithPascalString(kCFAllocatorDefault, "\p\024", kCFStringEncodingMacRoman)); // Create an about item InsertMenuItemTextWithCFString(menu, CFSTR("About Accordion"), 0, 0, kHICommandAbout); // Insert the menu InsertMenu(menu, 0); // Create a standard window menu CreateStandardWindowMenu(0, &menu); // Insert the menu InsertMenu(menu, 0); // Show and position the window ShowWindow(window); RepositionWindow(window, NULL, kWindowCascadeOnMainScreen); // Find the window content HIViewFindByID(HIViewGetRoot(window), kHIViewWindowContentID, &content); // Set bounds for group box bounds.bottom = 92; bounds.right = 550; // Create group box CreateGroupBoxControl(window, &bounds, NULL, true, &group); // Place in the window HIViewAddSubview(content, group); HIViewPlaceInSuperviewAt(group, 20, 20); // Bounds of text bounds.bottom = 16; bounds.right = 74; // Create static text CreateStaticTextControl(window, &bounds, CFSTR("Instrument:"), NULL, &text); // Place in the group box HIViewAddSubview(group, text); HIViewPlaceInSuperviewAt(text, 16, 18); // Bounds of combo box rect.size.height = 20; rect.size.width = 168; // Create combo box HIComboBoxCreate(&rect, CFSTR(" Accordion"), NULL, NULL, kHIComboBoxStandardAttributes, &combo); // Set visible and set command ID HIViewSetVisible(combo, true); HIViewSetCommandID(combo, kCommandInst); // Add the instruments for (int i = 0; i < Length(instruments); i++) { HIComboBoxAppendTextItem(combo, CFStringCreateWithCString(kCFAllocatorDefault, instruments[i], kCFStringEncodingMacRoman), NULL); // Set the current instrument if (strcmp(instruments[i], " Accordion") == 0) instrument = i; } // Place in the group box HIViewAddSubview(group, combo); HIViewPlaceInSuperviewAt(combo, 102, 16); // Bounds of check box bounds.bottom = 18; bounds.right = 121; // Create check box CreateCheckBoxControl(window, &bounds, CFSTR("Reverse"), false, true, &check); // Set the control ID and the command ID HIViewSetID(check, kHIViewIDReverse); HIViewSetCommandID(check, kCommandReverse); // Place in the group box HIViewAddSubview(group, check); HIViewPlaceInSuperviewAt(check, 286, 17); // Bounds of text bounds.bottom = 16; bounds.right = 32; // Create static text CreateStaticTextControl(window, &bounds, CFSTR("Key:"), NULL, &text); // Place in the group box HIViewAddSubview(group, text); HIViewPlaceInSuperviewAt(text, 400, 18); // Bounds of combo box rect.size.width = 90; // Create combo box HIComboBoxCreate(&rect, CFSTR(" A/D/G"), NULL, NULL, kHIComboBoxStandardAttributes, &combo); // Set visible and set command ID HIViewSetVisible(combo, true); HIViewSetID(combo, kHIViewIDKey); HIViewSetCommandID(combo, kCommandKey); // Add keys for (int i = 0; i < Length(keys); i++) { HIComboBoxAppendTextItem(combo, CFStringCreateWithCString(kCFAllocatorDefault, keys[i], kCFStringEncodingMacRoman), NULL); // Set current key if (strcmp(keys[i], " A/D/G") == 0) key = i; } // Place in the group box HIViewAddSubview(group, combo); HIViewPlaceInSuperviewAt(combo, 440, 16); // Bounds of text bounds.bottom = 16; bounds.right = 54; // Create static text CreateStaticTextControl(window, &bounds, CFSTR("Volume:"), NULL, &text); // Place in the group box HIViewAddSubview(group, text); HIViewPlaceInSuperviewAt(text, 16, 56); // Bounds of slider bounds.bottom = 16; bounds.right = 168; // Create slider CreateSliderControl(window, &bounds, MAXVOL, 0, MAXVOL, kControlSliderDoesNotPoint, 0, false, NULL, &slider); // Set command ID HIViewSetCommandID(slider, kCommandVolume); // Place in the group box HIViewAddSubview(group, slider); HIViewPlaceInSuperviewAt(slider, 100, 58); // Bounds of check box bounds.bottom = 18; bounds.right = 121; // Create check box CreateCheckBoxControl(window, &bounds, CFSTR("Notes"), false, true, &check); // Set the control ID and the command ID HIViewSetID(check, kHIViewIDNote); HIViewSetCommandID(check, kCommandNote); // Place in the group box HIViewAddSubview(group, check); HIViewPlaceInSuperviewAt(check, 286, 56); // Bounds of push button bounds.bottom = 20; bounds.right = 90; // Create push button CreatePushButtonControl(window, &bounds, CFSTR("Quit"), &quit); // Set command ID HIViewSetCommandID(quit, kHICommandQuit); // Place in the group box HIViewAddSubview(group, quit); HIViewPlaceInSuperviewAt(quit, 440, 54); // Group box bounds bounds.bottom = 48; bounds.right = 550; // Create group box CreateGroupBoxControl(window, &bounds, NULL, true, &group); // Place in the window HIViewAddSubview(content, group); HIViewPlaceInSuperviewAt(group, 20, 132); // Font style ControlFontStyleRec style; style.flags = kControlUseFontMask|kControlUseJustMask; style.font = kControlFontBigSystemFont; style.just = teCenter; // Bounds of text bounds.bottom = 16; bounds.right = 550; // Create static text CreateStaticTextControl(window, &bounds, CFSTR("Accordion"), &style, &text); // Place in the group box HIViewAddSubview(group, text); HIViewPlaceInSuperviewAt(text, 0, 8); // Bounds of text bounds.bottom = 16; bounds.right = 550; // Create static text CreateStaticTextControl(window, &bounds, CFSTR("Play accordion on your keyboard"), &style, &text); // Place in the group box HIViewAddSubview(group, text); HIViewPlaceInSuperviewAt(text, 0, 24); // Group box bounds bounds.bottom = 196; bounds.right = 550; // Create group box CreateGroupBoxControl(window, &bounds, NULL, true, &group); // Place in the window HIViewAddSubview(content, group); HIViewPlaceInSuperviewAt(group, 20, 200); // Button bounds bounds.bottom = SIZE; bounds.right = SIZE; // Create row of bass buttons for (int i = 0; i < Length(bassdisplay); i++) { int x = 15 + 44 * i; int y = 15; // Create button CreateBevelButtonControl(window, &bounds, NULL, kControlBevelButtonNormalBevel, kControlBehaviorPushbutton, NULL, 0, 0, 0, &bassdisplay[i]); // Place in the group box HIViewAddSubview(group, bassdisplay[i]); HIViewPlaceInSuperviewAt(bassdisplay[i], x, y); } // Create three rows of buttons for (int i = 0; i < Length(display); i++) { for (int j = 0; j < ((i == 1)? Length(display[i]): Length(display[i]) - 1); j++) { int x = (i == 1)? 37 + 44 * j: 59 + 44 * j; int y = 59 + 44 * i; // Create button CreateBevelButtonControl(window, &bounds, NULL, kControlBevelButtonNormalBevel, kControlBehaviorPushbutton, NULL, 0, 0, 0, &display[i][j]); // Place in the group box HIViewAddSubview(group, display[i][j]); HIViewPlaceInSuperviewAt(display[i][j], x, y); } } // Create spacebar button CreateBevelButtonControl(window, &bounds, NULL, kControlBevelButtonNormalBevel, kControlBehaviorPushbutton, NULL, 0, 0, 0, &spacebar); // Place in the group box HIViewAddSubview(group, spacebar); HIViewPlaceInSuperviewAt(spacebar, 16, 147); // Group box bounds, wider than the window to hide rounded corners bounds.bottom = 20; bounds.right = 598; // Create group box for fake status bar CreateGroupBoxControl(window, &bounds, NULL, false, &group); // Place in window at negative offset to hide rounded corners HIViewAddSubview(content, group); HIViewPlaceInSuperviewAt(group, -4, 416); // Text bounds bounds.bottom = 16; bounds.right = 590; // Font style style.flags = kControlUseFontMask|kControlUseJustMask; style.font = kControlFontSmallSystemFont; style.just = teCenter; // Create static text CreateStaticTextControl(window, &bounds, CFSTR("Press the keyboard keys as accordion buttons " "and the space bar as the bellows. 3rd button start."), &style, &text); // Place in group box HIViewAddSubview(group, text); HIViewPlaceInSuperviewAt(text, 0, 2); // Application events type spec EventTypeSpec applicationEvents[] = {{kEventClassApplication, kEventAppFrontSwitched}}; // Install event handler InstallApplicationEventHandler(NewEventHandlerUPP(ApplicationHandler), Length(applicationEvents), applicationEvents, NULL, NULL); // Mouse events type spec EventTypeSpec mouseEvents[] = {{kEventClassMouse, kEventMouseDown}}; // Install event handler on the event dispatcher, so that we can // see mouse events before the default handler gets them InstallEventHandler(GetEventDispatcherTarget(), NewEventHandlerUPP(MouseHandler), Length(mouseEvents), mouseEvents, NULL, NULL); // Window events type spec EventTypeSpec windowEvents[] = {{kEventClassWindow, kEventWindowClose}}; // Install event handler InstallWindowEventHandler(window, NewEventHandlerUPP(WindowHandler), Length(windowEvents), windowEvents, NULL, NULL); // Combo box events type spec EventTypeSpec comboBoxEvents[] = {{kEventClassHIComboBox, kEventComboBoxListItemSelected}}; // Install event handler InstallApplicationEventHandler(NewEventHandlerUPP(ComboBoxHandler), Length(comboBoxEvents), comboBoxEvents, NULL, NULL); // Command events type spec EventTypeSpec commandEvents[] = {{kEventClassCommand, kEventCommandProcess}}; // Install event handler InstallApplicationEventHandler(NewEventHandlerUPP(CommandHandler), Length(commandEvents), commandEvents, NULL, NULL); // Keyboard events type spec EventTypeSpec keyboardEvents[] = {{kEventClassKeyboard, kEventRawKeyDown}, {kEventClassKeyboard, kEventRawKeyUp}, {kEventClassKeyboard, kEventRawKeyModifiersChanged}}; // Install event handler on the event dispatcher InstallEventHandler(GetEventDispatcherTarget(), NewEventHandlerUPP(KeyboardHandler), Length(keyboardEvents), keyboardEvents, NULL, NULL); // Audio Unit graph AUGraph graph; // Audio Unit synthesizer and output node AUNode synthNode; AUNode outNode; // Component description ComponentDescription cd; cd.componentManufacturer = kAudioUnitManufacturer_Apple; cd.componentFlags = 0; cd.componentFlagsMask = 0; do { // New AU graph OSStatus status = NewAUGraph(&graph); if (status != noErr) { DisplayAlert(CFSTR("NewAUGraph"), CFSTR("Can't create a new AUGraph"), status); break; } // Synthesizer cd.componentType = kAudioUnitType_MusicDevice; cd.componentSubType = kAudioUnitSubType_DLSSynth; // New synthesizer node status = AUGraphNewNode(graph, &cd, 0, NULL, &synthNode); if (status != noErr) { DisplayAlert(CFSTR("AUGraphNewNode"), CFSTR("Can't create a new AUGraph node"), status); break; } // Output cd.componentType = kAudioUnitType_Output; cd.componentSubType = kAudioUnitSubType_DefaultOutput; // New output node status = AUGraphNewNode(graph, &cd, 0, NULL, &outNode); if (status != noErr) { DisplayAlert(CFSTR("AUGraphNewNode"), CFSTR("Can't create a new AUGraph node"), status); break; } // Open graph status = AUGraphOpen(graph); if (status != noErr) { DisplayAlert(CFSTR("AUGraphOpen"), CFSTR("Can't open AUGraph"), status); break; } // Connect synthesizer node to output node status = AUGraphConnectNodeInput(graph, synthNode, 0, outNode, 0); if (status != noErr) { DisplayAlert(CFSTR("AUGraphConnectNodeInput"), CFSTR("Can't connect AUGraph input node"), status); break; } // Get a synthesizer unit status = AUGraphGetNodeInfo(graph, synthNode, NULL, 0, NULL, &synthUnit); if (status != noErr) { DisplayAlert(CFSTR("AUGraphGetNodeInfo"), CFSTR("Can't get AUGraph node info"), status); break; } // Initialise status = AUGraphInitialize(graph); if (status != noErr) { DisplayAlert(CFSTR("AUGraphInitialize"), CFSTR("Can't initialize AUGraph"), status); break; } // Start status = AUGraphStart(graph); if (status != noErr) { DisplayAlert(CFSTR("AUGraphStart"), CFSTR("Can't start AUGraph"), status); break; } // Show the graph // CAShow(graph); } while (false); // Change instrument ChangeInstrument(instrument); // Run the application event loop RunApplicationEventLoop(); // Stop the graph AUGraphStop(graph); // Dispose of the graph DisposeAUGraph(graph); // Exit return 0; }
int main (int argc, const char * argv[]) { AUGraph graph = 0; AudioUnit synthUnit; OSStatus result; char* bankPath = 0; UInt8 midiChannelInUse = 0; //we're using midi channel 1... // this is the only option to main that we have... // just the full path of the sample bank... // On OS X there are known places were sample banks can be stored // Library/Audio/Sounds/Banks - so you could scan this directory and give the user options // about which sample bank to use... if (argc > 1) bankPath = const_cast<char*>(argv[1]); require_noerr (result = CreateAUGraph (graph, synthUnit), home); // if the user supplies a sound bank, we'll set that before we initialize and start playing if (bankPath) { FSSpec soundBankSpec; require_noerr (result = PathToFSSpec (bankPath, soundBankSpec), home); printf ("Setting Sound Bank:%s\n", bankPath); require_noerr (result = AudioUnitSetProperty (synthUnit, kMusicDeviceProperty_SoundBankFSSpec, kAudioUnitScope_Global, 0, &soundBankSpec, sizeof(soundBankSpec)), home); } // ok we're set up to go - initialize and start the graph require_noerr (result = AUGraphInitialize (graph), home); //set our bank require_noerr (result = MusicDeviceMIDIEvent(synthUnit, kMidiMessage_ControlChange << 4 | midiChannelInUse, kMidiMessage_BankMSBControl, 0, 0/*sample offset*/), home); require_noerr (result = MusicDeviceMIDIEvent(synthUnit, kMidiMessage_ProgramChange << 4 | midiChannelInUse, 0/*prog change num*/, 0, 0/*sample offset*/), home); CAShow (graph); // prints out the graph so we can see what it looks like... require_noerr (result = AUGraphStart (graph), home); // we're going to play an octave of MIDI notes: one a second for (int i = 0; i < 13; i++) { UInt32 noteNum = i + 60; UInt32 onVelocity = 127; UInt32 noteOnCommand = kMidiMessage_NoteOn << 4 | midiChannelInUse; printf ("Playing Note: Status: 0x%lX, Note: %ld, Vel: %ld\n", noteOnCommand, noteNum, onVelocity); require_noerr (result = MusicDeviceMIDIEvent(synthUnit, noteOnCommand, noteNum, onVelocity, 0), home); // sleep for a second usleep (1 * 1000 * 1000); require_noerr (result = MusicDeviceMIDIEvent(synthUnit, noteOnCommand, noteNum, 0, 0), home); } // ok we're done now home: if (graph) { AUGraphStop (graph); // stop playback - AUGraphDispose will do that for us but just showing you what to do DisposeAUGraph (graph); } return result; }
void start(int midiChannel, char const*const bankPath) { if (auGraph != 0) return; // don't multiply init midiChannelInUse = midiChannel; OSStatus result; //create the nodes of the graph AUNode synthNode; AudioComponentDescription cd; cd.componentManufacturer = kAudioUnitManufacturer_Apple; cd.componentFlags = 0; cd.componentFlagsMask = 0; require_noerr (result = NewAUGraph (&auGraph), home); cd.componentType = kAudioUnitType_MusicDevice; cd.componentSubType = kAudioUnitSubType_DLSSynth; require_noerr (result = AUGraphAddNode (auGraph, &cd, &synthNode), home); cd.componentType = kAudioUnitType_Effect; cd.componentSubType = kAudioUnitSubType_PeakLimiter; require_noerr (result = AUGraphAddNode (auGraph, &cd, &limiterNode), home); cd.componentType = kAudioUnitType_Output; cd.componentSubType = kAudioUnitSubType_DefaultOutput; require_noerr (result = AUGraphAddNode (auGraph, &cd, &outNode), home); require_noerr (result = AUGraphOpen (auGraph), home); require_noerr (result = AUGraphConnectNodeInput(auGraph, synthNode, 0, limiterNode, 0), home); require_noerr (result = AUGraphConnectNodeInput(auGraph, limiterNode, 0, outNode, 0), home); // ok we're good to go - get the Synth Unit... require_noerr (result = AUGraphNodeInfo(auGraph, synthNode, 0, &synthUnit), home); // if the user supplies a sound bank, we'll set that before we initialize and start playing if (bankPath) { // note: bankpath is a soundfont CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)bankPath, strlen(bankPath), false); if (url) { require_noerr (result = AudioUnitSetProperty(synthUnit, kMusicDeviceProperty_SoundBankURL, kAudioUnitScope_Global, 0, &url, sizeof(url) ), home); CFRelease(url); } } // ok we're set up to go - initialize and start the graph require_noerr (result = AUGraphInitialize (auGraph), home); //set our bank require_noerr (result = MusicDeviceMIDIEvent(synthUnit, kMidiMessage_ControlChange << 4 | midiChannelInUse, kMidiMessage_BankMSBControl, 0, 0/*sample offset*/), home); require_noerr (result = MusicDeviceMIDIEvent(synthUnit, kMidiMessage_ProgramChange << 4 | midiChannelInUse, 0/*prog change num*/, 0, 0/*sample offset*/), home); CAShow(auGraph); // prints out the graph so we can see what it looks like... require_noerr (result = AUGraphStart(auGraph), home); return; home: shutdown(); }
bool FIOSAudioDevice::InitializeHardware() { SIZE_T SampleSize = sizeof(AudioSampleType); double GraphSampleRate = 44100.0; if (!SetHardwareSampleRate(GraphSampleRate) || !SetAudioSessionActive(true)) { HandleError(TEXT("Failed to establish the audio session!")); return false; } // Retrieve the actual hardware sample rate GetHardwareSampleRate(GraphSampleRate); // Linear PCM stream format MixerFormat.mFormatID = kAudioFormatLinearPCM; MixerFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked; MixerFormat.mBytesPerPacket = SampleSize; MixerFormat.mFramesPerPacket = 1; MixerFormat.mBytesPerFrame = SampleSize; MixerFormat.mChannelsPerFrame = 1; MixerFormat.mBitsPerChannel = 8 * SampleSize; MixerFormat.mSampleRate = GraphSampleRate; OSStatus Status = NewAUGraph(&AudioUnitGraph); if (Status != noErr) { HandleError(TEXT("Failed to create audio unit graph!")); return false; } AudioComponentDescription UnitDescription; // Setup audio output unit UnitDescription.componentType = kAudioUnitType_Output; UnitDescription.componentSubType = kAudioUnitSubType_RemoteIO; UnitDescription.componentManufacturer = kAudioUnitManufacturer_Apple; UnitDescription.componentFlags = 0; UnitDescription.componentFlagsMask = 0; Status = AUGraphAddNode(AudioUnitGraph, &UnitDescription, &OutputNode); if (Status != noErr) { HandleError(TEXT("Failed to initialize audio output node!"), true); return false; } // Setup audo mixer unit UnitDescription.componentType = kAudioUnitType_Mixer; UnitDescription.componentSubType = kAudioUnitSubType_AU3DMixerEmbedded; UnitDescription.componentManufacturer = kAudioUnitManufacturer_Apple; UnitDescription.componentFlags = 0; UnitDescription.componentFlagsMask = 0; Status = AUGraphAddNode(AudioUnitGraph, &UnitDescription, &MixerNode); if (Status != noErr) { HandleError(TEXT("Failed to initialize audio mixer node!"), true); return false; } Status = AUGraphOpen(AudioUnitGraph); if (Status != noErr) { HandleError(TEXT("Failed to open audio unit graph"), true); return false; } Status = AUGraphNodeInfo(AudioUnitGraph, OutputNode, NULL, &OutputUnit); if (Status != noErr) { HandleError(TEXT("Failed to retrieve output unit reference!"), true); return false; } Status = AUGraphNodeInfo(AudioUnitGraph, MixerNode, NULL, &MixerUnit); if (Status != noErr) { HandleError(TEXT("Failed to retrieve mixer unit reference!"), true); return false; } uint32 BusCount = MaxChannels * CHANNELS_PER_BUS; Status = AudioUnitSetProperty(MixerUnit, kAudioUnitProperty_ElementCount, kAudioUnitScope_Input, 0, &BusCount, sizeof(BusCount)); if (Status != noErr) { HandleError(TEXT("Failed to set kAudioUnitProperty_ElementCount for audio mixer unit!"), true); return false; } // Initialize sound source early on, allowing for render callback hookups InitSoundSources(); // Setup the mixer unit sample rate Status = AudioUnitSetProperty(MixerUnit, kAudioUnitProperty_SampleRate, kAudioUnitScope_Output, 0, &GraphSampleRate, sizeof(GraphSampleRate)); if (Status != noErr) { HandleError(TEXT("Failed to set kAudioUnitProperty_SampleRate for audio mixer unit!"), true); return false; } // Connect mixer node output to output node input Status = AUGraphConnectNodeInput(AudioUnitGraph, MixerNode, 0, OutputNode, 0); if (Status != noErr) { HandleError(TEXT("Failed to connect mixer node to output node!"), true); return false; } // Initialize and start the audio unit graph Status = AUGraphInitialize(AudioUnitGraph); if (Status == noErr) { Status = AUGraphStart(AudioUnitGraph); } if (Status != noErr) { HandleError(TEXT("Failed to start audio graph!"), true); return false; } return true; }
JNIEXPORT jint JNICALL Java_com_apple_audio_toolbox_AUGraph_AUGraphStart (JNIEnv *, jclass, jint inGraph) { return (jint)AUGraphStart((AUGraph)inGraph); }
int MidiDriver_CORE::open() { OSStatus err = 0; if (isOpen()) return MERR_ALREADY_OPEN; // Open the Music Device. RequireNoErr(NewAUGraph(&_auGraph)); AUNode outputNode, synthNode; #if USE_DEPRECATED_COREAUDIO_API ComponentDescription desc; #else AudioComponentDescription desc; #endif // The default output device desc.componentType = kAudioUnitType_Output; desc.componentSubType = kAudioUnitSubType_DefaultOutput; desc.componentManufacturer = kAudioUnitManufacturer_Apple; desc.componentFlags = 0; desc.componentFlagsMask = 0; #if USE_DEPRECATED_COREAUDIO_API RequireNoErr(AUGraphNewNode(_auGraph, &desc, 0, NULL, &outputNode)); #else RequireNoErr(AUGraphAddNode(_auGraph, &desc, &outputNode)); #endif // The built-in default (softsynth) music device desc.componentType = kAudioUnitType_MusicDevice; desc.componentSubType = kAudioUnitSubType_DLSSynth; desc.componentManufacturer = kAudioUnitManufacturer_Apple; #if USE_DEPRECATED_COREAUDIO_API RequireNoErr(AUGraphNewNode(_auGraph, &desc, 0, NULL, &synthNode)); #else RequireNoErr(AUGraphAddNode(_auGraph, &desc, &synthNode)); #endif // Connect the softsynth to the default output RequireNoErr(AUGraphConnectNodeInput(_auGraph, synthNode, 0, outputNode, 0)); // Open and initialize the whole graph RequireNoErr(AUGraphOpen(_auGraph)); RequireNoErr(AUGraphInitialize(_auGraph)); // Get the music device from the graph. #if USE_DEPRECATED_COREAUDIO_API RequireNoErr(AUGraphGetNodeInfo(_auGraph, synthNode, NULL, NULL, NULL, &_synth)); #else RequireNoErr(AUGraphNodeInfo(_auGraph, synthNode, NULL, &_synth)); #endif // Load custom soundfont, if specified if (ConfMan.hasKey("soundfont")) { FSRef fsref; FSSpec fsSpec; const char *soundfont = ConfMan.get("soundfont").c_str(); err = FSPathMakeRef ((const byte *)soundfont, &fsref, NULL); if (err == noErr) { err = FSGetCatalogInfo (&fsref, kFSCatInfoNone, NULL, NULL, &fsSpec, NULL); } if (err == noErr) { // TODO: We should really check here whether the file contains an // actual soundfont... err = AudioUnitSetProperty ( _synth, kMusicDeviceProperty_SoundBankFSSpec, kAudioUnitScope_Global, 0, &fsSpec, sizeof(fsSpec) ); } if (err != noErr) warning("Failed loading custom sound font '%s' (error %ld)\n", soundfont, (long)err); } #ifdef COREAUDIO_DISABLE_REVERB // Disable reverb mode, as that sucks up a lot of CPU power, which can // be painful on low end machines. // TODO: Make this customizable via a config key? UInt32 usesReverb = 0; AudioUnitSetProperty (_synth, kMusicDeviceProperty_UsesInternalReverb, kAudioUnitScope_Global, 0, &usesReverb, sizeof (usesReverb)); #endif // Finally: Start the graph! RequireNoErr(AUGraphStart(_auGraph)); return 0; bail: if (_auGraph) { AUGraphStop(_auGraph); DisposeAUGraph(_auGraph); _auGraph = 0; } return MERR_CANNOT_CONNECT; }
MidiDevice * openMidiDevice (int errorLevel, const char *device) { MidiDevice *midi; int result; AUNode synthNode, outNode; ComponentDescription cd; UInt32 propVal; if (!(midi = malloc(sizeof(*midi)))) { logMallocError(); return NULL; } /* Create a graph with a software synth and a default output unit. */ cd.componentManufacturer = kAudioUnitManufacturer_Apple; cd.componentFlags = 0; cd.componentFlagsMask = 0; if ((result = NewAUGraph(&midi->graph)) != noErr) { logMessage(errorLevel, "Can't create audio graph component: %d", result); goto err; } cd.componentType = kAudioUnitType_MusicDevice; cd.componentSubType = kAudioUnitSubType_DLSSynth; if ((result = AUGraphNewNode(midi->graph, &cd, 0, NULL, &synthNode)) != noErr) { logMessage(errorLevel, "Can't create software synthersizer component: %d", result); goto err; } cd.componentType = kAudioUnitType_Output; cd.componentSubType = kAudioUnitSubType_DefaultOutput; if ((result = AUGraphNewNode(midi->graph, &cd, 0, NULL, &outNode)) != noErr) { logMessage(errorLevel, "Can't create default output audio component: %d", result); goto err; } if ((result = AUGraphOpen(midi->graph)) != noErr) { logMessage(errorLevel, "Can't open audio graph component: %d", result); goto err; } if ((result = AUGraphConnectNodeInput(midi->graph, synthNode, 0, outNode, 0)) != noErr) { logMessage(errorLevel, "Can't connect synth audio component to output: %d", result); goto err; } if ((result = AUGraphGetNodeInfo(midi->graph, synthNode, 0, 0, 0, &midi->synth)) != noErr) { logMessage(errorLevel, "Can't get audio component for software synth: %d", result); goto err; } if ((result = AUGraphInitialize(midi->graph)) != noErr) { logMessage(errorLevel, "Can't initialize audio graph: %d", result); goto err; } /* Turn off the reverb. The value range is -120 to 40 dB. */ propVal = false; if ((result = AudioUnitSetProperty(midi->synth, kMusicDeviceProperty_UsesInternalReverb, kAudioUnitScope_Global, 0, &propVal, sizeof(propVal))) != noErr) { /* So, having reverb isn't that critical, is it? */ logMessage(LOG_DEBUG, "Can't turn of software synth reverb: %d", result); } /* TODO: Maybe just start the graph when we are going to use it? */ if ((result = AUGraphStart(midi->graph)) != noErr) { logMessage(errorLevel, "Can't start audio graph component: %d", result); goto err; } return midi; err: if (midi->graph) DisposeAUGraph(midi->graph); free(midi); return NULL; }
OutputImplAudioUnit::OutputImplAudioUnit() : mAvailableBuses(), OutputImpl() { OSStatus err = noErr; NewAUGraph( &mGraph ); AudioComponentDescription cd; cd.componentManufacturer = kAudioUnitManufacturer_Apple; cd.componentFlags = 0; cd.componentFlagsMask = 0; //output node cd.componentType = kAudioUnitType_Output; cd.componentSubType = CINDER_AUDIOUNIT_OUTPUT_TYPE; //connect & setup AUGraphOpen( mGraph ); //initialize component - todo add error checking if( AUGraphAddNode( mGraph, &cd, &mOutputNode ) != noErr ) { std::cout << "Error 1!" << std::endl; } if( AUGraphNodeInfo( mGraph, mOutputNode, NULL, &mOutputUnit ) != noErr ) { std::cout << "Error 2!" << std::endl; } UInt32 dsize; #if defined( CINDER_MAC ) //get default output device id and set it as the outdevice for the output unit, unnessary on the iphone dsize = sizeof( AudioDeviceID ); err = AudioHardwareGetProperty( kAudioHardwarePropertyDefaultOutputDevice, &dsize, &mOutputDeviceId ); if( err != noErr ) { std::cout << "Error getting default output device" << std::endl; } err = AudioUnitSetProperty( mOutputUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &mOutputDeviceId, sizeof( mOutputDeviceId ) ); if( err != noErr ) { std::cout << "Error setting current output device" << std::endl; } #endif //Tell the output unit not to reset timestamps //Otherwise sample rate changes will cause sync los UInt32 startAtZero = 0; err = AudioUnitSetProperty( mOutputUnit, kAudioOutputUnitProperty_StartTimestampsAtZero, kAudioUnitScope_Global, 0, &startAtZero, sizeof( startAtZero ) ); if( err != noErr ) { std::cout << "Error telling output unit not to reset timestamps" << std::endl; } //stereo mixer node cd.componentType = kAudioUnitType_Mixer; cd.componentSubType = kAudioUnitSubType_MultiChannelMixer;//kAudioUnitSubType_StereoMixer; AUGraphAddNode( mGraph, &cd, &mMixerNode ); //setup mixer AU err = AUGraphNodeInfo( mGraph, mMixerNode, NULL, &mMixerUnit ); if( err ) { std::cout << "Error 4" << std::endl; } //TODO: cleanup error checking in all of this //check the element count, if it's less than our default element count, increase, or else just leave it alone err = AudioUnitGetProperty( mMixerUnit, kAudioUnitProperty_ElementCount, kAudioUnitScope_Input, 0, &mNumberBuses, &dsize ); if( err ) { std::cout << "Error getting mixer unit input elements" << std::endl; } if( mNumberBuses < sDefaultNumberBuses ) { mNumberBuses = sDefaultNumberBuses; err = AudioUnitSetProperty( mMixerUnit, kAudioUnitProperty_ElementCount, kAudioUnitScope_Input, 0, &mNumberBuses, sizeof(mNumberBuses) ); if( err ) { std::cout << "Error setting mixer unit input elements" << std::endl; } } for( uint32_t i = 1; i <= mNumberBuses; i++ ) { mAvailableBuses.push( mNumberBuses - i ); } AUGraphConnectNodeInput( mGraph, mMixerNode, 0, mOutputNode, 0 ); AudioStreamBasicDescription outDesc; UInt32 size = sizeof( outDesc ); err = AudioUnitGetProperty( mOutputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &outDesc, &size ); if( err ) { std::cout << "Error getting output unit stream format" << std::endl; } AUGraphInitialize( mGraph ); //Do all StreamFormat getting/setting after initialization, //since that's when the output unit is actually hooked up to the hardware dsize = sizeof( AudioStreamBasicDescription ); mPlayerDescription = new AudioStreamBasicDescription; err = AudioUnitGetProperty( mOutputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, mPlayerDescription, &dsize ); if( err ) { std::cout << "Error reading output unit stream format" << std::endl; } err = AudioUnitSetProperty( mMixerUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, mPlayerDescription, dsize ); if( err ) { std::cout << "Error setting mixer unit output stream format" << std::endl; } err = AudioUnitSetProperty( mOutputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, mPlayerDescription, dsize ); if( err ) { std::cout << "Error setting output unit input stream format" << std::endl; } //race condition work around?? usleep( 10 * 1000 ); //TODO: tell the output AU about the order of the channels if there are more than 2 // turn metering ON //UInt32 data = 1; //AudioUnitSetProperty( mMixerUnit, kAudioUnitProperty_MeteringMode, kAudioUnitScope_Global, 0, &data, sizeof(data) ); err = AudioUnitSetParameter( mMixerUnit, kMultiChannelMixerParam_Volume, kAudioUnitScope_Output, 0, CINDER_DEFAULT_VOLUME, 0 ); if( err ) { std::cout << "error setting default volume" << std::cout; } err = AUGraphStart( mGraph ); if( err ) { //throw } }
int main(int argc, char *argv[]) { AUGraph audioGraph; NewAUGraph(&audioGraph); AudioComponentDescription cd; AUNode outputNode; AudioUnit outputUnit; cd.componentManufacturer = kAudioUnitManufacturer_Apple; cd.componentFlags = 0; cd.componentFlagsMask = 0; cd.componentType = kAudioUnitType_Output; cd.componentSubType = kAudioUnitSubType_DefaultOutput; AUGraphAddNode(audioGraph, &cd, &outputNode); AUGraphNodeInfo(audioGraph, outputNode, &cd, &outputUnit); AUNode mixerNode; AudioUnit mixerUnit; cd.componentManufacturer = kAudioUnitManufacturer_Apple; cd.componentFlags = 0; cd.componentFlagsMask = 0; cd.componentType = kAudioUnitType_Mixer; cd.componentSubType = kAudioUnitSubType_StereoMixer; AUGraphAddNode(audioGraph, &cd, &mixerNode); AUGraphNodeInfo(audioGraph, mixerNode, &cd, &mixerUnit); AUGraphConnectNodeInput(audioGraph, mixerNode, 0, outputNode, 0); AUGraphOpen(audioGraph); AUGraphInitialize(audioGraph); AUGraphStart(audioGraph); AUNode synthNode; AudioUnit synthUnit; cd.componentManufacturer = kAudioUnitManufacturer_Apple; cd.componentFlags = 0; cd.componentFlagsMask = 0; cd.componentType = kAudioUnitType_MusicDevice; cd.componentSubType = kAudioUnitSubType_DLSSynth; AUGraphAddNode(audioGraph, &cd, &synthNode); AUGraphNodeInfo(audioGraph, synthNode, &cd, &synthUnit); AUGraphConnectNodeInput(audioGraph, synthNode, 0, mixerNode, 0); AUGraphUpdate(audioGraph, NULL); CAShow(audioGraph); MusicDeviceMIDIEvent(synthUnit, 0x90, 60, 127, 0); sleep(1); MusicDeviceMIDIEvent(synthUnit, 0x90, 62, 127, 0); sleep(1); MusicDeviceMIDIEvent(synthUnit, 0x90, 64, 127, 0); sleep(1); sleep(5); return(0); }
/** * Initializes the audio device and creates sources. * * @return true if initialization was successful, false otherwise */ bool FCoreAudioDevice::InitializeHardware() { if (IsRunningDedicatedServer()) { return false; } // Load ogg and vorbis dlls if they haven't been loaded yet LoadVorbisLibraries(); InverseTransform = FMatrix::Identity; for( SInt32 Index = 0; Index < MAX_AUDIOCHANNELS; ++Index ) { Mixer3DInputStatus[ Index ] = false; } for( SInt32 Index = 0; Index < MAX_MULTICHANNEL_AUDIOCHANNELS; ++Index ) { MatrixMixerInputStatus[ Index ] = false; } // Make sure the output audio device exists AudioDeviceID HALDevice; UInt32 Size = sizeof( AudioDeviceID ); AudioObjectPropertyAddress PropertyAddress; PropertyAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice; PropertyAddress.mScope = kAudioObjectPropertyScopeGlobal; PropertyAddress.mElement = kAudioObjectPropertyElementMaster; OSStatus Status = AudioObjectGetPropertyData( kAudioObjectSystemObject, &PropertyAddress, 0, NULL, &Size, &HALDevice ); if( Status != noErr ) { UE_LOG(LogInit, Log, TEXT( "No audio devices found!" ) ); return false; } Status = NewAUGraph( &AudioUnitGraph ); if( Status != noErr ) { UE_LOG(LogInit, Log, TEXT( "Failed to create audio unit graph!" ) ); return false; } AudioComponentDescription Desc; Desc.componentFlags = 0; Desc.componentFlagsMask = 0; Desc.componentType = kAudioUnitType_Output; Desc.componentSubType = kAudioUnitSubType_DefaultOutput; Desc.componentManufacturer = kAudioUnitManufacturer_Apple; Status = AUGraphAddNode( AudioUnitGraph, &Desc, &OutputNode ); if( Status == noErr ) { Status = AUGraphOpen( AudioUnitGraph ); if( Status == noErr ) { Status = AUGraphNodeInfo( AudioUnitGraph, OutputNode, NULL, &OutputUnit ); if( Status == noErr ) { Status = AudioUnitInitialize( OutputUnit ); } } } if( Status != noErr ) { UE_LOG(LogInit, Log, TEXT( "Failed to initialize audio output unit!" ) ); Teardown(); return false; } Desc.componentFlags = 0; Desc.componentFlagsMask = 0; Desc.componentType = kAudioUnitType_Mixer; Desc.componentSubType = kAudioUnitSubType_3DMixer; Desc.componentManufacturer = kAudioUnitManufacturer_Apple; Status = AUGraphAddNode( AudioUnitGraph, &Desc, &Mixer3DNode ); if( Status == noErr ) { Status = AUGraphNodeInfo( AudioUnitGraph, Mixer3DNode, NULL, &Mixer3DUnit ); if( Status == noErr ) { Status = AudioUnitInitialize( Mixer3DUnit ); } } if( Status != noErr ) { UE_LOG(LogInit, Log, TEXT( "Failed to initialize audio 3D mixer unit!" ) ); Teardown(); return false; } Desc.componentFlags = 0; Desc.componentFlagsMask = 0; Desc.componentType = kAudioUnitType_Mixer; Desc.componentSubType = kAudioUnitSubType_MatrixMixer; Desc.componentManufacturer = kAudioUnitManufacturer_Apple; Status = AUGraphAddNode( AudioUnitGraph, &Desc, &MatrixMixerNode ); if( Status == noErr ) { Status = AUGraphNodeInfo( AudioUnitGraph, MatrixMixerNode, NULL, &MatrixMixerUnit ); // Set number of buses for input uint32 NumBuses = MAX_MULTICHANNEL_AUDIOCHANNELS; Size = sizeof( NumBuses ); Status = AudioUnitSetProperty( MatrixMixerUnit, kAudioUnitProperty_ElementCount, kAudioUnitScope_Input, 0, &NumBuses, Size ); if( Status == noErr ) { // Set number fo buses for output NumBuses = 1; Status = AudioUnitSetProperty( MatrixMixerUnit, kAudioUnitProperty_ElementCount, kAudioUnitScope_Output, 0, &NumBuses, Size ); } if( Status != noErr ) { UE_LOG(LogInit, Log, TEXT( "Failed to setup audio matrix mixer unit!" ) ); Teardown(); return false; } // Get default input stream format Size = sizeof( AudioStreamBasicDescription ); Status = AudioUnitGetProperty( MatrixMixerUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &MatrixMixerInputFormat, &Size ); // Set output stream format to SPEAKER_COUT (6 channels) MatrixMixerInputFormat.mChannelsPerFrame = SPEAKER_COUNT; MatrixMixerInputFormat.mFramesPerPacket = 1; MatrixMixerInputFormat.mBytesPerPacket = MatrixMixerInputFormat.mBytesPerFrame; MatrixMixerInputFormat.mFormatFlags |= kAudioFormatFlagIsNonInterleaved; for( int32 Index = 0; Index < MAX_MULTICHANNEL_AUDIOCHANNELS; Index++ ) { Status = AudioUnitSetProperty( MatrixMixerUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, Index, &MatrixMixerInputFormat, Size ); if( Status != noErr ) { UE_LOG(LogInit, Log, TEXT( "Failed to setup audio matrix mixer unit input format!" ) ); Teardown(); return false; } } // Set output stream format Size = sizeof( AudioStreamBasicDescription ); Status = AudioUnitGetProperty( MatrixMixerUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &MatrixMixerOutputFormat, &Size ); if( Status != noErr ) { UE_LOG(LogInit, Log, TEXT( "Failed to setup audio matrix mixer unit output format!" ) ); Teardown(); return false; } // Initialize Matrix Mixer unit Status = AudioUnitInitialize( MatrixMixerUnit ); if( Status != noErr ) { UE_LOG(LogInit, Log, TEXT( "Failed to initialize audio matrix mixer unit!" ) ); Teardown(); return false; } // Enable Output AudioUnitSetParameter( MatrixMixerUnit, kMatrixMixerParam_Enable, kAudioUnitScope_Output, 0, 1.0, 0 ); // Set Output volume AudioUnitSetParameter( MatrixMixerUnit, kMatrixMixerParam_Volume, kAudioUnitScope_Output, 0, 1.0, 0 ); AudioUnitSetParameter( MatrixMixerUnit, kMatrixMixerParam_Volume, kAudioUnitScope_Output, 1, 1.0, 0 ); // Set Master volume AudioUnitSetParameter( MatrixMixerUnit, kMatrixMixerParam_Volume, kAudioUnitScope_Global, 0xFFFFFFFF, 1.0, 0 ); } Size = sizeof( AudioStreamBasicDescription ); Status = AudioUnitGetProperty( Mixer3DUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &Mixer3DFormat, &Size ); if( Status == noErr ) { // Connect 3D Mixer to Output node Status = AUGraphConnectNodeInput( AudioUnitGraph, Mixer3DNode, 0, OutputNode, 0 ); } if( Status != noErr ) { UE_LOG(LogInit, Log, TEXT( "Failed to start audio graph!" ) ); Teardown(); return false; } // Connect Matrix Mixer to 3D Mixer node Status = AUGraphConnectNodeInput( AudioUnitGraph, MatrixMixerNode, 0, Mixer3DNode, 0 ); Mixer3DInputStatus[0] = true; if( Status != noErr ) { UE_LOG(LogInit, Log, TEXT( "Failed to start audio graph!" ) ); Teardown(); return false; } Status = AUGraphInitialize( AudioUnitGraph ); if( Status == noErr ) { Status = AUGraphStart( AudioUnitGraph ); } if( Status != noErr ) { UE_LOG(LogInit, Log, TEXT( "Failed to start audio graph!" ) ); Teardown(); return false; } return true; }