예제 #1
0
OSStatus CAPlayThrough::MakeGraph()
{
	OSStatus err = noErr;
	AudioComponentDescription varispeedDesc,outDesc, mixerDesc;
	
	//Q:Why do we need a varispeed unit?
	//A:If the input device and the output device are running at different sample rates
	//we will need to move the data coming to the graph slower/faster to avoid a pitch change.
	varispeedDesc.componentType = kAudioUnitType_FormatConverter;
	varispeedDesc.componentSubType = kAudioUnitSubType_Varispeed;
	varispeedDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
	varispeedDesc.componentFlags = 0;        
	varispeedDesc.componentFlagsMask = 0;     
  
	outDesc.componentType = kAudioUnitType_Output;
	outDesc.componentSubType = kAudioUnitSubType_DefaultOutput;
	outDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
	outDesc.componentFlags = 0;
	outDesc.componentFlagsMask = 0;
	
	mixerDesc.componentType = kAudioUnitType_Mixer;
	mixerDesc.componentSubType = kAudioUnitSubType_StereoMixer;
	mixerDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
	mixerDesc.componentFlags = 0;
	mixerDesc.componentFlagsMask = 0;
	//////////////////////////
	///MAKE NODES
	//This creates a node in the graph that is an AudioUnit, using
	//the supplied ComponentDescription to find and open that unit	
	err = AUGraphAddNode(mGraph, &varispeedDesc, &mVarispeedNode);
	checkErr(err);
	//add a mixer node after the input to use for metering
	err = AUGraphAddNode(mGraph, &mixerDesc, &mMixerNode);
	checkErr(err);
	err = AUGraphAddNode(mGraph, &outDesc, &mOutputNode);
	checkErr(err);
	
	//Get Audio Units from AUGraph node
	err = AUGraphNodeInfo(mGraph, mVarispeedNode, NULL, &mVarispeedUnit);   
	checkErr(err);
	//get the mixer node
	err = AUGraphNodeInfo(mGraph, mMixerNode, NULL, &mMixerUnit);
	checkErr(err);
	err = AUGraphNodeInfo(mGraph, mOutputNode, NULL, &mOutputUnit);   
	checkErr(err);
	
	// don't connect nodes until the varispeed unit has input and output formats set

	return err;
}
예제 #2
0
/* we're looking for the sequence output audiounit. */
static OSStatus
GetSequenceAudioUnit(MusicSequence sequence, AudioUnit *aunit)
{
    AUGraph graph;
    UInt32 nodecount, i;
    OSStatus err;

    err = MusicSequenceGetAUGraph(sequence, &graph);
    if (err != noErr)
        return err;

    err = AUGraphGetNodeCount(graph, &nodecount);
    if (err != noErr)
        return err;

    for (i = 0; i < nodecount; i++) {
        AUNode node;

        if (AUGraphGetIndNode(graph, i, &node) != noErr)
            continue;  /* better luck next time. */

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 /* this is deprecated, but works back to 10.0 */
        {
            struct ComponentDescription desc;
            UInt32 classdatasize = 0;
            void *classdata = NULL;
            err = AUGraphGetNodeInfo(graph, node, &desc, &classdatasize,
                                     &classdata, aunit);
            if (err != noErr)
                continue;
            else if (desc.componentType != kAudioUnitType_Output)
                continue;
            else if (desc.componentSubType != kAudioUnitSubType_DefaultOutput)
                continue;
        }
        #else  /* not deprecated, but requires 10.5 or later */
        {
        # if !defined(AUDIO_UNIT_VERSION) || ((AUDIO_UNIT_VERSION + 0) < 1060)
         /* AUGraphAddNode () is changed to take an AudioComponentDescription*
          * desc parameter instead of a ComponentDescription* in the 10.6 SDK.
          * AudioComponentDescription is in 10.6 or newer, but it is actually
          * the same as struct ComponentDescription with 20 bytes of size and
          * the same offsets of all members, therefore, is binary compatible. */
        #   define AudioComponentDescription ComponentDescription
        # endif
            AudioComponentDescription desc;
            if (AUGraphNodeInfo(graph, node, &desc, aunit) != noErr)
                continue;
            else if (desc.componentType != kAudioUnitType_Output)
                continue;
            else if (desc.componentSubType != kAudioUnitSubType_DefaultOutput)
                continue;
        }
        #endif

        return noErr;  /* found it! */
    }

    return kAUGraphErr_NodeNotFound;
}
예제 #3
0
OSStatus FCoreAudioSoundSource::CreateAudioUnit( OSType Type, OSType SubType, OSType Manufacturer, AudioStreamBasicDescription* InputFormat, AudioStreamBasicDescription* OutputFormat, AUNode* OutNode, AudioUnit* OutUnit )
{
	AudioComponentDescription Desc;
	Desc.componentFlags = 0;
	Desc.componentFlagsMask = 0;
	Desc.componentType = Type;
	Desc.componentSubType = SubType;
	Desc.componentManufacturer = Manufacturer;

	OSStatus Status = AUGraphAddNode( AudioDevice->GetAudioUnitGraph(), &Desc, OutNode );
	if( Status == noErr )
	{
		Status = AUGraphNodeInfo( AudioDevice->GetAudioUnitGraph(), *OutNode, NULL, OutUnit );
	}

	if( Status == noErr )
	{
		if( InputFormat )
		{
			Status = AudioUnitSetProperty( *OutUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, InputFormat, sizeof( AudioStreamBasicDescription ) );
		}
		if( Status == noErr )
		{
			if( OutputFormat )
			{
				Status = AudioUnitSetProperty( *OutUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, OutputFormat, sizeof( AudioStreamBasicDescription ) );
			}
		}
	}

	return Status;
}
예제 #4
0
bool CCoreAudioUnit::Open(AUGraph audioGraph, AudioComponentDescription desc)
{
  if (m_audioUnit)
    Close();

  OSStatus ret;

  m_Initialized = false;

  ret = AUGraphAddNode(audioGraph, &desc, &m_audioNode);
  if (ret)
  {
    CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error add m_outputNode. Error = %s", GetError(ret).c_str());
    return false;
  }

  ret = AUGraphNodeInfo(audioGraph, m_audioNode, NULL, &m_audioUnit);
  if (ret)
  {
    CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error getting m_outputNode. Error = %s", GetError(ret).c_str());
    return false;
  }

  m_audioGraph  = audioGraph;
  m_Initialized = true;

  Start();

  return true;
}
예제 #5
0
	OSStatus get_next_node_info()
	{
		return AUGraphNodeInfo(
				m_graph,
				m_node_details[m_node_count].m_node,
				NULL,
				&m_node_details[m_node_count].m_unit);
	}
