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

2007-03-12 Thread Stephen Sinclair

You could also try sigaction and setitimer.
I've had good timing results with this approach in the past.
(I haven't tried it for audio tasks though.)

Steve


On 3/11/07, Robin Gareus [EMAIL PROTECTED] wrote:



Christian wrote:
 Robin Gareus schrieb:
 usleep( iTick-( passedTime-startTime ) );
 AFAIR usleep is not exact! - did you
  echo 1024  /proc/sys/dev/rtc/max-user-freq ?

 try sth like:

 void select_sleep (int usec) {
 fd_set fd;
 int max_fd=0;
 struct timeval tv = { 0, 0 };
 tv.tv_sec = 0; tv.tv_usec = usec;

 FD_ZERO(fd);
 if (remote_en) {
 max_fd=remote_fd_set(fd);
 }

 select(max_fd, fd, NULL, NULL, tv);

 }



 Interesting timing approach.
 But I can't find remote_en and remote_fd_set in the man pages.
 What does these arguments stand for?

sorry, cut the 3 if(remote_en) lines - I was too quick with pasting 
sending the mail - remote_en is some global var. that allows to
interrupt the sleep, if some other-event occurs... - actually you'd only
needed select (0,fd,0,0,tv);

anyway clock_nanosleep seems better; at least it takes less code
to set it up. I did not know about it, and it's even POSIX, how cool!

#robin



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

2007-03-11 Thread Robin Gareus


Christian wrote:
 Robin Gareus schrieb:
 usleep( iTick-( passedTime-startTime ) );
 AFAIR usleep is not exact! - did you
  echo 1024  /proc/sys/dev/rtc/max-user-freq ?
 
 try sth like:
 
 void select_sleep (int usec) {
 fd_set fd;
 int max_fd=0;
 struct timeval tv = { 0, 0 };
 tv.tv_sec = 0; tv.tv_usec = usec;
 
 FD_ZERO(fd);
 if (remote_en) {
 max_fd=remote_fd_set(fd);
 }
 
 select(max_fd, fd, NULL, NULL, tv);
 
 }
 
 
 
 Interesting timing approach.
 But I can't find remote_en and remote_fd_set in the man pages.
 What does these arguments stand for?

sorry, cut the 3 if(remote_en) lines - I was too quick with pasting 
sending the mail - remote_en is some global var. that allows to
interrupt the sleep, if some other-event occurs... - actually you'd only
needed select (0,fd,0,0,tv);

anyway clock_nanosleep seems better; at least it takes less code
to set it up. I did not know about it, and it's even POSIX, how cool!

#robin


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

2007-03-10 Thread Christian
-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::listSeq::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 * 100 ) + 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 * 100 ) + tv.tv_usec );

usleep( iTick-( passedTime-startTime ) );

gettimeofday( tv, NULL );
startTime=( ( tv.tv_sec * 100 ) + 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-


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

2007-03-10 Thread Robin Gareus

   usleep( iTick-( passedTime-startTime ) );

AFAIR usleep is not exact! - did you
 echo 1024  /proc/sys/dev/rtc/max-user-freq ?

try sth like:

void select_sleep (int usec) {
fd_set fd;
int max_fd=0;
struct timeval tv = { 0, 0 };
tv.tv_sec = 0; tv.tv_usec = usec;

FD_ZERO(fd);
if (remote_en) {
max_fd=remote_fd_set(fd);
}

select(max_fd, fd, NULL, NULL, tv);

}



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

2007-03-10 Thread Dmitry Baikov

In addition to select() there's also clock_nanosleep(CLOCK_MONOTONIC,
0, tv, NULL), which in theory should give best resolution possible.

To set realtime privileges, use (taken from jack):

struct sched_param rtparam;
memset (rtparam, 0, sizeof (rtparam));
rtparam.sched_priority = priority;
pthread_setschedparam (thread, SCHED_FIFO, rtparam);



Interesting project, btw. I planned to start something like this myself.

Please, publish results of your timing experiments - very interesting!


Dmitry.


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

2007-03-10 Thread Christian
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Robin Gareus schrieb:
  usleep( iTick-( passedTime-startTime ) );
 
 AFAIR usleep is not exact! - did you
  echo 1024  /proc/sys/dev/rtc/max-user-freq ?
 
 try sth like:
 
 void select_sleep (int usec) {
 fd_set fd;
 int max_fd=0;
 struct timeval tv = { 0, 0 };
 tv.tv_sec = 0; tv.tv_usec = usec;
 
 FD_ZERO(fd);
 if (remote_en) {
 max_fd=remote_fd_set(fd);
 }
 
 select(max_fd, fd, NULL, NULL, tv);
 
 }
 
 
 
