Skip to content
Snippets Groups Projects
Commit e1d28746 authored by moon2's avatar moon2
Browse files

wip

parent 2b359b23
No related branches found
No related tags found
No related merge requests found
#include "bl00mbox_line_in.h" #include "bl00mbox_line_in.h"
radspa_descriptor_t bl00mbox_line_in_desc = { radspa_descriptor_t bl00mbox_line_in_desc = {
.name = "line_in", .name = "bl00mbox_line_in",
.id = 4001, .id = 4001,
.description = "connects to the line input of bl00mbox", .description = "connects to the line input of bl00mbox",
.create_plugin_instance = bl00mbox_line_in_create, .create_plugin_instance = bl00mbox_line_in_create,
......
...@@ -15,6 +15,12 @@ radspa_descriptor_t sampler_desc = { ...@@ -15,6 +15,12 @@ radspa_descriptor_t sampler_desc = {
#define SAMPLER_REC_IN 2 #define SAMPLER_REC_IN 2
#define SAMPLER_REC_TRIGGER 3 #define SAMPLER_REC_TRIGGER 3
static int16_t define_behavior(uint32_t in){
int32_t ret = in & 0xFFFF;
if(ret > 32767) return ret - 65535;
return ret;
}
void sampler_run(radspa_t * sampler, uint16_t num_samples, uint32_t render_pass_id){ void sampler_run(radspa_t * sampler, uint16_t num_samples, uint32_t render_pass_id){
radspa_signal_t * output_sig = radspa_signal_get_by_index(sampler, SAMPLER_OUTPUT); radspa_signal_t * output_sig = radspa_signal_get_by_index(sampler, SAMPLER_OUTPUT);
if(output_sig->buffer == NULL) return; if(output_sig->buffer == NULL) return;
...@@ -26,7 +32,14 @@ void sampler_run(radspa_t * sampler, uint16_t num_samples, uint32_t render_pass_ ...@@ -26,7 +32,14 @@ void sampler_run(radspa_t * sampler, uint16_t num_samples, uint32_t render_pass_
static int32_t ret = 0; static int32_t ret = 0;
uint32_t buffer_size = sampler->plugin_table_len; buf[0] = define_behavior(data->read_head_position);
buf[1] = define_behavior(data->read_head_position>>16);
buf[2] = define_behavior(data->sample_start);
buf[3] = define_behavior(data->sample_start>>16);
buf[2] = define_behavior(data->sample_len);
buf[3] = define_behavior(data->sample_len>>16);
uint32_t buffer_size = sampler->plugin_table_len - 6;
for(uint16_t i = 0; i < num_samples; i++){ for(uint16_t i = 0; i < num_samples; i++){
int16_t rec_trigger = radspa_trigger_get(rec_trigger_sig->get_value(rec_trigger_sig, i, num_samples, render_pass_id), &(data->rec_trigger_prev)); int16_t rec_trigger = radspa_trigger_get(rec_trigger_sig->get_value(rec_trigger_sig, i, num_samples, render_pass_id), &(data->rec_trigger_prev));
...@@ -52,7 +65,7 @@ void sampler_run(radspa_t * sampler, uint16_t num_samples, uint32_t render_pass_ ...@@ -52,7 +65,7 @@ void sampler_run(radspa_t * sampler, uint16_t num_samples, uint32_t render_pass_
if(data->rec_active){ if(data->rec_active){
int16_t rec_in = rec_in_sig->get_value(rec_in_sig, i, num_samples, render_pass_id); int16_t rec_in = rec_in_sig->get_value(rec_in_sig, i, num_samples, render_pass_id);
buf[data->write_head_position] = rec_in; buf[data->write_head_position + 6] = rec_in;
data->write_head_position++; data->write_head_position++;
if(data->write_head_position >= buffer_size) data->write_head_position = 0; if(data->write_head_position >= buffer_size) data->write_head_position = 0;
if(data->sample_len < buffer_size) data->sample_len++; if(data->sample_len < buffer_size) data->sample_len++;
...@@ -67,7 +80,7 @@ void sampler_run(radspa_t * sampler, uint16_t num_samples, uint32_t render_pass_ ...@@ -67,7 +80,7 @@ void sampler_run(radspa_t * sampler, uint16_t num_samples, uint32_t render_pass_
if(data->read_head_position < data->sample_len){ if(data->read_head_position < data->sample_len){
uint32_t sample_offset_pos = data->read_head_position + data->sample_start; uint32_t sample_offset_pos = data->read_head_position + data->sample_start;
if(sample_offset_pos >= data->sample_len) sample_offset_pos -= data->sample_len; if(sample_offset_pos >= data->sample_len) sample_offset_pos -= data->sample_len;
ret = radspa_mult_shift(buf[sample_offset_pos], data->volume); ret = radspa_mult_shift(buf[sample_offset_pos + 6], data->volume);
data->read_head_position++; data->read_head_position++;
} else { } else {
//ret = (ret * 255)>>8; // avoid dc clicks with bad samples //ret = (ret * 255)>>8; // avoid dc clicks with bad samples
...@@ -81,7 +94,7 @@ void sampler_run(radspa_t * sampler, uint16_t num_samples, uint32_t render_pass_ ...@@ -81,7 +94,7 @@ void sampler_run(radspa_t * sampler, uint16_t num_samples, uint32_t render_pass_
radspa_t * sampler_create(uint32_t init_var){ radspa_t * sampler_create(uint32_t init_var){
if(init_var == 0) return NULL; //doesn't make sense if(init_var == 0) return NULL; //doesn't make sense
uint32_t buffer_size = init_var; uint32_t buffer_size = init_var;
radspa_t * sampler = radspa_standard_plugin_create(&sampler_desc, SAMPLER_NUM_SIGNALS, sizeof(sampler_data_t), buffer_size); radspa_t * sampler = radspa_standard_plugin_create(&sampler_desc, SAMPLER_NUM_SIGNALS, sizeof(sampler_data_t), buffer_size + 6*sizeof(int16_t);
if(sampler == NULL) return NULL; if(sampler == NULL) return NULL;
sampler->render = sampler_run; sampler->render = sampler_run;
radspa_signal_set(sampler, SAMPLER_OUTPUT, "output", RADSPA_SIGNAL_HINT_OUTPUT, 0); radspa_signal_set(sampler, SAMPLER_OUTPUT, "output", RADSPA_SIGNAL_HINT_OUTPUT, 0);
......
...@@ -16,10 +16,10 @@ class TinySampler(Application): ...@@ -16,10 +16,10 @@ class TinySampler(Application):
self.blm = bl00mbox.Channel("tiny sampler") self.blm = bl00mbox.Channel("tiny sampler")
self.samplers = [None] * 5 self.samplers = [None] * 5
self.line_in = self.blm.new(bl00mbox.plugins.line_in) self.line_in = self.blm.new(bl00mbox.plugins.bl00mbox_line_in)
self.line_in.signals.gain = 30000 self.line_in.signals.gain = 30000
for i in range(5): for i in range(5):
self.samplers[i] = self.blm.new(bl00mbox.patches.sampler, 5000) self.samplers[i] = self.blm.new(bl00mbox.patches.sampler, 1000)
self.samplers[i].signals.output = self.blm.mixer self.samplers[i].signals.output = self.blm.mixer
self.samplers[i].signals.rec_in = self.line_in.signals.mid self.samplers[i].signals.rec_in = self.line_in.signals.mid
self.is_recording = [False] * 5 self.is_recording = [False] * 5
...@@ -82,6 +82,7 @@ class TinySampler(Application): ...@@ -82,6 +82,7 @@ class TinySampler(Application):
): ):
if self.is_recording[i]: if self.is_recording[i]:
self.samplers[i].signals.rec_trigger.stop() self.samplers[i].signals.rec_trigger.stop()
self.samplers[i].normalize()
self.is_recording[i] = False self.is_recording[i] = False
self.ct_prev = ct self.ct_prev = ct
...@@ -100,7 +100,7 @@ class tinysynth_fm(tinysynth): ...@@ -100,7 +100,7 @@ class tinysynth_fm(tinysynth):
class sampler(_Patch): class sampler(_Patch):
""" """
requires a wave file. default path: /sys/samples/ requires a wave file (str) or max sample length in milliseconds (int). default path: /sys/samples/
""" """
def __init__(self, chan, init_var): def __init__(self, chan, init_var):
...@@ -113,9 +113,9 @@ class sampler(_Patch): ...@@ -113,9 +113,9 @@ class sampler(_Patch):
else: else:
f = wave.open("/flash/sys/samples/" + filename, "r") f = wave.open("/flash/sys/samples/" + filename, "r")
self.len_frames = f.getnframes() self._len_frames = f.getnframes()
self.plugins.sampler = chan.new( self.plugins.sampler = chan.new(
bl00mbox.plugins._sampler_ram, self.len_frames bl00mbox.plugins._sampler_ram, self._len_frames
) )
assert f.getsampwidth() == 2 assert f.getsampwidth() == 2
...@@ -125,22 +125,22 @@ class sampler(_Patch): ...@@ -125,22 +125,22 @@ class sampler(_Patch):
if f.getnchannels() == 1: if f.getnchannels() == 1:
# fast path for mono # fast path for mono
table = self.plugins.sampler.table_bytearray table = self.plugins.sampler.table_bytearray
for i in range(0, self.len_frames * 2, 100): for i in range(0, self._len_frames * 2, 100):
table[i : i + 100] = f.readframes(50) table[i + 6 : i + 100 + 6] = f.readframes(50)
else: else:
# somewhat fast path for stereo # somewhat fast path for stereo
table = self.plugins.sampler.table_int16_array table = self.plugins.sampler.table_int16_array
for i in range(self.len_frames): for i in range(self._len_frames):
frame = f.readframes(1) frame = f.readframes(1)
value = int.from_bytes(frame[0:2], "little") value = int.from_bytes(frame[0:2], "little")
table[i] = value table[i + 6] = value
f.close() f.close()
self._filename = filename self._filename = filename
else: else:
self.len_frames = int(48 * init_var) self._len_frames = int(48 * init_var)
self.plugins.sampler = chan.new( self.plugins.sampler = chan.new(
bl00mbox.plugins._sampler_ram, self.len_frames bl00mbox.plugins._sampler_ram, self._len_frames
) )
self._filename = "" self._filename = ""
...@@ -149,10 +149,51 @@ class sampler(_Patch): ...@@ -149,10 +149,51 @@ class sampler(_Patch):
self.signals.rec_in = self.plugins.sampler.signals.rec_in self.signals.rec_in = self.plugins.sampler.signals.rec_in
self.signals.rec_trigger = self.plugins.sampler.signals.rec_trigger self.signals.rec_trigger = self.plugins.sampler.signals.rec_trigger
def load(self, filename):
pass
def save(self, filename):
pass
def _extract_uint32_t(self, lsb, msb):
if lsb < 0:
lsb += 65535
if msb < 0:
msb += 65535
return lsb + (msb * (1<<16))
@property
def read_head_position(self):
return self._extract_uint32_t(self.plugins.sampler.table[0], self.plugins.sampler.table[1])
@property
def sample_start(self):
return self._extract_uint32_t(self.plugins.sampler.table[2], self.plugins.sampler.table[3])
@property
def sample_len(self):
return self._extract_uint32_t(self.plugins.sampler.table[4], self.plugins.sampler.table[5])
@property @property
def filename(self): def filename(self):
return self._filename return self._filename
def normalize(self):
maximum = 0
table = self.plugins.sampler.table_int16_array
for i in range(self.sample_len):
i = (i + self.sample_start) % self._len_frames
a = table[i+6]
if a < 0:
a = -a
if a > maximum:
maximum = a
if maximum != 0:
gain = 32767/maximum
for i in range(self.sample_len):
i = (i + self.sample_start) % self._len_frames
table[i+6] = gain * table[i+6]
class sequencer(_Patch): class sequencer(_Patch):
def __init__(self, chan, num_tracks, num_steps): def __init__(self, chan, num_tracks, num_steps):
...@@ -188,6 +229,7 @@ class sequencer(_Patch): ...@@ -188,6 +229,7 @@ class sequencer(_Patch):
+ str(self.signals.step_len.value) + str(self.signals.step_len.value)
) )
ret += "\n [tracks]" ret += "\n [tracks]"
"""
for x, seq in enumerate(self.seqs): for x, seq in enumerate(self.seqs):
ret += ( ret += (
"\n " "\n "
...@@ -196,6 +238,7 @@ class sequencer(_Patch): ...@@ -196,6 +238,7 @@ class sequencer(_Patch):
+ "".join(["X " if x > 0 else ". " for x in seq.table[1:]]) + "".join(["X " if x > 0 else ". " for x in seq.table[1:]])
+ "]" + "]"
) )
"""
ret += "\n" + "\n".join(super().__repr__().split("\n")[1:]) ret += "\n" + "\n".join(super().__repr__().split("\n")[1:])
return ret return ret
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment