Use libsamplerate to convert samples not at the same rate as the plugin is running at
This adds a dependency on libsamplerate
This commit is contained in:
parent
645a4b497c
commit
48bf1f33b9
4
Makefile
4
Makefile
@ -8,10 +8,10 @@ $(BUNDLE): manifest.ttl drmr.ttl drmr.so drmr_ui.so
|
||||
cp manifest.ttl drmr.ttl drmr.so drmr_ui.so $(BUNDLE)
|
||||
|
||||
drmr.so: drmr.c drmr_hydrogen.c
|
||||
$(CC) -shared -fPIC -DPIC drmr.c drmr_hydrogen.c `pkg-config --cflags --libs lv2-plugin sndfile` -lexpat -lm -o drmr.so
|
||||
$(CC) -shared -fPIC -DPIC drmr.c drmr_hydrogen.c `pkg-config --cflags --libs lv2-plugin sndfile samplerate` -lexpat -lm -o drmr.so
|
||||
|
||||
drmr_ui.so: drmr_ui.c drmr_hydrogen.c
|
||||
$(CC) -shared -fPIC -DPIC drmr_ui.c drmr_hydrogen.c `pkg-config --cflags --libs lv2-plugin gtk+-2.0 sndfile` -lexpat -lm -o drmr_ui.so
|
||||
$(CC) -shared -fPIC -DPIC drmr_ui.c drmr_hydrogen.c `pkg-config --cflags --libs lv2-plugin gtk+-2.0 sndfile samplerate` -lexpat -lm -o drmr_ui.so
|
||||
|
||||
install: $(BUNDLE)
|
||||
mkdir -p $(INSTALL_DIR)
|
||||
|
@ -28,6 +28,7 @@ Compilation and Install
|
||||
You'll need the following libraries to build and install DrMr:
|
||||
|
||||
- [libsndfile](http://www.mega-nerd.com/libsndfile/)
|
||||
- [libsamplerate](http://www.mega-nerd.com/SRC/index.html)
|
||||
- [lv2](http://lv2plug.in/)
|
||||
- [libexpat](http://expat.sourceforge.net)
|
||||
|
||||
|
1
drmr.c
1
drmr.c
@ -52,6 +52,7 @@ instantiate(const LV2_Descriptor* descriptor,
|
||||
DrMr* drmr = malloc(sizeof(DrMr));
|
||||
drmr->map = NULL;
|
||||
drmr->num_samples = 0;
|
||||
drmr->rate = rate;
|
||||
|
||||
if (pthread_mutex_init(&drmr->load_mutex, 0)) {
|
||||
fprintf(stderr, "Could not initialize load_mutex.\n");
|
||||
|
1
drmr.h
1
drmr.h
@ -147,6 +147,7 @@ typedef struct {
|
||||
float** gains;
|
||||
float** pans;
|
||||
float* kitReq;
|
||||
double rate;
|
||||
|
||||
// URIs
|
||||
LV2_URI_Map_Feature* map;
|
||||
|
@ -22,7 +22,9 @@
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "samplerate.h"
|
||||
#include "drmr.h"
|
||||
#include "drmr_hydrogen.h"
|
||||
#include "expat.h"
|
||||
@ -36,6 +38,8 @@ static char* default_drumkit_locations[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
#define RATE_CONV_QUALITY SRC_SINC_MEDIUM_QUALITY
|
||||
|
||||
#define MAX_CHAR_DATA 512
|
||||
|
||||
struct instrument_layer {
|
||||
@ -339,9 +343,9 @@ void free_kits(kits* kits) {
|
||||
free(kits);
|
||||
}
|
||||
|
||||
int load_sample(char* path, drmr_layer* layer) {
|
||||
int load_sample(char* path, drmr_layer* layer, double target_rate) {
|
||||
SNDFILE* sndf;
|
||||
int size;
|
||||
long size;
|
||||
|
||||
//printf("Loading: %s\n",path);
|
||||
|
||||
@ -360,6 +364,7 @@ int load_sample(char* path, drmr_layer* layer) {
|
||||
free(layer->info);
|
||||
return 1;
|
||||
}
|
||||
|
||||
size = layer->info->frames * layer->info->channels;
|
||||
layer->limit = size;
|
||||
layer->data = malloc(size*sizeof(float));
|
||||
@ -371,6 +376,41 @@ int load_sample(char* path, drmr_layer* layer) {
|
||||
|
||||
sf_read_float(sndf,layer->data,size);
|
||||
sf_close(sndf);
|
||||
|
||||
// convert rate if needed
|
||||
if (layer->info->samplerate != target_rate) {
|
||||
SRC_DATA src_data;
|
||||
int stat;
|
||||
double ratio = (target_rate/layer->info->samplerate);
|
||||
long out_frames = (long)ceil(layer->info->frames * ratio);
|
||||
long out_size = out_frames*layer->info->channels;
|
||||
float *data_out = malloc(sizeof(float)*out_size);
|
||||
|
||||
src_data.data_in = layer->data;
|
||||
src_data.input_frames = layer->info->frames;
|
||||
src_data.data_out = data_out;
|
||||
src_data.output_frames = out_frames;
|
||||
src_data.src_ratio = ratio;
|
||||
|
||||
stat = src_simple(&src_data,RATE_CONV_QUALITY,layer->info->channels);
|
||||
if (stat) {
|
||||
fprintf(stderr,"Failed to convert rate for %s: %s. Using original rate\n",
|
||||
path,src_strerror(stat));
|
||||
free(data_out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (src_data.input_frames_used != layer->info->frames)
|
||||
fprintf(stderr,"Didn't consume all input frames. used: %i had: %i gened: %i\n",
|
||||
src_data.input_frames_used, layer->info->frames,src_data.output_frames_gen);
|
||||
|
||||
free(layer->data);
|
||||
|
||||
layer->data = data_out;
|
||||
layer->limit = src_data.output_frames_gen*layer->info->channels;
|
||||
layer->info->samplerate = target_rate;
|
||||
layer->info->frames = src_data.output_frames_gen;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -435,7 +475,7 @@ int load_hydrogen_kit(DrMr* drmr, char* path) {
|
||||
layer->min = 0;
|
||||
layer->max = 1;
|
||||
snprintf(buf,BUFSIZ,"%s/%s",path,cur_i->filename);
|
||||
if (load_sample(buf,layer)) {
|
||||
if (load_sample(buf,layer,drmr->rate)) {
|
||||
fprintf(stderr,"Could not load sample: %s\n",buf);
|
||||
// set limit to zero, will never try and play
|
||||
layer->info = NULL;
|
||||
@ -463,7 +503,7 @@ int load_hydrogen_kit(DrMr* drmr, char* path) {
|
||||
j = 0;
|
||||
while(cur_l) {
|
||||
snprintf(buf,BUFSIZ,"%s/%s",path,cur_l->filename);
|
||||
if (load_sample(buf,samples[i].layers+j)) {
|
||||
if (load_sample(buf,samples[i].layers+j,drmr->rate)) {
|
||||
fprintf(stderr,"Could not load sample: %s\n",buf);
|
||||
// set limit to zero, will never try and play
|
||||
samples[i].layers[j].info = NULL;
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
kits* scan_kits();
|
||||
void free_samples(drmr_sample* samples, int num_samples);
|
||||
int load_sample(char* path,drmr_layer* layer);
|
||||
int load_sample(char* path,drmr_layer* layer,double target_rate);
|
||||
int load_hydrogen_kit(DrMr* drmr, char* path);
|
||||
|
||||
#endif // DRMR_HYDRO_H
|
||||
|
Loading…
Reference in New Issue
Block a user