Exemple #1
0
bool ARDevice::CreateAudioEngine()
{
	//	initialize some locals
	AREngine* theEngine = NULL;
	
	//	set the return value
	bool theAnswer = true;
	
	//	get the description of th engine to build
	OSDictionary* theEngineDictionary = OSDynamicCast(OSDictionary, getProperty(AUDIO_ENGINE_KEY));
	FailIfNULLWithAction(theEngineDictionary, theAnswer = false, Done, "ARDevice::CreateAudioEngines: couldn't get the engine description");
	
	//	create the engine
	theEngine = new AREngine;
	if(theEngine != NULL)
	{
		//	initialize the engine
		if(theEngine->init(theEngineDictionary))
		{
			//	activate the new engine, if initialization was successful
			activateAudioEngine(theEngine);
		}
		
		//	release the engine
		theEngine->release();
	}
	
Done:
	return theAnswer;
}
Exemple #2
0
bool	AREngine::CreateStreams(IOAudioSampleRate* outInitialSampleRate, UInt32* outNumberChannels)
{
	//	set the return values
	bool theAnswer = true;
	*outNumberChannels = 0;
	
	//	set up some local variables
	OSArray* theFormatArray = NULL;
	OSArray* theSampleRateArray = NULL;
	OSString* theOSString = NULL;
	UInt32 theNumberStreams = NUM_STREAMS;
	OSNumber* theOSNumber = NULL;
	
	//	get the array of formats
	theFormatArray = OSDynamicCast(OSArray, getProperty(FORMATS_KEY));
	FailIfNULLWithAction(theFormatArray, theAnswer = false, Done, "AREngine::CreateStreams: Couldn't get the format array");
	
	//	get the array of sample rates
	theSampleRateArray = OSDynamicCast(OSArray, getProperty(SAMPLE_RATES_KEY));
	FailIfNULLWithAction(theSampleRateArray, theAnswer = false, Done, "AREngine::CreateStreams: Couldn't get the sample rate array");
	
	//	get the description
	theOSString = OSDynamicCast(OSString, getProperty(DESCRIPTION_KEY));
	if(theOSString != NULL)
	{
		setDescription(theOSString->getCStringNoCopy());
	}
	
	//	get the number of streams
	theOSNumber = OSDynamicCast(OSNumber, getProperty(NUM_STREAMS_KEY));
	if(theOSNumber != NULL)
	{
		theNumberStreams = theOSNumber->unsigned32BitValue();
	}
	
	//	make the streams
	for(UInt32 theStreamNumber = 0; theStreamNumber < theNumberStreams; ++theStreamNumber)
	{
		//	initialize some local variables
		bool theResult = false;
		UInt32 theMaxBitWidth = 0;
		UInt32 theMaxNumberChannels = 0;
		IOAudioStream* theInputStream = NULL;
		IOAudioStream* theOutputStream = NULL;
		OSCollectionIterator* theFormatIterator = NULL;
		OSCollectionIterator* theSampleRateIterator = NULL;
		OSDictionary* theFormatDictionary = NULL;
		IOAudioSampleRate theSampleRate = { 0, 0 };
		IOAudioStreamFormat theInitialFormat;
		bool theInitialFormatSet = false;
		char theInputStreamName[32];
		char theOutputStreamName[32];
		UInt32 theStreamBufferSize = 0;

		//	allocate and initialize the input stream
		if(theNumberStreams > 1)
		{
			snprintf(theInputStreamName, 32, "Input Stream #%ld", theStreamNumber + 1);
		}
		else
		{
			snprintf(theInputStreamName, 32, "Input Stream");
		}
		theInputStream = new IOAudioStream;
		FailIfNULLWithAction(theInputStream, theAnswer = false, Error, "AREngine::CreateStreams: couldn't create the input stream");
		theResult = theInputStream->initWithAudioEngine(this, kIOAudioStreamDirectionInput, *outNumberChannels + 1, theInputStreamName);
		FailIfWithAction(!theResult, theAnswer = false, Error, "AREngine::CreateStreams: couldn't initialize the input stream");

		//	allocate and initialize the output stream
		if(theNumberStreams > 1)
		{
			snprintf(theOutputStreamName, 32, "Output Stream #%ld", theStreamNumber + 1);
		}
		else
		{
			snprintf(theOutputStreamName, 32, "Output Stream");
		}
		theOutputStream = new IOAudioStream;
		FailIfNULLWithAction(theOutputStream, theAnswer = false, Error, "AREngine::CreateStreams: couldn't create the output stream");
		theResult = theOutputStream->initWithAudioEngine(this, kIOAudioStreamDirectionOutput, *outNumberChannels + 1, theOutputStreamName);
		FailIfWithAction(!theResult, theAnswer = false, Error, "AREngine::CreateStreams: couldn't initialize the output stream");

		//	make an iterator for the format array
		theFormatIterator = OSCollectionIterator::withCollection(theFormatArray);
		FailIfNULLWithAction(theFormatIterator, theAnswer = false, Error, "AREngine::CreateStreams: couldn't create the format iterator");
		
		//	make an iterator for the sample rate array
		theSampleRateIterator = OSCollectionIterator::withCollection(theSampleRateArray);
		FailIfNULLWithAction(theSampleRateIterator, theAnswer = false, Error, "AREngine::CreateStreams: couldn't create the sample rate iterator");

		//	iterate through the formats
		theFormatIterator->reset();
		theFormatDictionary = (OSDictionary*)theFormatIterator->getNextObject();
		while(theFormatDictionary != NULL)
		{
			//	make sure we have a dictionary
			if(OSDynamicCast(OSDictionary, theFormatDictionary) != NULL)
			{
				//	convert the dictionary into something we can deal with
				IOAudioStreamFormat theFormat;
				FailIfNULLWithAction(IOAudioStream::createFormatFromDictionary(theFormatDictionary, &theFormat), theAnswer = false, Error, "AREngine::CreateStreams: couldn't make a format out of the dictionary");
				
				//	make sure the initial format is set
				if(!theInitialFormatSet)
				{
					theInitialFormat = theFormat;
				}
				
				//	iterate through the sample rates
				theSampleRateIterator->reset();
				theOSNumber = (OSNumber*)theSampleRateIterator->getNextObject();
				while(theOSNumber != NULL)
				{
					//	make sure we have a number
					if(OSDynamicCast(OSNumber, theOSNumber) != NULL)
					{
						//	get the sample rate
						theSampleRate.whole = theOSNumber->unsigned32BitValue();
						
						//	make sure the initial sample rate is set
						if(outInitialSampleRate->whole == 0)
						{
							outInitialSampleRate->whole = theSampleRate.whole;
						}

						//	add the format to the input stream
						theInputStream->addAvailableFormat(&theFormat, &theSampleRate, &theSampleRate);
						
						//	add the format to the output stream
						theOutputStream->addAvailableFormat(&theFormat, &theSampleRate, &theSampleRate);
						
						//	track a few things
						theMaxNumberChannels = (theFormat.fNumChannels > theMaxNumberChannels) ? theFormat.fNumChannels : theMaxNumberChannels;
						theMaxBitWidth = (theFormat.fBitWidth > theMaxBitWidth) ? theFormat.fBitWidth : theMaxBitWidth;
					}
					
					//	go to the next sample rate
					theOSNumber = (OSNumber*)theSampleRateIterator->getNextObject();
				}
			}
			
			//	go to the next format
			theFormatDictionary = (OSDictionary*)theFormatIterator->getNextObject();
		}
		
		//	calculate the size of the stream buffer
		theStreamBufferSize = mBlockSize * mNumberBlocks * theMaxNumberChannels * theMaxBitWidth / 8;
		
		//	allocate the buffers if necessary
		if(mOutputBuffer == NULL)
		{
			//	calculate the size
			mOutputBufferSize = theStreamBufferSize * theNumberStreams;
			
			//	allocate the output buffer
			mOutputBuffer = (void*)IOMallocAligned(mOutputBufferSize, PAGE_SIZE);
			FailIfNULLWithAction(mOutputBuffer, theAnswer = false, Error, "AREngine::CreateStreams: couldn't allocate the output buffer");
			
			//	the input size is the same as the output size
			mInputBufferSize = mOutputBufferSize;
			
			//	allocate the input buffer
			mInputBuffer = mOutputBuffer;
		}
		
		//	set some info about the stream
		theInputStream->setTerminalType(INPUT_UNDEFINED);
		theOutputStream->setTerminalType(OUTPUT_UNDEFINED);
		
		//	set the initial stream formats
		theInputStream->setFormat(&theInitialFormat, false);
		theOutputStream->setFormat(&theInitialFormat, false);
		
		//	set the data buffer for the streams
		theInputStream->setSampleBuffer(&((UInt8*)mInputBuffer)[theStreamBufferSize * theStreamNumber], theStreamBufferSize);
		theOutputStream->setSampleBuffer(&((UInt8*)mOutputBuffer)[theStreamBufferSize * theStreamNumber], theStreamBufferSize);
		
		//	add the streams to the engine
		addAudioStream(theInputStream);
		theInputStream->release();
		theInputStream = NULL;

		addAudioStream(theOutputStream);
		theOutputStream->release();
		theOutputStream = NULL;

		theFormatIterator->release();
		theFormatIterator = NULL;
		
		theSampleRateIterator->release();
		theSampleRateIterator = NULL;

		*outNumberChannels += theMaxNumberChannels;

		continue;

Error:
		if(theInputStream)
		{
			theInputStream->release();
		}

		if(theOutputStream)
		{
			theOutputStream->release();
		}

		if(theFormatIterator)
		{
			theFormatIterator->release();
		}

		if(theSampleRateIterator)
		{
			theSampleRateIterator->release();
		}

		goto Done;
	}
	
Done:
	return theAnswer;
}