Re: Multimedia timing on OS X
Re: Multimedia timing on OS X
- Subject: Re: Multimedia timing on OS X
- From: Ross Bencina <email@hidden>
- Date: Wed, 04 May 2011 14:15:46 +1000
Garett Shulman wrote:
Do folks on this list have any insight or wisdom about techniques for high
resolution multimedia timing on cocoa? Thanks! -Garett
I'm pretty sure the CA Midi API allows you to schedule events into the
future. So that's probably the best option for MIDI. In theory at least this
allows the MIDI hardware to do the scheduling. I have no idea how many
hardware devices can actually do hardware scheduling. My current MIDI Clock
sync code just sends MIDI events in immediate mode (probably not a good
idea) from a polling timer thread.
I just run a high priority thread and use mach_wait_until() to sleep until
the next time.
In general I prefer using mach level APIs for this kind of thing.
See below for the periodic timer code I use in place of the mmtimer I use on
Windows (only supports millisecond intervals, but you get the idea). Use the
code as you like, it's all info from the cited threads anyway...
----------------
/*
See the following for some discussion and links. our implementation here
is very preliminary. especially the use of THREAD_TIME_CONSTRAINT_POLICY
one of the links below recommends use of a normal high-priority thread
instead.
http://lists.apple.com/archives/darwin-development/2001/Oct/msg00354.html
http://lists.apple.com/archives/coreaudio-api/2006/Jan/msg00044.html
http://lists.apple.com/archives/darwin-development/2003/Jan/msg00206.html
http://lists.apple.com/archives/Darwin-dev/2008/May/msg00001.html
http://osdir.com/ml/apple.fink.cvs/2002-07/msg00283.html
http://lists.apple.com/archives/darwin-development/2001/Oct/msg00302.html
*/
class PeriodicTimer::Implementation{
pthread_t thread_;
bool isRunning_;
volatile bool stopTimerFlag_;
TimerClient *client_;
int periodMs_;
static void *threadFunc( void *param )
{
PeriodicTimer::Implementation *that =
static_cast<PeriodicTimer::Implementation*>( param );
struct thread_time_constraint_policy ttcpolicy;
//fprintf(stderr,"Getting real-time priority\n");
ttcpolicy.period = 833333;
ttcpolicy.computation = 60000;
ttcpolicy.constraint = 120000;
ttcpolicy.preemptible = 1;
if( thread_policy_set(mach_thread_self(),
THREAD_TIME_CONSTRAINT_POLICY, (int *)&ttcpolicy,
THREAD_TIME_CONSTRAINT_POLICY_COUNT) != KERN_SUCCESS ){
//fprintf(stderr, "Can't do thread_policy_set\n");
}
mach_timebase_info_data_t tbi;
mach_timebase_info(&tbi);
double invRatio = ((double)tbi.denom) / ((double)tbi.numer);
double timeResNanos = that->periodMs_ * 1000000; // In nanosecond
double nextDateNanos, curDateNanos = mach_absolute_time() / invRatio;
while (!that->stopTimerFlag_) {
pthread_testcancel();
nextDateNanos = mach_absolute_time() / invRatio;
while (curDateNanos < nextDateNanos) {
that->client_->timerTick();
curDateNanos += timeResNanos;
}
mach_wait_until(curDateNanos * invRatio);
}
return 0;
}
public:
Implementation()
: isRunning_( false )
, stopTimerFlag_( false )
{
}
~Implementation()
{
if( isRunning_ )
stop();
}
void start( TimerClient *client, int periodMs=1 )
{
assert( !isRunning_ );
client_ = client;
periodMs_ = periodMs;
stopTimerFlag_ = false;
isRunning_ = true;
pthread_attr_t attr;
pthread_attr_init( &attr );
pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM );
pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE );
/*
if( setPriority ){
sched_param param;
int resultCode = pthread_attr_getschedparam( &attr, ¶m );
assert( resultCode == 0 );
param.sched_priority = priority;
resultCode =pthread_attr_setschedparam ( &attr, ¶m );
assert( resultCode == 0 );
}
*/
int resultCode = pthread_create( &thread_, &attr, threadFunc, this );
pthread_attr_destroy( &attr );
assert( resultCode == 0 );
}
void stop()
{
assert( isRunning_ );
stopTimerFlag_ = true;
void *taskResult;
int resultCode = pthread_join( thread_, &taskResult );
assert( resultCode == 0 );
isRunning_ = false;
}
};
_______________________________________________
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