2012-02-07 12:52:59 +01:00
|
|
|
/* drmr_hydrogen.c
|
|
|
|
* LV2 DrMr plugin
|
|
|
|
* Copyright 2012 Nick Lanham <nick@afternight.org>
|
|
|
|
*
|
|
|
|
* Public License v3. source code is available at
|
|
|
|
* <http://github.com/nicklan/drmr>
|
2012-02-06 22:54:18 +01:00
|
|
|
|
2012-02-07 12:52:59 +01:00
|
|
|
* 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.
|
|
|
|
*/
|
2012-02-06 22:54:18 +01:00
|
|
|
|
|
|
|
// Utilities for loading up a hydrogen kit
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <ctype.h>
|
2012-02-07 10:59:24 +01:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <errno.h>
|
2012-02-06 22:54:18 +01:00
|
|
|
|
|
|
|
#include "drmr.h"
|
|
|
|
#include "drmr_hydrogen.h"
|
|
|
|
#include "expat.h"
|
|
|
|
|
2012-02-07 10:59:24 +01:00
|
|
|
static char* default_drumkit_locations[] = {
|
|
|
|
"/usr/share/hydrogen/data/drumkits/",
|
|
|
|
"/usr/local/share/hydrogen/data/drumkits/",
|
|
|
|
"~/.hydrogen/data/drumkits/",
|
|
|
|
NULL
|
|
|
|
};
|
2012-02-06 22:54:18 +01:00
|
|
|
|
|
|
|
#define MAX_CHAR_DATA 512
|
|
|
|
|
2012-02-13 12:57:32 +01:00
|
|
|
struct instrument_layer {
|
|
|
|
char* filename;
|
2012-02-13 16:11:30 +01:00
|
|
|
float min;
|
|
|
|
float max;
|
|
|
|
float gain;
|
2012-02-13 12:57:32 +01:00
|
|
|
struct instrument_layer *next;
|
|
|
|
};
|
|
|
|
|
2012-02-06 22:54:18 +01:00
|
|
|
struct instrument_info {
|
|
|
|
int id;
|
|
|
|
char* filename;
|
|
|
|
char* name;
|
2012-02-13 16:11:30 +01:00
|
|
|
float gain;
|
2012-02-13 12:57:32 +01:00
|
|
|
struct instrument_layer *layers;
|
|
|
|
struct instrument_info *next;
|
2012-02-06 22:54:18 +01:00
|
|
|
// maybe pan/vol/etc..
|
|
|
|
};
|
|
|
|
|
|
|
|
struct kit_info {
|
|
|
|
char* name;
|
|
|
|
char* desc;
|
2012-02-13 11:24:26 +01:00
|
|
|
int inst_count;
|
2012-02-06 22:54:18 +01:00
|
|
|
// linked list of intruments, null terminated
|
|
|
|
struct instrument_info* instruments;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct hp_info {
|
2012-02-07 10:59:24 +01:00
|
|
|
char scan_only;
|
2012-02-06 22:54:18 +01:00
|
|
|
char in_info;
|
|
|
|
char in_instrument_list;
|
|
|
|
char in_instrument;
|
2012-02-13 12:57:32 +01:00
|
|
|
char in_layer;
|
|
|
|
char counted_cur_inst;
|
2012-02-06 22:54:18 +01:00
|
|
|
int cur_off;
|
|
|
|
char cur_buf[MAX_CHAR_DATA];
|
|
|
|
struct instrument_info* cur_instrument;
|
2012-02-13 12:57:32 +01:00
|
|
|
struct instrument_layer* cur_layer;
|
2012-02-06 22:54:18 +01:00
|
|
|
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) {
|
2012-02-13 12:57:32 +01:00
|
|
|
if (info->in_instrument) {
|
|
|
|
if (!strcmp(name,"layer") && !info->scan_only) {
|
|
|
|
info->in_layer = 1;
|
|
|
|
info->cur_layer = malloc(sizeof(struct instrument_layer));
|
|
|
|
memset(info->cur_layer,0,sizeof(struct instrument_layer));
|
|
|
|
}
|
|
|
|
}
|
2012-02-06 22:54:18 +01:00
|
|
|
if (info->in_instrument_list) {
|
|
|
|
if (!strcmp(name,"instrument")) {
|
|
|
|
info->in_instrument = 1;
|
2012-02-07 10:59:24 +01:00
|
|
|
if (!info->scan_only) {
|
|
|
|
info->cur_instrument = malloc(sizeof(struct instrument_info));
|
|
|
|
memset(info->cur_instrument,0,sizeof(struct instrument_info));
|
|
|
|
}
|
2012-02-06 22:54:18 +01:00
|
|
|
}
|
|
|
|
} 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;
|
2012-02-07 10:59:24 +01:00
|
|
|
if (info->cur_off == MAX_CHAR_DATA) info->cur_off--;
|
2012-02-06 22:54:18 +01:00
|
|
|
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);
|
2012-02-07 10:59:24 +01:00
|
|
|
if (info->scan_only && info->in_info && !info->in_instrument_list && !strcmp(name,"info"))
|
|
|
|
info->kit_info->desc = strdup(info->cur_buf);
|
2012-02-06 22:54:18 +01:00
|
|
|
|
2012-02-13 12:57:32 +01:00
|
|
|
if (info->in_layer && !info->scan_only) {
|
|
|
|
if (!strcmp(name,"filename"))
|
|
|
|
info->cur_layer->filename = strdup(info->cur_buf);
|
|
|
|
if (!strcmp(name,"min"))
|
2012-02-13 16:11:30 +01:00
|
|
|
info->cur_layer->min = atof(info->cur_buf);
|
2012-02-13 12:57:32 +01:00
|
|
|
if (!strcmp(name,"max"))
|
2012-02-13 16:11:30 +01:00
|
|
|
info->cur_layer->max = atof(info->cur_buf);
|
2012-02-13 12:57:32 +01:00
|
|
|
if (!strcmp(name,"gain"))
|
2012-02-13 16:11:30 +01:00
|
|
|
info->cur_layer->gain = atof(info->cur_buf);
|
2012-02-13 12:57:32 +01:00
|
|
|
}
|
|
|
|
|
2012-02-13 11:24:26 +01:00
|
|
|
if (info->in_instrument) {
|
|
|
|
if (info->scan_only) {
|
2012-02-13 12:57:32 +01:00
|
|
|
if (!strcmp(name,"filename") && !info->counted_cur_inst) {
|
2012-02-13 11:24:26 +01:00
|
|
|
info->kit_info->inst_count++;
|
2012-02-13 12:57:32 +01:00
|
|
|
info->counted_cur_inst = 1;
|
|
|
|
}
|
2012-02-13 11:24:26 +01:00
|
|
|
}
|
2012-02-13 16:11:30 +01:00
|
|
|
else if (!info->in_layer) {
|
2012-02-13 11:24:26 +01:00
|
|
|
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);
|
|
|
|
}
|
2012-02-06 22:54:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
info->cur_off = 0;
|
|
|
|
|
2012-02-13 12:57:32 +01:00
|
|
|
if (!info->scan_only &&
|
|
|
|
info->in_layer &&
|
|
|
|
!strcmp(name,"layer") &&
|
|
|
|
info->cur_layer->filename) {
|
|
|
|
struct instrument_layer *cur_l = info->cur_instrument->layers;
|
|
|
|
if (cur_l) {
|
|
|
|
while(cur_l->next) cur_l = cur_l->next;
|
|
|
|
cur_l->next = info->cur_layer;
|
|
|
|
} else
|
|
|
|
info->cur_instrument->layers = info->cur_layer;
|
|
|
|
info->cur_layer = NULL;
|
|
|
|
info->in_layer = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (info->scan_only && info->in_instrument && !strcmp(name,"instrument")) {
|
|
|
|
info->counted_cur_inst = 0;
|
|
|
|
info->in_instrument = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!info->scan_only && info->in_instrument &&
|
|
|
|
(info->cur_instrument && (info->cur_instrument->filename || info->cur_instrument->layers)) &&
|
|
|
|
!strcmp(name,"instrument")) {
|
2012-02-06 22:54:18 +01:00
|
|
|
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;
|
2012-02-07 10:59:24 +01:00
|
|
|
if (!info->in_info) return;
|
2012-02-06 22:54:18 +01:00
|
|
|
for(i = 0;i<len;i++) {
|
|
|
|
if (info->cur_off < MAX_CHAR_DATA) {
|
|
|
|
info->cur_buf[info->cur_off] = data[i];
|
|
|
|
info->cur_off++;
|
2012-02-07 10:59:24 +01:00
|
|
|
}
|
2012-02-06 22:54:18 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-07 10:59:24 +01:00
|
|
|
struct kit_list {
|
|
|
|
scanned_kit* skit;
|
|
|
|
struct kit_list* next;
|
|
|
|
};
|
|
|
|
|
|
|
|
kits* scan_kits() {
|
|
|
|
DIR* dp;
|
|
|
|
FILE* file;
|
|
|
|
XML_Parser parser;
|
|
|
|
int done;
|
|
|
|
struct hp_info info;
|
|
|
|
struct kit_info kit_info;
|
|
|
|
struct dirent *ep;
|
|
|
|
int cp = 0;
|
|
|
|
char* cur_path = default_drumkit_locations[cp++];
|
|
|
|
kits* ret = malloc(sizeof(kits));
|
|
|
|
struct kit_list* scanned_kits = NULL,*cur_kit;
|
|
|
|
char buf[BUFSIZ];
|
|
|
|
|
|
|
|
ret->num_kits = 0;
|
|
|
|
|
|
|
|
while (cur_path) {
|
|
|
|
dp = opendir (cur_path);
|
|
|
|
if (dp != NULL) {
|
|
|
|
while (ep = readdir (dp)) {
|
|
|
|
if (ep->d_name[0]=='.') continue;
|
|
|
|
if (snprintf(buf,BUFSIZ,"%s/%s/drumkit.xml",cur_path,ep->d_name) >= BUFSIZ) {
|
|
|
|
fprintf(stderr,"Warning: Skipping scan of %s as path name is too long\n",cur_path);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
file = fopen(buf,"r");
|
|
|
|
if (!file) continue; // couldn't open file
|
|
|
|
parser = XML_ParserCreate(NULL);
|
|
|
|
memset(&info,0,sizeof(struct hp_info));
|
|
|
|
memset(&kit_info,0,sizeof(struct kit_info));
|
|
|
|
info.kit_info = &kit_info;
|
|
|
|
info.scan_only = 1;
|
|
|
|
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));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (!done);
|
|
|
|
XML_ParserFree(parser);
|
|
|
|
if (info.kit_info->name) {
|
|
|
|
scanned_kit* kit = malloc(sizeof(scanned_kit));
|
|
|
|
struct kit_list* node = malloc(sizeof(struct kit_list));
|
|
|
|
memset(kit,0,sizeof(scanned_kit));
|
|
|
|
memset(node,0,sizeof(struct kit_list));
|
|
|
|
kit->name = info.kit_info->name;
|
|
|
|
kit->desc = info.kit_info->desc;
|
2012-02-13 11:24:26 +01:00
|
|
|
kit->samples = info.kit_info->inst_count;
|
2012-02-07 10:59:24 +01:00
|
|
|
snprintf(buf,BUFSIZ,"%s/%s/",cur_path,ep->d_name);
|
|
|
|
kit->path = strdup(buf);
|
|
|
|
node->skit = kit;
|
|
|
|
struct kit_list * cur_k = scanned_kits;
|
|
|
|
if (cur_k) {
|
|
|
|
while(cur_k->next) cur_k = cur_k->next;
|
|
|
|
cur_k->next = node;
|
|
|
|
} else
|
|
|
|
scanned_kits = node;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
(void) closedir (dp);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fprintf(stderr,"Couldn't open %s: %s\n",cur_path,strerror(errno));
|
|
|
|
cur_path = default_drumkit_locations[cp++];
|
|
|
|
}
|
|
|
|
|
|
|
|
// valid kits are in scanned_kits at this point
|
|
|
|
cp = 0;
|
|
|
|
struct kit_list * cur_k = scanned_kits;
|
|
|
|
while(cur_k) {
|
|
|
|
//printf("found kit: %s\nat:%s\n\n",cur_k->skit->name,cur_k->skit->path);
|
|
|
|
cur_k = cur_k->next;
|
|
|
|
cp++;
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("found %i kits\n",cp);
|
|
|
|
ret->num_kits = cp;
|
|
|
|
ret->kits = malloc(cp*sizeof(scanned_kit));
|
|
|
|
|
|
|
|
cur_k = scanned_kits;
|
|
|
|
cp = 0;
|
|
|
|
while(cur_k) {
|
|
|
|
ret->kits[cp].name = cur_k->skit->name;
|
|
|
|
ret->kits[cp].desc = cur_k->skit->desc;
|
|
|
|
ret->kits[cp].path = cur_k->skit->path;
|
2012-02-13 11:24:26 +01:00
|
|
|
ret->kits[cp].samples = cur_k->skit->samples;
|
2012-02-07 10:59:24 +01:00
|
|
|
cp++;
|
|
|
|
free(cur_k->skit);
|
|
|
|
cur_k = cur_k->next;
|
|
|
|
// free each node as we go along
|
|
|
|
free(scanned_kits);
|
|
|
|
scanned_kits = cur_k;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2012-02-06 22:54:18 +01:00
|
|
|
|
2012-02-07 12:22:26 +01:00
|
|
|
void free_samples(drmr_sample* samples, int num_samples) {
|
2012-02-13 16:11:30 +01:00
|
|
|
int i,j;
|
|
|
|
for (i=0;i<num_samples;i++) {
|
|
|
|
if (samples[i].layer_count == 0) {
|
|
|
|
if (samples[i].info) free(samples[i].info);
|
|
|
|
if (samples[i].data) free(samples[i].data);
|
|
|
|
} else {
|
|
|
|
for (j = 0;j < samples[i].layer_count;j++) {
|
|
|
|
if (samples[i].layers[j].info) free(samples[i].layers[j].info);
|
|
|
|
if (samples[i].layers[j].data) free(samples[i].layers[j].data);
|
|
|
|
}
|
|
|
|
free(samples[i].layers);
|
|
|
|
}
|
|
|
|
}
|
2012-02-07 12:00:07 +01:00
|
|
|
free(samples);
|
|
|
|
}
|
|
|
|
|
2012-02-13 16:11:30 +01:00
|
|
|
int load_sample(char* path, drmr_layer* layer) {
|
2012-02-07 21:33:20 +01:00
|
|
|
SNDFILE* sndf;
|
|
|
|
int size;
|
|
|
|
|
|
|
|
//printf("Loading: %s\n",path);
|
|
|
|
|
2012-02-13 16:11:30 +01:00
|
|
|
layer->info = malloc(sizeof(SF_INFO));
|
|
|
|
memset(layer->info,0,sizeof(SF_INFO));
|
|
|
|
sndf = sf_open(path,SFM_READ,layer->info);
|
2012-02-07 21:33:20 +01:00
|
|
|
|
|
|
|
if (!sndf) {
|
|
|
|
fprintf(stderr,"Failed to open sound file: %s - %s\n",path,sf_strerror(sndf));
|
2012-02-13 16:11:30 +01:00
|
|
|
free(layer->info);
|
2012-02-07 21:33:20 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2012-02-13 16:11:30 +01:00
|
|
|
if (layer->info->channels > 2) {
|
2012-02-07 21:33:20 +01:00
|
|
|
fprintf(stderr, "File has too many channels. Can only handle mono/stereo samples\n");
|
2012-02-13 16:11:30 +01:00
|
|
|
free(layer->info);
|
2012-02-07 21:33:20 +01:00
|
|
|
return 1;
|
|
|
|
}
|
2012-02-13 16:11:30 +01:00
|
|
|
size = layer->info->frames * layer->info->channels;
|
|
|
|
layer->limit = size;
|
|
|
|
layer->data = malloc(size*sizeof(float));
|
|
|
|
if (!layer->data) {
|
2012-02-07 21:33:20 +01:00
|
|
|
fprintf(stderr,"Failed to allocate sample memory for %s\n",path);
|
2012-02-13 16:11:30 +01:00
|
|
|
free(layer->info);
|
2012-02-07 21:33:20 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2012-02-13 16:11:30 +01:00
|
|
|
sf_read_float(sndf,layer->data,size);
|
2012-02-07 21:33:20 +01:00
|
|
|
sf_close(sndf);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-02-06 22:54:18 +01:00
|
|
|
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);
|
|
|
|
|
|
|
|
{
|
2012-02-07 12:00:07 +01:00
|
|
|
drmr_sample *samples, *old_samples;
|
2012-02-06 22:54:18 +01:00
|
|
|
struct instrument_info * cur_i;
|
2012-02-07 12:00:07 +01:00
|
|
|
int i = 0, num_inst = 0, old_scount;
|
2012-02-06 22:54:18 +01:00
|
|
|
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) {
|
2012-02-13 16:11:30 +01:00
|
|
|
if (cur_i->filename) { // top level filename, just make one dummy layer
|
|
|
|
drmr_layer *layer = malloc(sizeof(drmr_layer));
|
|
|
|
layer->min = 0;
|
|
|
|
layer->max = 1;
|
|
|
|
snprintf(buf,BUFSIZ,"%s/%s",path,cur_i->filename);
|
|
|
|
if (load_sample(buf,layer)) {
|
|
|
|
fprintf(stderr,"Could not load sample: %s\n",buf);
|
|
|
|
// set limit to zero, will never try and play
|
|
|
|
layer->info = NULL;
|
|
|
|
layer->limit = 0;
|
|
|
|
layer->data = NULL;
|
|
|
|
}
|
|
|
|
samples[i].layer_count = 0;
|
|
|
|
samples[i].layers = NULL;
|
2012-02-07 21:08:33 +01:00
|
|
|
samples[i].offset = 0;
|
2012-02-13 16:11:30 +01:00
|
|
|
samples[i].info = layer->info;
|
|
|
|
samples[i].limit = layer->limit;
|
|
|
|
samples[i].data = layer->data;
|
|
|
|
free(layer);
|
|
|
|
} else {
|
|
|
|
int layer_count = 0;
|
|
|
|
int j;
|
|
|
|
struct instrument_layer *cur_l = cur_i->layers;
|
|
|
|
while(cur_l) {
|
|
|
|
layer_count++;
|
|
|
|
cur_l = cur_l->next;
|
|
|
|
}
|
|
|
|
samples[i].layer_count = layer_count;
|
|
|
|
samples[i].layers = malloc(sizeof(drmr_layer)*layer_count);
|
|
|
|
cur_l = cur_i->layers;
|
|
|
|
j = 0;
|
|
|
|
while(cur_l) {
|
|
|
|
snprintf(buf,BUFSIZ,"%s/%s",path,cur_l->filename);
|
|
|
|
if (load_sample(buf,samples[i].layers+j)) {
|
|
|
|
fprintf(stderr,"Could not load sample: %s\n",buf);
|
|
|
|
// set limit to zero, will never try and play
|
|
|
|
samples[i].layers[j].info = NULL;
|
|
|
|
samples[i].layers[j].limit = 0;
|
|
|
|
samples[i].layers[j].data = NULL;
|
|
|
|
}
|
|
|
|
samples[i].layers[j].min = cur_l->min;
|
|
|
|
samples[i].layers[j].max = cur_l->max;
|
|
|
|
j++;
|
|
|
|
cur_l = cur_l->next;
|
|
|
|
}
|
2012-02-06 22:54:18 +01:00
|
|
|
}
|
2012-02-13 16:11:30 +01:00
|
|
|
samples[i].active = 0;
|
2012-02-06 22:54:18 +01:00
|
|
|
i++;
|
|
|
|
cur_i = cur_i->next;
|
|
|
|
}
|
2012-02-07 12:00:07 +01:00
|
|
|
old_samples = drmr->samples;
|
|
|
|
old_scount = drmr->num_samples;
|
2012-02-06 22:54:18 +01:00
|
|
|
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;
|
|
|
|
}
|
2012-02-07 12:00:07 +01:00
|
|
|
if (old_samples) free_samples(old_samples,old_scount);
|
2012-02-06 22:54:18 +01:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|