Measure time difference between two inputs
Joe Masi
1月 25 2015 | 9:55 午後
Since this is my first post here: Hello to all of you!
Lets say I have two contact mics attached to a table. One on the left side and one on the right. The table is about 2 meters wide. I want to measure the runtime difference (is that correct english?) between the two mics when I knock on the table (Presuming that i am not knocking in the exact middle between the two mics). In a wooden table (c = 4000m/s) with a Sample Rate of 44100 I would get a resolution of 11 samples / meter. So the only chance to do this is in gen and since i am a max newbie I figured this out the hard way. Vector size :)
So what I want to achieve is: An impulse from contact mic 1 is arriving at in1. Once its amplitude is beyond lets say 0.4 (BTW whats the signal format in gen? 64 bit float with a range from -1.0 to 1 right?) I want to start a counter that counts until the impulse from contact mic 2 arrives at in 2 and exceeds 0.4
Then the counter resets.
My big problem is: How do I keep the counter running until the impulse at mic 2 arrives?
Or to put it another way: How can I transform the signal from in1 to 1 right after the first transient has arrived and set it to zero when the impulse arrives at in2?
I tried if else statements but had no success.
BTW is it possible in gen to use && in an if statement to check for two conditions?
Would you do this patch completely in gen? Or would it be smarter to do the sample precise "triggering" in gen (since edge or anything similar isn´t usable) and then use a count~ in max? Why can count~ be sample accurate? Is that because bang and messages don´t depend from the vector size?
So many questions...
I have been working the last two nights on this without success so any help is greatly valued.
Thanks for your help!
Joe
nonlocality
1月 27 2015 | 2:57 午後
you could have a += running that is sampled and then reset at the moment an impulse arrives at in2.
here's one (quickly thrown together) solution. this only works provided input 1 gets the first impulse every time. setting it up to get the difference between every impulse should be fairly simple, given this patch as a starting point. also, i convert from samples to milliseconds, i'm not sure if you needed that, but it's easily removed.
edit: after reading through your post one more time, i realize this isn't exactly what you're looking for! whoops. hopefully it's somehow helpful. i would use bonk~ to detect the transients, and the counter method i used in the patch is the way i turn bangs into impulses in gen (there's probably a better way, but this is how i do it!)
bertrandfraysse
1月 28 2015 | 12:16 午後
I added a simple method for envelope following.
btw you could use click~ to convert bang into impulses.
JesterN
1月 28 2015 | 10:17 午後
I had some attempt with a similar project using xcorrelation and found some good results on this...
Joe Masi
2月 03 2015 | 2:22 午後
Thanks for all the replies! Very helpful!
@ bertrandfraysse: Thanks for the code! Why did you use the sqrt after the abs? I know what it does mathematically but I don´t get what it does to the signal.
@ jestern: What exactly is xcorrelation? I was searching for it but didnt find any useful information.
So far this is working now for very short impulses. But if you look at the screenshot below you see that the impulses from the contact mics are about 5 to 10 ms long. So how would you achieve it that the counter does not reset every time the delta is below zero. I tried it with an if statement hoping that the two for loops would be executed one after another. But this doesn´t seem to work.
Joe Masi
2月 03 2015 | 2:25 午後
hmm, the pic link does not seem to work.
so here is the direct link:
https://www.dropbox.com/s/d9j191emd3i6uu9/Screenshot%202015-02-03%2012.20.52.jpg?dl=0
JesterN
2月 08 2015 | 3:26 午後
Hi Joe, sorry for the late reply, it's called cross correlation and it's used to estimate for example the delay of two signals..
bertrandfraysse
2月 08 2015 | 5:53 午後
the sqrt is used to grow the low values so the trigger is detected even if the amplitue is low. The abs is here because a negative sqrt will stay at zero.
Graham Wakefield
2月 11 2015 | 10:29 午後
Jersten is right, cross-correlation should be a good way of detecting the time difference. Since the number of samples is fairly low, it's cheap enough to do this in the time domain. It is also somewhat robust to amplitude differences between microphones.
Here's an example -- it might not be optimal, but it works:
bertrandfraysse
2月 12 2015 | 11:40 午前
very nice graham, thank you for sharing.
DRegz
8月 28 2024 | 2:36 午後
Hi All,
Sorry to waken this thread up! Graham, I am just trying to get my head around cross correlation and am very much enjoying your patch. My only issue is, I need to compare two signals that might be upto 6 seconds different from each other, so potentially 288000 samples. Could you give me a pointer if I'd be able to achieve that with this patch?
Graham Wakefield
8月 31 2024 | 3:57 午後
Well this is I'm sure a different kind of question to the OP, who was measuring the time difference between two contact mics on a surface, where time-domain xcorrelation is short enough to be feasible. 6 seconds would but quite a huge surface, so I assume your goal is something quite different. Time-domain cross correlation isn't efficient once the delay times are getting larger than a thousand samples or so (a handful of ms; and 6 seconds could well crash your patch). Beyond that point using FFTs is going to be much cheaper. Sorry I don't have an example patch of that to hand but someone might.
Another option you could look at is using a simpler method to get a rough estimate of the delay, and delay the input by say 95% of that estimate and use cross correlation for another 10% to get something more precise. For example, you could downsample (by taking an average, rms, or max of each 100 samples) and then do cross correlation of those downsampled signals, which would keep the buffer sizes down. Use that to get an estimate, then use a full sample rate xcorrelation around that estimate to refine it.