2 Calf Box, an open source musical instrument.
3 Copyright (C) 2010-2011 Krzysztof Foltman
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "config-api.h"
32 #define STD_WAVEFORM_FRAMES 1024
33 #define STD_WAVEFORM_BITS 10
35 ///////////////////////////////////////////////////////////////////////////////
38 static complex float euler_table
[STD_WAVEFORM_FRAMES
];
41 static int map_table
[STD_WAVEFORM_FRAMES
];
43 // Initialise tables using for FFT
44 static void init_tables(void)
46 int rev
= 1 << (STD_WAVEFORM_BITS
- 1);
47 for (int i
= 0; i
< STD_WAVEFORM_FRAMES
; i
++)
49 euler_table
[i
] = cos(i
* 2 * M_PI
/ STD_WAVEFORM_FRAMES
) + I
* sin(i
* 2 * M_PI
/ STD_WAVEFORM_FRAMES
);
51 for (int j
= 0; j
< STD_WAVEFORM_BITS
; j
++)
60 // Trivial implementation of Cooley-Tukey, only works for even values of ANALYSIS_BUFFER_BITS
61 static void my_fft_main(complex float output
[STD_WAVEFORM_FRAMES
])
63 complex float temp
[STD_WAVEFORM_FRAMES
];
65 for (int i
= 0; i
< STD_WAVEFORM_BITS
; i
++)
67 complex float *src
= (i
& 1) ? temp
: output
;
68 complex float *dst
= (i
& 1) ? output
: temp
;
69 int invi
= STD_WAVEFORM_BITS
- i
- 1;
73 for (int j
= 0; j
< STD_WAVEFORM_FRAMES
/ 2; j
++)
75 int jj1
= (j
& mask
) + ((j
& ~mask
) << 1); // insert 0 at ith bit to get the left arm of the butterfly
76 int jj2
= jj1
+ disp
; // insert 1 at ith bit to get the right arm
77 assert((jj1
+ disp
) == (jj1
| disp
));
80 complex float eiw1
= euler_table
[(jj1
<< invi
) & (STD_WAVEFORM_FRAMES
- 1)];
81 complex float eiw2
= euler_table
[(jj2
<< invi
) & (STD_WAVEFORM_FRAMES
- 1)];
83 // printf("%d -> %d, %d\n", j, jj, jj + disp);
84 butterfly(&dst
[jj1
], &dst
[jj2
], src
[jj1
], src
[jj2
], eiw1
, eiw2
);
89 static void my_fft_r2c(complex float output
[STD_WAVEFORM_FRAMES
], int16_t input
[STD_WAVEFORM_FRAMES
])
91 assert(!(STD_WAVEFORM_BITS
&1));
92 // Copy + bit reversal addressing
93 for (int i
= 0; i
< STD_WAVEFORM_FRAMES
; i
++)
94 output
[i
] = input
[map_table
[i
]] * (1.0 / STD_WAVEFORM_FRAMES
);
100 static void my_ifft_c2r(int16_t output
[STD_WAVEFORM_FRAMES
], complex float input
[STD_WAVEFORM_FRAMES
])
102 complex float temp2
[STD_WAVEFORM_FRAMES
];
103 for (int i
= 0; i
< STD_WAVEFORM_FRAMES
; i
++)
104 temp2
[i
] = input
[map_table
[i
]];
105 assert(!(STD_WAVEFORM_BITS
&1));
108 // Copy + bit reversal addressing
110 for (int i
= 0; i
< STD_WAVEFORM_FRAMES
; i
++)
112 float value
= creal(temp2
[i
]);
113 if (value
< -32768) value
= -32768;
114 if (value
> 32767) value
= 32767;
115 if (fabs(value
) > maxv
)
117 output
[i
] = (int16_t)value
;
123 int64_t bytes
, maxbytes
, serial_no
;
124 GHashTable
*waveforms_by_name
, *waveforms_by_id
;
125 GSList
*std_waveforms
;
126 uint32_t streaming_prefetch_size
;
129 static struct wave_bank bank
;
131 GQuark
cbox_waveform_error_quark(void)
133 return g_quark_from_string("cbox-waveform-error-quark");
136 float func_sine(float v
, void *user_data
)
138 return sin(2 * M_PI
* v
);
141 float func_sqr(float v
, void *user_data
)
143 return v
< 0.5 ? -1 : 1;
146 float func_saw(float v
, void *user_data
)
151 float func_tri(float v
, void *user_data
)
156 return 1 - (v
- 0.25f
) * 4;
157 return -1 + 4 * (v
- 0.75f
);
160 void cbox_waveform_generate_levels(struct cbox_waveform
*waveform
, int levels
, double ratio
)
162 complex float output
[STD_WAVEFORM_FRAMES
], bandlimited
[STD_WAVEFORM_FRAMES
];
163 my_fft_r2c(output
, waveform
->data
);
164 int N
= STD_WAVEFORM_FRAMES
;
166 waveform
->levels
= calloc(levels
, sizeof(struct cbox_waveform_level
));
167 double rate
= 65536.0 * 65536.0; // / waveform->info.frames;
168 double orig_rate
= 65536.0 * 65536.0; // / waveform->info.frames;
169 for (int i
= 0; i
< levels
; i
++)
171 int harmonics
= N
/ 2 / (rate
/ orig_rate
);
174 for (int j
= 1; j
<= harmonics
; j
++)
176 bandlimited
[j
] = output
[j
];
177 bandlimited
[N
- j
] = output
[N
- j
];
179 for (int j
= harmonics
; j
<= N
/ 2; j
++)
180 bandlimited
[j
] = bandlimited
[N
- j
] = 0;
182 waveform
->levels
[i
].data
= calloc(N
+ MAX_INTERPOLATION_ORDER
, sizeof(int16_t));
183 my_ifft_c2r(waveform
->levels
[i
].data
, bandlimited
);
184 memcpy(waveform
->levels
[i
].data
+ N
, waveform
->levels
[i
].data
, MAX_INTERPOLATION_ORDER
* sizeof(int16_t));
185 waveform
->levels
[i
].max_rate
= (uint64_t)(rate
);
188 waveform
->level_count
= levels
;
191 void cbox_wavebank_add_std_waveform(const char *name
, float (*getfunc
)(float v
, void *user_data
), void *user_data
, int levels
)
193 int nsize
= STD_WAVEFORM_FRAMES
;
194 int16_t *wave
= calloc(nsize
, sizeof(int16_t));
195 for (int i
= 0; i
< nsize
; i
++)
197 float v
= getfunc(i
* 1.0 / nsize
, user_data
);
199 v
= (v
< 0) ? -1 : 1;
200 // cannot use full scale here, because bandlimiting will introduce
201 // some degree of overshoot
202 wave
[i
] = (int16_t)(25000 * v
);
204 struct cbox_waveform
*waveform
= calloc(1, sizeof(struct cbox_waveform
));
205 waveform
->data
= wave
;
206 waveform
->info
.channels
= 1;
207 waveform
->preloaded_frames
= waveform
->info
.frames
= nsize
;
208 waveform
->info
.samplerate
= (int)(nsize
* 261.6255);
209 waveform
->id
= ++bank
.serial_no
;
210 waveform
->bytes
= waveform
->info
.channels
* 2 * (waveform
->info
.frames
+ 1);
211 waveform
->refcount
= 1;
212 waveform
->canonical_name
= g_strdup(name
);
213 waveform
->display_name
= g_strdup(name
);
214 waveform
->has_loop
= TRUE
;
215 waveform
->loop_start
= 0;
216 waveform
->loop_end
= nsize
;
217 waveform
->levels
= NULL
;
218 waveform
->level_count
= 0;
221 cbox_waveform_generate_levels(waveform
, levels
, 2);
223 g_hash_table_insert(bank
.waveforms_by_name
, waveform
->canonical_name
, waveform
);
224 g_hash_table_insert(bank
.waveforms_by_id
, &waveform
->id
, waveform
);
225 bank
.std_waveforms
= g_slist_prepend(bank
.std_waveforms
, waveform
);
226 // These waveforms are not included in the bank size, I don't think it has
227 // much value for the user.
230 void cbox_wavebank_init()
237 bank
.waveforms_by_name
= g_hash_table_new(g_str_hash
, g_str_equal
);
238 bank
.waveforms_by_id
= g_hash_table_new(g_int_hash
, g_int_equal
);
239 bank
.std_waveforms
= NULL
;
240 bank
.streaming_prefetch_size
= cbox_config_get_int("streaming", "prefetch_size", 65536);
242 cbox_wavebank_add_std_waveform("*sine", func_sine
, NULL
, 0);
243 cbox_wavebank_add_std_waveform("*saw", func_saw
, NULL
, 11);
244 cbox_wavebank_add_std_waveform("*sqr", func_sqr
, NULL
, 11);
245 cbox_wavebank_add_std_waveform("*tri", func_tri
, NULL
, 11);
248 struct cbox_waveform
*cbox_wavebank_get_waveform(const char *context_name
, const char *sample_dir
, const char *filename
, GError
**error
)
255 g_set_error(error
, CBOX_WAVEFORM_ERROR
, CBOX_WAVEFORM_ERROR_FAILED
, "%s: no filename specified", context_name
);
259 // Built in waveforms don't go through path canonicalization
260 if (filename
[0] == '*')
262 gpointer value
= g_hash_table_lookup(bank
.waveforms_by_name
, filename
);
265 struct cbox_waveform
*waveform
= value
;
266 cbox_waveform_ref(waveform
);
271 gchar
*value_copy
= g_strdup(filename
);
272 for (int i
= 0; value_copy
[i
]; i
++)
274 if (value_copy
[i
] == '\\')
277 gchar
*pathname
= value_copy
[0] == '/' ? g_strdup(value_copy
) : g_build_filename(sample_dir
, value_copy
, NULL
);
280 char *canonical
= realpath(pathname
, NULL
);
283 g_set_error(error
, CBOX_WAVEFORM_ERROR
, CBOX_WAVEFORM_ERROR_FAILED
, "%s: cannot find a real path for '%s': %s", context_name
, pathname
, strerror(errno
));
287 gpointer value
= g_hash_table_lookup(bank
.waveforms_by_name
, canonical
);
293 struct cbox_waveform
*waveform
= value
;
294 cbox_waveform_ref(waveform
);
298 struct cbox_waveform
*waveform
= calloc(1, sizeof(struct cbox_waveform
));
299 SNDFILE
*sndfile
= sf_open(pathname
, SFM_READ
, &waveform
->info
);
300 SF_INSTRUMENT instrument
;
303 g_set_error(error
, G_FILE_ERROR
, g_file_error_from_errno (errno
), "%s: cannot open '%s'", context_name
, pathname
);
308 if (waveform
->info
.channels
!= 1 && waveform
->info
.channels
!= 2)
310 g_set_error(error
, CBOX_WAVEFORM_ERROR
, CBOX_WAVEFORM_ERROR_FAILED
,
311 "%s: cannot open file '%s': unsupported channel count %d", context_name
, pathname
, (int)waveform
->info
.channels
);
318 uint32_t preloaded_frames
= waveform
->info
.frames
+ 1;
319 // If sample is larger than 2x prefetch buffer size, then load only
320 // a prefetch buffer worth of data, and stream the rest.
321 if (preloaded_frames
> 2 * bank
.streaming_prefetch_size
)
322 preloaded_frames
= bank
.streaming_prefetch_size
;
323 waveform
->id
= ++bank
.serial_no
;
324 waveform
->bytes
= waveform
->info
.channels
* 2 * preloaded_frames
;
325 waveform
->data
= malloc(waveform
->bytes
);
326 waveform
->refcount
= 1;
327 waveform
->canonical_name
= canonical
;
328 waveform
->display_name
= g_filename_display_name(canonical
);
329 waveform
->has_loop
= FALSE
;
330 waveform
->levels
= NULL
;
331 waveform
->level_count
= 0;
332 waveform
->preloaded_frames
= preloaded_frames
;
334 if (sf_command(sndfile
, SFC_GET_INSTRUMENT
, &instrument
, sizeof(SF_INSTRUMENT
)))
336 for (int i
= 0; i
< instrument
.loop_count
; i
++)
338 if (instrument
.loops
[i
].mode
== SF_LOOP_FORWARD
)
340 waveform
->loop_start
= instrument
.loops
[i
].start
;
341 waveform
->loop_end
= instrument
.loops
[i
].end
;
342 waveform
->has_loop
= TRUE
;
348 nshorts
= waveform
->info
.channels
* preloaded_frames
;
349 for (i
= 0; i
< nshorts
; i
++)
350 waveform
->data
[i
] = 0;
351 sf_readf_short(sndfile
, waveform
->data
, preloaded_frames
);
353 bank
.bytes
+= waveform
->bytes
;
354 if (bank
.bytes
> bank
.maxbytes
)
355 bank
.maxbytes
= bank
.bytes
;
356 g_hash_table_insert(bank
.waveforms_by_name
, waveform
->canonical_name
, waveform
);
357 g_hash_table_insert(bank
.waveforms_by_id
, &waveform
->id
, waveform
);
362 int64_t cbox_wavebank_get_bytes()
367 int64_t cbox_wavebank_get_maxbytes()
369 return bank
.maxbytes
;
372 int cbox_wavebank_get_count()
374 return g_hash_table_size(bank
.waveforms_by_id
);
377 struct cbox_waveform
*cbox_wavebank_peek_waveform_by_id(int id
)
379 return g_hash_table_lookup(bank
.waveforms_by_id
, &id
);
382 void cbox_wavebank_foreach(void (*cb
)(void *, struct cbox_waveform
*), void *user_data
)
387 g_hash_table_iter_init (&iter
, bank
.waveforms_by_id
);
388 while (g_hash_table_iter_next (&iter
, &key
, &value
))
390 (*cb
)(user_data
, value
);
394 void cbox_wavebank_close()
397 g_warning("Warning: %lld bytes in unfreed samples", (long long int)bank
.bytes
);
398 while(bank
.std_waveforms
)
400 cbox_waveform_unref((struct cbox_waveform
*)bank
.std_waveforms
->data
);
401 bank
.std_waveforms
= g_slist_delete_link(bank
.std_waveforms
, bank
.std_waveforms
);
403 g_hash_table_destroy(bank
.waveforms_by_id
);
404 g_hash_table_destroy(bank
.waveforms_by_name
);
405 bank
.waveforms_by_id
= NULL
;
406 bank
.waveforms_by_name
= NULL
;
409 /////////////////////////////////////////////////////////////////////////////////////////////////////
411 void cbox_waveform_ref(struct cbox_waveform
*waveform
)
413 ++waveform
->refcount
;
416 void cbox_waveform_unref(struct cbox_waveform
*waveform
)
418 if (--waveform
->refcount
> 0)
421 g_hash_table_remove(bank
.waveforms_by_name
, waveform
->canonical_name
);
422 g_hash_table_remove(bank
.waveforms_by_id
, &waveform
->id
);
423 bank
.bytes
-= waveform
->bytes
;
425 g_free(waveform
->display_name
);
426 free(waveform
->canonical_name
);
427 for (int i
= 0; i
< waveform
->level_count
; i
++)
428 free(waveform
->levels
[i
].data
);
429 free(waveform
->levels
);
430 free(waveform
->data
);
435 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
437 struct waves_foreach_data
439 struct cbox_command_target
*fb
;
444 void wave_list_cb(void *user_data
, struct cbox_waveform
*waveform
)
446 struct waves_foreach_data
*wfd
= user_data
;
448 wfd
->success
= wfd
->success
&& cbox_execute_on(wfd
->fb
, NULL
, "/waveform", "i", wfd
->error
, (int)waveform
->id
);
451 static gboolean
waves_process_cmd(struct cbox_command_target
*ct
, struct cbox_command_target
*fb
, struct cbox_osc_command
*cmd
, GError
**error
)
453 if (!strcmp(cmd
->command
, "/status") && !strcmp(cmd
->arg_types
, ""))
455 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
458 // XXXKF this only supports 4GB - not a big deal for now yet?
459 return cbox_execute_on(fb
, NULL
, "/bytes", "i", error
, (int)cbox_wavebank_get_bytes()) &&
460 cbox_execute_on(fb
, NULL
, "/max_bytes", "i", error
, (int)cbox_wavebank_get_maxbytes()) &&
461 cbox_execute_on(fb
, NULL
, "/count", "i", error
, (int)cbox_wavebank_get_count())
464 else if (!strcmp(cmd
->command
, "/list") && !strcmp(cmd
->arg_types
, ""))
466 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
469 struct waves_foreach_data wfd
= { fb
, error
, TRUE
};
470 cbox_wavebank_foreach(wave_list_cb
, &wfd
);
473 else if (!strcmp(cmd
->command
, "/info") && !strcmp(cmd
->arg_types
, "i"))
475 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
478 int id
= CBOX_ARG_I(cmd
, 0);
479 struct cbox_waveform
*waveform
= cbox_wavebank_peek_waveform_by_id(id
);
480 if (waveform
== NULL
)
482 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Waveform %d not found", id
);
485 assert(id
== waveform
->id
);
486 if (!cbox_execute_on(fb
, NULL
, "/filename", "s", error
, waveform
->canonical_name
)) // XXXKF convert to utf8
488 if (!cbox_execute_on(fb
, NULL
, "/name", "s", error
, waveform
->display_name
))
490 if (!cbox_execute_on(fb
, NULL
, "/bytes", "i", error
, (int)waveform
->bytes
))
492 if (waveform
->has_loop
&& !cbox_execute_on(fb
, NULL
, "/loop", "ii", error
, (int)waveform
->loop_start
, (int)waveform
->loop_end
))
498 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Unknown combination of target path and argument: '%s', '%s'", cmd
->command
, cmd
->arg_types
);
503 struct cbox_command_target cbox_waves_cmd_target
=
505 .process_cmd
= waves_process_cmd
,