### TimeSeries Tracks

### Vertical ruler

Painting of ruler and tracks.
A track's samples/amplitudes must be converted to an y coord. in the trackpanel's coordinate system. The ruler's range has a min value and a max value and it has a height h for painting. Amplitude values of tracks are converted to an y value using the h, min and max values of the ruler.

     val  coord

     max    0    -- origin (0, 0) of (translated) Graphics coordinate system

                   |

                   |     .  y

                   |

                   |

                   |

     min    h    --

calculate a vertical base unit: the available height divided by the total value range
float unit = h / (max - min)
calculate an y value: the unit value times the diff between the rulers max and the amplitude
float y = unit * (max - ampl)

Examples:
ruler range | [2 - 10]
ruler height | 100 pix
amplitude of sample | [8]
unit | unit = 100 / (10 - 2) = 12.5
y | y = 12.5 * (10 - 8) = 25
amplitude of sample | [13]
y | y = 12.5 * (10 - 13) = -37.5

### Tracks: rate and media times

Conversion of sample index to a media time and to an x coordinate.
In contrast to the TimelineViewer and SignalViewer floats are used from the start for values like milliseconds per sample to avoid rounding related imprecision.
The following applies to a tracks with a fixed/continuous sample frequency.
sps: track sample frequency: number of samples per second
msps: track millisec per sample, virtual duration per sample, or time until next sample
float sps = samplefreq
float msps = 1000 / sps
Sample index to time value and time value to sample index calculation.
Index is zero based (first sample is index 0). Samples are treated begin time inclusive, (virtual) end time exclusive. This means that all time values between index x and index x + 1, are considered to belong to sample x.
sps = 40
msps = 1000 / 40 = 25

    0     1     2     3     4     5

    |-----|-----|-----|-----|-----|

    0     25    50    75   100   125

So, sample 0 is from time 0 - 24 ms, sample 1 from 25 - 49 ms etc.
Index i to time t:
float t = i * msps
this results in the actual (begin) time of the sample. (**see consideration below)
Time t to index i:
int i = (int)(t / msps)
rounding down results in the index of the sample in which virtual time interval that includes the time value t.
**) The smallest time unit in the ELAN media world is 1 millisecond, which is a long value, so non floating point. This consequence is that different samples can calculate to the same time value (as a result of rounding) and that a time value could calculate to more than one sample index.
sps = 4410
msps = 1000 / 4410 = 0.2267...

    0          1          2          3          4          5

    |----------|----------|----------|----------|----------|

    0       0.2267     0.4535     0.6802     0.9070     1.1337

Index to time example:
indices 0, 1, 2, 3, 4 all return t = 0 ms
indices 5, 6, 7, 8 return t = 1 ms
This also means that the number of samples per millisecond is not constant.
Time to index example:
time t = 0 returns index 0, t = 1 returns 4, t = 2 returns 8, which seems inconsistent. Rounding up would seem to be a better solutions in such case.
So, time t to index i:
int i = msps >= 1 ? (int) (t / msps) : (int) Math.ceil(t / msps)

In painting the tracks similar considerations go for calculations from pixel to time (to sample) and from (sample to) time to pixel.
Current approach: get the millisecondsPerPixel setting, get the samples for all milliseconds corresponding to a pixel and calculate the average amplitude.
Calculation form pixel to ms will probably result in the first ms for that pixel and from that to the first sample for that ms....Pending .
.

Last modified: 04 november 2005