File: sin.c

package info (click to toggle)
jack-tools 20101210-2
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 504 kB
  • sloc: ansic: 4,678; makefile: 122; lisp: 48; sh: 16
file content (79 lines) | stat: -rw-r--r-- 1,815 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/* gcc -shared -I ~/include sin.c -o sin.so */

#include <stdlib.h>
#include <math.h>
#include <jack.dl.h>

struct sinosc {
  float f;                      /* frequency */
  float a;                      /* amplitude */
  float p;                      /* pan */
  float phase;                  /* oscillator phase */
}; 

#define TWO_PI (2 * M_PI)

/* convert frequency in hertz to phase increment in radians */
float hz_to_incr(float hz, float sr)
{
  return (TWO_PI / sr) * hz;
}

/* increment phase within (0,2pi) */
float step_phasor(float *phase, float incr)
{
  *phase += incr;
  if(*phase > TWO_PI) {
    *phase -= TWO_PI;
  }
}
  
/* allocate state data and initialize private control data */
void *dsp_init(struct world *w, int g)
{
  struct sinosc *s = malloc(sizeof(struct sinosc));
  s->phase = 0.0;
  s->f = 440.0;
  s->a = 0.1;
  s->p = 0.5;
  w_p_set1(w, g, 0, s->f);
  w_p_set1(w, g, 1, s->a);
  w_p_set1(w, g, 2, s->p);
  return (void*)s;
}

/* process nf frames of data */
void dsp_step(struct world *w, int g, void *ptr, int nf)
{
  int i;
  struct sinosc *s = (struct sinosc *)ptr;
  /* load state */
  float f = s->f;
  float a = s->a;
  float p = s->p;
  float phase = s->phase;
  /* read control values */
  float fe = w_p_get1(w, g, 0);
  float ae = w_p_get1(w, g, 1);
  float pe = w_p_get1(w, g, 2);
  /* calculate control increments */
  float fi = (fe - f) / (float)nf;
  float ai = (ae - a) / (float)nf;
  float pi = (pe - p) / (float)nf;
  for(i = 0; i < nf; i++) {
    /* algorithm */
    float n = sinf(phase) * a;
    w_out2(w, i, n * p, n * (1 - p));
    float incr = hz_to_incr(f, w_sr(w));
    step_phasor(&phase, incr);
    /* apply control increments */
    f += fi;
    a += ai;
    p += pi;
  }
  /* store state */
  s->f = fe;
  s->a = ae;
  s->p = pe;
  s->phase = phase;
}