Interesting timing approach.
But I can't find remote_en and remote_fd_set in the man pages.
What does these arguments stand for?
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFF8w15VC26eJ+o0+0RAsGVAJ0WRpmImWy+MZaAsSha4x6Rgt9RWgCeLkiF
4BwEtaUL9OREI+MhSVGe/Yg=
=MriT
-END PGP SIGNATURE-


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

2007-03-10 Thread Christian
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Dmitry Baikov schrieb:
 In addition to select() there's also clock_nanosleep(CLOCK_MONOTONIC,
 0, tv, NULL), which in theory should give best resolution possible.
 
 To set realtime privileges, use (taken from jack):
 
 struct sched_param rtparam;
 memset (rtparam, 0, sizeof (rtparam));
 rtparam.sched_priority = priority;
 pthread_setschedparam (thread, SCHED_FIFO, rtparam);
 
 
 
 Interesting project, btw. I planned to start something like this myself.
 
 Please, publish results of your timing experiments - very interesting!
 
 
 Dmitry.
 
 
Taken your code to set the thread to realtime I now get very exactly 78
bpm which don't change much.
On the one hand this indicates the thread running stable in realtime but
having a restriction to ~4ms/4000µs. Perhaps this is an in-system value
of sleep and the select approach Robin Gareus posted will help out.
Christian

-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFF8w7GVC26eJ+o0+0RAnEfAKCXD2rWLK+MO4kFWyzd7PwtVL/qWgCgnYUi
/M3jB2t4fatk/SXnWUKTAe4=
=MzSS
-END PGP SIGNATURE-


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

2007-03-10 Thread Dmitry Baikov

On 3/10/07, Christian [EMAIL PROTECTED] wrote:

On the one hand this indicates the thread running stable in realtime but
having a restriction to ~4ms/4000µs. Perhaps this is an in-system value

4ms means you have 250Hz kernel tick. Set it to 1024Hz or better try
tickless setup.


of sleep and the select approach Robin Gareus posted will help out.

I'd suggest using clock_nanosleep() and clock_gettime() with
clockid=CLOCK_MONOTONIC.
This is the more right approach than select/gettimeofday().


Dmitry.


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

2007-03-10 Thread Christian
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Dmitry Baikov schrieb:
 4ms means you have 250Hz kernel tick. Set it to 1024Hz or better try
 tickless setup.
/proc/asound/timers says:

G0: system timer : 1000.000us (1000 ticks)
G1: RTC timer : 976.562us (1 ticks)

Seq24 for example is running correctly so I don't think it's an error in
my system setup.

-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFF8xSSVC26eJ+o0+0RArk9AKCSPnuk+k0C2iDVF66M3ZIr6b2n1gCfRe5u
1BgsXmwU9hBRjtYq8bmRo5Y=
=eIOK
-END PGP SIGNATURE-


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

2007-03-10 Thread Christian
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

 I'd suggest using clock_nanosleep() and clock_gettime() with
 clockid=CLOCK_MONOTONIC.
 This is the more right approach than select/gettimeofday().
 
 
 Dmitry.

Yeah clock_nanosleep did it!
I got a stable absolute bpm exact midi clock.
I'll test the osc messages tomorrow( I've to rewrite some stuff of my
first sequencer ).
Whooo, thanks alot.
Christian

p.s.:
The Code:
[CODE]
void Timer::runThread()
{
std::listSeq::iterator iter;
timespec timeOut;
int shortTickCount=0;
int longTickCount=0;
int midiTickCount=0;

struct sched_param rtparam;
memset (rtparam, 0, sizeof (rtparam));
rtparam.sched_priority = 99;
pthread_setschedparam (thread, SCHED_FIFO, rtparam);

while( !bRunning )
usleep ( 100 );

clock_gettime( CLOCK_MONOTONIC, timeOut );

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++;

timeOut.tv_nsec+=iTick*1000;
if( timeOut.tv_nsec 10 )
{
timeOut.tv_sec++;
timeOut.tv_nsec=timeOut.tv_nsec-10;
}

clock_nanosleep( CLOCK_MONOTONIC, TIMER_ABSTIME, timeOut, NULL 
);
}
pthread_exit( 0 );
}
[/CODE]
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFF8x9oVC26eJ+o0+0RAr5gAJ9/a/UMEIKzlA3ZKXhPhEidXs4FGgCgopIC
am0HTYe66SLHV0o9e/hE4oM=
=1owC
-END PGP SIGNATURE-