source: src/synth/wavetable.c @ ce3ff2b

feature/autosinkfeature/constantqfeature/pitchshiftfeature/pydocstringsfeature/timestretchpitchshiftsamplertimestretchyinfft+
Last change on this file since ce3ff2b was ce3ff2b, checked in by Paul Brossier <piem@piem.org>, 4 years ago

src/pitch/: add const qualifiers, filter_do_outplace to avoid modifying input

  • Property mode set to 100644
File size: 5.4 KB
Line 
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 "config.h"
23#include "aubio_priv.h"
24#include "fvec.h"
25#include "fmat.h"
26#include "utils/parameter.h"
27#include "synth/wavetable.h"
28
29#define WAVETABLE_LEN 4096
30
31struct _aubio_wavetable_t {
32  uint_t samplerate;
33  uint_t blocksize;
34  uint_t wavetable_length;
35  fvec_t *wavetable;
36  uint_t playing;
37  smpl_t last_pos;
38
39  aubio_parameter_t *freq;
40  aubio_parameter_t *amp;
41};
42
43aubio_wavetable_t *new_aubio_wavetable(uint_t samplerate, uint_t blocksize)
44{
45  uint_t i = 0;
46  aubio_wavetable_t *s = AUBIO_NEW(aubio_wavetable_t);
47  if ((sint_t)samplerate <= 0) {
48    AUBIO_ERR("Can not create wavetable with samplerate %d\n", samplerate);
49    goto beach;
50  }
51  s->samplerate = samplerate;
52  s->blocksize = blocksize;
53  s->wavetable_length = WAVETABLE_LEN;
54  s->wavetable = new_fvec(s->wavetable_length + 3);
55  for (i = 0; i < s->wavetable_length; i++) {
56    s->wavetable->data[i] = SIN(TWO_PI * i / (smpl_t) s->wavetable_length );
57  }
58  s->wavetable->data[s->wavetable_length] = s->wavetable->data[0];
59  s->wavetable->data[s->wavetable_length + 1] = s->wavetable->data[1];
60  s->wavetable->data[s->wavetable_length + 2] = s->wavetable->data[2];
61  s->playing = 0;
62  s->last_pos = 0.;
63  s->freq = new_aubio_parameter( 0., s->samplerate / 2., 10 );
64  s->amp = new_aubio_parameter( 0., 1., 100 );
65  return s;
66beach:
67  AUBIO_FREE(s);
68  return NULL;
69}
70
71static smpl_t interp_2(const fvec_t *input, smpl_t pos) {
72  uint_t idx = (uint_t)FLOOR(pos);
73  smpl_t frac = pos - (smpl_t)idx;
74  smpl_t a = input->data[idx];
75  smpl_t b = input->data[idx + 1];
76  return a + frac * ( b - a );
77}
78
79void aubio_wavetable_do ( aubio_wavetable_t * s, const fvec_t * input, fvec_t * output)
80{
81  uint_t i;
82  if (s->playing) {
83    smpl_t pos = s->last_pos;
84    for (i = 0; i < output->length; i++) {
85      smpl_t inc = aubio_parameter_get_next_value( s->freq );
86      inc *= (smpl_t)(s->wavetable_length) / (smpl_t) (s->samplerate);
87      pos += inc;
88      while (pos > s->wavetable_length) {
89        pos -= s->wavetable_length;
90      }
91      output->data[i] = aubio_parameter_get_next_value ( s->amp );
92      output->data[i] *= interp_2(s->wavetable, pos);
93    }
94    s->last_pos = pos;
95  } else {
96    for (i = 0; i < output->length; i++) {
97      aubio_parameter_get_next_value ( s->freq );
98      aubio_parameter_get_next_value ( s->amp );
99    }
100    fvec_zeros (output);
101  }
102  // add input to output if needed
103  if (input && input != output) {
104    for (i = 0; i < output->length; i++) {
105      output->data[i] += input->data[i];
106    }
107  }
108}
109
110void aubio_wavetable_do_multi ( aubio_wavetable_t * s, const fmat_t * input, fmat_t * output)
111{
112  uint_t i, j;
113  if (s->playing) {
114    smpl_t pos = s->last_pos;
115    for (j = 0; j < output->length; j++) {
116      smpl_t inc = aubio_parameter_get_next_value( s->freq );
117      smpl_t amp = aubio_parameter_get_next_value ( s->amp );
118      inc *= (smpl_t)(s->wavetable_length) / (smpl_t) (s->samplerate);
119      pos += inc;
120      while (pos > s->wavetable_length) {
121        pos -= s->wavetable_length;
122      }
123      for (i = 0; i < output->height; i++) {
124        output->data[i][j] = amp * interp_2(s->wavetable, pos);
125      }
126    }
127    s->last_pos = pos;
128  } else {
129    for (j = 0; j < output->length; j++) {
130      aubio_parameter_get_next_value ( s->freq );
131      aubio_parameter_get_next_value ( s->amp );
132    }
133    fmat_zeros (output);
134  }
135  // add output to input if needed
136  if (input && input != output) {
137    for (i = 0; i < output->height; i++) {
138      for (j = 0; j < output->length; j++) {
139        output->data[i][j] += input->data[i][j];
140      }
141    }
142  }
143}
144
145uint_t aubio_wavetable_get_playing ( const aubio_wavetable_t * s )
146{
147  return s->playing;
148}
149
150uint_t aubio_wavetable_set_playing ( aubio_wavetable_t * s, uint_t playing )
151{
152  s->playing = (playing == 1) ? 1 : 0;
153  return 0;
154}
155
156uint_t aubio_wavetable_play ( aubio_wavetable_t * s )
157{
158  aubio_wavetable_set_amp (s, 0.7);
159  return aubio_wavetable_set_playing (s, 1);
160}
161
162uint_t aubio_wavetable_stop ( aubio_wavetable_t * s )
163{
164  //aubio_wavetable_set_freq (s, 0.);
165  aubio_wavetable_set_amp (s, 0.);
166  //s->last_pos = 0;
167  return aubio_wavetable_set_playing (s, 1);
168}
169
170uint_t aubio_wavetable_set_freq ( aubio_wavetable_t * s, smpl_t freq )
171{
172  return aubio_parameter_set_target_value ( s->freq, freq );
173}
174
175smpl_t aubio_wavetable_get_freq ( const aubio_wavetable_t * s) {
176  return aubio_parameter_get_current_value ( s->freq);
177}
178
179uint_t aubio_wavetable_set_amp ( aubio_wavetable_t * s, smpl_t amp )
180{
181  return aubio_parameter_set_target_value ( s->amp, amp );
182}
183
184smpl_t aubio_wavetable_get_amp ( const aubio_wavetable_t * s) {
185  return aubio_parameter_get_current_value ( s->amp );
186}
187
188void del_aubio_wavetable( aubio_wavetable_t * s )
189{
190  del_aubio_parameter(s->freq);
191  del_aubio_parameter(s->amp);
192  del_fvec(s->wavetable);
193  AUBIO_FREE(s);
194}
Note: See TracBrowser for help on using the repository browser.