예제 #6
0
/** Set the volume of the current sequence. */
static void DoSetVolume()
{
	if (_sequence == NULL) return;

	AUGraph graph;
	MusicSequenceGetAUGraph(_sequence, &graph);

	AudioUnit output_unit = NULL;

	/* Get output audio unit */
	UInt32 node_count = 0;
	AUGraphGetNodeCount(graph, &node_count);
	for (UInt32 i = 0; i < node_count; i++) {
		AUNode node;
		AUGraphGetIndNode(graph, i, &node);

		AudioUnit unit;
		OSType comp_type = 0;

#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
		if (MacOSVersionIsAtLeast(10, 5, 0)) {
			/* The 10.6 SDK has changed the function prototype of
			 * AUGraphNodeInfo. This is a binary compatible change,
			 * but we need to get the type declaration right or
			 * risk compilation errors. The header AudioComponent.h
			 * was introduced in 10.6 so use it to decide which
			 * type definition to use. */
#ifdef __AUDIOCOMPONENT_H__
			AudioComponentDescription desc;
#else
			ComponentDescription desc;
#endif
			AUGraphNodeInfo(graph, node, &desc, &unit);
			comp_type = desc.componentType;
		} else
#endif
		{
#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
			ComponentDescription desc;
			AUGraphGetNodeInfo(graph, node, &desc, NULL, NULL, &unit);
			comp_type = desc.componentType;
#endif
		}

		if (comp_type == kAudioUnitType_Output) {
			output_unit = unit;
			break;
		}
	}
	if (output_unit == NULL) {
		DEBUG(driver, 1, "cocoa_m: Failed to get output node to set volume");
		return;
	}

	Float32 vol = _volume / 127.0f;  // 0 - +127 -> 0.0 - 1.0
	AudioUnitSetParameter(output_unit, kHALOutputParam_Volume, kAudioUnitScope_Global, 0, vol, 0);
}
AudioUnitNode::AudioUnitNode(AUGraph graph, const AudioComponentDescription& cd) : mGraph(graph)
{
    OSStatus err;
    err = AUGraphAddNode(graph, &cd, &mNode);
    if ((int)err == -2005) {
        AudioNodeException exception("badComponentType.");
        throw exception;
    }
    err = AUGraphNodeInfo(graph, mNode, NULL, &mUnit);
}
예제 #8
0
/* we're looking for the sequence output audiounit. */
static OSStatus
GetSequenceAudioUnit(MusicSequence sequence, AudioUnit *aunit)
{
    AUGraph graph;
    UInt32 nodecount, i;
    OSStatus err;

    err = MusicSequenceGetAUGraph(sequence, &graph);
    if (err != noErr)
        return err;

    err = AUGraphGetNodeCount(graph, &nodecount);
    if (err != noErr)
        return err;

    for (i = 0; i < nodecount; i++) {
        AUNode node;

        if (AUGraphGetIndNode(graph, i, &node) != noErr)
            continue;  /* better luck next time. */

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 /* this is deprecated, but works back to 10.0 */
        {
            struct ComponentDescription desc;
            UInt32 classdatasize = 0;
            void *classdata = NULL;
            err = AUGraphGetNodeInfo(graph, node, &desc, &classdatasize,
                                     &classdata, aunit);
            if (err != noErr)
                continue;
            else if (desc.componentType != kAudioUnitType_Output)
                continue;
            else if (desc.componentSubType != kAudioUnitSubType_DefaultOutput)
                continue;
        }
        #else  /* not deprecated, but requires 10.5 or later */
        {
            AudioComponentDescription desc;
            if (AUGraphNodeInfo(graph, node, &desc, aunit) != noErr)
                continue;
            else if (desc.componentType != kAudioUnitType_Output)
                continue;
            else if (desc.componentSubType != kAudioUnitSubType_DefaultOutput)
                continue;
        }
        #endif

        return noErr;  /* found it! */
    }

    return kAUGraphErr_NodeNotFound;
}
예제 #9
0
OSStatus GetSynthFromGraph (AUGraph& inGraph, AudioUnit& outSynth)
{	
	UInt32 nodeCount;
	OSStatus result = noErr;
	FailIf ((result = AUGraphGetNodeCount (inGraph, &nodeCount)), fail, "AUGraphGetNodeCount");
	
	for (UInt32 i = 0; i < nodeCount; ++i) 
	{
		AUNode node;
		FailIf ((result = AUGraphGetIndNode(inGraph, i, &node)), fail, "AUGraphGetIndNode");

		AudioComponentDescription desc;
		FailIf ((result = AUGraphNodeInfo(inGraph, node, &desc, 0)), fail, "AUGraphNodeInfo");
		
		if (desc.componentType == kAudioUnitType_MusicDevice) 
		{
			FailIf ((result = AUGraphNodeInfo(inGraph, node, 0, &outSynth)), fail, "AUGraphNodeInfo");
			return noErr;
		}
	}
	
fail:		// didn't find the synth AU
	return -1;
}
예제 #10
0
OSStatus SetUpGraph (AUGraph &inGraph, UInt32 numFrames, Float64 &sampleRate, bool isOffline)
{
	OSStatus result = noErr;
	AudioUnit outputUnit = 0;
	AUNode outputNode;
	
	// the frame size is the I/O size to the device
	// the device is going to run at a sample rate it is set at
	// so, when we set this, we also have to set the max frames for the graph nodes
	UInt32 nodeCount;
	FailIf ((result = AUGraphGetNodeCount (inGraph, &nodeCount)), home, "AUGraphGetNodeCount");

	for (int i = 0; i < (int)nodeCount; ++i) 
	{
		AUNode node;
		FailIf ((result = AUGraphGetIndNode(inGraph, i, &node)), home, "AUGraphGetIndNode");

		AudioComponentDescription desc;
		AudioUnit unit;
		FailIf ((result = AUGraphNodeInfo(inGraph, node, &desc, &unit)), home, "AUGraphNodeInfo");
		
		if (desc.componentType == kAudioUnitType_Output) 
		{
			if (outputUnit == 0) {
				outputUnit = unit;
				FailIf ((result = AUGraphNodeInfo(inGraph, node, 0, &outputUnit)), home, "AUGraphNodeInfo");
				
				if (!isOffline) {
					// these two properties are only applicable if its a device we're playing too
					FailIf ((result = AudioUnitSetProperty (outputUnit, 
													kAudioDevicePropertyBufferFrameSize, 
													kAudioUnitScope_Output, 0,
													&numFrames, sizeof(numFrames))), home, "AudioUnitSetProperty: kAudioDevicePropertyBufferFrameSize");
				
					FailIf ((result = AudioUnitAddPropertyListener (outputUnit, 
													kAudioDeviceProcessorOverload, 
													OverlaodListenerProc, 0)), home, "AudioUnitAddPropertyListener: kAudioDeviceProcessorOverload");

					// if we're rendering to the device, then we render at its sample rate
					UInt32 theSize;
					theSize = sizeof(sampleRate);
					
					FailIf ((result = AudioUnitGetProperty (outputUnit,
												kAudioUnitProperty_SampleRate,
												kAudioUnitScope_Output, 0,
												&sampleRate, &theSize)), home, "AudioUnitGetProperty: kAudioUnitProperty_SampleRate");
				} else {
						// remove device output node and add generic output
					FailIf ((result = AUGraphRemoveNode (inGraph, node)), home, "AUGraphRemoveNode");
					desc.componentSubType = kAudioUnitSubType_GenericOutput;
					FailIf ((result = AUGraphAddNode (inGraph, &desc, &node)), home, "AUGraphAddNode");
					FailIf ((result = AUGraphNodeInfo(inGraph, node, NULL, &unit)), home, "AUGraphNodeInfo");
					outputUnit = unit;
					outputNode = node;
					
					// we render the output offline at the desired sample rate
					FailIf ((result = AudioUnitSetProperty (outputUnit,
												kAudioUnitProperty_SampleRate,
												kAudioUnitScope_Output, 0,
												&sampleRate, sizeof(sampleRate))), home, "AudioUnitSetProperty: kAudioUnitProperty_SampleRate");
				}
				// ok, lets start the loop again now and do it all...
				i = -1;
			}
		}
		else
		{
				// we only have to do this on the output side
				// as the graph's connection mgmt will propogate this down.
			if (outputUnit) {	
					// reconnect up to the output unit if we're offline
				if (isOffline && desc.componentType != kAudioUnitType_MusicDevice) {
					FailIf ((result = AUGraphConnectNodeInput (inGraph, node, 0, outputNode, 0)), home, "AUGraphConnectNodeInput");
				}
				
				FailIf ((result = AudioUnitSetProperty (unit,
											kAudioUnitProperty_SampleRate,
											kAudioUnitScope_Output, 0,
											&sampleRate, sizeof(sampleRate))), home, "AudioUnitSetProperty: kAudioUnitProperty_SampleRate");
			
			
			}
		}
		FailIf ((result = AudioUnitSetProperty (unit, kAudioUnitProperty_MaximumFramesPerSlice,
												kAudioUnitScope_Global, 0,
												&numFrames, sizeof(numFrames))), home, "AudioUnitSetProperty: kAudioUnitProperty_MaximumFramesPerSlice");
	}
	
home:
	return result;
}
예제 #11
0
파일: main.cpp 프로젝트: ebakan/SMS
void MakeSimpleGraph (AUGraph &theGraph, CAAudioUnit &fileAU, CAStreamBasicDescription &fileFormat, AudioFileID audioFile)
{
	XThrowIfError (NewAUGraph (&theGraph), "NewAUGraph");
	
	CAComponentDescription cd;

	// output node
	cd.componentType = kAudioUnitType_Output;
	cd.componentSubType = kAudioUnitSubType_DefaultOutput;
	cd.componentManufacturer = kAudioUnitManufacturer_Apple;

	AUNode outputNode;
	XThrowIfError (AUGraphAddNode (theGraph, &cd, &outputNode), "AUGraphAddNode");
	
	// file AU node
	AUNode fileNode;
	cd.componentType = kAudioUnitType_Generator;
	cd.componentSubType = kAudioUnitSubType_AudioFilePlayer;
	
	XThrowIfError (AUGraphAddNode (theGraph, &cd, &fileNode), "AUGraphAddNode");
	
	// connect & setup
	XThrowIfError (AUGraphOpen (theGraph), "AUGraphOpen");
	
	// install overload listener to detect when something is wrong
	AudioUnit anAU;
	XThrowIfError (AUGraphNodeInfo(theGraph, fileNode, NULL, &anAU), "AUGraphNodeInfo");
	
	fileAU = CAAudioUnit (fileNode, anAU);

// prepare the file AU for playback
// set its output channels
	XThrowIfError (fileAU.SetNumberChannels (kAudioUnitScope_Output, 0, fileFormat.NumberChannels()), "SetNumberChannels");

// set the output sample rate of the file AU to be the same as the file:
	XThrowIfError (fileAU.SetSampleRate (kAudioUnitScope_Output, 0, fileFormat.mSampleRate), "SetSampleRate");

// load in the file 
	XThrowIfError (fileAU.SetProperty(kAudioUnitProperty_ScheduledFileIDs, 
						kAudioUnitScope_Global, 0, &audioFile, sizeof(audioFile)), "SetScheduleFile");


	XThrowIfError (AUGraphConnectNodeInput (theGraph, fileNode, 0, outputNode, 0), "AUGraphConnectNodeInput");

// AT this point we make sure we have the file player AU initialized
// this also propogates the output format of the AU to the output unit
	XThrowIfError (AUGraphInitialize (theGraph), "AUGraphInitialize");
	
	// workaround a race condition in the file player AU
	usleep (10 * 1000);

// if we have a surround file, then we should try to tell the output AU what the order of the channels will be
	if (fileFormat.NumberChannels() > 2) {
		UInt32 layoutSize = 0;
		OSStatus err;
		XThrowIfError (err = AudioFileGetPropertyInfo (audioFile, kAudioFilePropertyChannelLayout, &layoutSize, NULL),
								"kAudioFilePropertyChannelLayout");
		
		if (!err && layoutSize) {
			char* layout = new char[layoutSize];
			
			err = AudioFileGetProperty(audioFile, kAudioFilePropertyChannelLayout, &layoutSize, layout);
			XThrowIfError (err, "Get Layout From AudioFile");
			
			// ok, now get the output AU and set its layout
			XThrowIfError (AUGraphNodeInfo(theGraph, outputNode, NULL, &anAU), "AUGraphNodeInfo");
			
			err = AudioUnitSetProperty (anAU, kAudioUnitProperty_AudioChannelLayout, 
							kAudioUnitScope_Input, 0, layout, layoutSize);
			XThrowIfError (err, "kAudioUnitProperty_AudioChannelLayout");
			
			delete [] layout;
		}
	}
}
void setupAUGraph(MyMIDIPlayer *player) {
	
	CheckError(NewAUGraph(&player->graph),
			   "Couldn't open AU Graph");
	
	// generate description that will match our output device (speakers)
	AudioComponentDescription outputcd = {0};
	outputcd.componentType = kAudioUnitType_Output;
	outputcd.componentSubType = kAudioUnitSubType_DefaultOutput;
	outputcd.componentManufacturer = kAudioUnitManufacturer_Apple;
	
	// adds a node with above description to the graph
	AUNode outputNode;
	CheckError(AUGraphAddNode(player->graph, &outputcd, &outputNode),
			   "AUGraphAddNode[kAudioUnitSubType_DefaultOutput] failed");
	
	
	AudioComponentDescription instrumentcd = {0};
	instrumentcd.componentManufacturer = kAudioUnitManufacturer_Apple;
	instrumentcd.componentType = kAudioUnitType_MusicDevice;
	instrumentcd.componentSubType = kAudioUnitSubType_Sampler;  // changed!
	
	AUNode instrumentNode;
	CheckError(AUGraphAddNode(player->graph, &instrumentcd, &instrumentNode),
			   "AUGraphAddNode[kAudioUnitSubType_DLSSynth] failed");
	
	// opening the graph opens all contained audio units but does not allocate any resources yet
	CheckError(AUGraphOpen(player->graph),
			   "AUGraphOpen failed");
	
	// get the reference to the AudioUnit object for the instrument graph node
	CheckError(AUGraphNodeInfo(player->graph, instrumentNode, NULL, &player->instrumentUnit),
			   "AUGraphNodeInfo failed");
	
	// connect the output source of the instrument AU to the input source of the output node
	CheckError(AUGraphConnectNodeInput(player->graph, instrumentNode, 0, outputNode, 0),
			   "AUGraphConnectNodeInput");
	
	// now initialize the graph (causes resources to be allocated)
	CheckError(AUGraphInitialize(player->graph),
			   "AUGraphInitialize failed");
	
	
	// configure the AUSampler
	// 2nd parameter obviously needs to be a full path on your system, and 3rd param is its length in characters
	CFURLRef presetURL = CFURLCreateFromFileSystemRepresentation(
						    kCFAllocatorDefault,
							"/Users/cadamson/Library/Audio/Presets/Apple/AUSampler/ch12-aupreset.aupreset",
							77,
							false);
	
	// load preset file into a CFDataRef
	CFDataRef presetData = NULL;
	SInt32 errorCode = noErr;
	Boolean gotPresetData =
	CFURLCreateDataAndPropertiesFromResource(kCFAllocatorSystemDefault,
											 presetURL,
											 &presetData,
											 NULL,
											 NULL,
											 &errorCode);
	CheckError(errorCode, "couldn't load .aupreset data");
	CheckError(!gotPresetData, "couldn't load .aupreset data");
	
	// convert this into a property list
	CFPropertyListFormat presetPlistFormat = {0};
	CFErrorRef presetPlistError = NULL;
	CFPropertyListRef presetPlist = CFPropertyListCreateWithData(kCFAllocatorSystemDefault,
																 presetData,
																 kCFPropertyListImmutable,
																 &presetPlistFormat, 
																 &presetPlistError);
	if (presetPlistError) {
		printf ("Couldn't create plist object for .aupreset");
		return;
	}
	
	// set this plist as the kAudioUnitProperty_ClassInfo on _auSampler
	if (presetPlist) {
		CheckError(AudioUnitSetProperty(player->instrumentUnit,
										kAudioUnitProperty_ClassInfo,
										kAudioUnitScope_Global,
										0,
										&presetPlist, 
										sizeof(presetPlist)),
				   "Couldn't set aupreset plist as sampler's class info");
	}

	
	
}
예제 #13
0
    CoreAudioChkError(AUGraphAddNode(*theGraph, &cd, &outputNode), "AUGraphAddNode Output",);

    /* Initialize and add the AU node */
    AUNode fileNode;
    cd.componentType = kAudioUnitType_Generator;
    cd.componentSubType = kAudioUnitSubType_AudioFilePlayer;

    CoreAudioChkError(AUGraphAddNode(*theGraph, &cd, &fileNode), "AUGraphAddNode AU",);

    /* Make connections */
    CoreAudioChkError(AUGraphOpen(*theGraph), "AUGraphOpen",);

    /* Set Schedule properties and initialize the graph with the file */
    AudioUnit anAU;
    memset(&anAU, 0, sizeof(anAU));
    CoreAudioChkError(AUGraphNodeInfo(*theGraph, fileNode, NULL, &anAU), "AUGraphNodeInfo",);

    *fileAU = anAU;

    CoreAudioChkError(AudioUnitSetProperty(*fileAU, kAudioUnitProperty_ScheduledFileIDs,
                                           kAudioUnitScope_Global, 0, &audioFile, sizeof(audioFile)),
                      "SetScheduleFile",);
    CoreAudioChkError(AUGraphConnectNodeInput(*theGraph, fileNode, 0, outputNode, 0), "AUGraphConnectNodeInput",);
    CoreAudioChkError(AUGraphInitialize(*theGraph), "AUGraphInitialize",);
}

