pdhalf

Files: pdhalf.h, pdhalf.c

Casio-style phase distortion with "pivot point" on the X axis This module is designed to emulate the classic phase distortion synthesis technique. From the mid 90's. The technique reads the first and second halves of the ftbl at different rates in order to warp the waveform. For example, pdhalf can smoothly transition a sinewave into something approximating a sawtooth wave.

Functions

sp_pdhalf_create(sp_pdhalf **pdhalf)
sp_pdhalf_init(sp_data *sp, sp_pdhalf *pdhalf)
sp_pdhalf_compute(sp_data *sp, sp_pdhalf *pdhalf, SPFLOAT *sig, SPFLOAT *out)
sp_pdhalf_destroy(sp_pdhalf **pdhalf)

Optional Parameters

amount: Amount of distortion, within the range [-1, 1]. 0 is no distortion.
(Default value: 0)

Inputs

sig: Input signal, typically a phasor normalize 0-1.

Outputs

out: Signal output.

Example Code

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "soundpipe.h"

typedef struct {
    sp_metro *met;
    sp_ftbl *ft; 
    sp_tabread *tab;
    sp_phasor *phs;
    sp_tenv *tenv;
    sp_pdhalf *pdhalf;
    sp_scale *scl;
    sp_tseq *ts;
    sp_ftbl *seq; 
} UserData;

void process(sp_data *sp, void *udata) 
{
    UserData *ud = udata;
    SPFLOAT met = 0;
    SPFLOAT tenv = 0;
    SPFLOAT phs = 0;
    SPFLOAT pd = 0;
    SPFLOAT tr = 0;
    SPFLOAT amt = 0;
    SPFLOAT rev = 0;
    SPFLOAT frq = 0;

    sp_metro_compute(sp, ud->met, NULL, &met);
    sp_tenv_compute(sp, ud->tenv, &met, &tenv);
    sp_tseq_compute(sp, ud->ts, &met, &frq);
    frq = sp_midi2cps(frq);
    ud->phs->freq = frq;
    sp_phasor_compute(sp, ud->phs, NULL, &phs);
    rev = 1 - tenv;
    sp_scale_compute(sp, ud->scl, &rev, &amt);
    ud->pdhalf->amount = amt;
    sp_pdhalf_compute(sp, ud->pdhalf, &phs, &pd);
    ud->tab->index = pd;
    sp_tabread_compute(sp, ud->tab, NULL, &tr);

    sp_out(sp, 0, tr * tenv);

}

int main() 
{
    UserData ud;
    sp_data *sp;
    sp_create(&sp);
    sp_srand(sp, 1234567);

    sp_pdhalf_create(&ud.pdhalf);
    sp_ftbl_create(sp, &ud.ft, 2048);
    sp_gen_sine(sp, ud.ft);
    sp_metro_create(&ud.met);

    sp_tabread_create(&ud.tab);
    sp_tenv_create(&ud.tenv);
    sp_phasor_create(&ud.phs);
    sp_scale_create(&ud.scl);
    sp_ftbl_create(sp, &ud.seq, 1);
    sp_gen_vals(sp, ud.seq, "62 67 69 72");
    sp_tseq_create(&ud.ts);


    sp_pdhalf_init(sp, ud.pdhalf);
    sp_tabread_init(sp, ud.tab, ud.ft, 1);
    sp_phasor_init(sp, ud.phs, 0);
    ud.phs->freq = 440;
    sp_tenv_init(sp, ud.tenv);
    ud.tenv->atk = 0.001;
    ud.tenv->hold = 0.01;
    ud.tenv->rel = 0.2;
    sp_metro_init(sp, ud.met);
    ud.met->freq = 8;
    sp_scale_init(sp, ud.scl);
    ud.scl->min = -0.8;
    ud.scl->max = 0;
    sp_tseq_init(sp, ud.ts, ud.seq);


    sp->len = 44100 * 5;
    sp_process(sp, &ud, process);

    sp_pdhalf_destroy(&ud.pdhalf);
    sp_ftbl_destroy(&ud.ft);
    sp_tabread_destroy(&ud.tab);
    sp_phasor_destroy(&ud.phs);
    sp_tenv_destroy(&ud.tenv);
    sp_metro_destroy(&ud.met);
    sp_scale_destroy(&ud.scl);
    sp_tseq_destroy(&ud.ts);
    sp_ftbl_destroy(&ud.seq);

    sp_destroy(&sp);
    return 0;
}