source: src/synth/wavetable.c @ 95af88b

sampler
Last change on this file since 95af88b was 33d0242, checked in by Paul Brossier <piem@piem.org>, 7 years ago

src/aubio_priv.h: move include config.h here

  • Property mode set to 100644
File size: 5.4 KB
RevLine 
[dd15573]1/*
2  Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
3
4  This file is part of aubio.
5
6  aubio is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10
11  aubio is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15
16  You should have received a copy of the GNU General Public License
17  along with aubio.  If not, see <http://www.gnu.org/licenses/>.
18
19*/
20
21
22#include "aubio_priv.h"
23#include "fvec.h"
24#include "fmat.h"
[c2e0aef]25#include "utils/parameter.h"
[dd15573]26#include "synth/wavetable.h"
27
28#define WAVETABLE_LEN 4096
29
30struct _aubio_wavetable_t {
31  uint_t samplerate;
32  uint_t blocksize;
33  uint_t wavetable_length;
34  fvec_t *wavetable;
35  uint_t playing;
36  smpl_t last_pos;
37
[c2e0aef]38  aubio_parameter_t *freq;
39  aubio_parameter_t *amp;
[dd15573]40};
41
42aubio_wavetable_t *new_aubio_wavetable(uint_t samplerate, uint_t blocksize)
43{
[c21acb9]44  uint_t i = 0;
[dd15573]45  aubio_wavetable_t *s = AUBIO_NEW(aubio_wavetable_t);
[44e94f3c]46  if ((sint_t)samplerate <= 0) {
47    AUBIO_ERR("Can not create wavetable with samplerate %d\n", samplerate);
48    goto beach;
49  }
[dd15573]50  s->samplerate = samplerate;
51  s->blocksize = blocksize;
52  s->wavetable_length = WAVETABLE_LEN;
53  s->wavetable = new_fvec(s->wavetable_length + 3);
54  for (i = 0; i < s->wavetable_length; i++) {
55    s->wavetable->data[i] = SIN(TWO_PI * i / (smpl_t) s->wavetable_length );
56  }
57  s->wavetable->data[s->wavetable_length] = s->wavetable->data[0];
58  s->wavetable->data[s->wavetable_length + 1] = s->wavetable->data[1];
59  s->wavetable->data[s->wavetable_length + 2] = s->wavetable->data[2];
60  s->playing = 0;
61  s->last_pos = 0.;
[c2e0aef]62  s->freq = new_aubio_parameter( 0., s->samplerate / 2., 10 );
63  s->amp = new_aubio_parameter( 0., 1., 100 );
[dd15573]64  return s;
[44e94f3c]65beach:
66  AUBIO_FREE(s);
67  return NULL;
[dd15573]68}
69
[ce3ff2b]70static smpl_t interp_2(const fvec_t *input, smpl_t pos) {
[dd15573]71  uint_t idx = (uint_t)FLOOR(pos);
72  smpl_t frac = pos - (smpl_t)idx;
73  smpl_t a = input->data[idx];
74  smpl_t b = input->data[idx + 1];
75  return a + frac * ( b - a );
76}
77
[ce3ff2b]78void aubio_wavetable_do ( aubio_wavetable_t * s, const fvec_t * input, fvec_t * output)
[dd15573]79{
80  uint_t i;
81  if (s->playing) {
82    smpl_t pos = s->last_pos;
83    for (i = 0; i < output->length; i++) {
[c2e0aef]84      smpl_t inc = aubio_parameter_get_next_value( s->freq );
85      inc *= (smpl_t)(s->wavetable_length) / (smpl_t) (s->samplerate);
[dd15573]86      pos += inc;
87      while (pos > s->wavetable_length) {
88        pos -= s->wavetable_length;
89      }
[c2e0aef]90      output->data[i] = aubio_parameter_get_next_value ( s->amp );
91      output->data[i] *= interp_2(s->wavetable, pos);
[dd15573]92    }
93    s->last_pos = pos;
94  } else {
[c2e0aef]95    for (i = 0; i < output->length; i++) {
96      aubio_parameter_get_next_value ( s->freq );
97      aubio_parameter_get_next_value ( s->amp );
98    }
[a7e766b]99    fvec_zeros (output);
[dd15573]100  }
101  // add input to output if needed
102  if (input && input != output) {
103    for (i = 0; i < output->length; i++) {
104      output->data[i] += input->data[i];
105    }
106  }
107}
108
[ce3ff2b]109void aubio_wavetable_do_multi ( aubio_wavetable_t * s, const fmat_t * input, fmat_t * output)
[dd15573]110{
111  uint_t i, j;
112  if (s->playing) {
113    smpl_t pos = s->last_pos;
114    for (j = 0; j < output->length; j++) {
[c2e0aef]115      smpl_t inc = aubio_parameter_get_next_value( s->freq );
[c21acb9]116      smpl_t amp = aubio_parameter_get_next_value ( s->amp );
[c2e0aef]117      inc *= (smpl_t)(s->wavetable_length) / (smpl_t) (s->samplerate);
[dd15573]118      pos += inc;
119      while (pos > s->wavetable_length) {
120        pos -= s->wavetable_length;
121      }
122      for (i = 0; i < output->height; i++) {
[c2e0aef]123        output->data[i][j] = amp * interp_2(s->wavetable, pos);
[dd15573]124      }
125    }
126    s->last_pos = pos;
127  } else {
128    for (j = 0; j < output->length; j++) {
[c2e0aef]129      aubio_parameter_get_next_value ( s->freq );
130      aubio_parameter_get_next_value ( s->amp );
[dd15573]131    }
[a7e766b]132    fmat_zeros (output);
[dd15573]133  }
134  // add output to input if needed
135  if (input && input != output) {
136    for (i = 0; i < output->height; i++) {
137      for (j = 0; j < output->length; j++) {
138        output->data[i][j] += input->data[i][j];
139      }
140    }
141  }
142}
143
[ce3ff2b]144uint_t aubio_wavetable_get_playing ( const aubio_wavetable_t * s )
[dd15573]145{
146  return s->playing;
147}
148
149uint_t aubio_wavetable_set_playing ( aubio_wavetable_t * s, uint_t playing )
150{
151  s->playing = (playing == 1) ? 1 : 0;
152  return 0;
153}
154
155uint_t aubio_wavetable_play ( aubio_wavetable_t * s )
156{
157  aubio_wavetable_set_amp (s, 0.7);
158  return aubio_wavetable_set_playing (s, 1);
159}
160
161uint_t aubio_wavetable_stop ( aubio_wavetable_t * s )
162{
163  //aubio_wavetable_set_freq (s, 0.);
164  aubio_wavetable_set_amp (s, 0.);
165  //s->last_pos = 0;
166  return aubio_wavetable_set_playing (s, 1);
167}
168
169uint_t aubio_wavetable_set_freq ( aubio_wavetable_t * s, smpl_t freq )
170{
[c2e0aef]171  return aubio_parameter_set_target_value ( s->freq, freq );
[dd15573]172}
173
[ce3ff2b]174smpl_t aubio_wavetable_get_freq ( const aubio_wavetable_t * s) {
[c2e0aef]175  return aubio_parameter_get_current_value ( s->freq);
[dd15573]176}
177
178uint_t aubio_wavetable_set_amp ( aubio_wavetable_t * s, smpl_t amp )
179{
[c2e0aef]180  return aubio_parameter_set_target_value ( s->amp, amp );
[dd15573]181}
182
[ce3ff2b]183smpl_t aubio_wavetable_get_amp ( const aubio_wavetable_t * s) {
[c2e0aef]184  return aubio_parameter_get_current_value ( s->amp );
[dd15573]185}
186
187void del_aubio_wavetable( aubio_wavetable_t * s )
188{
[cc6b221]189  del_aubio_parameter(s->freq);
190  del_aubio_parameter(s->amp);
[dd15573]191  del_fvec(s->wavetable);
192  AUBIO_FREE(s);
193}
Note: See TracBrowser for help on using the repository browser.