/* 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;
}
/** 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);
}
Example #3
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;
}
Example #4
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;
}
Example #5
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);
}
Example #6
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;
}
Example #7
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);
}
JNIEXPORT jint JNICALL Java_com_apple_audio_toolbox_AUGraph_AUGraphGetIndNode
  (JNIEnv *, jclass, jint inGraph, jint inIndex, jint outNode)
{
	return (jint)AUGraphGetIndNode((AUGraph)inGraph, (UInt32)inIndex, (AUNode *)outNode);
}