[linux-audio-dev] Realtime problems with midi/osc sequencer

Christian krampenschiesser at freenet.de
Sat Mar 10 16:20:32 UTC 2007


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,
I'm writing on a sequencer system based on osc and midi.( No audio )
I'll first describe how it is build up.
As libs I'm using liblo and rtmidi.
The whole app is splitted into different small apps dealing with
specific data.
So there is a timer which has got the main goal to run a loop which
sends an osc message with current tact information.
This msg contains current tact( 0-inf ) the current amount of 192 notes
( eg 45/192 ) and the current amount of 256 notes ( eg 65/256 ).
As a resolution i have chosen 768.
Here is the source code of it.
The function is startet inside a pthread.
iTick is the amount of µsecs the timer has to sleep at the specific bpm
speed.
[CODE]
void Timer::runThread()
{
	std::list<Seq>::iterator iter;
	timeval tv;
	unsigned long startTime, passedTime;
	int shortTickCount=0;
	int longTickCount=0;
	int midiTickCount=0;
	
	while( !bRunning )
		usleep ( 100 );
	
	gettimeofday( &tv, NULL );
	startTime=( ( tv.tv_sec * 1000000 ) + tv.tv_usec );
	
	for( iter=seqs.begin(); iter!=seqs.end(); iter++ )
	{
		lo_send_timestamped( iter->address, LO_TT_IMMEDIATE, "/timer/tick",
"iii", iTact, iShortTick, iLongTick );
	}
	
	while( !bQuit )
	{
		if( shortTickCount == 3 )
		{
			iShortTick++;
			shortTickCount=0;
			if( iShortTick == 256 )
			{			
				iShortTick=0;
				iLongTick=0;
				iTact++;
			}
			for( iter=seqs.begin(); iter!=seqs.end(); iter++ )
			{
				lo_send_timestamped( iter->address, LO_TT_IMMEDIATE, "/timer/tick",
"iii", iTact, iShortTick, iLongTick );
			}
		}
		
		if( longTickCount == 4 )
		{
			longTickCount=0;
			iLongTick++;
		}
		
		if( midiTickCount == 8 )
		{
			midiTickCount=0;
  			midiOut->sendMessage( &midiMsg );
		}
		
		shortTickCount++;
		longTickCount++;
		midiTickCount++;
		
		gettimeofday( &tv, NULL );
		passedTime=( ( tv.tv_sec * 1000000 ) + tv.tv_usec );
		
		usleep( iTick-( passedTime-startTime ) );
				
		gettimeofday( &tv, NULL );
		startTime=( ( tv.tv_sec * 1000000 ) + tv.tv_usec );
	}
	pthread_exit( 0 );
}
[/CODE]
The sequencers then play their notes depending on these information.
And of course external midi sequencers play their notes depending on the
midi clock.


So my problem is that this works like crap!
Even if there are no sequencers registered at the timer(seqs.size()==0)
the midi ouput only sends clock messages measuring a speed of ~70BPM.
Although 120 BPM are specified in the app.
And I can't get faster than 150 BPM with the midi clock( internal BPM
would be ~500 )
So I thought it would help to make this thread a realtime thread.
But I found nothing about which scheduling model is currently availabe
for userspace apps and how I append it to the thread.
And I think the sequencers will need a realtime thread for their midi
output, too.
And as I read around a bit I saw that usual system clock is working at
64hz but my loop needs at least 768hz.
Another problem is that I don't know if liblo is fast enough to deliver
the timing messages to usual sequencer clients in realtime.
I found that jack might be useful for me because it supports realtime
threads of usespace apps.
But there might still be a problem with osc.
And there would be a mass of connections in qjackctl then.
So please help me and post anything related that drives and rotates
through your mind.
THANKS for your time reading this!
Christian
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFF8trPVC26eJ+o0+0RAo/IAJ0eon+tgnNvH+XXn+nYsUFf8IvYJwCbBcjh
EHDn9hFf1VVR2bEqT6twdeQ=
=nMYI
-----END PGP SIGNATURE-----



More information about the Linux-audio-dev mailing list