// ----------------------------------------------------------
void ofxAudioUnitInput::connectTo(ofxAudioUnit &otherUnit, int destinationBus, int sourceBus)
// ----------------------------------------------------------
{
	AURenderCallbackStruct callback;
	callback.inputProc = pullCallback;
	callback.inputProcRefCon = &_renderContext;
	
	AudioStreamBasicDescription ASBD;
	UInt32 ASBDSize = sizeof(ASBD);
	
	OFXAU_RETURN(AudioUnitGetProperty(*otherUnit.getUnit(),
									  kAudioUnitProperty_StreamFormat,
									  kAudioUnitScope_Input,
									  destinationBus,
									  &ASBD,
									  &ASBDSize),
				 "getting hardware input destination's format");
	
	OFXAU_RETURN(AudioUnitSetProperty(*_unit,
									  kAudioUnitProperty_StreamFormat,
									  kAudioUnitScope_Output,
									  1,
									  &ASBD,
									  sizeof(ASBD)),
				 "setting hardware input's output format");
	
	otherUnit.setRenderCallback(callback, destinationBus);
}
void ofxAudioUnitFilePlayer::prime() {
	
	_region = RegionForEntireFile(_fileID[0]);
	
	if(_seekSampleTime) {
		_region.mStartFrame = _seekSampleTime;
		_pauseTimeAccumulator += _seekSampleTime;
	} else if(_pauseTimeStamp.mSampleTime > 0) {
		_region.mStartFrame = _pauseTimeStamp.mSampleTime + _pauseTimeAccumulator;
		_pauseTimeAccumulator += _pauseTimeStamp.mSampleTime;
	} else {
		_pauseTimeAccumulator = 0;
	}
	
	if(_loopCount > 0) {
		_region.mLoopCount = _loopCount;
	}
	
	// resetting time-tracking members
	memset(&_pauseTimeStamp, 0, sizeof(_pauseTimeStamp));
	_loopCount = 0;
	_seekSampleTime = 0;
	
	if(!(_region.mTimeStamp.mFlags & kAudioTimeStampHostTimeValid)) {
		cout << "ofxAudioUnitFilePlayer has no file to play" << endl;
		return;
	}
	
	OFXAU_RETURN(AudioUnitSetProperty(*_unit,
	                                  kAudioUnitProperty_ScheduledFileIDs,
	                                  kAudioUnitScope_Global,
	                                  0,
	                                  _fileID,
	                                  sizeof(_fileID)),
	             "setting file player's file ID");
	
	OFXAU_RETURN(AudioUnitSetProperty(*_unit,
	                                  kAudioUnitProperty_ScheduledFileRegion,
	                                  kAudioUnitScope_Global,
	                                  0,
	                                  &_region,
	                                  sizeof(_region)),
	             "setting file player region");
	
	UInt32 framesToPrime = 0; // 0 = "use the default"
	OFXAU_RETURN(AudioUnitSetProperty(*_unit,
									  kAudioUnitProperty_ScheduledFilePrime,
									  kAudioUnitScope_Global,
									  0,
									  &framesToPrime,
									  sizeof(framesToPrime)),
				 "priming file player");
	
	_primed = true;
}
// ----------------------------------------------------------
void ofxAudioUnitFilePlayer::play(uint64_t startTime)
// ----------------------------------------------------------
{
	if(!(_region.mTimeStamp.mFlags & kAudioTimeStampHostTimeValid))
	{
		cout << "ofxAudioUnitFilePlayer has no file to play" << endl;
		return;
	}
	
	OFXAU_RETURN(AudioUnitSetProperty(*_unit,
	                                  kAudioUnitProperty_ScheduledFileIDs,
	                                  kAudioUnitScope_Global,
	                                  0,
	                                  _fileID,
	                                  sizeof(_fileID)),
	             "setting file player's file ID");
	
	OFXAU_RETURN(AudioUnitSetProperty(*_unit,
	                                  kAudioUnitProperty_ScheduledFileRegion,
	                                  kAudioUnitScope_Global,
	                                  0,
	                                  &_region,
	                                  sizeof(_region)),
	             "setting file player region");
	
	if(startTime == 0)
	{
		startTime = mach_absolute_time();
	}
	AudioTimeStamp startTimeStamp = {0};
	FillOutAudioTimeStampWithHostTime(startTimeStamp, startTime);
	
	OFXAU_RETURN(AudioUnitSetProperty(*_unit,
	                                  kAudioUnitProperty_ScheduleStartTimeStamp,
	                                  kAudioUnitScope_Global,
	                                  0,
	                                  &startTimeStamp,
	                                  sizeof(startTimeStamp)),
	             "setting file player start time");
}
void ofxAudioUnitFilePlayer::play(uint64_t startTime) {
	
	if(!_primed) {
		prime();
	}
	
	_primed = false;
	
	if(startTime == 0) {
		startTime = mach_absolute_time();
	}
	
	AudioTimeStamp startTimeStamp = {0};
	FillOutAudioTimeStampWithHostTime(startTimeStamp, startTime);
	
	OFXAU_RETURN(AudioUnitSetProperty(*_unit,
	                                  kAudioUnitProperty_ScheduleStartTimeStamp,
	                                  kAudioUnitScope_Global,
	                                  0,
	                                  &startTimeStamp,
	                                  sizeof(startTimeStamp)),
	             "setting file player start time");
}