4. Step Helper Functions

These are various functions that are used to abstract away common functions needed to be carried out.

4.1. Deriving Pitch and Octave (and back again)

A note is decomposed into a pitch offset (semitones 0 to 11, inclusive) and octave (0 to 3, inclusive). This is done with the function to_pitchoct. The octave is kept positive because it is one less step to display it.

<<step_function_declarations>>=
static void to_pitchoct(signed char note, int *pitch, int *oct);

The note is expected to be in the range of -12 to 24. This note is first biased by 12 to be in range 0 to 36. This is done to avoid negative modulo operations. From there, the pitch is derived using modulo 12, and the octave is derived by doing an integer divde by 12.

<<step_functions>>=
static void to_pitchoct(signed char note, int *pitch, int *oct)
{
    if(pitch == NULL || oct == NULL) return;
    note += 12;
    *pitch = (note % 12);
    *oct = (note / 12);
}

Once any manipulations have been done to pitch or the octave, it can be converted back into a note. The reverse operation is done with to_note.

<<step_function_declarations>>=
static signed char to_note(int pitch, int oct);

Note that octave supplied reflects the monome display (0,3) and not what the musical octave is (-1, 2). To compensate for this, subtract 1.

<<step_functions>>=
static signed char to_note(int pitch, int oct)
{
    signed char out;
    out = ((oct-1) * 12) + pitch;
    return out;
}

4.2. Manipulating the pitch

The currently selected note can be retrieved with the function get_current_note. This will select what is under the edit cursor. The currently performed note is selected with get_performed_note. This will select the current note under the playhead.

<<step_function_declarations>>=
static signed char get_current_note(page_step_d *pg);
static signed char get_performed_note(page_step_d *pg);
<<step_functions>>=
static signed char get_current_note(page_step_d *pg)
{
    return step_pattern_note_get(&pg->pat[pg->curpat],
                                 page_step_editpos_get(pg));
}
static signed char get_performed_note(page_step_d *pg)
{
    return step_pattern_note_get(&pg->pat[pg->curpat],
                                 page_step_playpos_get(pg));
}

The note currently selected can be set using the function set_current_note.

<<step_function_declarations>>=
static void set_current_note(page_step_d *pg, signed char note);
<<step_functions>>=
static void set_current_note(page_step_d *pg, signed char note)
{
    step_pattern_note_set(&pg->pat[pg->curpat],
                          page_step_editpos_get(pg),
                          note);
}

4.3. Manipulation of the currently selected gate

The currently selected gate can be set with the function set_current_gate.

<<step_function_declarations>>=
void set_current_gate(page_step_d *step, signed char g);
<<step_functions>>=
void set_current_gate(page_step_d *step, signed char g)
{
    step_pattern_gate_set(&step->pat[step->curpat],
                          page_step_editpos_get(step),
                          g);
}

The currently selected gate can be retrieved with the function get_current_gate. The gate under the playhead can be retrieved using the function get_performed_gate.

<<step_function_declarations>>=
static signed char get_current_gate(page_step_d *step);
static signed char get_performed_gate(page_step_d *step);
<<step_functions>>=
static signed char get_current_gate(page_step_d *step)
{
    return step_pattern_gate_get(&step->pat[step->curpat],
                                 page_step_editpos_get(step));
}
static signed char get_performed_gate(page_step_d *step)
{
    return step_pattern_gate_get(&step->pat[step->curpat],
                                 page_step_playpos_get(step));
}

4.4. Clock Incrementor

When the function step_step is called, the sequence moves forward in time.

<<step_function_declarations>>=
static void step_step(page_step_d *step);
<<step_functions>>=
static void step_step(page_step_d *step)
{
    int pos;
    if(page_step_is_playing(step)) {
        pos = page_step_playpos_get(step);
        pos = (pos + step->step);
        if (pos < 0) pos += step_current_patsize(step);
        /* still stubborn? back to 0 */
        if (pos < 0) pos = 0;
<<wait_and_reset>>
        pos %= step_current_patsize(step);
        page_step_playpos_set(step, pos);
        if(!page_step_jam_mode(step)) {
            page_step_draw_playhead(step);
            page_step_draw_current_note(step);
        }
    }
}

4.5. Get current pattern size

The current pattern size can be retrived with the function step_current_patsize.

<<step_function_declarations>>=
int step_current_patsize(page_step_d *step);
<<step_functions>>=
int step_current_patsize(page_step_d *step)
{
    return step_pattern_size_get(&step->pat[step->curpat]);
}

4.6. TODO Set playhead position

4.7. TODO Set note

4.8. TODO Set gate

4.9. TODO Wait and Reset

When called, will halt and wait for the next clock trigger. The patch will subsequently rewind to 0.

To be used to (hopefully) sync up multiple pages together.

<<step_function_declarations>>=
void step_wait_and_reset(page_step_d *step);

The idea here will be to have some kind of flag that gets set. The next time the step page steps with step_step, it will now to set the position back to 0.

<<step_functions>>=
void step_wait_and_reset(page_step_d *step)
{
    step->wait_and_reset = 1;
}
<<wait_and_reset>>=
if (step->wait_and_reset) {
    step->wait_and_reset = 0;
    pos = 0;
}



prev | home | next