View Raw SPL
/*****************************************************************************
*                                                                            *
*   TIMESYNC.SPL  Copyright (C) 2019 DSP Development Corporation             *
*                               All Rights Reserved                          *
*                                                                            *
*   Author:      Randy Race                                                  *
*                                                                            *
*   Synopsis:    Simple time synchronization of two series                   *
*                                                                            *
*   Revisions:   24 Jul 2019  RRR  Creation                                  *
*                                                                            *
*****************************************************************************/

#if @HELP_TIMESYNC

    TIMESYNC

    Purpose: Time synchronization of two series by resampling and extraction.

    Syntax:  TIMESYNC(s1, s2, fs)

                s1 - A series, the first series.

                s2 - A series, the second series.

                fs - Optional. A real, the new sample rate. Defaults to -1,
                     the maximum rate of s1 and s2;

    Returns: A stripchart of the resulting resampled series.

             (y1, y2) = timesync(w1, w2, fs) returns the synched series
             as separate series.

    Example:
             W1: 1..10;settime(w0, "12:00");sethunits("Time")
             W2: 3..0.1..20;settime(w0, "12:00");sethunits("Time")
             W3: timesync(w1, w2)

             The series in W1 starts at 12:00:01 and contains 10 samples.
             The series in W2 starts at 12:00:03 and contains 171 samples.
             The sample rate of W1 is 1 Hz and the sample rate of W2 is 10 Hz.
             W3 contains a stripchart with a sample rate of 10 Hz. Both series
             start at 12:00:03. The first trace of the stripchart is produced
             by extracting from the 3rd sample of W1, the index of W1 that
             corresponds to the starting time of W2.

    Example:
             W1: 1..10;settime(w0, "12:00");sethunits("Time")
             W2: 3..0.1..20;settime(w0, "12:00");sethunits("Time")
             W3: timesync(w2, w1)

             Same as above except the input series are swapped. The start
             time of the resulting series is 12:00:01 and the sample rate
             is 10 Hz. The first trace of W3 is produced by prepending 20
             zeros to W2.

    Example:
             W1: 1..10;settime(w0, "12:00");sethunits("Time")
             W2: 3..0.1..20;settime(w0, "12:00");sethunits("Time")
             W3: timesync(w2, w1, 15.0)

             Same as above except the output sample rate is set to 15 Hz.

    Remarks:
             TIMESYNC synchronizes S1 to S2 by adjusting the starting index
             of S1 to match the wall clock starting time of S2. The
             adjustment is achieved by extracting or prepending samples to S1.
             Both series are resampled to FS to produce a point by point
             correspondence between the resulting series.

             If FS < 0 or unspecified, the sample rate is set to the largest
             (fastest) rate of the two input series.

             Both input series should have horizontal units (i.e. X units)
             of "Time" or "Real Time" to yield wall clock synchronization.

             TIMESYNC resamples XY input series to regularly sampled
             interval series.

    See Also:
             Extract
             Resample
             Xtoidx

#endif


/* time synchronize two series */
timesync(s1, s2, fs)
{
        local dx, dx1, dx2, xs, x1, x2, toff, idx;

        if (argc < 3)
        {
                if (argc < 2) error(sprintf("%s - two input series required", __FUNC__));

                fs = -1;
        }

        if (fs <= 0)
        {
                /* find smallest dx */
                dx1 = xyinterp(s1, -1, 1);
                dx2 = xyinterp(s2, -1, 1);

                dx  = min(dx1, dx2);
                fs  = 1.0 / dx[1];
        }

        /* resample s1 and normalize time to zero xoffset */
        xs = xvals(s1, 1, 1);
        x1 = xs[1];

        s1 = resample(s1, fs);
        setxoffset(s1, 0.0);
        settime(s1, strtodmsec(x1));

        /* resample s2 and normalize time to zero xoffset */
        xs = xvals(s2, 1, 1);
        x2 = xs[1];

        s2 = resample(s2, fs);
        setxoffset(s2, 0.0);
        settime(s2, strtodmsec(x2));

        /* time offset */
        toff = x2 - x1;

        /* find index in s1 corresponding to time offset */
        idx = xtoidx(s1, toff, 0);

        /* extract s1 to toff */
        s1 = extract(s1, idx, -1, 0.0);

        /* adjust time */
        settime(s1, strtodmsec(x2));

        if (outargc == 0)
        {
                stripchart(s1, s2);
        }
        else
        {
                return(s1, s2);
        }
}