virtual IAudioFormat* GetAudioFormat() { if (!Singleton) { LoadVorbisLibraries(); Singleton = new FAudioFormatOgg(); } return Singleton; }
/** * 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; }