#include "fluid_ramsfont.h"
#include "fluid_sys.h"
#include "fluid_synth.h"
#define SAMPLE_LOOP_MARGIN 8
int fluid_rampreset_add_sample(fluid_rampreset_t* preset, fluid_sample_t* sample, int lokey, int hikey);
int fluid_rampreset_izone_set_gen(fluid_rampreset_t* preset, fluid_sample_t* sample, int gen_type, float value);
int fluid_rampreset_izone_set_loop(fluid_rampreset_t* preset, fluid_sample_t* sample, int on, float loopstart, float loopend);
int fluid_rampreset_remove_izone(fluid_rampreset_t* preset, fluid_sample_t* sample);
void fluid_rampreset_updatevoices(fluid_rampreset_t* preset, int gen_type, float val);
fluid_sfont_t*
fluid_ramsfont_create_sfont()
{
fluid_sfont_t* sfont;
fluid_ramsfont_t* ramsfont;
ramsfont = new_fluid_ramsfont();
if (ramsfont == NULL) {
return NULL;
}
sfont = FLUID_NEW(fluid_sfont_t);
if (sfont == NULL) {
FLUID_LOG(FLUID_ERR, "Out of memory");
return NULL;
}
sfont->data = ramsfont;
sfont->free = fluid_ramsfont_sfont_delete;
sfont->get_name = fluid_ramsfont_sfont_get_name;
sfont->get_preset = fluid_ramsfont_sfont_get_preset;
sfont->iteration_start = fluid_ramsfont_sfont_iteration_start;
sfont->iteration_next = fluid_ramsfont_sfont_iteration_next;
return sfont;
}
int fluid_ramsfont_sfont_delete(fluid_sfont_t* sfont)
{
if (delete_fluid_ramsfont(sfont->data) != 0)
return -1;
FLUID_FREE(sfont);
return 0;
}
char* fluid_ramsfont_sfont_get_name(fluid_sfont_t* sfont)
{
return fluid_ramsfont_get_name((fluid_ramsfont_t*) sfont->data);
}
fluid_preset_t* fluid_ramsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum)
{
fluid_preset_t* preset;
fluid_rampreset_t* rampreset;
rampreset = fluid_ramsfont_get_preset((fluid_ramsfont_t*) sfont->data, bank, prenum);
if (rampreset == NULL) {
return NULL;
}
preset = FLUID_NEW(fluid_preset_t);
if (preset == NULL) {
FLUID_LOG(FLUID_ERR, "Out of memory");
return NULL;
}
preset->sfont = sfont;
preset->data = rampreset;
preset->free = fluid_rampreset_preset_delete;
preset->get_name = fluid_rampreset_preset_get_name;
preset->get_banknum = fluid_rampreset_preset_get_banknum;
preset->get_num = fluid_rampreset_preset_get_num;
preset->noteon = fluid_rampreset_preset_noteon;
preset->notify = NULL;
return preset;
}
void fluid_ramsfont_sfont_iteration_start(fluid_sfont_t* sfont)
{
fluid_ramsfont_iteration_start((fluid_ramsfont_t*) sfont->data);
}
int fluid_ramsfont_sfont_iteration_next(fluid_sfont_t* sfont, fluid_preset_t* preset)
{
preset->free = fluid_rampreset_preset_delete;
preset->get_name = fluid_rampreset_preset_get_name;
preset->get_banknum = fluid_rampreset_preset_get_banknum;
preset->get_num = fluid_rampreset_preset_get_num;
preset->noteon = fluid_rampreset_preset_noteon;
preset->notify = NULL;
return fluid_ramsfont_iteration_next((fluid_ramsfont_t*) sfont->data, preset);
}
int fluid_rampreset_preset_delete(fluid_preset_t* preset)
{
FLUID_FREE(preset);
return 0;
}
char* fluid_rampreset_preset_get_name(fluid_preset_t* preset)
{
return fluid_rampreset_get_name((fluid_rampreset_t*) preset->data);
}
int fluid_rampreset_preset_get_banknum(fluid_preset_t* preset)
{
return fluid_rampreset_get_banknum((fluid_rampreset_t*) preset->data);
}
int fluid_rampreset_preset_get_num(fluid_preset_t* preset)
{
return fluid_rampreset_get_num((fluid_rampreset_t*) preset->data);
}
int fluid_rampreset_preset_noteon(fluid_preset_t* preset, fluid_synth_t* synth, int chan, int key, int vel)
{
return fluid_rampreset_noteon((fluid_rampreset_t*) preset->data, synth, chan, key, vel);
}
fluid_ramsfont_t* new_fluid_ramsfont()
{
fluid_ramsfont_t* sfont;
sfont = FLUID_NEW(fluid_ramsfont_t);
if (sfont == NULL) {
FLUID_LOG(FLUID_ERR, "Out of memory");
return NULL;
}
sfont->name[0] = 0;
sfont->sample = NULL;
sfont->preset = NULL;
return sfont;
}
int delete_fluid_ramsfont(fluid_ramsfont_t* sfont)
{
fluid_list_t *list;
fluid_rampreset_t* preset;
for (list = sfont->sample; list; list = fluid_list_next(list)) {
fluid_sample_t* sam = (fluid_sample_t*) fluid_list_get(list);
if (fluid_sample_refcount(sam) != 0) {
return -1;
}
}
for (list = sfont->sample; list; list = fluid_list_next(list)) {
fluid_sample_t* sam = (fluid_sample_t*)fluid_list_get(list);
delete_fluid_ramsample(sam);
}
if (sfont->sample) {
delete_fluid_list(sfont->sample);
}
preset = sfont->preset;
while (preset != NULL) {
sfont->preset = preset->next;
delete_fluid_rampreset(preset);
preset = sfont->preset;
}
FLUID_FREE(sfont);
return FLUID_OK;
}
char* fluid_ramsfont_get_name(fluid_ramsfont_t* sfont)
{
return sfont->name;
}
int
fluid_ramsfont_set_name(fluid_ramsfont_t* sfont, char * name)
{
FLUID_MEMCPY(sfont->name, name, 20);
return FLUID_OK;
}
int fluid_ramsfont_add_preset(fluid_ramsfont_t* sfont, fluid_rampreset_t* preset)
{
fluid_rampreset_t *cur, *prev;
if (sfont->preset == NULL) {
preset->next = NULL;
sfont->preset = preset;
} else {
cur = sfont->preset;
prev = NULL;
while (cur != NULL) {
if ((preset->bank < cur->bank)
|| ((preset->bank == cur->bank) && (preset->num < cur->num))) {
if (prev == NULL) {
preset->next = cur;
sfont->preset = preset;
} else {
preset->next = cur;
prev->next = preset;
}
return FLUID_OK;
}
prev = cur;
cur = cur->next;
}
preset->next = NULL;
prev->next = preset;
}
return FLUID_OK;
}
int fluid_ramsfont_add_izone(fluid_ramsfont_t* sfont,
unsigned int bank, unsigned int num, fluid_sample_t* sample,
int lokey, int hikey)
{
int err;
fluid_rampreset_t* preset = fluid_ramsfont_get_preset(sfont, bank, num);
if (preset == NULL) {
preset = new_fluid_rampreset(sfont);
if (preset == NULL) {
return FLUID_FAILED;
}
preset->bank = bank;
preset->num = num;
err = fluid_rampreset_add_sample(preset, sample, lokey, hikey);
if (err != FLUID_OK) {
return FLUID_FAILED;
}
fluid_ramsfont_add_preset(sfont, preset);
} else {
err = fluid_rampreset_add_sample(preset, sample, lokey, hikey);
if (err != FLUID_OK) {
return FLUID_FAILED;
}
}
sfont->sample = fluid_list_append(sfont->sample, sample);
return FLUID_OK;
}
int fluid_ramsfont_remove_izone(fluid_ramsfont_t* sfont,
unsigned int bank, unsigned int num, fluid_sample_t* sample) {
int err;
fluid_rampreset_t* preset = fluid_ramsfont_get_preset(sfont, bank, num);
if (preset == NULL) {
return FLUID_FAILED;
}
err = fluid_rampreset_remove_izone(preset, sample);
if (err != FLUID_OK)
return err;
sfont->sample = fluid_list_remove(sfont->sample, sample);
return FLUID_OK;
}
int fluid_ramsfont_izone_set_gen(fluid_ramsfont_t* sfont,
unsigned int bank, unsigned int num, fluid_sample_t* sample,
int gen_type, float value) {
fluid_rampreset_t* preset = fluid_ramsfont_get_preset(sfont, bank, num);
if (preset == NULL) {
return FLUID_FAILED;
}
return fluid_rampreset_izone_set_gen(preset, sample, gen_type, value);
}
int fluid_ramsfont_izone_set_loop(fluid_ramsfont_t* sfont,
unsigned int bank, unsigned int num, fluid_sample_t* sample,
int on, float loopstart, float loopend) {
fluid_rampreset_t* preset = fluid_ramsfont_get_preset(sfont, bank, num);
if (preset == NULL) {
return FLUID_FAILED;
}
return fluid_rampreset_izone_set_loop(preset, sample, on, loopstart, loopend);
}
fluid_rampreset_t* fluid_ramsfont_get_preset(fluid_ramsfont_t* sfont, unsigned int bank, unsigned int num)
{
fluid_rampreset_t* preset = sfont->preset;
while (preset != NULL) {
if ((preset->bank == bank) && ((preset->num == num))) {
return preset;
}
preset = preset->next;
}
return NULL;
}
void fluid_ramsfont_iteration_start(fluid_ramsfont_t* sfont)
{
sfont->iter_cur = sfont->preset;
}
int fluid_ramsfont_iteration_next(fluid_ramsfont_t* sfont, fluid_preset_t* preset)
{
if (sfont->iter_cur == NULL) {
return 0;
}
preset->data = (void*) sfont->iter_cur;
sfont->iter_cur = fluid_rampreset_next(sfont->iter_cur);
return 1;
}
typedef struct _fluid_rampreset_voice_t fluid_rampreset_voice_t;
struct _fluid_rampreset_voice_t {
fluid_voice_t *voice;
unsigned int voiceID;
};
fluid_rampreset_t*
new_fluid_rampreset(fluid_ramsfont_t* sfont)
{
fluid_rampreset_t* preset = FLUID_NEW(fluid_rampreset_t);
if (preset == NULL) {
FLUID_LOG(FLUID_ERR, "Out of memory");
return NULL;
}
preset->next = NULL;
preset->sfont = sfont;
preset->name[0] = 0;
preset->bank = 0;
preset->num = 0;
preset->global_zone = NULL;
preset->zone = NULL;
preset->presetvoices = NULL;
return preset;
}
int
delete_fluid_rampreset(fluid_rampreset_t* preset)
{
int err = FLUID_OK;
fluid_preset_zone_t* zone;
fluid_rampreset_voice_t *data;
if (preset->global_zone != NULL) {
if (delete_fluid_preset_zone(preset->global_zone) != FLUID_OK) {
err = FLUID_FAILED;
}
preset->global_zone = NULL;
}
zone = preset->zone;
while (zone != NULL) {
preset->zone = zone->next;
if (delete_fluid_preset_zone(zone) != FLUID_OK) {
err = FLUID_FAILED;
}
zone = preset->zone;
}
if (preset->presetvoices != NULL) {
fluid_list_t *tmp = preset->presetvoices, *next;
while (tmp) {
data = (fluid_rampreset_voice_t *)(tmp->data);
FLUID_FREE(data);
next = tmp->next;
FLUID_FREE(tmp);
tmp = next;
}
}
preset->presetvoices = NULL;
FLUID_FREE(preset);
return err;
}
int
fluid_rampreset_get_banknum(fluid_rampreset_t* preset)
{
return preset->bank;
}
int
fluid_rampreset_get_num(fluid_rampreset_t* preset)
{
return preset->num;
}
char*
fluid_rampreset_get_name(fluid_rampreset_t* preset)
{
return preset->name;
}
fluid_rampreset_t*
fluid_rampreset_next(fluid_rampreset_t* preset)
{
return preset->next;
}
int
fluid_rampreset_add_zone(fluid_rampreset_t* preset, fluid_preset_zone_t* zone)
{
if (preset->zone == NULL) {
zone->next = NULL;
preset->zone = zone;
} else {
zone->next = preset->zone;
preset->zone = zone;
}
return FLUID_OK;
}
int fluid_rampreset_add_sample(fluid_rampreset_t* preset, fluid_sample_t* sample, int lokey, int hikey)
{
if (preset->zone == NULL) {
fluid_preset_zone_t* zone;
zone = new_fluid_preset_zone("");
if (zone == NULL) {
return FLUID_FAILED;
}
zone->inst = (fluid_inst_t*) new_fluid_inst();
if (zone->inst == NULL) {
delete_fluid_preset_zone(zone);
return FLUID_FAILED;
}
fluid_rampreset_add_zone(preset, zone);
}
{
fluid_inst_t* inst = fluid_preset_zone_get_inst(preset->zone);
fluid_inst_zone_t* izone = new_fluid_inst_zone("");
if (izone == NULL) {
return FLUID_FAILED;
}
if (fluid_inst_add_zone(inst, izone) != FLUID_OK) {
delete_fluid_inst_zone(izone);
return FLUID_FAILED;
}
izone->sample = sample;
izone->keylo = lokey;
izone->keyhi = hikey;
FLUID_MEMCPY(preset->name, sample->name, 20);
}
return FLUID_OK;
}
fluid_inst_zone_t* fluid_rampreset_izoneforsample(fluid_rampreset_t* preset, fluid_sample_t* sample)
{
fluid_inst_t* inst;
fluid_inst_zone_t* izone;
if (preset->zone == NULL) return NULL;
inst = fluid_preset_zone_get_inst(preset->zone);
izone = inst->zone;
while (izone) {
if (izone->sample == sample)
return izone;
izone = izone->next;
}
return NULL;
}
int fluid_rampreset_izone_set_loop(fluid_rampreset_t* preset, fluid_sample_t* sample,
int on, float loopstart, float loopend) {
fluid_inst_zone_t* izone = fluid_rampreset_izoneforsample(preset, sample);
short coarse, fine;
if (izone == NULL)
return FLUID_FAILED;
if (!on) {
izone->gen[GEN_SAMPLEMODE].flags = GEN_SET;
izone->gen[GEN_SAMPLEMODE].val = FLUID_UNLOOPED;
fluid_rampreset_updatevoices(preset, GEN_SAMPLEMODE, FLUID_UNLOOPED);
return FLUID_OK;
}
if (loopstart > 32767. || loopstart < -32767.) {
coarse = (short)(loopstart/32768.);
fine = (short)(loopstart - (float)(coarse)*32768.);
} else {
coarse = 0;
fine = (short)loopstart;
}
izone->gen[GEN_STARTLOOPADDROFS].flags = GEN_SET;
izone->gen[GEN_STARTLOOPADDROFS].val = fine;
fluid_rampreset_updatevoices(preset, GEN_STARTLOOPADDROFS, fine);
if (coarse) {
izone->gen[GEN_STARTLOOPADDRCOARSEOFS].flags = GEN_SET;
izone->gen[GEN_STARTLOOPADDRCOARSEOFS].val = coarse;
} else {
izone->gen[GEN_STARTLOOPADDRCOARSEOFS].flags = GEN_UNUSED;
}
fluid_rampreset_updatevoices(preset, GEN_STARTLOOPADDRCOARSEOFS, coarse);
if (loopend > 32767. || loopend < -32767.) {
coarse = (short)(loopend/32768.);
fine = (short)(loopend - (float)(coarse)*32768.);
} else {
coarse = 0;
fine = (short)loopend;
}
izone->gen[GEN_ENDLOOPADDROFS].flags = GEN_SET;
izone->gen[GEN_ENDLOOPADDROFS].val = fine;
fluid_rampreset_updatevoices(preset, GEN_ENDLOOPADDROFS, fine);
if (coarse) {
izone->gen[GEN_ENDLOOPADDRCOARSEOFS].flags = GEN_SET;
izone->gen[GEN_ENDLOOPADDRCOARSEOFS].val = coarse;
} else {
izone->gen[GEN_ENDLOOPADDRCOARSEOFS].flags = GEN_UNUSED;
}
fluid_rampreset_updatevoices(preset, GEN_ENDLOOPADDRCOARSEOFS, coarse);
izone->gen[GEN_SAMPLEMODE].flags = GEN_SET;
izone->gen[GEN_SAMPLEMODE].val = FLUID_LOOP_DURING_RELEASE;
fluid_rampreset_updatevoices(preset, GEN_SAMPLEMODE, FLUID_LOOP_DURING_RELEASE);
return FLUID_OK;
}
int fluid_rampreset_izone_set_gen(fluid_rampreset_t* preset, fluid_sample_t* sample,
int gen_type, float value) {
fluid_inst_zone_t* izone = fluid_rampreset_izoneforsample(preset, sample);
if (izone == NULL)
return FLUID_FAILED;
izone->gen[gen_type].flags = GEN_SET;
izone->gen[gen_type].val = value;
fluid_rampreset_updatevoices(preset, gen_type, value);
return FLUID_OK;
}
int fluid_rampreset_remove_izone(fluid_rampreset_t* preset, fluid_sample_t* sample) {
fluid_inst_t* inst;
fluid_inst_zone_t* izone, * prev;
int found = 0;
if (preset->zone == NULL) return FLUID_FAILED;
inst = fluid_preset_zone_get_inst(preset->zone);
izone = inst->zone;
prev = NULL;
while (izone && !found) {
if (izone->sample == sample) {
if (prev == NULL) {
inst->zone = izone->next;
} else {
prev->next = izone->next;
}
izone->next = NULL;
delete_fluid_inst_zone(izone);
found = 1;
} else {
prev = izone;
izone = izone->next;
}
}
if (!found)
return FLUID_FAILED;
{
fluid_list_t *tmp = preset->presetvoices;
while (tmp) {
fluid_rampreset_voice_t *presetvoice = (fluid_rampreset_voice_t *)(tmp->data);
fluid_voice_t *voice = presetvoice->voice;
if (fluid_voice_is_playing(voice) && (fluid_voice_get_id(voice) == presetvoice->voiceID)) {
if (voice->sample == sample) {
fluid_voice_off(voice);
}
}
tmp = tmp->next;
}
}
return FLUID_OK;
}
int
fluid_rampreset_remembervoice(fluid_rampreset_t* preset, fluid_voice_t* voice) {
fluid_rampreset_voice_t *presetvoice = FLUID_NEW(fluid_rampreset_voice_t);
if (presetvoice == NULL) {
FLUID_LOG(FLUID_ERR, "Out of memory");
return FLUID_FAILED;
}
presetvoice->voice = voice;
presetvoice->voiceID = fluid_voice_get_id(voice);
preset->presetvoices = fluid_list_append(preset->presetvoices, (void *)presetvoice);
if (preset->presetvoices == NULL) {
FLUID_FREE(presetvoice);
FLUID_LOG(FLUID_ERR, "Out of memory");
return FLUID_FAILED;
}
return FLUID_OK;
}
void
fluid_rampreset_updatevoices(fluid_rampreset_t* preset, int gen_type, float val) {
fluid_list_t *tmp = preset->presetvoices, *prev = NULL, *next;
while (tmp) {
fluid_rampreset_voice_t *presetvoice = (fluid_rampreset_voice_t *)(tmp->data);
fluid_voice_t *voice = presetvoice->voice;
if (!fluid_voice_is_playing(voice) || (fluid_voice_get_id(voice) != presetvoice->voiceID)) {
FLUID_FREE(presetvoice);
next = tmp->next;
FLUID_FREE(tmp);
if (prev) {
prev->next = next;
} else {
preset->presetvoices = next;
}
tmp = next;
} else {
fluid_voice_gen_set(voice, gen_type, val);
fluid_voice_update_param(voice, gen_type);
prev = tmp;
tmp = tmp->next;
}
}
}
int
fluid_rampreset_noteon(fluid_rampreset_t* preset, fluid_synth_t* synth, int chan, int key, int vel)
{
fluid_preset_zone_t *preset_zone;
fluid_inst_t* inst;
fluid_inst_zone_t *inst_zone, *global_inst_zone, *z;
fluid_sample_t* sample;
fluid_voice_t* voice;
fluid_mod_t * mod;
fluid_mod_t * mod_list[FLUID_NUM_MOD];
int mod_list_count;
int i;
preset_zone = preset->zone;
while (preset_zone != NULL) {
if (fluid_preset_zone_inside_range(preset_zone, key, vel)) {
inst = fluid_preset_zone_get_inst(preset_zone);
global_inst_zone = fluid_inst_get_global_zone(inst);
inst_zone = fluid_inst_get_zone(inst);
while (inst_zone != NULL) {
sample = fluid_inst_zone_get_sample(inst_zone);
if (fluid_sample_in_rom(sample) || (sample == NULL)) {
inst_zone = fluid_inst_zone_next(inst_zone);
continue;
}
if (fluid_inst_zone_inside_range(inst_zone, key, vel) && (sample != NULL)) {
voice = fluid_synth_alloc_voice(synth, sample, chan, key, vel);
if (voice == NULL) {
return FLUID_FAILED;
}
if (fluid_rampreset_remembervoice(preset, voice) != FLUID_OK) {
return FLUID_FAILED;
}
z = inst_zone;
for (i = 0; i < GEN_LAST; i++) {
if (inst_zone->gen[i].flags){
fluid_voice_gen_set(voice, i, inst_zone->gen[i].val);
} else if (global_inst_zone != NULL && global_inst_zone->gen[i].flags){
fluid_voice_gen_set(voice, i, global_inst_zone->gen[i].val);
} else {
};
};
mod_list_count = 0;
if (global_inst_zone){
mod = global_inst_zone->mod;
while (mod){
mod_list[mod_list_count++] = mod;
mod = mod->next;
};
};
mod = inst_zone->mod;
while (mod){
for (i = 0; i < mod_list_count; i++){
if (fluid_mod_test_identity(mod,mod_list[i])){
mod_list[i] = NULL;
};
};
mod_list[mod_list_count++] = mod;
mod = mod->next;
};
for (i = 0; i < mod_list_count; i++){
mod = mod_list[i];
if (mod != NULL){
fluid_voice_add_mod(voice, mod, FLUID_VOICE_OVERWRITE);
};
};
for (i = 0; i < GEN_LAST; i++) {
if ((i != GEN_STARTADDROFS)
&& (i != GEN_ENDADDROFS)
&& (i != GEN_STARTLOOPADDROFS)
&& (i != GEN_ENDLOOPADDROFS)
&& (i != GEN_STARTADDRCOARSEOFS)
&& (i != GEN_ENDADDRCOARSEOFS)
&& (i != GEN_STARTLOOPADDRCOARSEOFS)
&& (i != GEN_KEYNUM)
&& (i != GEN_VELOCITY)
&& (i != GEN_ENDLOOPADDRCOARSEOFS)
&& (i != GEN_SAMPLEMODE)
&& (i != GEN_EXCLUSIVECLASS)
&& (i != GEN_OVERRIDEROOTKEY)) {
if (preset_zone->gen[i].flags){
fluid_voice_gen_incr(voice, i, preset_zone->gen[i].val);
} else {
};
};
};
mod_list_count = 0;
mod = preset_zone->mod;
while (mod){
for (i = 0; i < mod_list_count; i++){
if (fluid_mod_test_identity(mod,mod_list[i])){
mod_list[i] = NULL;
};
};
mod_list[mod_list_count++] = mod;
mod = mod->next;
};
for (i = 0; i < mod_list_count; i++){
mod = mod_list[i];
if ((mod != NULL) && (mod->amount != 0)) {
fluid_voice_add_mod(voice, mod, FLUID_VOICE_ADD);
};
};
fluid_synth_start_voice(synth, voice);
}
inst_zone = fluid_inst_zone_next(inst_zone);
}
}
preset_zone = fluid_preset_zone_next(preset_zone);
}
return FLUID_OK;
}
int
fluid_sample_set_name(fluid_sample_t* sample, char * name)
{
FLUID_MEMCPY(sample->name, name, 20);
return FLUID_OK;
}
int
fluid_sample_set_sound_data(fluid_sample_t* sample, short *data, unsigned int nbframes, short copy_data, int rootkey)
{
unsigned int storedNbFrames;
if (sample->data != NULL) {
FLUID_FREE(sample->data);
}
if (copy_data) {
storedNbFrames = nbframes;
if (storedNbFrames < 48) storedNbFrames = 48;
sample->data = FLUID_MALLOC(storedNbFrames*2 + 4*SAMPLE_LOOP_MARGIN);
if (sample->data == NULL) {
FLUID_LOG(FLUID_ERR, "Out of memory");
return FLUID_FAILED;
}
FLUID_MEMSET(sample->data, 0, storedNbFrames*2 + 4*SAMPLE_LOOP_MARGIN);
FLUID_MEMCPY((char*)(sample->data) + 2*SAMPLE_LOOP_MARGIN, data, nbframes*2);
#if 0#endif
sample->start = SAMPLE_LOOP_MARGIN;
sample->end = SAMPLE_LOOP_MARGIN + storedNbFrames;
} else {
sample->data = data;
sample->start = 0;
sample->end = nbframes;
}
sample->loopstart = sample->start;
sample->loopend = sample->end;
sample->samplerate = 44100;
sample->origpitch = rootkey;
sample->pitchadj = 0;
sample->sampletype = FLUID_SAMPLETYPE_MONO;
sample->valid = 1;
return FLUID_OK;
}
fluid_sample_t*
new_fluid_ramsample()
{
fluid_sample_t* sample = NULL;
sample = FLUID_NEW(fluid_sample_t);
if (sample == NULL) {
FLUID_LOG(FLUID_ERR, "Out of memory");
return NULL;
}
memset(sample, 0, sizeof(fluid_sample_t));
return sample;
}
int
delete_fluid_ramsample(fluid_sample_t* sample)
{
if (sample->data != NULL) {
FLUID_FREE(sample->data);
}
sample->data = NULL;
FLUID_FREE(sample);
return FLUID_OK;
}