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"
33 #define STD_WAVEFORM_FRAMES 1024
34 #define STD_WAVEFORM_BITS 10
36 ///////////////////////////////////////////////////////////////////////////////
39 static complex float euler_table
[STD_WAVEFORM_FRAMES
];
42 static int map_table
[STD_WAVEFORM_FRAMES
];
44 // Initialise tables using for FFT
45 static void init_tables(void)
47 int rev
= 1 << (STD_WAVEFORM_BITS
- 1);
48 for (int i
= 0; i
< STD_WAVEFORM_FRAMES
; i
++)
50 euler_table
[i
] = cos(i
* 2 * M_PI
/ STD_WAVEFORM_FRAMES
) + I
* sin(i
* 2 * M_PI
/ STD_WAVEFORM_FRAMES
);
52 for (int j
= 0; j
< STD_WAVEFORM_BITS
; j
++)
61 // Trivial implementation of Cooley-Tukey, only works for even values of ANALYSIS_BUFFER_BITS
62 static void my_fft_main(complex float output
[STD_WAVEFORM_FRAMES
])
64 complex float temp
[STD_WAVEFORM_FRAMES
];
66 for (int i
= 0; i
< STD_WAVEFORM_BITS
; i
++)
68 complex float *src
= (i
& 1) ? temp
: output
;
69 complex float *dst
= (i
& 1) ? output
: temp
;
70 int invi
= STD_WAVEFORM_BITS
- i
- 1;
74 for (int j
= 0; j
< STD_WAVEFORM_FRAMES
/ 2; j
++)
76 int jj1
= (j
& mask
) + ((j
& ~mask
) << 1); // insert 0 at ith bit to get the left arm of the butterfly
77 int jj2
= jj1
+ disp
; // insert 1 at ith bit to get the right arm
78 assert((jj1
+ disp
) == (jj1
| disp
));
81 complex float eiw1
= euler_table
[(jj1
<< invi
) & (STD_WAVEFORM_FRAMES
- 1)];
82 complex float eiw2
= euler_table
[(jj2
<< invi
) & (STD_WAVEFORM_FRAMES
- 1)];
84 // printf("%d -> %d, %d\n", j, jj, jj + disp);
85 butterfly(&dst
[jj1
], &dst
[jj2
], src
[jj1
], src
[jj2
], eiw1
, eiw2
);
90 static void my_fft_r2c(complex float output
[STD_WAVEFORM_FRAMES
], int16_t input
[STD_WAVEFORM_FRAMES
])
92 assert(!(STD_WAVEFORM_BITS
&1));
93 // Copy + bit reversal addressing
94 for (int i
= 0; i
< STD_WAVEFORM_FRAMES
; i
++)
95 output
[i
] = input
[map_table
[i
]] * (1.0 / STD_WAVEFORM_FRAMES
);
101 static void my_ifft_c2r(int16_t output
[STD_WAVEFORM_FRAMES
], complex float input
[STD_WAVEFORM_FRAMES
])
103 complex float temp2
[STD_WAVEFORM_FRAMES
];
104 for (int i
= 0; i
< STD_WAVEFORM_FRAMES
; i
++)
105 temp2
[i
] = input
[map_table
[i
]];
106 assert(!(STD_WAVEFORM_BITS
&1));
109 // Copy + bit reversal addressing
111 for (int i
= 0; i
< STD_WAVEFORM_FRAMES
; i
++)
113 float value
= creal(temp2
[i
]);
114 if (value
< -32768) value
= -32768;
115 if (value
> 32767) value
= 32767;
116 if (fabs(value
) > maxv
)
118 output
[i
] = (int16_t)value
;
124 int64_t bytes
, maxbytes
, serial_no
;
125 GHashTable
*waveforms_by_name
, *waveforms_by_id
;
126 GSList
*std_waveforms
;
127 uint32_t streaming_prefetch_size
;
130 static struct wave_bank bank
;
132 GQuark
cbox_waveform_error_quark(void)
134 return g_quark_from_string("cbox-waveform-error-quark");
137 float func_sine(float v
, void *user_data
)
139 return sin(2 * M_PI
* v
);
142 float func_sqr(float v
, void *user_data
)
144 return v
< 0.5 ? -1 : 1;
147 float func_saw(float v
, void *user_data
)
152 float func_tri(float v
, void *user_data
)
157 return 1 - (v
- 0.25f
) * 4;
158 return -1 + 4 * (v
- 0.75f
);
161 void cbox_waveform_generate_levels(struct cbox_waveform
*waveform
, int levels
, double ratio
)
163 complex float output
[STD_WAVEFORM_FRAMES
], bandlimited
[STD_WAVEFORM_FRAMES
];
164 my_fft_r2c(output
, waveform
->data
);
165 int N
= STD_WAVEFORM_FRAMES
;
167 waveform
->levels
= calloc(levels
, sizeof(struct cbox_waveform_level
));
168 double rate
= 65536.0 * 65536.0; // / waveform->info.frames;
169 double orig_rate
= 65536.0 * 65536.0; // / waveform->info.frames;
170 for (int i
= 0; i
< levels
; i
++)
172 int harmonics
= N
/ 2 / (rate
/ orig_rate
);
175 for (int j
= 1; j
<= harmonics
; j
++)
177 bandlimited
[j
] = output
[j
];
178 bandlimited
[N
- j
] = output
[N
- j
];
180 for (int j
= harmonics
; j
<= N
/ 2; j
++)
181 bandlimited
[j
] = bandlimited
[N
- j
] = 0;
183 waveform
->levels
[i
].data
= calloc(N
+ MAX_INTERPOLATION_ORDER
, sizeof(int16_t));
184 my_ifft_c2r(waveform
->levels
[i
].data
, bandlimited
);
185 memcpy(waveform
->levels
[i
].data
+ N
, waveform
->levels
[i
].data
, MAX_INTERPOLATION_ORDER
* sizeof(int16_t));
186 waveform
->levels
[i
].max_rate
= (uint64_t)(rate
);
189 waveform
->level_count
= levels
;
192 void cbox_wavebank_add_std_waveform(const char *name
, float (*getfunc
)(float v
, void *user_data
), void *user_data
, int levels
)
194 int nsize
= STD_WAVEFORM_FRAMES
;
195 int16_t *wave
= calloc(nsize
, sizeof(int16_t));
196 for (int i
= 0; i
< nsize
; i
++)
198 float v
= getfunc(i
* 1.0 / nsize
, user_data
);
200 v
= (v
< 0) ? -1 : 1;
201 // cannot use full scale here, because bandlimiting will introduce
202 // some degree of overshoot
203 wave
[i
] = (int16_t)(25000 * v
);
205 struct cbox_waveform
*waveform
= calloc(1, sizeof(struct cbox_waveform
));
206 waveform
->data
= wave
;
207 waveform
->info
.channels
= 1;
208 waveform
->preloaded_frames
= waveform
->info
.frames
= nsize
;
209 waveform
->info
.samplerate
= (int)(nsize
* 261.6255);
210 waveform
->id
= ++bank
.serial_no
;
211 waveform
->bytes
= waveform
->info
.channels
* 2 * (waveform
->info
.frames
+ 1);
212 waveform
->refcount
= 1;
213 waveform
->canonical_name
= g_strdup(name
);
214 waveform
->display_name
= g_strdup(name
);
215 waveform
->has_loop
= TRUE
;
216 waveform
->loop_start
= 0;
217 waveform
->loop_end
= nsize
;
218 waveform
->levels
= NULL
;
219 waveform
->level_count
= 0;
222 cbox_waveform_generate_levels(waveform
, levels
, 2);
224 g_hash_table_insert(bank
.waveforms_by_name
, waveform
->canonical_name
, waveform
);
225 g_hash_table_insert(bank
.waveforms_by_id
, &waveform
->id
, waveform
);
226 bank
.std_waveforms
= g_slist_prepend(bank
.std_waveforms
, waveform
);
227 // These waveforms are not included in the bank size, I don't think it has
228 // much value for the user.
231 void cbox_wavebank_init()
238 bank
.waveforms_by_name
= g_hash_table_new(g_str_hash
, g_str_equal
);
239 bank
.waveforms_by_id
= g_hash_table_new(g_int_hash
, g_int_equal
);
240 bank
.std_waveforms
= NULL
;
241 bank
.streaming_prefetch_size
= cbox_config_get_int("streaming", "prefetch_size", 65536);
243 cbox_wavebank_add_std_waveform("*sine", func_sine
, NULL
, 0);
244 cbox_wavebank_add_std_waveform("*saw", func_saw
, NULL
, 11);
245 cbox_wavebank_add_std_waveform("*sqr", func_sqr
, NULL
, 11);
246 cbox_wavebank_add_std_waveform("*tri", func_tri
, NULL
, 11);
249 struct cbox_waveform
*cbox_wavebank_get_waveform(const char *context_name
, struct cbox_tarfile
*tarfile
, const char *sample_dir
, const char *filename
, GError
**error
)
253 g_set_error(error
, CBOX_WAVEFORM_ERROR
, CBOX_WAVEFORM_ERROR_FAILED
, "%s: no filename specified", context_name
);
257 // Built in waveforms don't go through path canonicalization
258 if (filename
[0] == '*')
260 gpointer value
= g_hash_table_lookup(bank
.waveforms_by_name
, filename
);
263 struct cbox_waveform
*waveform
= value
;
264 cbox_waveform_ref(waveform
);
269 gchar
*value_copy
= g_strdup(filename
);
270 for (int i
= 0; value_copy
[i
]; i
++)
272 if (value_copy
[i
] == '\\')
275 gchar
*pathname
= value_copy
[0] == '/' ? g_strdup(value_copy
) : g_build_filename(sample_dir
, value_copy
, NULL
);
278 char *canonical
= NULL
;
280 canonical
= g_strdup_printf("sbtar:%s;%s", tarfile
->file_pathname
, pathname
);
283 // make sure canonical is always allocated on the same (glib) heap
284 char *p
= realpath(pathname
, NULL
);
287 canonical
= g_strdup(p
);
293 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
));
297 gpointer value
= g_hash_table_lookup(bank
.waveforms_by_name
, canonical
);
303 struct cbox_waveform
*waveform
= value
;
304 cbox_waveform_ref(waveform
);
308 struct cbox_waveform
*waveform
= calloc(1, sizeof(struct cbox_waveform
));
309 SNDFILE
*sndfile
= NULL
;
310 struct cbox_taritem
*taritem
= NULL
;
313 taritem
= cbox_tarfile_get_item_by_name(tarfile
, pathname
, TRUE
);
315 sndfile
= cbox_tarfile_opensndfile(tarfile
, taritem
, &waveform
->sndstream
, &waveform
->info
);
318 sndfile
= sf_open(pathname
, SFM_READ
, &waveform
->info
);
321 g_set_error(error
, G_FILE_ERROR
, g_file_error_from_errno (errno
), "%s: cannot open '%s'", context_name
, pathname
);
328 SF_INSTRUMENT instrument
;
330 if (waveform
->info
.channels
!= 1 && waveform
->info
.channels
!= 2)
332 g_set_error(error
, CBOX_WAVEFORM_ERROR
, CBOX_WAVEFORM_ERROR_FAILED
,
333 "%s: cannot open file '%s': unsupported channel count %d", context_name
, pathname
, (int)waveform
->info
.channels
);
340 uint32_t preloaded_frames
= waveform
->info
.frames
+ 1;
341 // If sample is larger than 2x prefetch buffer size, then load only
342 // a prefetch buffer worth of data, and stream the rest.
343 if (preloaded_frames
> 2 * bank
.streaming_prefetch_size
)
344 preloaded_frames
= bank
.streaming_prefetch_size
;
345 waveform
->id
= ++bank
.serial_no
;
346 waveform
->bytes
= waveform
->info
.channels
* 2 * preloaded_frames
;
347 waveform
->data
= malloc(waveform
->bytes
);
348 waveform
->refcount
= 1;
349 waveform
->canonical_name
= canonical
;
350 waveform
->display_name
= g_filename_display_name(canonical
);
351 waveform
->has_loop
= FALSE
;
352 waveform
->levels
= NULL
;
353 waveform
->level_count
= 0;
354 waveform
->preloaded_frames
= preloaded_frames
;
355 waveform
->tarfile
= tarfile
;
356 waveform
->taritem
= taritem
;
358 if (sf_command(sndfile
, SFC_GET_INSTRUMENT
, &instrument
, sizeof(SF_INSTRUMENT
)))
360 for (int i
= 0; i
< instrument
.loop_count
; i
++)
362 if (instrument
.loops
[i
].mode
== SF_LOOP_FORWARD
)
364 waveform
->loop_start
= instrument
.loops
[i
].start
;
365 waveform
->loop_end
= instrument
.loops
[i
].end
;
366 waveform
->has_loop
= TRUE
;
372 nshorts
= waveform
->info
.channels
* preloaded_frames
;
373 for (uint32_t i
= 0; i
< nshorts
; i
++)
374 waveform
->data
[i
] = 0;
375 sf_readf_short(sndfile
, waveform
->data
, preloaded_frames
);
377 bank
.bytes
+= waveform
->bytes
;
378 if (bank
.bytes
> bank
.maxbytes
)
379 bank
.maxbytes
= bank
.bytes
;
380 g_hash_table_insert(bank
.waveforms_by_name
, waveform
->canonical_name
, waveform
);
381 g_hash_table_insert(bank
.waveforms_by_id
, &waveform
->id
, waveform
);
386 int64_t cbox_wavebank_get_bytes()
391 int64_t cbox_wavebank_get_maxbytes()
393 return bank
.maxbytes
;
396 int cbox_wavebank_get_count()
398 return g_hash_table_size(bank
.waveforms_by_id
);
401 struct cbox_waveform
*cbox_wavebank_peek_waveform_by_id(int id
)
403 return g_hash_table_lookup(bank
.waveforms_by_id
, &id
);
406 void cbox_wavebank_foreach(void (*cb
)(void *, struct cbox_waveform
*), void *user_data
)
411 g_hash_table_iter_init (&iter
, bank
.waveforms_by_id
);
412 while (g_hash_table_iter_next (&iter
, &key
, &value
))
414 (*cb
)(user_data
, value
);
418 void cbox_wavebank_close()
421 g_warning("Warning: %lld bytes in unfreed samples", (long long int)bank
.bytes
);
422 while(bank
.std_waveforms
)
424 cbox_waveform_unref((struct cbox_waveform
*)bank
.std_waveforms
->data
);
425 bank
.std_waveforms
= g_slist_delete_link(bank
.std_waveforms
, bank
.std_waveforms
);
427 g_hash_table_destroy(bank
.waveforms_by_id
);
428 g_hash_table_destroy(bank
.waveforms_by_name
);
429 bank
.waveforms_by_id
= NULL
;
430 bank
.waveforms_by_name
= NULL
;
433 /////////////////////////////////////////////////////////////////////////////////////////////////////
435 void cbox_waveform_ref(struct cbox_waveform
*waveform
)
437 ++waveform
->refcount
;
440 void cbox_waveform_unref(struct cbox_waveform
*waveform
)
442 if (--waveform
->refcount
> 0)
445 g_hash_table_remove(bank
.waveforms_by_name
, waveform
->canonical_name
);
446 g_hash_table_remove(bank
.waveforms_by_id
, &waveform
->id
);
447 bank
.bytes
-= waveform
->bytes
;
449 g_free(waveform
->display_name
);
450 g_free(waveform
->canonical_name
);
451 for (int i
= 0; i
< waveform
->level_count
; i
++)
452 free(waveform
->levels
[i
].data
);
453 free(waveform
->levels
);
454 free(waveform
->data
);
459 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
461 struct waves_foreach_data
463 struct cbox_command_target
*fb
;
468 void wave_list_cb(void *user_data
, struct cbox_waveform
*waveform
)
470 struct waves_foreach_data
*wfd
= user_data
;
472 wfd
->success
= wfd
->success
&& cbox_execute_on(wfd
->fb
, NULL
, "/waveform", "i", wfd
->error
, (int)waveform
->id
);
475 static gboolean
waves_process_cmd(struct cbox_command_target
*ct
, struct cbox_command_target
*fb
, struct cbox_osc_command
*cmd
, GError
**error
)
477 if (!strcmp(cmd
->command
, "/status") && !strcmp(cmd
->arg_types
, ""))
479 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
482 // XXXKF this only supports 4GB - not a big deal for now yet?
483 return cbox_execute_on(fb
, NULL
, "/bytes", "i", error
, (int)cbox_wavebank_get_bytes()) &&
484 cbox_execute_on(fb
, NULL
, "/max_bytes", "i", error
, (int)cbox_wavebank_get_maxbytes()) &&
485 cbox_execute_on(fb
, NULL
, "/count", "i", error
, (int)cbox_wavebank_get_count())
488 else if (!strcmp(cmd
->command
, "/list") && !strcmp(cmd
->arg_types
, ""))
490 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
493 struct waves_foreach_data wfd
= { fb
, error
, TRUE
};
494 cbox_wavebank_foreach(wave_list_cb
, &wfd
);
497 else if (!strcmp(cmd
->command
, "/info") && !strcmp(cmd
->arg_types
, "i"))
499 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
502 int id
= CBOX_ARG_I(cmd
, 0);
503 struct cbox_waveform
*waveform
= cbox_wavebank_peek_waveform_by_id(id
);
504 if (waveform
== NULL
)
506 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Waveform %d not found", id
);
509 assert(id
== waveform
->id
);
510 if (!cbox_execute_on(fb
, NULL
, "/filename", "s", error
, waveform
->canonical_name
)) // XXXKF convert to utf8
512 if (!cbox_execute_on(fb
, NULL
, "/name", "s", error
, waveform
->display_name
))
514 if (!cbox_execute_on(fb
, NULL
, "/bytes", "i", error
, (int)waveform
->bytes
))
516 if (waveform
->has_loop
&& !cbox_execute_on(fb
, NULL
, "/loop", "ii", error
, (int)waveform
->loop_start
, (int)waveform
->loop_end
))
522 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
);
527 struct cbox_command_target cbox_waves_cmd_target
=
529 .process_cmd
= waves_process_cmd
,