TSmp

TSmp

Description

TSmp is triggerable in-memory sample generator with playback speed control.

Generated Files

<<tsmp.h>>=
#ifndef SK_TSMP_H
#define SK_TSMP_H

#ifndef SKFLT
#define SKFLT float
#endif

#ifdef SK_TSMP_PRIV
<<structs>>
#endif
<<typedefs>>
<<funcdefs>>

#endif

<<tsmp.c>>=
#include <math.h>
#define SK_TSMP_PRIV
#include "tsmp.h"

<<funcs>>

Data

Data is stored in a struct called sk_tsmp, and initialized with sk_tsmp_init.

Struct Declaration

<<typedefs>>=
typedef struct sk_tsmp sk_tsmp;

<<structs>>=
struct sk_tsmp {
    <<tsmp>>
};

Init

<<funcdefs>>=
void sk_tsmp_init(sk_tsmp *tsmp, SKFLT *tab, unsigned long sz);

<<funcs>>=
void sk_tsmp_init(sk_tsmp *tsmp, SKFLT *tab, unsigned long sz)
{
    <<tsmp_init>>
}

Stored playback position

The current playback position is stored in units of samples as a double to preserve fractional sample amounts.

<<tsmp>>=
double pos;

By setting position to be negative, it prevents the sample from firing off in the beginning.

<<tsmp_init>>=
tsmp->pos = -1;

A trigger signal resets the playback position to be 0.

<<reset>>=
tsmp->pos = 0;

Parameters

This thing takes in 3 parameters: a trigger signal, a playback speed amount, and an ftable (presumably containing sample data).

Playback Rate

Playback speed happens at audio rate, and determines the increment amount. A value of 1 is normal, 2 double speed, 0.5 half speed. Negative values are ignored for now. If they did work, they would go in reverse.

<<tsmp>>=
SKFLT play;

<<tsmp_init>>=
tsmp->play = 1.0;

<<funcdefs>>=
void sk_tsmp_rate(sk_tsmp *ts, SKFLT play);

<<funcs>>=
void sk_tsmp_rate(sk_tsmp *ts, SKFLT play)
{
    ts->play = play;
}

Table

The ftable is assumed to be sample data loaded from some audio file like loadwav.

<<tsmp>>=
SKFLT *tab;
unsigned long tabsz;

<<tsmp_init>>=
tsmp->tab = tab;
tsmp->tabsz = sz;

Processing

<<funcdefs>>=
SKFLT sk_tsmp_tick(sk_tsmp *tsmp, SKFLT trig);

<<funcs>>=
SKFLT sk_tsmp_tick(sk_tsmp *tsmp, SKFLT trig)
{
    SKFLT smp;

    smp = 0;

    if (trig != 0) {
        <<reset>>
    }

    <<process>>

    return smp;
}

Sampling only happens if the playback position is in bounds. Otherwise, it is assumed to have been completely fired.

<<process>>=
if (tsmp->pos >= 0 && tsmp->pos < (tsmp->tabsz - 1)) {
    SKFLT play;
    <<lerpvars>>
    play = tsmp->play;
    <<lerp>>
    tsmp->pos += play;
}

Most of this interpolation code has been lifted from other soundpipe modules.

<<lerpvars>>=
unsigned int ipos;
double fract;
SKFLT v1, v2;
SKFLT *tab;

<<lerp>>=
tab = tsmp->tab;
ipos = floor(tsmp->pos);
fract = tsmp->pos - ipos;
v1 = tab[ipos];
v2 = tab[ipos + 1];
smp = (v1 + (v2 - v1) * fract);