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)
|
cp manifest.ttl drmr.ttl drmr.so drmr_ui.so $(BUNDLE)
|
||||||
|
|
||||||
drmr.so: drmr.c drmr_hydrogen.c
|
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
|
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)
|
install: $(BUNDLE)
|
||||||
mkdir -p $(INSTALL_DIR)
|
mkdir -p $(INSTALL_DIR)
|
||||||
|
@ -28,6 +28,7 @@ Compilation and Install
|
|||||||
You'll need the following libraries to build and install DrMr:
|
You'll need the following libraries to build and install DrMr:
|
||||||
|
|
||||||
- [libsndfile](http://www.mega-nerd.com/libsndfile/)
|
- [libsndfile](http://www.mega-nerd.com/libsndfile/)
|
||||||
|
- [libsamplerate](http://www.mega-nerd.com/SRC/index.html)
|
||||||
- [lv2](http://lv2plug.in/)
|
- [lv2](http://lv2plug.in/)
|
||||||
- [libexpat](http://expat.sourceforge.net)
|
- [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* drmr = malloc(sizeof(DrMr));
|
||||||
drmr->map = NULL;
|
drmr->map = NULL;
|
||||||
drmr->num_samples = 0;
|
drmr->num_samples = 0;
|
||||||
|
drmr->rate = rate;
|
||||||
|
|
||||||
if (pthread_mutex_init(&drmr->load_mutex, 0)) {
|
if (pthread_mutex_init(&drmr->load_mutex, 0)) {
|
||||||
fprintf(stderr, "Could not initialize load_mutex.\n");
|
fprintf(stderr, "Could not initialize load_mutex.\n");
|
||||||
|
1
drmr.h
1
drmr.h
@ -147,6 +147,7 @@ typedef struct {
|
|||||||
float** gains;
|
float** gains;
|
||||||
float** pans;
|
float** pans;
|
||||||
float* kitReq;
|
float* kitReq;
|
||||||
|
double rate;
|
||||||
|
|
||||||
// URIs
|
// URIs
|
||||||
LV2_URI_Map_Feature* map;
|
LV2_URI_Map_Feature* map;
|
||||||
|
@ -22,7 +22,9 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "samplerate.h"
|
||||||
#include "drmr.h"
|
#include "drmr.h"
|
||||||
#include "drmr_hydrogen.h"
|
#include "drmr_hydrogen.h"
|
||||||
#include "expat.h"
|
#include "expat.h"
|
||||||
@ -36,6 +38,8 @@ static char* default_drumkit_locations[] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define RATE_CONV_QUALITY SRC_SINC_MEDIUM_QUALITY
|
||||||
|
|
||||||
#define MAX_CHAR_DATA 512
|
#define MAX_CHAR_DATA 512
|
||||||
|
|
||||||
struct instrument_layer {
|
struct instrument_layer {
|
||||||
@ -339,9 +343,9 @@ void free_kits(kits* kits) {
|
|||||||
free(kits);
|
free(kits);
|
||||||
}
|
}
|
||||||
|
|
||||||
int load_sample(char* path, drmr_layer* layer) {
|
int load_sample(char* path, drmr_layer* layer, double target_rate) {
|
||||||
SNDFILE* sndf;
|
SNDFILE* sndf;
|
||||||
int size;
|
long size;
|
||||||
|
|
||||||
//printf("Loading: %s\n",path);
|
//printf("Loading: %s\n",path);
|
||||||
|
|
||||||
@ -360,6 +364,7 @@ int load_sample(char* path, drmr_layer* layer) {
|
|||||||
free(layer->info);
|
free(layer->info);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = layer->info->frames * layer->info->channels;
|
size = layer->info->frames * layer->info->channels;
|
||||||
layer->limit = size;
|
layer->limit = size;
|
||||||
layer->data = malloc(size*sizeof(float));
|
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_read_float(sndf,layer->data,size);
|
||||||
sf_close(sndf);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,7 +475,7 @@ int load_hydrogen_kit(DrMr* drmr, char* path) {
|
|||||||
layer->min = 0;
|
layer->min = 0;
|
||||||
layer->max = 1;
|
layer->max = 1;
|
||||||
snprintf(buf,BUFSIZ,"%s/%s",path,cur_i->filename);
|
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);
|
fprintf(stderr,"Could not load sample: %s\n",buf);
|
||||||
// set limit to zero, will never try and play
|
// set limit to zero, will never try and play
|
||||||
layer->info = NULL;
|
layer->info = NULL;
|
||||||
@ -463,7 +503,7 @@ int load_hydrogen_kit(DrMr* drmr, char* path) {
|
|||||||
j = 0;
|
j = 0;
|
||||||
while(cur_l) {
|
while(cur_l) {
|
||||||
snprintf(buf,BUFSIZ,"%s/%s",path,cur_l->filename);
|
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);
|
fprintf(stderr,"Could not load sample: %s\n",buf);
|
||||||
// set limit to zero, will never try and play
|
// set limit to zero, will never try and play
|
||||||
samples[i].layers[j].info = NULL;
|
samples[i].layers[j].info = NULL;
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
kits* scan_kits();
|
kits* scan_kits();
|
||||||
void free_samples(drmr_sample* samples, int num_samples);
|
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);
|
int load_hydrogen_kit(DrMr* drmr, char* path);
|
||||||
|
|
||||||
#endif // DRMR_HYDRO_H
|
#endif // DRMR_HYDRO_H
|
||||||
|
Loading…
Reference in New Issue
Block a user