Music2Light (M2L)

   Print  Previous  Next

Introduction

Music2Light effects can go a step further and analyze music regarding music theoretical aspects. Tonality, scale, or intervals are only some examples of the data that can be retrieved by the sound analysis. This chapter describes how to retrieve the data provided by MADRIX. However, it does not describe any music theory.

 

Using Tonality And Scale

Let us start with tonality and scale of a chord. The two can be retrieved via the functions GetTonality() and GetToneScale(), respectively. The exemplary sample source code for the MAS Script Effect below uses tonality and scale to select a color and the alpha value will be the background color. Please remember: an audio input signal is needed.

const color g_colorTable[] = {

            {255, 0, 0, 0},         //C

            {255, 128, 128, 128},   //C#

            {0,  255, 0, 0},        //D

            {128, 255,128,128},     //D#

            {0,  0,   255,0},       //E

            {255, 255, 0, 0},       //F

            {255, 255, 128, 128},   //F#

            {255, 0, 255, 0},       //G

            {255, 128,255,128},     //G#

            {255, 128, 0, 0},       //A

            {255, 100, 100, 100},   //A#

            {255, 255, 255, 128}    //B

                             };

void InitEffect()

{

}

 

void RenderEffect()

{

    int idx=GetTonality();

    if (idx>=0 && idx<=11) ClearColor(g_colorTable[idx]);

    else ClearColor(BLACK);

    int alpha = (255 / (1 + GetToneScale()));

    ClearAlpha(alpha);

}

 

Explanation:

The first thing is to create a color table in which each entry equals a tonality. If the tonality is undetermined, the function GetTonality() results in -1.
Therefore, we have to check if the value is a valid array index and eventually draw a black matrix. You could use the function IsTonality() to check if the tonality was set or not.

 

Using Notes

MADRIX is able to identify the notes played in a song. The lowest note that can be evaluated is the C with 8.25 Hz. The highest note is an G with 12.6 kHz. There are two functions available to get information about the identified notes. GetNoteValue() retrieves the volume of the given note and IsNote() returns true if the given note has been detected, otherwise false. There is the function GetAllNoteValues(), which fills an array with the volume of each note. Using this method for a lot of notes is much faster then calling GetNoteValue(). An overview over which index corresponds to which note is given by the »Table Of Notes

The next example for the MAS Script Effect uses played notes to fill the matrix with different colors. It uses only the values of three frequencies of C.

void InitEffect()

{

}

 

void RenderEffect()

{

    float val[];

    //C with 528Hz

    val[0] = (float)GetNoteValue(72) / 127.0;

    //C with 1056KHz

    val[1] = (float)GetNoteValue(84) / 127.0;

    //C with 2112KHz

    val[2] = (float)GetNoteValue(96) / 127.0;

 

    color c;

    c.r = (int)(255.0 * val[0]);

    c.g = (int)(255.0 * val[1]);

    c.b = (int)(255.0 * val[2]);

 

    Clear(c);

}

 

Explanation:

First, the levels of the notes are retrieved and normalized to the range of 0.0 to 1.0. Hereby, only three C notes are used.
Then, a color is initialized and the matrix is filled.

 

Using Intervals

There are similar functions to get information about the intervals indexed from 0 (small second interval) to 10 (large seventh interval). The function IsInterval() returns true if the specified interval  could be analyzed, otherwise false. Again, the function GetAllIntervals() fills an array rapidly, each element with either true (interval was analyzed) or false (interval was not analyzed). The following short example for the MAS Script Effect clarifies the usage of GetAllIntervals():

const int middle=GetMatrixHeight()/2;

int buf[];

int xStep;

 

void InitEffect()

{

    GetAllIntervals(buf);

    xStep=max(GetMatrixWidth()/buf.length,1);

}

 

void RenderEffect()

{

    ClearAlpha(255);

    GetAllIntervals(buf);

    for (int i=0;i<buf.length;i++)

    {

        DrawPixelLine(WHITE,i*xStep,!buf[i]*middle,i*xStep,(1+!buf[i])*middle);

    }

}

 

 

Explanation:

At first, in InitEffect() the buffer buf is filled once, just in order to get the buffer length. With the buffer length, a horizontal distance xStep is calculated to separate some lines equally later on. Using the function max(), the distance is at least 1.
Calling RenderEffect() the buffer buf is filled with the current interval appearances. Then, a vertical line is drawn for every interval, either from the middle to the top of the matrix (if the interval was analyzed) or from middle to bottom (if not).

 

Using Other Tone Theoretical Parameters

There is lots of other data which may be used to create effects, e.g. the sound level or the note of the currently lowest note (bass tone). The handling is similar to the functions described above. Further details are given in the »List Of Functions

 

MADRIX Version: 3.6g | Script Version: 2.21
[Ctrl & +/-] = Zoom In/Out | [Ctrl & 0] = 100%
Print   Previous   Next