Search code examples
javaaudiofingerprinting

Measuring delay with audio fingerprinting (Java)


I would like to measure the delay between one live stream on two different platforms using audio fingerprinting. Currently I am using musicg library for Java. I can obtain information such as the spectrogram and the fingerprints but I couldn't figure out how to use the data for measuring the delay.

My question is whether the musicg library is enough for this kind of operation. If so, how can I use the data I've acquired to find the delay between the two streams.

Thanks in advance.


Solution

  • Here's what I would do. I would create 2 HashMap<FingerprintData, Long>s. Essentially you are mapping fingerprint data from your streams to a reply from System.nanoTime().

    I would then create a "game-loop" that runs "forever", or until you don't want it to anymore, and each iteration I would take the fingerprint data from each stream and and check if either HashMap.keySet().contains(theFingerPrintData) from the opposite stream. If it does, you'll release it from the HashMap and do the math to find the delay like so:

    Also, I'm not sure what your class is used for your fingerprint data, so for my example I will just call it FingerprintData

    Map<FingerprintData, Long> stream1Timestamps = new HashMap<>();
    Map<FingerprintData, Long> stream2Timestamps = new HashMap<>();
    
    StreamClass stream1 = howEverYouFetchStream(1);
    StreamClass stream2 = howEverYouFetchStream(2);
    
    while(true /*or if you have conditional to terminate place it here*/){
         FingerprintData stream1fpd = stream1.getFingerprintData();
         FingerprintData stream2fpd = stream2.getFingerprintData();
    
         if(stream1Timestamps.keySet().contains(stream2fpd)){
             Long firstHeard = stream1Timestamps.get(stream2fpd);
             System.out.println("stream 2 is delayed:" +System.nanoTime()-firstHeard + " nanoseconds");
             stream1Timestamps.remove(stream2fpd);
         }else{
             stream2Timestamps.put(stream2fpd, System.nanoTime();
         }
    
         if(stream2Timestamps.keySet().contains(stream1fpd)){
             Long firstHeard = stream2Timestamps.get(stream1fpd);
             System.out.println("stream 1 is delayed:" +System.nanoTime()-firstHeard + " nanoseconds");
             stream2Timestamps.remove(stream1fpd);
         }else{
             stream1Timestamps.put(stream1fpd, System.nanoTime();
         }
    
      }
    

    This may need to be tweaked a little bit, but essentially I believe this is what you are looking for.