#elif HAVE_CANBERRA
#include <canberra.h>
#include <canberra-gtk.h>
#endif
예제 #14
0
        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();
        }
예제 #15
0
void WriteOutputFile (const char*	outputFilePath, 
					OSType			dataFormat, 
					Float64			srate, 
					MusicTimeStamp	sequenceLength, 
					bool			shouldPrint,
					AUGraph			inGraph,
					UInt32			numFrames,
					MusicPlayer		player)
{
		// delete existing output  file
	TestFile (outputFilePath, true);
	OSStatus result = 0;
	UInt32 size;

	CAStreamBasicDescription outputFormat;
	outputFormat.mChannelsPerFrame = 2;
	outputFormat.mSampleRate = srate;
	outputFormat.mFormatID = dataFormat;
	
	AudioFileTypeID destFileType;
	CAAudioFileFormats::Instance()->InferFileFormatFromFilename (outputFilePath, destFileType);
	
	if (dataFormat == kAudioFormatLinearPCM) {
		outputFormat.mBytesPerPacket = outputFormat.mChannelsPerFrame * 2;
		outputFormat.mFramesPerPacket = 1;
		outputFormat.mBytesPerFrame = outputFormat.mBytesPerPacket;
		outputFormat.mBitsPerChannel = 16;
		
		if (destFileType == kAudioFileWAVEType)
			outputFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger
								| kLinearPCMFormatFlagIsPacked;
		else
			outputFormat.mFormatFlags = kLinearPCMFormatFlagIsBigEndian
								| kLinearPCMFormatFlagIsSignedInteger
								| kLinearPCMFormatFlagIsPacked;
	} else {
		// use AudioFormat API to fill out the rest.
		size = sizeof(outputFormat);
		require_noerr (result = AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, NULL, &size, &outputFormat), fail);
	}

	if (shouldPrint) {
		printf ("Writing to file: %s with format:\n* ", outputFilePath);
		outputFormat.Print();
	}
	
	FSRef parentDir;
	CFStringRef destFileName;
	require_noerr (result = PosixPathToParentFSRefAndName(outputFilePath, parentDir, destFileName), fail);

	ExtAudioFileRef outfile;
	result = ExtAudioFileCreateNew (&parentDir, destFileName, destFileType, &outputFormat, NULL, &outfile);
	CFRelease (destFileName);
	require_noerr (result, fail);

	AudioUnit outputUnit;	
	UInt32 nodeCount;
	require_noerr (result = AUGraphGetNodeCount (inGraph, &nodeCount), fail);
	
	for (UInt32 i = 0; i < nodeCount; ++i) 
	{
		AUNode node;
		require_noerr (result = AUGraphGetIndNode(inGraph, i, &node), fail);

		ComponentDescription desc;
		require_noerr (result = AUGraphNodeInfo(inGraph, node, &desc, NULL), fail);
		
		if (desc.componentType == kAudioUnitType_Output) 
		{
			require_noerr (result = AUGraphNodeInfo(inGraph, node, 0, &outputUnit), fail);
			break;
		}
	}

	{
		CAStreamBasicDescription clientFormat;
		size = sizeof(clientFormat);
		require_noerr (result = AudioUnitGetProperty (outputUnit,
													kAudioUnitProperty_StreamFormat,
													kAudioUnitScope_Output, 0,
													&clientFormat, &size), fail);
		size = sizeof(clientFormat);
		require_noerr (result = ExtAudioFileSetProperty(outfile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat), fail);
		
		{
			MusicTimeStamp currentTime;
			AUOutputBL outputBuffer (clientFormat, numFrames);
			AudioTimeStamp tStamp;
			memset (&tStamp, 0, sizeof(AudioTimeStamp));
			tStamp.mFlags = kAudioTimeStampSampleTimeValid;
			int i = 0;
			int numTimesFor10Secs = (int)(10. / (numFrames / srate));
			do {
				outputBuffer.Prepare();
				AudioUnitRenderActionFlags actionFlags = 0;
				require_noerr (result = AudioUnitRender (outputUnit, &actionFlags, &tStamp, 0, numFrames, outputBuffer.ABL()), fail);

				tStamp.mSampleTime += numFrames;
				
				require_noerr (result = ExtAudioFileWrite(outfile, numFrames, outputBuffer.ABL()), fail);	

				require_noerr (result = MusicPlayerGetTime (player, &currentTime), fail);
				if (shouldPrint && (++i % numTimesFor10Secs == 0))
					printf ("current time: %6.2f beats\n", currentTime);
			} while (currentTime < sequenceLength);
		}
	}
	
