Increasing The Speed Of Effects

   Print  Previous  Next

BPM vs. FPS

The speed of the MAS Script Effect is controlled by the BPM slider (and edit field) which has a range between 0 and 9999. With regard to this, 0 implies that the effect is stopped and will not be rendered any more. Transferred to a script, it means that RenderEffect is not called anymore. Consequently, the effect stops automatically. 9999 is the maximum value and would mean that the effect runs with round about 166 FPS. Here is how BPM and FPS values are related to each other:

BPM = FPS * 60

FPS = BPM / 60

 

Since DMX maximally supports a data frequency of 43Hz (or FPS), MADRIX renders effects with a maximum of 50Hz (or FPS), which equals 3000 BPM. Any render frequency that is higher would not make any sense. That means that a script is not called more often than 50 times per second, no matter if the BPM slider shows 3000 or 9000 BPM.

To illustrate this fact, copy and paste the following script. It makes a rectangle move from the left to the right side of the matrix.

int g_pos[];

int g_rectSize[] = {4, 4}; //size of the rect

 

void MatrixSizeChanged()

{

    g_pos[1] = GetMatrixHeight() / 2 - g_rectSize[1] / 2;;

}

 

void InitEffect()

{

    MatrixSizeChanged();

}

 

void RenderEffect()

{

    Clear();

    FillPixelRect(WHITE, g_pos[0], g_pos[1], g_rectSize[0], g_rectSize[1]);

    //move the rectangle

    g_pos[0] += 1;

    //check if the rectangle has left the matrix and set it back

    if(g_pos[0] > GetMatrixWidth() + g_rectSize[0])

        g_pos[0] = -g_rectSize[0];

}

 

Subsequently, set the matrix to a width of 50. Use the BPM slider to increase or decrease the speed. You should be  able to recognize that the rectangle always needs one second to move across the whole matrix, whether you select 3000 BPM or 9000 BPM. This is due to two facts. First, the rectangle is moved exactly one pixel per call. Second, the maximal render frequency of an effect, and therefore also for a script, is 50 FPS. So, the rectangle will maximally be moved 50 times per second by exactly one pixel.

Please note: A script is called a maximum of 50 times per second.

 

Creating Faster Effects

Now we know that we can not increase the maximal render frequency. If we cannot render the rectangle more often, we need to move the rectangle a little bit more than one pixel per call. The solution is framesteps, a value which can be determined by the function:

float GetFrameSteps()

 

This function tells us, how many frames would have been left since the last call of our RenderEffect function. E.g. if we have a speed of 6000 BPM, GetFrameSteps results in a value of 2.0 (6000  BPM/ 2.0 = 3000 BPM or 50Hz). To use this in our script, we need to change one line:

g_pos[0] += 1; 

to

g_pos[0] += (int)GetFrameSteps();

 

 

In the end, the script looks like this:

int g_pos[];

int g_rectSize[] = {4, 4}; //size of the rect

 

void MatrixSizeChanged()

{

    g_pos[1] = GetMatrixHeight() / 2 - g_rectSize[1] / 2;;

}

 

void InitEffect()

{

    MatrixSizeChanged();

}

 

void RenderEffect()

{

    Clear();

    FillPixelRect(WHITE, g_pos[0], g_pos[1], g_rectSize[0], g_rectSize[1]);

 

    //move the rectangle

    g_pos[0] += (int)GetFrameSteps();

    //check if the rectangle has left the matrix and set it to the other side       

    if(g_pos[0] > GetMatrixWidth() + g_rectSize[0])

        g_pos[0] = -g_rectSize[0];

    else if(g_pos[0] < -g_rectSize[0])

        g_pos[0] = GetMatrixWidth()+g_rectSize[0];

}

 

Explanation:

This script is now able to play much faster than 3000 BPM and you can increase the speed even more using the Speed Master. Furthermore, if you set the Speed Master to its negative range of values, it will play backwards. This is due to the fact that if the Speed Master is negative, framesteps is also negative. Since we are making direct use of FrameSteps, the position will be decreased automatically.

Due to this fact, the script has not only to check if the rectangle has left the matrix to the right side (which we have done in the other script, too). It also needs to be checked if the rectangle  has left the matrix to the left side. And if so, the rectangle needs to be set to the other side. This is done with the help of the last two lines that were added to the script.

Now we have a script which is able to run very fast and which can be controlled by the Speed Master as well.

 

Using Floating-point Values

Up to this point, GetFrameSteps always delivers integer values, like 1.0, 2.0, 3.0, and so on. The minimal value was 1.0. It is also possible, and sometimes necessary, to have values inbetween, like 1.5 for example. Especially if a fixed render frequency is used, this is absolutely necessary as you will see later on. Some effects require floating point values, or else the effect will not be rendered smoothly. You can enable floating point frame steps with the function:

void SetUseFloatFrames(int enable)

 

Add this line to the following script and start it. Now, if you move the BPM slider you will see that GetFrameSteps delivers values like 2.5, etc.

void InitEffect()

{

    SetUseFloatFrames(true);

}

 

void RenderEffect()

{

    WriteText((string)GetFrameSteps());

}

 

Note: Even if a script enables floating point frame steps, after recompiling and starting another script it is disabled again.