Overview
The TimeLineV2 class is a static class that manages timeline playback, time conversions between ticks/seconds/pixels, and musical time calculations in Lumix. It provides the core timing functionality for the DAW.
Namespace
Constants
Pulses Per Quarter note - the resolution of the timeline.public const int PPQ = 960;
Properties
Number of beats per bar. Represents the time signature denominator.public static float BeatsPerBar { get; set; }
Conversion factor from ticks to screen pixels, based on current zoom level.public static float PixelsPerTick { get; }
Calculated as: 0.05f * ArrangementView.Zoom
Playback Methods
StartPlayback
Starts timeline playback from the current position.
public static void StartPlayback()
Example:
// Start playback
TimeLineV2.StartPlayback();
StopPlayback
Stops timeline playback and optionally resets to the beginning.
public static void StopPlayback(bool moveToStart = false)
If true, resets playback position to tick 0. If false, maintains current position.
Example:
// Stop and stay at current position
TimeLineV2.StopPlayback();
// Stop and return to start
TimeLineV2.StopPlayback(moveToStart: true);
IsPlaying
Checks if the timeline is currently playing.
public static bool IsPlaying()
Returns: true if playback is active, false otherwise
Example:
if (TimeLineV2.IsPlaying())
{
// Update playback UI
}
UpdatePlayback
Updates the current tick position during playback. Should be called each frame.
public static void UpdatePlayback()
Example:
// In your render loop
TimeLineV2.UpdatePlayback();
Time Position Methods
GetCurrentTick
Gets the current playback position in ticks.
public static long GetCurrentTick()
Returns: Current position in ticks
Example:
long currentTick = TimeLineV2.GetCurrentTick();
Console.WriteLine($"Current position: {currentTick} ticks");
SetCurrentTick
Sets the current playback position in ticks.
public static void SetCurrentTick(long ticks)
Example:
// Jump to bar 5
long bar5Ticks = 5 * 4 * TimeLineV2.PPQ;
TimeLineV2.SetCurrentTick(bar5Ticks);
GetLastTickStart
Gets the tick position where playback last started.
public static long GetLastTickStart()
Returns: Starting tick position of current/last playback
SetLastTickStart
Sets the tick position for playback start.
public static void SetLastTickStart(long ticks)
The tick position to set as playback start
Time Conversion Methods
TicksToSeconds
Converts ticks to seconds based on current or default tempo.
public static double TicksToSeconds(long ticks, bool useTempo = true)
Number of ticks to convert
If true, uses current project tempo. If false, uses default 120 BPM.
Returns: Time in seconds
Example:
// Convert one bar to seconds at current tempo
long oneBar = 4 * TimeLineV2.PPQ;
double seconds = TimeLineV2.TicksToSeconds(oneBar);
SecondsToTicks
Converts seconds to ticks based on current or default tempo.
public static long SecondsToTicks(double seconds, bool useTempo = true)
Number of seconds to convert
If true, uses current project tempo. If false, uses default 120 BPM.
Returns: Time in ticks
Example:
// Convert 5 seconds to ticks
long ticks = TimeLineV2.SecondsToTicks(5.0);
TimeToPosition
Converts ticks to horizontal pixel position.
public static float TimeToPosition(long ticks)
Number of ticks to convert
Returns: Horizontal position in pixels
Example:
long clipStart = 960 * 4; // One bar
float xPosition = TimeLineV2.TimeToPosition(clipStart);
PositionToTime
Converts horizontal pixel position to ticks.
public static long PositionToTime(float x)
Horizontal position in pixels
Returns: Time in ticks
Example:
float mouseX = ImGui.GetMousePos().X;
long tickAtMouse = TimeLineV2.PositionToTime(mouseX);
TicksToPixels
Converts ticks directly to pixel width.
public static float TicksToPixels(long ticks)
Number of ticks to convert
Returns: Width in pixels
Example:
long clipLength = 960 * 4; // One bar
float clipWidth = TimeLineV2.TicksToPixels(clipLength);
Musical Time Methods
TicksToMusicalTime
Converts ticks to musical time notation (bars:beats:ticks).
public static MusicalTime TicksToMusicalTime(long ticks, bool applyOffset = false)
Number of ticks to convert
If true, starts counting from 1:1:1 instead of 0:0:0
Returns: MusicalTime struct with Bars, Beats, and Ticks
Example:
long position = 960 * 8; // Two bars
var musicalTime = TimeLineV2.TicksToMusicalTime(position, applyOffset: true);
Console.WriteLine($"{musicalTime.Bars}:{musicalTime.Beats}:{musicalTime.Ticks}");
// Output: 3:1:1 (bar 3, beat 1, tick 1)
MusicalTimeToTicks
Converts musical time notation to ticks.
public static long MusicalTimeToTicks(MusicalTime musicalTime, bool applyOffset = false)
Musical time with Bars, Beats, and Ticks
If true, treats input as 1-indexed (1:1:1 = tick 0)
Returns: Time in ticks
Example:
var musicalTime = new MusicalTime(5, 2, 480); // Bar 5, beat 2, tick 480
long ticks = TimeLineV2.MusicalTimeToTicks(musicalTime);
MusicalTimeToPixels
Converts musical time directly to pixel position.
public static float MusicalTimeToPixels(MusicalTime musicalTime)
Returns: Position in pixels
Example:
var time = new MusicalTime(4, 1, 0); // Bar 4, beat 1
float xPos = TimeLineV2.MusicalTimeToPixels(time);
Grid Methods
SnapToGrid
Snaps a tick position to the nearest grid line based on BeatsPerBar.
public static long SnapToGrid(long tick)
Returns: Snapped tick position
Example:
// Snap mouse position to grid
long mouseTick = TimeLineV2.PositionToTime(mouseX);
long snappedTick = TimeLineV2.SnapToGrid(mouseTick);
TimeLineV2.SetCurrentTick(snappedTick);
Usage Example
using Lumix.Views.Arrangement;
// Start playback
TimeLineV2.SetCurrentTick(0);
TimeLineV2.StartPlayback();
// Update in render loop
while (running)
{
TimeLineV2.UpdatePlayback();
// Get current position
long currentTick = TimeLineV2.GetCurrentTick();
var musicalTime = TimeLineV2.TicksToMusicalTime(currentTick, applyOffset: true);
// Display time
Console.WriteLine($"Position: {musicalTime.Bars}:{musicalTime.Beats}:{musicalTime.Ticks}");
// Convert to seconds for display
double seconds = TimeLineV2.TicksToSeconds(currentTick);
Console.WriteLine($"Time: {seconds:F2}s");
}
// Stop playback
TimeLineV2.StopPlayback();
Notes
- All time calculations are based on PPQ = 960 (high resolution)
- Musical time uses standard 4/4 time signature by default
- The
useTempo parameter allows for tempo-independent calculations
- Grid snapping respects the current
BeatsPerBar setting
- Pixel conversions automatically adjust based on arrangement zoom level