// close
	ExtAudioFileDispose(outfile);

	return;

fail:
	printf ("Problem: %ld\n", result); 
	exit(1);
}
예제 #16
0
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;
}
예제 #17
0
void CreateMyAUGraph(MyAUGraphPlayer *player)
{
	// create a new AUGraph
	CheckError(NewAUGraph(&player->graph),
			   "NewAUGraph failed");
	
	// generate description that will match our output device (speakers)
	AudioComponentDescription outputcd = {0};
	outputcd.componentType = kAudioUnitType_Output;
	outputcd.componentSubType = kAudioUnitSubType_DefaultOutput;
	outputcd.componentManufacturer = kAudioUnitManufacturer_Apple;
	
	// adds a node with above description to the graph
	AUNode outputNode;
	CheckError(AUGraphAddNode(player->graph, &outputcd, &outputNode),
			   "AUGraphAddNode[kAudioUnitSubType_DefaultOutput] failed");
	
	// generate description that will match a generator AU of type: speech synthesizer
	AudioComponentDescription speechcd = {0};
	speechcd.componentType = kAudioUnitType_Generator;
	speechcd.componentSubType = kAudioUnitSubType_SpeechSynthesis;
	speechcd.componentManufacturer = kAudioUnitManufacturer_Apple;
	
	// adds a node with above description to the graph
	AUNode speechNode;
	CheckError(AUGraphAddNode(player->graph, &speechcd, &speechNode),
			   "AUGraphAddNode[kAudioUnitSubType_SpeechSynthesis] failed");
	
	// opening the graph opens all contained audio units but does not allocate any resources yet
	CheckError(AUGraphOpen(player->graph),
			   "AUGraphOpen failed");
	
	// get the reference to the AudioUnit object for the speech synthesis graph node
	CheckError(AUGraphNodeInfo(player->graph, speechNode, NULL, &player->speechAU),
			   "AUGraphNodeInfo failed");
	
	//	// debug - get the asbd
	//	UInt32 propSize = sizeof (AudioStreamBasicDescription);
	//	CheckError(AudioUnitGetProperty(player->speechAU,
	//									kAudioUnitProperty_StreamFormat,
	//									kAudioUnitScope_Output,
	//									0,
	//									&player->streamFormat,
	//									&propSize),
	//			   "Couldn't get ASBD");	
	
#ifdef PART_II
	//
	// FUN! re-route the speech thru a reverb effect before sending to speakers
	//
	// generate description that will match out reverb effect
	AudioComponentDescription reverbcd = {0};
	reverbcd.componentType = kAudioUnitType_Effect;
	reverbcd.componentSubType = kAudioUnitSubType_MatrixReverb;
	reverbcd.componentManufacturer = kAudioUnitManufacturer_Apple;
	
	// adds a node with above description to the graph
	AUNode reverbNode;
	CheckError(AUGraphAddNode(player->graph, &reverbcd, &reverbNode),
			   "AUGraphAddNode[kAudioUnitSubType_MatrixReverb] failed");
	
	// connect the output source of the speech synthesizer AU to the input source of the reverb node
	CheckError(AUGraphConnectNodeInput(player->graph, speechNode, 0, reverbNode, 0),
			   "AUGraphConnectNodeInput");
	
	// connect the output source of the reverb AU to the input source of the output node
	CheckError(AUGraphConnectNodeInput(player->graph, reverbNode, 0, outputNode, 0),
			   "AUGraphConnectNodeInput");
	
	// get the reference to the AudioUnit object for the reverb graph node
	AudioUnit reverbUnit;
	CheckError(AUGraphNodeInfo(player->graph, reverbNode, NULL, &reverbUnit),
			   "AUGraphNodeInfo failed");
	
	/*
	 enum {
	 kReverbRoomType_SmallRoom		= 0,
	 kReverbRoomType_MediumRoom		= 1,
	 kReverbRoomType_LargeRoom		= 2,
	 kReverbRoomType_MediumHall		= 3,
	 kReverbRoomType_LargeHall		= 4,
	 kReverbRoomType_Plate			= 5,
	 kReverbRoomType_MediumChamber	= 6,
	 kReverbRoomType_LargeChamber	= 7,
	 kReverbRoomType_Cathedral		= 8,
	 kReverbRoomType_LargeRoom2		= 9,
	 kReverbRoomType_MediumHall2		= 10,
	 kReverbRoomType_MediumHall3		= 11,
	 kReverbRoomType_LargeHall2		= 12	
	 };
	 
	 */
	
	// now initialize the graph (causes resources to be allocated)
	CheckError(AUGraphInitialize(player->graph),
			   "AUGraphInitialize failed");
	
	
	// set the reverb preset for room size
	//	UInt32 roomType = kReverbRoomType_SmallRoom;
	//	UInt32 roomType = kReverbRoomType_MediumRoom;
	UInt32 roomType = kReverbRoomType_LargeHall;
	//	UInt32 roomType = kReverbRoomType_Cathedral;
	
	CheckError(AudioUnitSetProperty(reverbUnit, kAudioUnitProperty_ReverbRoomType, 
									kAudioUnitScope_Global, 0, &roomType, sizeof(UInt32)),
			   "AudioUnitSetProperty[kAudioUnitProperty_ReverbRoomType] failed");
	
	
#else
	
	// connect the output source of the speech synthesis AU to the input source of the output node
	CheckError(AUGraphConnectNodeInput(player->graph, speechNode, 0, outputNode, 0),
			   "AUGraphConnectNodeInput");
	
	// now initialize the graph (causes resources to be allocated)
	CheckError(AUGraphInitialize(player->graph),
			   "AUGraphInitialize failed");
	
#endif
	CAShow(player->graph);
}
예제 #18
0
파일: main.c 프로젝트: rraallvv/AUTest
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);
}
예제 #19
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;
}
예제 #20
0
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
	}
}
void CreateMyAUGraph(MyAUGraphPlayer *player)
{
	
	// create a new AUGraph
	CheckError(NewAUGraph(&player->graph),
			   "NewAUGraph failed");
	
	// generate description that will match default output
	//	ComponentDescription outputcd = {0};
	//	outputcd.componentType = kAudioUnitType_Output;
	//	outputcd.componentSubType = kAudioUnitSubType_DefaultOutput;
	//	outputcd.componentManufacturer = kAudioUnitManufacturer_Apple;
	//	
	//	Component comp = FindNextComponent(NULL, &outputcd);
	//	if (comp == NULL) {
	//		printf ("can't get output unit"); exit (-1);
	//	}
	
	AudioComponentDescription outputcd = {0};
	outputcd.componentType = kAudioUnitType_Output;
	outputcd.componentSubType = kAudioUnitSubType_DefaultOutput;
	outputcd.componentManufacturer = kAudioUnitManufacturer_Apple;
	
	AudioComponent comp = AudioComponentFindNext(NULL, &outputcd);
	if (comp == NULL) {
		printf ("can't get output unit"); exit (-1);
	}
	
	
	// adds a node with above description to the graph
	AUNode outputNode;
	CheckError(AUGraphAddNode(player->graph, &outputcd, &outputNode),
			   "AUGraphAddNode[kAudioUnitSubType_DefaultOutput] failed");
	
#ifdef PART_II
	
	// add a mixer to the graph,
	AudioComponentDescription mixercd = {0};
	mixercd.componentType = kAudioUnitType_Mixer;
	mixercd.componentSubType = kAudioUnitSubType_StereoMixer; // doesn't work: kAudioUnitSubType_MatrixMixer
	mixercd.componentManufacturer = kAudioUnitManufacturer_Apple;
	AUNode mixerNode;
	CheckError(AUGraphAddNode(player->graph, &mixercd, &mixerNode),
			   "AUGraphAddNode[kAudioUnitSubType_StereoMixer] failed");
	
	// adds a node with above description to the graph
	AudioComponentDescription speechcd = {0};
	speechcd.componentType = kAudioUnitType_Generator;
	speechcd.componentSubType = kAudioUnitSubType_SpeechSynthesis;
	speechcd.componentManufacturer = kAudioUnitManufacturer_Apple;
	AUNode speechNode;
	CheckError(AUGraphAddNode(player->graph, &speechcd, &speechNode),
			   "AUGraphAddNode[kAudioUnitSubType_AudioFilePlayer] failed");
	
	// opening the graph opens all contained audio units but does not allocate any resources yet
	CheckError(AUGraphOpen(player->graph),
			   "AUGraphOpen failed");
	
	// get the reference to the AudioUnit objects for the various nodes
	CheckError(AUGraphNodeInfo(player->graph, outputNode, NULL, &player->outputUnit),
			   "AUGraphNodeInfo failed");
	CheckError(AUGraphNodeInfo(player->graph, speechNode, NULL, &player->speechUnit),
			   "AUGraphNodeInfo failed");
	AudioUnit mixerUnit;
	CheckError(AUGraphNodeInfo(player->graph, mixerNode, NULL, &mixerUnit),
			   "AUGraphNodeInfo failed");
	
	// set ASBDs here
	UInt32 propertySize = sizeof (AudioStreamBasicDescription);
	CheckError(AudioUnitSetProperty(player->outputUnit,
									kAudioUnitProperty_StreamFormat,
									kAudioUnitScope_Input,
									0,
									&player->streamFormat,
									propertySize),
			   "Couldn't set stream format on output unit");
	
	// problem: badComponentInstance (-2147450879)
	CheckError(AudioUnitSetProperty(mixerUnit,
									kAudioUnitProperty_StreamFormat,
									kAudioUnitScope_Input,
									0,
									&player->streamFormat,
									propertySize),
			   "Couldn't set stream format on mixer unit bus 0");
	CheckError(AudioUnitSetProperty(mixerUnit,
									kAudioUnitProperty_StreamFormat,
									kAudioUnitScope_Input,
									1,
									&player->streamFormat,
									propertySize),
			   "Couldn't set stream format on mixer unit bus 1");
	
	
	// connections
	// mixer output scope / bus 0 to outputUnit input scope / bus 0
	// mixer input scope / bus 0 to render callback (from ringbuffer, which in turn is from inputUnit)
	// mixer input scope / bus 1 to speech unit output scope / bus 0
	
	CheckError(AUGraphConnectNodeInput(player->graph, mixerNode, 0, outputNode, 0),
			   "Couldn't connect mixer output(0) to outputNode (0)");
	CheckError(AUGraphConnectNodeInput(player->graph, speechNode, 0, mixerNode, 1),
			   "Couldn't connect speech synth unit output (0) to mixer input (1)");
	AURenderCallbackStruct callbackStruct;
	callbackStruct.inputProc = GraphRenderProc; 
	callbackStruct.inputProcRefCon = player;
	CheckError(AudioUnitSetProperty(mixerUnit,
									kAudioUnitProperty_SetRenderCallback,
									kAudioUnitScope_Global,
									0,
									&callbackStruct,
									sizeof(callbackStruct)),
			   "Couldn't set render callback on mixer unit");
	
	
#else	
	
	// opening the graph opens all contained audio units but does not allocate any resources yet
	CheckError(AUGraphOpen(player->graph),
			   "AUGraphOpen failed");
	
	// get the reference to the AudioUnit object for the output graph node
	CheckError(AUGraphNodeInfo(player->graph, outputNode, NULL, &player->outputUnit),
			   "AUGraphNodeInfo failed");
	
	// set the stream format on the output unit's input scope
	UInt32 propertySize = sizeof (AudioStreamBasicDescription);
	CheckError(AudioUnitSetProperty(player->outputUnit,
									kAudioUnitProperty_StreamFormat,
									kAudioUnitScope_Input,
									0,
									&player->streamFormat,
									propertySize),
			   "Couldn't set stream format on output unit");
	
	AURenderCallbackStruct callbackStruct;
	callbackStruct.inputProc = GraphRenderProc; 
	callbackStruct.inputProcRefCon = player;
	
	CheckError(AudioUnitSetProperty(player->outputUnit,
									kAudioUnitProperty_SetRenderCallback,
									kAudioUnitScope_Global,
									0,
									&callbackStruct,
									sizeof(callbackStruct)),
			   "Couldn't set render callback on output unit");
	
#endif
	
	
	// now initialize the graph (causes resources to be allocated)
	CheckError(AUGraphInitialize(player->graph),
			   "AUGraphInitialize failed");
	
	player->firstOutputSampleTime = -1;
	
	printf ("Bottom of CreateSimpleAUGraph()\n");
}
예제 #22
0
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;
}
예제 #23
0
void WriteOutputFile (const char*	outputFilePath, 
					OSType			dataFormat, 
					Float64			srate, 
					MusicTimeStamp	sequenceLength, 
					bool			shouldPrint,
					AUGraph			inGraph,
					UInt32			numFrames,
					MusicPlayer		player)
{
	OSStatus result = 0;
	UInt32 size;

	CAStreamBasicDescription outputFormat;
	outputFormat.mChannelsPerFrame = 2;
	outputFormat.mSampleRate = srate;
	outputFormat.mFormatID = dataFormat;
	
	AudioFileTypeID destFileType;
	CAAudioFileFormats::Instance()->InferFileFormatFromFilename (outputFilePath, destFileType);
	
	if (dataFormat == kAudioFormatLinearPCM) {
		outputFormat.mBytesPerPacket = outputFormat.mChannelsPerFrame * 2;
		outputFormat.mFramesPerPacket = 1;
		outputFormat.mBytesPerFrame = outputFormat.mBytesPerPacket;
		outputFormat.mBitsPerChannel = 16;
		
		if (destFileType == kAudioFileWAVEType)
			outputFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger
								| kLinearPCMFormatFlagIsPacked;
		else
			outputFormat.mFormatFlags = kLinearPCMFormatFlagIsBigEndian
								| kLinearPCMFormatFlagIsSignedInteger
								| kLinearPCMFormatFlagIsPacked;
	} else {
		// use AudioFormat API to fill out the rest.
		size = sizeof(outputFormat);
		FailIf ((result = AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, NULL, &size, &outputFormat)), fail, "");
	}

	if (shouldPrint) {
		printf ("Writing to file: %s with format:\n* ", outputFilePath);
		outputFormat.Print();
	}
	
	CFURLRef url; url = CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8*)outputFilePath, strlen(outputFilePath), false);
    
    // create output file, delete existing file
	ExtAudioFileRef outfile;
	result = ExtAudioFileCreateWithURL(url, destFileType, &outputFormat, NULL, kAudioFileFlags_EraseFile, &outfile);
	if (url) CFRelease (url);	
	FailIf (result, fail, "ExtAudioFileCreateWithURL");

	AudioUnit outputUnit; outputUnit = NULL;
	UInt32 nodeCount;
	FailIf ((result = AUGraphGetNodeCount (inGraph, &nodeCount)), fail, "AUGraphGetNodeCount");
	
	for (UInt32 i = 0; i < nodeCount; ++i) 
	{
		AUNode node;
		FailIf ((result = AUGraphGetIndNode(inGraph, i, &node)), fail, "AUGraphGetIndNode");

		AudioComponentDescription desc;
		FailIf ((result = AUGraphNodeInfo(inGraph, node, &desc, NULL)), fail, "AUGraphNodeInfo");
		
		if (desc.componentType == kAudioUnitType_Output) 
		{
			FailIf ((result = AUGraphNodeInfo(inGraph, node, 0, &outputUnit)), fail, "AUGraphNodeInfo");
			break;
		}
	}
    
    FailIf ((result = (outputUnit == NULL)), fail, "outputUnit == NULL");
	{
		CAStreamBasicDescription clientFormat = CAStreamBasicDescription();
		size = sizeof(clientFormat);
		FailIf ((result = AudioUnitGetProperty (outputUnit,
													kAudioUnitProperty_StreamFormat,
													kAudioUnitScope_Output, 0,
													&clientFormat, &size)), fail, "AudioUnitGetProperty: kAudioUnitProperty_StreamFormat");
		size = sizeof(clientFormat);
		FailIf ((result = ExtAudioFileSetProperty(outfile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat)), fail, "ExtAudioFileSetProperty: kExtAudioFileProperty_ClientDataFormat");
		
		{
			MusicTimeStamp currentTime;
			AUOutputBL outputBuffer (clientFormat, numFrames);
			AudioTimeStamp tStamp;
			memset (&tStamp, 0, sizeof(AudioTimeStamp));
			tStamp.mFlags = kAudioTimeStampSampleTimeValid;
			int i = 0;
			int numTimesFor10Secs = (int)(10. / (numFrames / srate));
			do {
				outputBuffer.Prepare();
				AudioUnitRenderActionFlags actionFlags = 0;
				FailIf ((result = AudioUnitRender (outputUnit, &actionFlags, &tStamp, 0, numFrames, outputBuffer.ABL())), fail, "AudioUnitRender");

				tStamp.mSampleTime += numFrames;
				
				FailIf ((result = ExtAudioFileWrite(outfile, numFrames, outputBuffer.ABL())), fail, "ExtAudioFileWrite");	

				FailIf ((result = MusicPlayerGetTime (player, &currentTime)), fail, "MusicPlayerGetTime");
				if (shouldPrint && (++i % numTimesFor10Secs == 0))
					printf ("current time: %6.2f beats\n", currentTime);
			} while (currentTime < sequenceLength);
		}
	}
	
// close
	ExtAudioFileDispose(outfile);

	return;

fail:
	printf ("Problem: %ld\n", (long)result); 
	exit(1);
}
예제 #24
0
int QBSoundMac::initGraph()
{
	OSStatus err;

	mAudioFormat.mSampleRate = 44100.000000;
	mAudioFormat.mFormatID = kAudioFormatLinearPCM;

#ifdef __FLOAT_BUFFER__
    mAudioFormat.mFormatFlags = 0
	| kLinearPCMFormatFlagIsPacked
	| kLinearPCMFormatFlagIsFloat
#if __BIG_ENDIAN__
	| kLinearPCMFormatFlagIsBigEndian
#endif
	;
	mAudioFormat.mBytesPerPacket = 8;
	mAudioFormat.mFramesPerPacket = 1;
	mAudioFormat.mBytesPerFrame = 8;
	mAudioFormat.mChannelsPerFrame = 2;
	mAudioFormat.mBitsPerChannel = 32;
	mAudioFormat.mReserved = 0;
#else
    mAudioFormat.mFormatFlags = 0
	| kLinearPCMFormatFlagIsPacked
	| kLinearPCMFormatFlagIsSignedInteger 
#if __BIG_ENDIAN__
	| kLinearPCMFormatFlagIsBigEndian
#endif
	;
	mAudioFormat.mBytesPerPacket = 4;
	mAudioFormat.mFramesPerPacket = 1;
	mAudioFormat.mBytesPerFrame = 4;
	mAudioFormat.mChannelsPerFrame = 2;
	mAudioFormat.mBitsPerChannel = 16;
	mAudioFormat.mReserved = 0;
#endif

	err = NewAUGraph(&mGraph);

#if !TARGET_OS_IPHONE
    AudioComponentDescription description;
    description.componentSubType = kAudioUnitSubType_DefaultOutput;
#else
	AudioComponentDescription description;
	description.componentSubType = kAudioUnitSubType_RemoteIO;
#endif
    description.componentType = kAudioUnitType_Output;
    description.componentManufacturer = kAudioUnitManufacturer_Apple;
    description.componentFlags = 0;
    description.componentFlagsMask = 0;
#if 1
	err = AUGraphAddNode(mGraph,&description,&mOutputNode);
#else
	err = AUGraphNewNode(mGraph,&description, 0, NULL, &mOutputNode);
#endif

	err = AUGraphOpen(mGraph);

#if 1
	err = AUGraphNodeInfo(mGraph,mOutputNode,NULL,&mAudioUnit);
#else
	err = AUGraphGetNodeInfo(mGraph,mOutputNode,NULL,NULL,NULL,&mAudioUnit);
#endif

   err =  AudioUnitSetProperty(mAudioUnit,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Input,
                                  0,
                                  &mAudioFormat,
                                  sizeof(AudioStreamBasicDescription));

	{
		AURenderCallbackStruct input;
		input.inputProc = callback;
		input.inputProcRefCon = this;
	err = 	AudioUnitSetProperty(mAudioUnit,
									  kAudioUnitProperty_SetRenderCallback,
									  kAudioUnitScope_Input,
									  0,
									  &input, sizeof(input));
	}
	
//	{
//		AudioUnitSetParameter (mAudioUnit,
//										kHALOutputParam_Volume,
//										kAudioUnitScope_Global,0,1,0);
//	}

	err = AUGraphInitialize(mGraph);
	//err = AUGraphStart(mGraph);
	
	//pthread_mutex_init(&mLoaderThreadMutex,NULL);

#ifdef __USE_OGG_VORBIS__
	mThreadEnd = false;
	pthread_create(&mLoaderThread,NULL,LoaderThreadProc,this);
#endif

//	mOpenGraph = false;
//	mInitGraph = false;

//	startAUGraph();

//printf("openAUGraph\n");
	return err;
}