|
View:
New views
9 Messages
—
Rating Filter:
Alert me
|
|
|
How to measure time intervals with JACK?Hi, I'm new at JACK and I'm trying to write some code to measure how
much people synchronize with metronomes. I hope my question is just a basic one, but i have to measure time intervals with JACK in "realtime". I mean, not recording audio and THEN analyze it and measure time between two events (like zero crossings). I coulnd't see how to achieve this. I'm trying just modifying the simple_client.c example, but i'm clueless when it comes to time measurement. For example, how can I measure the time between zero-crossings (of the signal at the input of the soundcard)? In particular, how can I measure that when the two zero crossings are further apart than the time of the buffer? I red the reference, but I can't figure out what "usecs" is or means ("monotonic, free-rolling" ? ) ANYTHING helps... Sorry for my english, cheers from Argentina, trece. _______________________________________________ Jack-Devel mailing list Jack-Devel@... http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org |
|
|
Re: How to measure time intervals with JACK?On Sat, May 10, 2008 at 12:47:33AM -0300, trece ocho wrote:
> For example, how can I measure the time between zero-crossings (of the > signal at the input of the soundcard)? In particular, how can I > measure that when the two zero crossings are further apart than the > time of the buffer? Clearly you need to 'remember' some data from one call to your process callback to the next. There are several ways to do this. The quick and dirty one is to use global variables. The clean way is to use the "arg" parameter you give when registering your callback. You get it back in each callback. Use it as a pointer to a struct (C) or object (C++) that contains the data you want to keep. Inding the distance between zero crossings. For example, you get a buffer wich contains a zero crossing at offset K, and the buffer is N samples long. You remember the value D = N - K. That is how long ago the last zero crossing was as seen from the the start of the next buffer. You store D somewhere you can find it back next time, as explained above. You get the next buffer. Suppose there is no zero crossing. You add N to D. You get the nex buffer, and there is a zero crossing at position K The distance to the last one is D + K. The time between the two (in seconds) is this value divided by the sample frequency (use floats or doubles for this). Ciao, -- FA Laboratorio di Acustica ed Elettroacustica Parma, Italia Lascia la spina, cogli la rosa. _______________________________________________ Jack-Devel mailing list Jack-Devel@... http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org |
|
|
|
|
|
Re: How to measure time intervals with JACK?On Sat, May 10, 2008 at 09:44:15AM -0500, Gabriel M. Beddingfield wrote:
> Well, for me, I've been working on a tap-tempo thing that controls the Jack > Transport (for use in live performance). So, I'm looking for real-time > intervals (not absolute time). When I last worked on it, I was confused > about what notion of time I should use to record taps. It's still not clear at all what you want to do. Measure a tempo ? Make jack_transport start after you tapped two measures ? What is it ? Please explain what you mean by 'real time' and 'real time intervals', if that is not the same as absolute time. If you want to measure the time *between* two or more events in an audio stream you don't need any clock or timer. Just count samples and divide by the sample frequency. > * Using transport frames for this is only valid > while the transport is rolling and not freewheeling. > > * Using absolute sample frames is only valid as > long as jack isn't freewheeling. What are 'absolute frames' ?? Anyway forget freewheeling. There is _no meaningfull concept of time_ when jack is freewheeling. 'Live' and freewheeling are contradictory. You can count samples and convert differences to time intervals, but they only tell you what the timing would be if jack were not freewheeling. > * I couldn't find a good definition of freewheeling > anywhere -- so I wasn't sure what it meant or when > it happens. Just forget about it. You don't want it. > * If the sample rate changes, time calcs using frame > rates get messy. No. You get the sample rate from jack when your app starts. Normally the sample rate does not change as long as jack is running. If it does, you can have a callback to inform you of the change. But nobody does that while an app is running. > * Using timestamps (usecs) looks like a good way, but > it appears to be very machine-dependent and I don't > think there's a mechanism in libjack to make the > conversion to real-time intervals (e.g. > jack_usec_per_sec()). usec means 'microsecond'. There are always 1000000 of them in a second. That never changes. Ciao, -- FA Laboratorio di Acustica ed Elettroacustica Parma, Italia Lascia la spina, cogli la rosa. _______________________________________________ Jack-Devel mailing list Jack-Devel@... http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org |
|
|
Re: How to measure time intervals with JACK?Fons,
First: Thanks a lot! You're really clearing up a lot of stuff. > It's still not clear at all what you want to do. Measure a tempo ? > Make jack_transport start after you tapped two measures ? What is > it ? Yes. Measure a tempo. Make the transport start after tapping (but also adjust the tempo while the transport is rolling). > Please explain what you mean by 'real time' and 'real time intervals', > if that is not the same as absolute time. Real time (absolute): The actual time of day, or some direct indication of the time of day that can be mapped back to the actual day/date/time. Real time interval: The actual difference in time between two events. In simple terms it's the D/S (D = number of frames between, S = sample rate). When you throw in freewheeling and whether or not you're counting transport frames, I wasn't sure what to use to measure this. > What are 'absolute frames' ?? Anyway forget freewheeling. jack_frame_time() or jack_get_time()... as opposed to jack_get_current_transport_frame(). However, while jack_get_time() is sample-rate independent, it's not guaranteed to be linear. Thanks, Gabriel _______________________________________________ Jack-Devel mailing list Jack-Devel@... http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org |
|
|
Re: How to measure time intervals with JACK?On Sun, May 11, 2008 at 10:12:09PM -0500, Gabriel M. Beddingfield wrote:
> Yes. Measure a tempo. Make the transport start after tapping I'll assume you tap someting like 1 - 2 - 1 2 3 - S - - - .... and you want the transport to start on S. (but also adjust the tempo while the transport is rolling). You can't change jack's speed, so I assume you mean updating the tempo information in the transport data. Note that for the first part, the transport can start only on a period boundary. That will almost never be exactly the sample corresponding to S. How you handle the remaining error depends on what exactly you want to do with the transport. If you want some app to start playback at S, you will have to remove the remaining error by adjusting its start position. There are some other complications with starting the transport in this way but let's keep those for later. Before we can go on, you should really understand the following: 1. Freewheeling. Forget about it. When freewheeling jack does not use the soundcard. There is no audio input and output. All jack does it run as fast as the clients will permit. When all the processing for a period is done, the next one starts immediately. Freewheeling is used to make jack clients work as fast as possible on *stored* data, without any consideration of physical time. 2. When as a musician you maintain tempo, or you start a song after a countdown like the one above, does it matter what time it is ? When a DJ starts a track in sync with the previous one, does he look at his watch ? You will agree that the answer is no. This means that *you don't need 'absolute' time at all*. Any attempt to try and use it will only lead to failure and frustration, or in the best case, a solution that is much more complicated than it should be. This is all about tempo (i.e. relative timing, and speed), and you can select the time unit (seconds, frames) and the reference time (the 'zero' of your time scale) as you want. Since you are dealing with samples, and these have a fixed speed, the easiest thing to do is to 'think' in samples as the time unit and only convert to more conventional units (seconds, BPM) where it is needed. 3. Since you are dealing with samples and try to extract timing information from them, you will need to use the sample rate if you like it or not. There is no problem with this - it is in effect a just a constant you get from jack. I know of no situation or application where it could ever change while clients are running. 4. In Jack, audio processing and transport are completely independent of each other, except that transport states can change only on a period boundary. Transport is just a set of data that is passed between clients. It does not affect anything in the audio processing part. I'll try to give an outline of how you could make the transport start at S (assuming that's what you want). R = sample rate N = period size First we need to define a time scale, measured in samples. It will be zero at the start of some period. You could start counting from the first callback you get, or use jack's built-in counter. The function jack_last_frame_time() gives the count for the first sample of the current period. Call it once in the first callback, then continue counting from there by adding N in each period. Or just start from zero. Suppose you can somehow detect the taps, and obtain the corresponding sample counts for each of them. For the sequence 1 - 2 - 1 2 3 - S Let k1 be the sample index of the first '1' and k2 the one for the '3' in the second measure. There are six beats between them. So one beat is B = (k2 - k1) / 6 frames. The tempo is 60 * R / B in beats per minute. We can now predict the sample count corresponding to 'S', the first beat of the first measure. Clearly this will be S = k1 + 8 * B. Now we need to take into account the round-trip latency of your system. This will be close to the number of periods 'n' that the jack backend is configured for (the -n parameter). The adjusted start index is now S' = S - n * N. Given S', you can work out in which period (relative to the current one) it will fall, and what will be the offset within that period. You set the transport position to minus that offset, and set the transport state to RUNNING two periods before the one S' is in. Note that clients can delay the transport start, but this can be disabled. Ciao, -- FA Laboratorio di Acustica ed Elettroacustica Parma, Italia Lascia la spina, cogli la rosa. _______________________________________________ Jack-Devel mailing list Jack-Devel@... http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org |
|
|
Re: How to measure time intervals with JACK?Hi Fons,
Fons Adriaensen wrote: > >> Yes. Measure a tempo. Make the transport start after tapping > > I'll assume you tap someting like > > 1 - 2 - 1 2 3 - S - - - .... > > and you want the transport to start on S. Yes, that's correct. Thanks for all the other info, too. It's helped a lot. You're awesome! > Now we need to take into account the round-trip latency > of your system. This will be close to the number of > periods 'n' that the jack backend is configured for > (the -n parameter). The adjusted start index is now > S' = S - n * N. Is there currently any way for a jack client to query this parameter (--nperiods)? If not... could there be? Maybe add a new driver interface like JackDriverNTQueryFunction to jack_driver_nt_t, and then an API function like jack_query_backend()? It could be used for more than just nperiods. In the mean-time... I'll add it as a user-option to my application. It just doesn't look good. :-) Thanks, Gabriel _______________________________________________ Jack-Devel mailing list Jack-Devel@... http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org |
|
|
Re: How to measure time intervals with JACK?Hi Gabriel,
> Is there currently any way for a jack client to query this parameter > (--nperiods)? If not... could there be? Maybe add a new driver interface > like JackDriverNTQueryFunction to jack_driver_nt_t, and then an API > function like jack_query_backend()? It could be used for more than just > nperiods. There is as far as I know no way to query the value of the -n parameter, but you can find the round-trip latency in frames like this: D = jack_port_get_latency (jack_port_by_name (jack_client, "system:capture_1")) + jack_port_get_latency (jack_port_by_name (jack_client, "system:playback_1")); where 'jack_client' is your jack client handle. If you have an older Jack then "system" should be "alsa_pcm". Ciao, -- FA Laboratorio di Acustica ed Elettroacustica Parma, Italia Lascia la spina, cogli la rosa. _______________________________________________ Jack-Devel mailing list Jack-Devel@... http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org |
|
|
Re: How to measure time intervals with JACK?Fons Adriaensen wrote:
> There is as far as I know no way to query the value of the -n parameter, > but you can find the round-trip latency in frames like this: > > D = jack_port_get_latency (jack_port_by_name (jack_client, "system:capture_1")) > + jack_port_get_latency (jack_port_by_name (jack_client, "system:playback_1")); Thanks, Fons. I think this would work a little better for the app. Having the user declare primary in/out ports is a little more intuitive than asking for the --nperiods parameter. Thanks, Gabriel _______________________________________________ Jack-Devel mailing list Jack-Devel@... http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org |
| Free Forum Powered by Nabble | Forum Help |