New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Virtual device #41

Merged
merged 122 commits into from Oct 2, 2017
Commits
Jump to file or symbol
Failed to load files and symbols.
+132 −14
Diff settings

Always

Just for now

Viewing a subset of changes. View all

vegas: add fluidsynth additions to demo music making

This commit introduces the fluidsynth component into the
vegas-mode example, and has basic mappings from the mikro
mk2 machine devices to play notes and choose sounds.

Signed-off-by: Harry van Haaren <harryhaaren@gmail.com>
  • Loading branch information...
harryhaaren committed Sep 29, 2017
commit 843490daa29ef6b4ec833045b2995af183d6f833
View
@@ -6,6 +6,80 @@
#include <stdlib.h>
#include <string.h>
#include <fluidsynth.h>
struct soffa_t {
fluid_synth_t* synth;
fluid_settings_t* settings;
int sf_id;
};
struct soffa_t *
soffa_init(uint32_t sr)
{
struct soffa_t *s = calloc(1, sizeof(struct soffa_t));
if(!s) return 0;
s->settings = new_fluid_settings();
s->synth = new_fluid_synth(s->settings);
fluid_synth_set_sample_rate(s->synth, sr);
/* TODO: fluid_synth_sfunload(); */
s->sf_id = fluid_synth_sfload(s->synth, "example.sf2", 0);
if(s->sf_id == -1)
goto fail;
int midi_chan = 0;
int bank = 0;
int patch = 0;
fluid_synth_program_select(s->synth, midi_chan, s->sf_id, bank, patch);
fluid_synth_program_select(s->synth, midi_chan+1, s->sf_id, bank, patch + 4);
for(int i = 0; i < 10; i++) {
fluid_synth_channel_info_t channelInfo;
fluid_synth_program_change(s->synth, 0, i);
fluid_synth_get_channel_info(s->synth, 0, &channelInfo);
printf("%d: %s\n", i, channelInfo.name);
}
fluid_synth_program_change(s->synth, 0, patch);
return s;
fail:
if(s)
free(s);
return 0;
}
void
soffa_note_on(struct soffa_t *s, uint8_t chan, uint8_t note, float vel)
{
fluid_synth_noteon(s->synth, chan, note, vel * 127.f);
printf("note on %d\n", note);
}
void
soffa_note_off(struct soffa_t *s, uint8_t chan, uint8_t note)
{
fluid_synth_noteoff(s->synth, chan, note);
}
void
soffa_set_patch(struct soffa_t *s, uint8_t chan, uint8_t bank, uint8_t patch)
{
fluid_synth_program_select(s->synth, chan, s->sf_id, bank, patch);
}
void soffa_process(struct soffa_t *s, int nframes, float** output)
{
int ignored = 0;
void *ignore_ptr = 0;
fluid_synth_process(s->synth, nframes, ignored, ignore_ptr,
2, output);
}
jack_port_t* outputPort = 0;
static int playbackIndex = 0;
@@ -17,22 +91,32 @@ static jack_client_t* client;
int process(jack_nframes_t nframes, void* arg)
{
struct dummy_data *d = arg;
float* outputBuffer= (float*)jack_port_get_buffer ( outputPort, nframes);
memset(outputBuffer, 0, nframes * sizeof(float));
if(!sample_size)
return 0;
if(sample_size) {
for ( int i = 0; i < (int) nframes; i++) {
outputBuffer[i] = sample[playbackIndex % sample_size] * d->volume;
playbackIndex++;
}
struct dummy_data *d = arg;
for ( int i = 0; i < (int) nframes; i++) {
outputBuffer[i] = sample[playbackIndex % sample_size] * d->volume;
playbackIndex++;
/* 0 - 1 ranged progress */
float idx = playbackIndex % sample_size;
d->progress = ((float)idx) / sample_size;
}
/* 0 - 1 ranged progress */
float idx = playbackIndex % sample_size;
d->progress = ((float)idx) / sample_size;
float *buf2[] = {outputBuffer, outputBuffer};
soffa_process(d->soffa, nframes, buf2);
for (int i = 0; i < (int) nframes; i++) {
outputBuffer[i] *= 2;
}
/* mark dummy data updated, so controllers get updates */
d->revision++;
return 0;
}
@@ -52,11 +136,22 @@ int audio_init(void *dummy)
/* setup JACK */
client = jack_client_open("CtlraPlayer", JackNullOption, 0, 0 );
jack_set_process_callback(client, process , dummy);
int sr = jack_get_sample_rate(client);
if(jack_set_process_callback(client, process, dummy)) {
printf("error setting JACK callback\n");
}
outputPort = jack_port_register(client, "output",
JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, 0 );
struct dummy_data *d = dummy;
//int sr = 44100;
d->soffa = soffa_init(sr);
if(!d->soffa) {
printf("soffa init() failed\n");
exit(-1);
}
jack_activate(client);
return 0;
}
@@ -9,19 +9,27 @@
#define VEGAS_BTN_COUNT 512
struct soffa_t;
struct dummy_data {
uint8_t print_events;
uint64_t revision;
float volume;
float progress;
int playing[2];
int buttons[VEGAS_BTN_COUNT];
struct soffa_t *soffa;
};
/* "useful" parts of the program */
int audio_init();
void audio_exit();
/* SF2 sound generation */
void soffa_set_patch(struct soffa_t *s, uint8_t chan, uint8_t bank, uint8_t patch);
void soffa_note_on(struct soffa_t *s, uint8_t chan, uint8_t note, float vel);
void soffa_note_off(struct soffa_t *s, uint8_t chan, uint8_t note);
/* Functions to poll / push state to the devs */
void kontrol_x1_update_state(struct ctlra_dev_t *dev, void *d);
void kontrol_x1_func(struct ctlra_dev_t* dev, uint32_t num_events,
@@ -4,6 +4,8 @@
#include "ctlra.h"
#include "devices/ni_maschine_mikro_mk2.h"
static int chan;
void mm_update_state(struct ctlra_dev_t *dev, void *ud)
{
struct dummy_data *d = ud;
@@ -30,7 +32,16 @@ void mm_func(struct ctlra_dev_t* dev,
ctlra_dev_light_set(dev, e->button.id, UINT32_MAX);
break;
case CTLRA_EVENT_ENCODER:
//printf("enc %d, %d\n", e->encoder.id, e->encoder.delta);
if(e->encoder.delta > 0)
chan++;
else
chan--;
if(chan < 0)
chan = 0;
printf("enc %d, %d, patch = %d\n",
e->encoder.id, e->encoder.delta, chan);
soffa_set_patch(dummy->soffa, 0, 0, chan);
break;
case CTLRA_EVENT_SLIDER:
if(e->slider.id == 11) {
@@ -49,7 +60,10 @@ void mm_func(struct ctlra_dev_t* dev,
case CTLRA_EVENT_GRID:
if(e->grid.flags & CTLRA_EVENT_GRID_FLAG_BUTTON) {
dummy->buttons[e->grid.pos] = e->grid.pressed;
//pressed = e->grid.pressed ? " X " : " ";
if(e->grid.pressed)
soffa_note_on(dummy->soffa, 0, 36 + e->grid.pos, 0.8);
else
soffa_note_off(dummy->soffa, 0, 36 + e->grid.pos);
} else {
//pressed = "---";
}
View
@@ -61,10 +61,11 @@ endif
cairo = dependency('cairo', required: false)
sndfile = dependency('sndfile', required: false)
if(jack.found() and cairo.found() and sndfile.found())
fluid = dependency('fluidsynth', required: false)
if(jack.found() and cairo.found() and sndfile.found() and fluid.found())
executable('vegas_mode',
example_vegas,
include_directories: ctlra_includes,
link_with: ctlra,
dependencies: [jack, cairo, sndfile])
dependencies: [jack, cairo, sndfile, fluid])
endif
ProTip! Use n and p to navigate between commits in a pull request.