• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: User-land CoreAudio driver and Leopard
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: User-land CoreAudio driver and Leopard


  • Subject: Re: User-land CoreAudio driver and Leopard
  • From: Stéphane Letz <email@hidden>
  • Date: Mon, 19 Nov 2007 13:59:50 +0100



On Nov 16, 2007, at 7:22 AM, Stéphane Letz wrote:

Some more questions, trying to understand the HP_IOThread class:

- in HP_IOThread::WorkLoop() the mIOGuard is locked before the while
loop. What happens for commands that come from a thread different
from the IO thread? (they are supposed to execute immediately, so
SHP_Device::StartCommandExecution is called trying to Lock the
mIOGuard, but since mIOGuard is alreadystill locked in
HP_IOThread::WorkLoop() ?? ) Is the mIOGuard unlocked somewhere so
that the pendind commands can be done?

This is what the command mechanism is for. It manages the operations that need to synch against the IO thread and change things that are manipulated on the IO thread.

Yes, mIOGuard is take right at the top of the work loop, but it is
also released each time the IO thread goes to sleep (the
mIOGuard.WaitUntil() call in the middle there). This is what allows
other threads that might be blocked synchronizing against the IO
thread to run.


- in HP_IOThread::WorkLoop(), commands coming from the IO thread
itself are pushed in mCommandList if IsSafeToExecuteCommand returns
false, then executed at the end of the IO cycle. But I see that some
commands may do some non real-time safe operations (memory
operations....), and are actually executed in the real-time thread...

Yes indeed they do, but they are doing so only at the behest of the HAL client making the appropriate API call. Thus, any pain that it causes is considered self-inflicted from the HAL's perspective.

--

Thanks for the explanations.

Actually after trying all sort of implementation variants, my plugin still does not working properly: it works with some applications (Live, Reason, Garageband..) and fails with many others (iTunes: for example switching from JackRouter to Built-in output and vice-versa repeatidly fails, same issue with QuickTimePlayer, DVD player refuses to see it...)

The *simplest* implementation does basically the following:

void JackRouterDevice::StartHardware()
{
// JACK
[START JACK IO]

// set the device state to know the engine is running
IOEngineStarted();

// notify clients that the engine is running
CAPropertyAddress theIsRunningAddress(kAudioDevicePropertyDeviceIsRunning);
PropertiesChanged(1, &theIsRunningAddress);
}


void JackRouterDevice::StopHardware()
{
// set the device state to know the engine has stopped
IOEngineStopped();

// Notify clients that the IO callback is stopping
CAPropertyAddress theIsRunningAddress(kAudioDevicePropertyDeviceIsRunning);
PropertiesChanged(1, &theIsRunningAddress);

// JACK
[STOP JACK IO]
}


I'm using a CAGuard to protect access to the IOProc list thus:

bool	JackRouterDevice::IsSafeToExecuteCommand()
{
	bool theAnswer = true;

// Checking if call is done in Jack IO thread
if (mClient) {
theAnswer = jack_client_thread_id(mClient) != pthread_self();
}

JARLog("JackRouterDevice::IsSafeToExecuteCommand theAnswer = %ld\n", theAnswer);

return theAnswer;
}


bool JackRouterDevice::StartCommandExecution(void** outSavedCommandState)
{
*outSavedCommandState = mIOGuard.Lock() ? (void*)1 : (void*)0;
return true;
}


void	JackRouterDevice::FinishCommandExecution(void* inSavedCommandState)
{
	if (inSavedCommandState != 0) {
		mIOGuard.Unlock();
	}
}

And Jack IO callback does:

int JackRouterDevice::Process(jack_nframes_t nframes, void* arg)
{
	bool wasLocked;
      	JackRouterDevice* client = (JackRouterDevice*)arg;

	// Lock is on, so drop this cycle.
	if (!client->mIOGuard.Try(wasLocked)) {
		return 0;
	}

	// JACK processing
	[JACK IO]  (use the  IOProc list...)

	client->mIOGuard.Unlock();

	//	execute any deferred commands
	client->ExecuteAllCommands();

	return 0;
}

As said before this version does not work well, second try was to follow more what SHP_PlugIn example does : that is using the 4 state system kNotRunningPhase, kInitializingPhase, kRunningPhase, kTeardownPhase, having the JackRouterDevice::StartHardware() start JACK and wait for the Jack IO callback to actually run... and so on. But same kind of problems

Can I expect to have the simpler first version working? what important thing is still lacking?

Stephane Letz

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: User-land CoreAudio driver and Leopard
      • From: Jeff Moore <email@hidden>
  • Prev by Date: Re: Problem with AudioQueueEnqueueBufferWithParameters - bug?
  • Next by Date: Realtion between callback count and audio file duration
  • Previous by thread: Re: User-land CoreAudio driver and Leopard
  • Next by thread: Re: User-land CoreAudio driver and Leopard
  • Index(es):
    • Date
    • Thread