source: src/synth/wavetable.c @ 1910fed

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5sampleryinfft+
Last change on this file since 1910fed 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
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 "aubio_priv.h"
23#include "fvec.h"
24#include "fmat.h"
25#include "utils/parameter.h"
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
38  aubio_parameter_t *freq;
39  aubio_parameter_t *amp;
40};
41
42aubio_wavetable_t *new_aubio_wavetable(uint_t samplerate, uint_t blocksize)
43{
44  uint_t i = 0;
45  aubio_wavetable_t *s = AUBIO_NEW(aubio_wavetable_t);
46  if ((sint_t)samplerate <= 0) {
47    AUBIO_ERR("Can not create wavetable with samplerate %d\n", samplerate);
48    goto beach;
49  }
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.;
62  s->freq = new_aubio_parameter( 0., s->samplerate / 2., 10 );
63  s->amp = new_aubio_parameter( 0., 1., 100 );
64  return s;
65beach:
66  AUBIO_FREE(s);
67  return NULL;
68}
69
70static smpl_t interp_2(const fvec_t *input, smpl_t pos) {
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
78void aubio_wavetable_do ( aubio_wavetable_t * s, const fvec_t * input, fvec_t * output)
79{
80  uint_t i;
81  if (s->playing) {
82    smpl_t pos = s->last_pos;
83    for (i = 0; i < output->length; i++) {
84      smpl_t inc = aubio_parameter_get_next_value( s->freq );
85      inc *= (smpl_t)(s->wavetable_length) / (smpl_t) (s->samplerate);
86      pos += inc;
87      while (pos > s->wavetable_length) {
88        pos -= s->wavetable_length;
89      }
90      output->data[i] = aubio_parameter_get_next_value ( s->amp );
91      output->data[i] *= interp_2(s->wavetable, pos);
92    }
93    s->last_pos = pos;
94  } else {
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    }
99    fvec_zeros (output);
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
109void aubio_wavetable_do_multi ( aubio_wavetable_t * s, const fmat_t * input, fmat_t * output)
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++) {
115      smpl_t inc = aubio_parameter_get_next_value( s->freq );
116      smpl_t amp = aubio_parameter_get_next_value ( s->amp );
117      inc *= (smpl_t)(s->wavetable_length) / (smpl_t) (s->samplerate);
118      pos += inc;
119      while (pos > s->wavetable_length) {
120        pos -= s->wavetable_length;
121      }
122      for (i = 0; i < output->height; i++) {
123        output->data[i][j] = amp * interp_2(s->wavetable, pos);
124      }
125    }
126    s->last_pos = pos;
127  } else {
128    for (j = 0; j < output->length; j++) {
129      aubio_parameter_get_next_value ( s->freq );
130      aubio_parameter_get_next_value ( s->amp );
131    }
132    fmat_zeros (output);
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
144uint_t aubio_wavetable_get_playing ( const aubio_wavetable_t * s )
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{
171  return aubio_parameter_set_target_value ( s->freq, freq );
172}
173
174smpl_t aubio_wavetable_get_freq ( const aubio_wavetable_t * s) {
175  return aubio_parameter_get_current_value ( s->freq);
176}
177
178uint_t aubio_wavetable_set_amp ( aubio_wavetable_t * s, smpl_t amp )
179{
180  return aubio_parameter_set_target_value ( s->amp, amp );
181}
182
183smpl_t aubio_wavetable_get_amp ( const aubio_wavetable_t * s) {
184  return aubio_parameter_get_current_value ( s->amp );
185}
186
187void del_aubio_wavetable( aubio_wavetable_t * s )
188{
189  del_aubio_parameter(s->freq);
190  del_aubio_parameter(s->amp);
191  del_fvec(s->wavetable);
192  AUBIO_FREE(s);
193}
Note: See TracBrowser for help on using the repository browser.