initial commit, working basics.
- loads a hard-coded hydrogen kit - repsonds to midi - no individual control - no gui
This commit is contained in:
commit
1976f033a3
19
Makefile
Normal file
19
Makefile
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
BUNDLE = lv2pftci-drmr.lv2
|
||||||
|
INSTALL_DIR = /home/nick/.lv2
|
||||||
|
CC=gcc
|
||||||
|
|
||||||
|
$(BUNDLE): manifest.ttl drmr.ttl drmr.so
|
||||||
|
rm -rf $(BUNDLE)
|
||||||
|
mkdir $(BUNDLE)
|
||||||
|
cp manifest.ttl drmr.ttl drmr.so $(BUNDLE)
|
||||||
|
|
||||||
|
drmr.so: drmr.c drmr_hydrogen.c
|
||||||
|
$(CC) -g -shared -fPIC -DPIC drmr.c drmr_hydrogen.c `pkg-config --cflags --libs lv2-plugin sndfile` -lexpat -o drmr.so
|
||||||
|
|
||||||
|
install: $(BUNDLE)
|
||||||
|
mkdir -p $(INSTALL_DIR)
|
||||||
|
rm -rf $(INSTALL_DIR)/$(BUNDLE)
|
||||||
|
cp -R $(BUNDLE) $(INSTALL_DIR)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(BUNDLE) drmr.so
|
228
drmr.c
Normal file
228
drmr.c
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
/*
|
||||||
|
LV2 DrMr plugin
|
||||||
|
Copyright 2012 Nick Lanham <nick@afternight.org>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "drmr.h"
|
||||||
|
|
||||||
|
int load_sample(char* path, drmr_sample* samp) {
|
||||||
|
SNDFILE* sndf;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
printf("Loading: %s\n",path);
|
||||||
|
|
||||||
|
samp->active = 0;
|
||||||
|
|
||||||
|
memset(&(samp->info),0,sizeof(SF_INFO));
|
||||||
|
sndf = sf_open(path,SFM_READ,&(samp->info));
|
||||||
|
|
||||||
|
if (!sndf) {
|
||||||
|
fprintf(stderr,"Failed to open sound file: %s\n",sf_strerror(sndf));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (samp->info.channels > 2) {
|
||||||
|
fprintf(stderr, "File has too many channels. Can only handle mono/stereo samples\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
size = samp->info.frames * samp->info.channels;
|
||||||
|
samp->limit = size;
|
||||||
|
samp->data = malloc(size*sizeof(float));
|
||||||
|
if (!samp->data) {
|
||||||
|
fprintf(stderr,"Failed to allocate sample memory for %s\n",path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sf_read_float(sndf,samp->data,size);
|
||||||
|
sf_close(sndf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LV2_Handle
|
||||||
|
instantiate(const LV2_Descriptor* descriptor,
|
||||||
|
double rate,
|
||||||
|
const char* bundle_path,
|
||||||
|
const LV2_Feature* const* features) {
|
||||||
|
int i;
|
||||||
|
DrMr* drmr = malloc(sizeof(DrMr));
|
||||||
|
drmr->map = NULL;
|
||||||
|
drmr->num_samples = 0;
|
||||||
|
|
||||||
|
// Map midi uri
|
||||||
|
while(*features) {
|
||||||
|
if (!strcmp((*features)->URI, LV2_URI_MAP_URI)) {
|
||||||
|
drmr->map = (LV2_URI_Map_Feature *)((*features)->data);
|
||||||
|
drmr->uris.midi_event = drmr->map->uri_to_id
|
||||||
|
(drmr->map->callback_data,
|
||||||
|
"http://lv2plug.in/ns/ext/event",
|
||||||
|
"http://lv2plug.in/ns/ext/midi#MidiEvent");
|
||||||
|
}
|
||||||
|
features++;
|
||||||
|
}
|
||||||
|
if (!drmr->map) {
|
||||||
|
fprintf(stderr, "LV2 host does not support urid:map.\n");
|
||||||
|
free(drmr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
load_hydrogen_kit(drmr,"/usr/share/hydrogen/data/drumkits/GMkit/");
|
||||||
|
//load_hydrogen_kit(drmr,"/usr/share/hydrogen/data/drumkits/3355606kit/");
|
||||||
|
|
||||||
|
return (LV2_Handle)drmr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
connect_port(LV2_Handle instance,
|
||||||
|
uint32_t port,
|
||||||
|
void* data) {
|
||||||
|
DrMr* drmr = (DrMr*)instance;
|
||||||
|
switch ((DrMrPortIndex)port) {
|
||||||
|
case DRMR_MIDI:
|
||||||
|
drmr->midi_port = (LV2_Event_Buffer*)data;
|
||||||
|
break;
|
||||||
|
case DRMR_LEFT:
|
||||||
|
drmr->left = (float*)data;
|
||||||
|
break;
|
||||||
|
case DRMR_RIGHT:
|
||||||
|
drmr->right = (float*)data;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void activate(LV2_Handle instance) { }
|
||||||
|
|
||||||
|
|
||||||
|
static void run(LV2_Handle instance, uint32_t n_samples) {
|
||||||
|
int i;
|
||||||
|
char first_active, one_active;
|
||||||
|
DrMr* drmr = (DrMr*)instance;
|
||||||
|
|
||||||
|
LV2_Event_Iterator eit;
|
||||||
|
if (lv2_event_begin(&eit,drmr->midi_port)) { // if we have any events
|
||||||
|
LV2_Event *cur_ev;
|
||||||
|
uint8_t* data;
|
||||||
|
while (lv2_event_is_valid(&eit)) {
|
||||||
|
cur_ev = lv2_event_get(&eit,&data);
|
||||||
|
if (cur_ev->type == drmr->uris.midi_event) {
|
||||||
|
int channel = *data & 15;
|
||||||
|
switch ((*data) >> 4) {
|
||||||
|
case 8: // ignore note-offs for now, should probably be a setting
|
||||||
|
//if (drmr->cur_samp) drmr->cur_samp->active = 0;
|
||||||
|
break;
|
||||||
|
case 9: {
|
||||||
|
uint8_t nn = data[1];
|
||||||
|
nn-=60; // middle c is our root note (setting?)
|
||||||
|
if (nn >= 0 && nn < drmr->num_samples) {
|
||||||
|
drmr->samples[nn].active = 1;
|
||||||
|
drmr->samples[nn].offset = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
printf("Unhandeled status: %i\n",(*data)>>4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lv2_event_increment(&eit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
first_active = 1;
|
||||||
|
for (i = 0;i < drmr->num_samples;i++) {
|
||||||
|
int pos,lim;
|
||||||
|
drmr_sample* cs = drmr->samples+i;
|
||||||
|
if (cs->active) {
|
||||||
|
one_active = 1;
|
||||||
|
if (cs->info.channels == 1) { // play mono sample
|
||||||
|
lim = (n_samples < (cs->limit - cs->offset)?n_samples:(cs->limit-cs->offset));
|
||||||
|
if (first_active) {
|
||||||
|
for(pos = 0;pos < lim;pos++) {
|
||||||
|
drmr->left[pos] = cs->data[cs->offset];
|
||||||
|
drmr->right[pos] = cs->data[cs->offset];
|
||||||
|
cs->offset++;
|
||||||
|
}
|
||||||
|
first_active = 0;
|
||||||
|
} else {
|
||||||
|
for(pos = 0;pos < lim;pos++) {
|
||||||
|
drmr->left[pos] += cs->data[cs->offset];
|
||||||
|
drmr->right[pos] += cs->data[cs->offset];
|
||||||
|
cs->offset++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // play stereo sample
|
||||||
|
lim = (cs->limit-cs->offset)/cs->info.channels;
|
||||||
|
if (lim > n_samples) lim = n_samples;
|
||||||
|
if (first_active) {
|
||||||
|
for (pos=0;pos<lim;pos++) {
|
||||||
|
drmr->left[pos] = cs->data[cs->offset++];
|
||||||
|
drmr->right[pos] = cs->data[cs->offset++];
|
||||||
|
}
|
||||||
|
first_active = 0;
|
||||||
|
} else {
|
||||||
|
for (pos=0;pos<lim;pos++) {
|
||||||
|
drmr->left[pos] += cs->data[cs->offset++];
|
||||||
|
drmr->right[pos] += cs->data[cs->offset++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cs->offset >= cs->limit) cs->active = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (first_active) { // didn't find any samples
|
||||||
|
int pos;
|
||||||
|
for(pos = 0;pos<n_samples;pos++) {
|
||||||
|
drmr->left[pos] = 0.0f;
|
||||||
|
drmr->right[pos] = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deactivate(LV2_Handle instance) {}
|
||||||
|
|
||||||
|
static void cleanup(LV2_Handle instance) {
|
||||||
|
free(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
const void* extension_data(const char* uri) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const LV2_Descriptor descriptor = {
|
||||||
|
DRMR_URI,
|
||||||
|
instantiate,
|
||||||
|
connect_port,
|
||||||
|
activate,
|
||||||
|
run,
|
||||||
|
deactivate,
|
||||||
|
cleanup,
|
||||||
|
extension_data
|
||||||
|
};
|
||||||
|
|
||||||
|
LV2_SYMBOL_EXPORT
|
||||||
|
const LV2_Descriptor*
|
||||||
|
lv2_descriptor(uint32_t index)
|
||||||
|
{
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
return &descriptor;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
70
drmr.h
Normal file
70
drmr.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
LV2 DrMr plugin
|
||||||
|
Copyright 2012 Nick Lanham <nick@afternight.org>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef DRMR_H
|
||||||
|
#define DRMR_H
|
||||||
|
|
||||||
|
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
|
||||||
|
#include "lv2/lv2plug.in/ns/ext/event/event.h"
|
||||||
|
#include "lv2/lv2plug.in/ns/ext/event/event-helpers.h"
|
||||||
|
#include "lv2/lv2plug.in/ns/ext/uri-map/uri-map.h"
|
||||||
|
#include <sndfile.h>
|
||||||
|
|
||||||
|
// libsndfile stuff
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SF_INFO info;
|
||||||
|
char active;
|
||||||
|
uint32_t offset;
|
||||||
|
uint32_t limit;
|
||||||
|
float* data;
|
||||||
|
} drmr_sample;
|
||||||
|
|
||||||
|
int load_sample(char* path,drmr_sample* smp);
|
||||||
|
|
||||||
|
// lv2 stuff
|
||||||
|
|
||||||
|
#define DRMR_URI "http://github.com/nicklan/drmr"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
DRMR_MIDI = 0,
|
||||||
|
DRMR_LEFT,
|
||||||
|
DRMR_RIGHT,
|
||||||
|
DRMR_NUM_PORTS
|
||||||
|
} DrMrPortIndex;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// Ports
|
||||||
|
float* left;
|
||||||
|
float* right;
|
||||||
|
LV2_Event_Buffer *midi_port;
|
||||||
|
|
||||||
|
// URIs
|
||||||
|
LV2_URI_Map_Feature* map;
|
||||||
|
struct {
|
||||||
|
uint32_t midi_event;
|
||||||
|
} uris;
|
||||||
|
|
||||||
|
// Samples
|
||||||
|
drmr_sample* samples;
|
||||||
|
uint8_t num_samples;
|
||||||
|
|
||||||
|
} DrMr;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // DRMR_H
|
37
drmr.ttl
Normal file
37
drmr.ttl
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#>.
|
||||||
|
@prefix ev: <http://lv2plug.in/ns/ext/event#> .
|
||||||
|
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
||||||
|
@prefix doap: <http://usefulinc.com/ns/doap#>.
|
||||||
|
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
|
||||||
|
|
||||||
|
<http://github.com/nicklan/drmr>
|
||||||
|
a lv2:Plugin;
|
||||||
|
lv2:binary <drmr.so>;
|
||||||
|
doap:name "DrMr Sampler";
|
||||||
|
doap:maintainer [
|
||||||
|
foaf:name "Nick Lanham" ;
|
||||||
|
foaf:homepage <http://github.com/nick/drmr/wiki> ;
|
||||||
|
foaf:mbox <nick@afternight.org>
|
||||||
|
] ;
|
||||||
|
doap:license <http://usefulinc.com/doap/licenses/gpl>;
|
||||||
|
lv2:port [
|
||||||
|
a ev:EventPort, lv2:InputPort;
|
||||||
|
lv2:index 0;
|
||||||
|
ev:supportsEvent <http://lv2plug.in/ns/ext/midi#MidiEvent>;
|
||||||
|
lv2:symbol "midi";
|
||||||
|
lv2:name "MIDI";
|
||||||
|
],
|
||||||
|
[
|
||||||
|
a lv2:AudioPort, lv2:OutputPort;
|
||||||
|
lv2:index 1;
|
||||||
|
lv2:symbol "left";
|
||||||
|
lv2:name "Left";
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
a lv2:AudioPort, lv2:OutputPort;
|
||||||
|
lv2:index 2;
|
||||||
|
lv2:symbol "right";
|
||||||
|
lv2:name "Right";
|
||||||
|
].
|
208
drmr_hydrogen.c
Normal file
208
drmr_hydrogen.c
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
/*
|
||||||
|
LV2 DrMr plugin
|
||||||
|
Copyright 2012 Nick Lanham <nick@afternight.org>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Utilities for loading up a hydrogen kit
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "drmr.h"
|
||||||
|
#include "drmr_hydrogen.h"
|
||||||
|
#include "expat.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_CHAR_DATA 512
|
||||||
|
|
||||||
|
struct instrument_info {
|
||||||
|
int id;
|
||||||
|
char* filename;
|
||||||
|
char* name;
|
||||||
|
struct instrument_info* next;
|
||||||
|
// maybe pan/vol/etc..
|
||||||
|
};
|
||||||
|
|
||||||
|
struct kit_info {
|
||||||
|
char* name;
|
||||||
|
char* desc;
|
||||||
|
// linked list of intruments, null terminated
|
||||||
|
struct instrument_info* instruments;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hp_info {
|
||||||
|
char in_info;
|
||||||
|
char in_instrument_list;
|
||||||
|
char in_instrument;
|
||||||
|
int cur_off;
|
||||||
|
char cur_buf[MAX_CHAR_DATA];
|
||||||
|
struct instrument_info* cur_instrument;
|
||||||
|
struct kit_info* kit_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void XMLCALL
|
||||||
|
startElement(void *userData, const char *name, const char **atts)
|
||||||
|
{
|
||||||
|
struct hp_info* info = (struct hp_info*)userData;
|
||||||
|
info->cur_off = 0;
|
||||||
|
if (info->in_info) {
|
||||||
|
if (info->in_instrument_list) {
|
||||||
|
if (!strcmp(name,"instrument")) {
|
||||||
|
info->in_instrument = 1;
|
||||||
|
info->cur_instrument = malloc(sizeof(struct instrument_info));
|
||||||
|
memset(info->cur_instrument,0,sizeof(struct instrument_info));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!strcmp(name,"instrumentList"))
|
||||||
|
info->in_instrument_list = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!strcmp(name,"drumkit_info"))
|
||||||
|
info->in_info = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void XMLCALL
|
||||||
|
endElement(void *userData, const char *name)
|
||||||
|
{
|
||||||
|
struct hp_info* info = (struct hp_info*)userData;
|
||||||
|
info->cur_buf[info->cur_off]='\0';
|
||||||
|
|
||||||
|
if (info->in_info && !info->in_instrument_list && !strcmp(name,"name"))
|
||||||
|
info->kit_info->name = strdup(info->cur_buf);
|
||||||
|
|
||||||
|
if (info->in_instrument) {
|
||||||
|
if (!strcmp(name,"id"))
|
||||||
|
info->cur_instrument->id = atoi(info->cur_buf);
|
||||||
|
if (!strcmp(name,"filename"))
|
||||||
|
info->cur_instrument->filename = strdup(info->cur_buf);
|
||||||
|
if (!strcmp(name,"name"))
|
||||||
|
info->cur_instrument->name = strdup(info->cur_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
info->cur_off = 0;
|
||||||
|
|
||||||
|
if (info->in_instrument && !strcmp(name,"instrument")) {
|
||||||
|
// ending an instrument, add current struct to end of list
|
||||||
|
struct instrument_info * cur_i = info->kit_info->instruments;
|
||||||
|
if (cur_i) {
|
||||||
|
while(cur_i->next) cur_i = cur_i->next;
|
||||||
|
cur_i->next = info->cur_instrument;
|
||||||
|
} else
|
||||||
|
info->kit_info->instruments = info->cur_instrument;
|
||||||
|
info->cur_instrument = NULL;
|
||||||
|
info->in_instrument = 0;
|
||||||
|
}
|
||||||
|
if (info->in_instrument_list && !strcmp(name,"instrumentList")) info->in_instrument_list = 0;
|
||||||
|
if (info->in_info && !strcmp(name,"drumkit_info")) info->in_info = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void XMLCALL
|
||||||
|
charData(void *userData,
|
||||||
|
const char* data,
|
||||||
|
int len) {
|
||||||
|
int i;
|
||||||
|
struct hp_info* info = (struct hp_info*)userData;
|
||||||
|
for(i = 0;i<len;i++) {
|
||||||
|
if (info->cur_off < MAX_CHAR_DATA) {
|
||||||
|
info->cur_buf[info->cur_off] = data[i];
|
||||||
|
info->cur_off++;
|
||||||
|
} else
|
||||||
|
fprintf(stderr,"Warning, losing data because too much\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int load_hydrogen_kit(DrMr* drmr, char* path) {
|
||||||
|
char* fp_buf;
|
||||||
|
FILE* file;
|
||||||
|
char buf[BUFSIZ];
|
||||||
|
XML_Parser parser;
|
||||||
|
int done;
|
||||||
|
struct hp_info info;
|
||||||
|
struct kit_info kit_info;
|
||||||
|
|
||||||
|
snprintf(buf,BUFSIZ,"%s/drumkit.xml",path);
|
||||||
|
|
||||||
|
printf("trying to load: %s\n",buf);
|
||||||
|
|
||||||
|
file = fopen(buf,"r");
|
||||||
|
if (!file) {
|
||||||
|
perror("Unable to open file:");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
parser = XML_ParserCreate(NULL);
|
||||||
|
memset(&info,0,sizeof(struct hp_info));
|
||||||
|
memset(&kit_info,0,sizeof(struct kit_info));
|
||||||
|
|
||||||
|
info.kit_info = &kit_info;
|
||||||
|
|
||||||
|
XML_SetUserData(parser, &info);
|
||||||
|
XML_SetElementHandler(parser, startElement, endElement);
|
||||||
|
XML_SetCharacterDataHandler(parser, charData);
|
||||||
|
|
||||||
|
do {
|
||||||
|
int len = (int)fread(buf, 1, sizeof(buf), file);
|
||||||
|
done = len < sizeof(buf);
|
||||||
|
if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s at line %lu\n",
|
||||||
|
XML_ErrorString(XML_GetErrorCode(parser)),
|
||||||
|
XML_GetCurrentLineNumber(parser));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} while (!done);
|
||||||
|
XML_ParserFree(parser);
|
||||||
|
|
||||||
|
{
|
||||||
|
drmr_sample* samples;
|
||||||
|
struct instrument_info * cur_i;
|
||||||
|
int i = 0, num_inst = 0;
|
||||||
|
printf("Read kit: %s\n",kit_info.name);
|
||||||
|
cur_i = kit_info.instruments;
|
||||||
|
while(cur_i) { // first count how many samples we have
|
||||||
|
num_inst ++;
|
||||||
|
cur_i = cur_i->next;
|
||||||
|
}
|
||||||
|
printf("Loading %i instruments\n",num_inst);
|
||||||
|
samples = malloc(num_inst*sizeof(drmr_sample));
|
||||||
|
cur_i = kit_info.instruments;
|
||||||
|
while(cur_i) {
|
||||||
|
snprintf(buf,BUFSIZ,"%s/%s",path,cur_i->filename);
|
||||||
|
if (load_sample(buf,samples+i)) {
|
||||||
|
fprintf(stderr,"Could not load sample: %s\n",buf);
|
||||||
|
// TODO: Memory leak on previously loaded samples
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
cur_i = cur_i->next;
|
||||||
|
}
|
||||||
|
if (num_inst > drmr->num_samples) {
|
||||||
|
// we have more, so we can safely swap our sample list in before updating num_samples
|
||||||
|
drmr->samples = samples;
|
||||||
|
drmr->num_samples = num_inst;
|
||||||
|
} else {
|
||||||
|
// previous has more, update count first
|
||||||
|
drmr->num_samples = num_inst;
|
||||||
|
drmr->samples = samples;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
6
drmr_hydrogen.h
Normal file
6
drmr_hydrogen.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef DRMR_HYDRO_H
|
||||||
|
#define DRMR_HYDRO_H
|
||||||
|
|
||||||
|
int load_hydrogen_kit(DrMr* drmr, char* path);
|
||||||
|
|
||||||
|
#endif // DRMR_HYDRO_H
|
5
manifest.ttl
Normal file
5
manifest.ttl
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#>.
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
|
||||||
|
<http://github.com/nicklan/drmr>
|
||||||
|
a lv2:Plugin;
|
||||||
|
rdfs:seeAlso <drmr.ttl>.
|
Loading…
Reference in New Issue
Block a user