From 8fd8a75b9f7f69db8529c04862d6a0c78f6559f8 Mon Sep 17 00:00:00 2001 From: derselbst Date: Sat, 7 Oct 2017 11:34:53 +0200 Subject: [PATCH 01/13] parse sm24 chunk --- include/fluidsynth/sfont.h | 3 ++- src/sfloader/fluid_defsfont.c | 50 +++++++++++++++++++++++++++++++++-- src/sfloader/fluid_defsfont.h | 9 +++++-- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/include/fluidsynth/sfont.h b/include/fluidsynth/sfont.h index e027d025..aab5ec31 100644 --- a/include/fluidsynth/sfont.h +++ b/include/fluidsynth/sfont.h @@ -244,7 +244,8 @@ struct _fluid_sample_t int pitchadj; /**< Fine pitch adjustment (+/- 99 cents) */ int sampletype; /**< Values: #FLUID_SAMPLETYPE_MONO, FLUID_SAMPLETYPE_RIGHT, FLUID_SAMPLETYPE_LEFT, FLUID_SAMPLETYPE_ROM */ int valid; /**< Should be TRUE if sample data is valid, FALSE otherwise (in which case it will not be synthesized) */ - short* data; /**< Pointer to the sample's data */ + short* data; /**< Pointer to the sample's 16 bit PCM data */ + char* data24; /**< If not NULL, pointer to the sample's contains the least significant byte counterparts to each sample data point */ int amplitude_that_reaches_noise_floor_is_valid; /**< Indicates if \a amplitude_that_reaches_noise_floor is valid (TRUE), set to FALSE initially to calculate. */ double amplitude_that_reaches_noise_floor; /**< The amplitude at which the sample's loop will be below the noise floor. For voice off optimization, calculated automatically. */ diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index 1580eeb3..25962bd7 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -2134,7 +2134,7 @@ static int fixup_sample (SFData * sf); char idlist[] = { "RIFFLISTsfbkINFOsdtapdtaifilisngINAMiromiverICRDIENGIPRD" - "ICOPICMTISFTsnamsmplphdrpbagpmodpgeninstibagimodigenshdr" + "ICOPICMTISFTsnamsmplphdrpbagpmodpgeninstibagimodigenshdrsm24" }; static unsigned int sdtachunk_size; @@ -2411,8 +2411,51 @@ process_sdta (unsigned int size, SFData * sf, FILE * fd) sdtachunk_size = chunk.size; sf->samplesize = chunk.size; + FSKIP (chunk.size, fd); + size -= chunk.size; + + if(sf->version.major >= 2 && sf->version.minor >= 4) + { + /* any chance to find another chunk here? */ + if(size > 8) + { + /* read sub chunk */ + READCHUNK (&chunk, fd); + size -= 8; + + if (chunkid (chunk.id) == SM24_ID) + { + int sm24size, sdtahalfsize; + + FLUID_LOG(FLUID_DBG, "Found SM24 chunk"); + if (chunk.size > size) + { + FLUID_LOG(FLUID_WARN, "SM24 exeeds SDTA chunk, ignoring SM24"); + goto ret; // no error + } + + sdtahalfsize = sf->samplesize/2; + /* + 1 byte in the case that half the size of smpl chunk is an odd value */ + sdtahalfsize += sdtahalfsize%2; + sm24size = chunk.size; + + if (sdtahalfsize != sm24size) + { + FLUID_LOG(FLUID_WARN, "SM24 not equal to half the size of SMPL chunk (0x%X != 0x%X), ignoring SM24", sm24size, sdtahalfsize); + goto ret; // no error + } + + /* sample data24 follows */ + sf->hassample24 = TRUE; + sf->sample24pos = ftell (fd); + sf->sample24size = chunk.size; + } + } + } + +ret: FSKIP (size, fd); - + return (OK); } @@ -3337,6 +3380,9 @@ fixup_sample (SFData * sf) { sam = (SFSample *) (p->data); + if(sf->samplesize != sdtachunk_size) + FLUID_LOG(FLUID_ERR, "OMGOMGOMGOM"); + /* The SoundFont 2.4 spec defines the loopstart index as the first sample point of the loop */ invalid_loopstart = (sam->loopstart < sam->start) || (sam->loopstart >= sam->loopend); /* while loopend is the first point AFTER the last sample of the loop. diff --git a/src/sfloader/fluid_defsfont.h b/src/sfloader/fluid_defsfont.h index 56f87dd5..2e7850ab 100644 --- a/src/sfloader/fluid_defsfont.h +++ b/src/sfloader/fluid_defsfont.h @@ -145,6 +145,10 @@ typedef struct _SFData SFVersion romver; /* ROM version */ unsigned int samplepos; /* position within sffd of the sample chunk */ unsigned int samplesize; /* length within sffd of the sample chunk */ + + int hassample24; /* TRUE if valid 24 bit samples are available (i.e. the two members below are set */ + unsigned int sample24pos; /* position within sffd of the sm24 chunk */ + unsigned int sample24size; /* length within sffd of the sm24 chunk */ char *fname; /* file name */ FILE *sffd; /* loaded sfont file descriptor */ fluid_list_t *info; /* linked list of info strings (1st byte is ID) */ @@ -166,7 +170,8 @@ enum SNAM_ID, SMPL_ID, /* sample ids */ PHDR_ID, PBAG_ID, PMOD_ID, PGEN_ID, /* preset ids */ IHDR_ID, IBAG_ID, IMOD_ID, IGEN_ID, /* instrument ids */ - SHDR_ID /* sample info */ + SHDR_ID, /* sample info */ + SM24_ID }; /* generator types */ @@ -403,7 +408,7 @@ struct _fluid_defsfont_t { char* filename; /* the filename of this soundfont */ unsigned int samplepos; /* the position in the file at which the sample data starts */ - unsigned int samplesize; /* the size of the sample data */ + unsigned int samplesize; /* the size of the sample data in bytes */ short* sampledata; /* the sample data, loaded in ram */ fluid_list_t* sample; /* the samples in this soundfont */ fluid_defpreset_t* preset; /* the presets of this soundfont */ From 07e63d181b684b96940214caeb03bb445fe54740 Mon Sep 17 00:00:00 2001 From: derselbst Date: Sat, 7 Oct 2017 18:43:19 +0200 Subject: [PATCH 02/13] remove unused iter_preset from fluid_defsfont_t --- src/sfloader/fluid_defsfont.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sfloader/fluid_defsfont.h b/src/sfloader/fluid_defsfont.h index 2e7850ab..dd6d4520 100644 --- a/src/sfloader/fluid_defsfont.h +++ b/src/sfloader/fluid_defsfont.h @@ -414,7 +414,6 @@ struct _fluid_defsfont_t fluid_defpreset_t* preset; /* the presets of this soundfont */ int mlock; /* Should we try memlock (avoid swapping)? */ - fluid_preset_t iter_preset; /* preset interface used in the iteration */ fluid_defpreset_t* iter_cur; /* the current preset in the iteration */ fluid_preset_t** preset_stack; /* List of presets that are available to use */ From fb36c245aadd3652462f87b1063d70e51529cadf Mon Sep 17 00:00:00 2001 From: derselbst Date: Sun, 8 Oct 2017 13:18:03 +0200 Subject: [PATCH 03/13] start implementing 24 bit sample support --- src/sfloader/fluid_defsfont.c | 39 ++++++++++++++++++++--------------- src/sfloader/fluid_defsfont.h | 8 +++++++ 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index 25962bd7..babc224a 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -224,8 +224,11 @@ typedef struct _fluid_cached_sampledata_t { int num_references; int mlock; - const short* sampledata; + short* sampledata; unsigned int samplesize; + + char* sample24data; + unsigned int sample24size; } fluid_cached_sampledata_t; static fluid_cached_sampledata_t* all_cached_sampledata = NULL; @@ -248,11 +251,18 @@ static int fluid_get_file_modification_time(char *filename, time_t *modification #endif } -static int fluid_cached_sampledata_load(char *filename, unsigned int samplepos, - unsigned int samplesize, short **sampledata, int try_mlock) +static int fluid_cached_sampledata_load(char *filename, + unsigned int samplepos, + unsigned int samplesize, + short **sampledata, + unsigned int sample24pos, + unsigned int sample24size, + char **sample24data, + int try_mlock) { fluid_file fd = NULL; short *loaded_sampledata = NULL; + char *loaded_sample24data = NULL; fluid_cached_sampledata_t* cached_sampledata = NULL; time_t modification_time; @@ -282,7 +292,8 @@ static int fluid_cached_sampledata_load(char *filename, unsigned int samplepos, } cached_sampledata->num_references++; - loaded_sampledata = (short*) cached_sampledata->sampledata; + loaded_sampledata = cached_sampledata->sampledata; + loaded_sample24data = cached_sampledata->sample24data; goto success_exit; } @@ -453,12 +464,8 @@ fluid_defsfont_t* new_fluid_defsfont(fluid_settings_t* settings) return NULL; } - sfont->filename = NULL; - sfont->samplepos = 0; - sfont->samplesize = 0; - sfont->sample = NULL; - sfont->sampledata = NULL; - sfont->preset = NULL; + FLUID_MEMSET(sfont, 0, sizeof(*sfont)); + fluid_settings_getint(settings, "synth.lock-memory", &sfont->mlock); /* Initialise preset cache, so we don't have to call malloc on program changes. @@ -466,7 +473,7 @@ fluid_defsfont_t* new_fluid_defsfont(fluid_settings_t* settings) so optimise for that case. */ fluid_settings_getint(settings, "synth.midi-channels", &sfont->preset_stack_capacity); sfont->preset_stack_capacity++; - sfont->preset_stack_size = 0; + sfont->preset_stack = FLUID_ARRAY(fluid_preset_t*, sfont->preset_stack_capacity); if (!sfont->preset_stack) { FLUID_LOG(FLUID_ERR, "Out of memory"); @@ -574,6 +581,9 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const char* file) it's loaded separately (and might be unoaded/reloaded in future) */ sfont->samplepos = sfdata->samplepos; sfont->samplesize = sfdata->samplesize; + sfont->hassample24 = sfdata->hassample24; + sfont->sample24pos = sfdata->sample24pos; + sfont->sample24size = sfdata->sample24size; /* load sample data in one block */ if (fluid_defsfont_load_sampledata(sfont) != FLUID_OK) @@ -2137,8 +2147,6 @@ char idlist[] = { "ICOPICMTISFTsnamsmplphdrpbagpmodpgeninstibagimodigenshdrsm24" }; -static unsigned int sdtachunk_size; - /* sound font file load functions */ static int chunkid (unsigned int id) @@ -2408,7 +2416,6 @@ process_sdta (unsigned int size, SFData * sf, FILE * fd) sf->samplepos = ftell (fd); /* used in fixup_sample() to check validity of sample headers */ - sdtachunk_size = chunk.size; sf->samplesize = chunk.size; FSKIP (chunk.size, fd); @@ -3374,15 +3381,13 @@ fixup_sample (SFData * sf) int invalid_loops=FALSE; int invalid_loopstart; int invalid_loopend, loopend_end_mismatch; + unsigned int sdtachunk_size = sf->samplesize; p = sf->sample; while (p) { sam = (SFSample *) (p->data); - if(sf->samplesize != sdtachunk_size) - FLUID_LOG(FLUID_ERR, "OMGOMGOMGOM"); - /* The SoundFont 2.4 spec defines the loopstart index as the first sample point of the loop */ invalid_loopstart = (sam->loopstart < sam->start) || (sam->loopstart >= sam->loopend); /* while loopend is the first point AFTER the last sample of the loop. diff --git a/src/sfloader/fluid_defsfont.h b/src/sfloader/fluid_defsfont.h index dd6d4520..81d81dd1 100644 --- a/src/sfloader/fluid_defsfont.h +++ b/src/sfloader/fluid_defsfont.h @@ -143,12 +143,14 @@ typedef struct _SFData { /* Sound font data structure */ SFVersion version; /* sound font version */ SFVersion romver; /* ROM version */ + unsigned int samplepos; /* position within sffd of the sample chunk */ unsigned int samplesize; /* length within sffd of the sample chunk */ int hassample24; /* TRUE if valid 24 bit samples are available (i.e. the two members below are set */ unsigned int sample24pos; /* position within sffd of the sm24 chunk */ unsigned int sample24size; /* length within sffd of the sm24 chunk */ + char *fname; /* file name */ FILE *sffd; /* loaded sfont file descriptor */ fluid_list_t *info; /* linked list of info strings (1st byte is ID) */ @@ -410,6 +412,12 @@ struct _fluid_defsfont_t unsigned int samplepos; /* the position in the file at which the sample data starts */ unsigned int samplesize; /* the size of the sample data in bytes */ short* sampledata; /* the sample data, loaded in ram */ + + int hassample24; /* TRUE if valid 24 bit samples are available (i.e. the two members below are set */ + unsigned int sample24pos; /* position within sffd of the sm24 chunk */ + unsigned int sample24size; /* length within sffd of the sm24 chunk */ + char* sample24data; /* if not NULL, the least significant byte of the 24bit sample data, loaded in ram */ + fluid_list_t* sample; /* the samples in this soundfont */ fluid_defpreset_t* preset; /* the presets of this soundfont */ int mlock; /* Should we try memlock (avoid swapping)? */ From 45bc3343337259663087e46e7908921478b75a27 Mon Sep 17 00:00:00 2001 From: derselbst Date: Tue, 21 Nov 2017 09:03:12 +0100 Subject: [PATCH 04/13] add 24 bit sample support to fluid_cached_sampledata_load() --- src/sfloader/fluid_defsfont.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index a4c8f943..1a7d0c12 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -313,6 +313,16 @@ static int fluid_cached_sampledata_load(char *filename, goto error_exit; } + loaded_sample24data = (char*) FLUID_MALLOC(sample24size); + if (loaded_sampledata == NULL) { + FLUID_LOG(FLUID_ERR, "Out of memory when allocating 24bit sample, ignoring"); + } + else if (FLUID_FREAD(loaded_sample24data, 1, sample24size, fd) < sample24size) { + FLUID_LOG(FLUID_ERR, "Failed to read sample24 data"); + FLUID_FREE(loaded_sample24data); + loaded_sample24data = NULL; + } + FLUID_FCLOSE(fd); fd = NULL; @@ -359,6 +369,8 @@ static int fluid_cached_sampledata_load(char *filename, cached_sampledata->num_references = 1; cached_sampledata->sampledata = loaded_sampledata; cached_sampledata->samplesize = samplesize; + cached_sampledata->sample24data = loaded_sample24data; + cached_sampledata->sample24size = sample24size; cached_sampledata->next = all_cached_sampledata; all_cached_sampledata = cached_sampledata; @@ -367,25 +379,25 @@ static int fluid_cached_sampledata_load(char *filename, success_exit: fluid_mutex_unlock(cached_sampledata_mutex); *sampledata = loaded_sampledata; + *sample24data = loaded_sample24data; return FLUID_OK; error_exit: if (fd != NULL) { FLUID_FCLOSE(fd); } - if (loaded_sampledata != NULL) { - FLUID_FREE(loaded_sampledata); - } + + FLUID_FREE(loaded_sampledata); + FLUID_FREE(loaded_sample24data); if (cached_sampledata != NULL) { - if (cached_sampledata->filename != NULL) { FLUID_FREE(cached_sampledata->filename); - } - FLUID_FREE(cached_sampledata); } + FLUID_FREE(cached_sampledata); fluid_mutex_unlock(cached_sampledata_mutex); *sampledata = NULL; + *sample24data = NULL; return FLUID_FAILED; } @@ -678,8 +690,10 @@ int fluid_defsfont_add_preset(fluid_defsfont_t* sfont, fluid_defpreset_t* preset int fluid_defsfont_load_sampledata(fluid_defsfont_t* sfont) { - return fluid_cached_sampledata_load(sfont->filename, sfont->samplepos, - sfont->samplesize, &sfont->sampledata, sfont->mlock); + return fluid_cached_sampledata_load(sfont->filename, + sfont->samplepos, sfont->samplesize, &sfont->sampledata, + sfont->sample24pos, sfont->sample24size, &sfont->sample24data, + sfont->mlock); } /* From 0802fdfe5eed42641d4a081ed6f477953888f286 Mon Sep 17 00:00:00 2001 From: derselbst Date: Tue, 21 Nov 2017 09:14:19 +0100 Subject: [PATCH 05/13] use FLUID_STRDUP rather than custom copy --- src/sfloader/fluid_defsfont.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index 1a7d0c12..bf086e33 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -334,7 +334,7 @@ static int fluid_cached_sampledata_load(char *filename, } /* Lock the memory to disable paging. It's okay if this fails. It - probably means that the user doesn't have to required permission. */ + probably means that the user doesn't have the required permission. */ cached_sampledata->mlock = 0; if (try_mlock) { if (fluid_mlock(loaded_sampledata, samplesize) != 0) @@ -358,13 +358,12 @@ static int fluid_cached_sampledata_load(char *filename, } } - cached_sampledata->filename = (char*) FLUID_MALLOC(strlen(filename) + 1); + cached_sampledata->filename = FLUID_STRDUP(filename); if (cached_sampledata->filename == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory."); goto error_exit; } - sprintf(cached_sampledata->filename, "%s", filename); cached_sampledata->modification_time = modification_time; cached_sampledata->num_references = 1; cached_sampledata->sampledata = loaded_sampledata; From c56943cfc695f66bc42fad4d6894c15666d16587 Mon Sep 17 00:00:00 2001 From: derselbst Date: Tue, 21 Nov 2017 21:41:12 +0100 Subject: [PATCH 06/13] complete 24bit sample support for sfloader --- src/sfloader/fluid_defsfont.c | 46 +++++++++++++++++++++++------------ src/sfloader/fluid_defsfont.h | 6 ++--- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index bf086e33..8720cd40 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -272,7 +272,7 @@ static int fluid_cached_sampledata_load(char *filename, continue; if (cached_sampledata->modification_time != modification_time) continue; - if (cached_sampledata->samplesize != samplesize) { + if (cached_sampledata->samplesize != samplesize || cached_sampledata->sample24size != sample24size) { FLUID_LOG(FLUID_ERR, "Cached size of soundfont doesn't match actual size of soundfont (cached: %u. actual: %u)", cached_sampledata->samplesize, samplesize); continue; @@ -283,6 +283,10 @@ static int fluid_cached_sampledata_load(char *filename, FLUID_LOG(FLUID_WARN, "Failed to pin the sample data to RAM; swapping is possible."); else cached_sampledata->mlock = try_mlock; + + if (cached_sampledata->sample24data != NULL) + if(fluid_mlock(cached_sampledata->sample24data, sample24size) != 0) + FLUID_LOG(FLUID_WARN, "Failed to pin the sample24 data to RAM; swapping is possible."); } cached_sampledata->num_references++; @@ -296,13 +300,13 @@ static int fluid_cached_sampledata_load(char *filename, FLUID_LOG(FLUID_ERR, "Can't open soundfont file"); goto error_exit; } + if (FLUID_FSEEK(fd, samplepos, SEEK_SET) == -1) { perror("error"); FLUID_LOG(FLUID_ERR, "Failed to seek position in data file"); goto error_exit; } - loaded_sampledata = (short*) FLUID_MALLOC(samplesize); if (loaded_sampledata == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); @@ -313,14 +317,23 @@ static int fluid_cached_sampledata_load(char *filename, goto error_exit; } - loaded_sample24data = (char*) FLUID_MALLOC(sample24size); - if (loaded_sampledata == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory when allocating 24bit sample, ignoring"); - } - else if (FLUID_FREAD(loaded_sample24data, 1, sample24size, fd) < sample24size) { - FLUID_LOG(FLUID_ERR, "Failed to read sample24 data"); - FLUID_FREE(loaded_sample24data); - loaded_sample24data = NULL; + if(sample24pos > 0) + { + if (FLUID_FSEEK(fd, sample24pos, SEEK_SET) == -1) { + perror("error"); + FLUID_LOG(FLUID_ERR, "Failed to seek position in data file"); + goto error_exit; + } + + loaded_sample24data = (char*) FLUID_MALLOC(sample24size); + if (loaded_sample24data == NULL) { + FLUID_LOG(FLUID_ERR, "Out of memory when allocating 24bit sample, ignoring"); + } + else if (FLUID_FREAD(loaded_sample24data, 1, sample24size, fd) < sample24size) { + FLUID_LOG(FLUID_ERR, "Failed to read sample24 data"); + FLUID_FREE(loaded_sample24data); + loaded_sample24data = NULL; + } } FLUID_FCLOSE(fd); @@ -415,8 +428,12 @@ static int fluid_cached_sampledata_unload(const short *sampledata) if (cached_sampledata->num_references == 0) { if (cached_sampledata->mlock) + { fluid_munlock(cached_sampledata->sampledata, cached_sampledata->samplesize); - FLUID_FREE((short*) cached_sampledata->sampledata); + fluid_munlock(cached_sampledata->sample24data, cached_sampledata->sample24size); + } + FLUID_FREE(cached_sampledata->sampledata); + FLUID_FREE(cached_sampledata->sample24data); FLUID_FREE(cached_sampledata->filename); if (prev != NULL) { @@ -588,7 +605,6 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const char* file) it's loaded separately (and might be unoaded/reloaded in future) */ sfont->samplepos = sfdata->samplepos; sfont->samplesize = sfdata->samplesize; - sfont->hassample24 = sfdata->hassample24; sfont->sample24pos = sfdata->sample24pos; sfont->sample24size = sfdata->sample24size; @@ -1902,6 +1918,7 @@ fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defs { FLUID_STRCPY(sample->name, sfsample->name); sample->data = sfont->sampledata; + sample->data24 = sfont->sample24data; sample->start = sfsample->start; sample->end = sfsample->start + sfsample->end; sample->loopstart = sfsample->start + sfsample->loopstart; @@ -2421,7 +2438,7 @@ process_sdta (unsigned int size, SFData * sf, FILE * fd) sdtahalfsize = sf->samplesize/2; /* + 1 byte in the case that half the size of smpl chunk is an odd value */ sdtahalfsize += sdtahalfsize%2; - sm24size = chunk.size; + sm24size = chunk.size; if (sdtahalfsize != sm24size) { @@ -2430,9 +2447,8 @@ process_sdta (unsigned int size, SFData * sf, FILE * fd) } /* sample data24 follows */ - sf->hassample24 = TRUE; sf->sample24pos = ftell (fd); - sf->sample24size = chunk.size; + sf->sample24size = sm24size; } } } diff --git a/src/sfloader/fluid_defsfont.h b/src/sfloader/fluid_defsfont.h index 53aca077..0f4696fa 100644 --- a/src/sfloader/fluid_defsfont.h +++ b/src/sfloader/fluid_defsfont.h @@ -147,8 +147,7 @@ typedef struct _SFData unsigned int samplepos; /* position within sffd of the sample chunk */ unsigned int samplesize; /* length within sffd of the sample chunk */ - int hassample24; /* TRUE if valid 24 bit samples are available (i.e. the two members below are set */ - unsigned int sample24pos; /* position within sffd of the sm24 chunk */ + unsigned int sample24pos; /* position within sffd of the sm24 chunk, set to zero if no 24 bit sample support */ unsigned int sample24size; /* length within sffd of the sm24 chunk */ char *fname; /* file name */ @@ -384,8 +383,7 @@ struct _fluid_defsfont_t unsigned int samplesize; /* the size of the sample data in bytes */ short* sampledata; /* the sample data, loaded in ram */ - int hassample24; /* TRUE if valid 24 bit samples are available (i.e. the two members below are set */ - unsigned int sample24pos; /* position within sffd of the sm24 chunk */ + unsigned int sample24pos; /* position within sffd of the sm24 chunk, set to zero if no 24 bit sample support */ unsigned int sample24size; /* length within sffd of the sm24 chunk */ char* sample24data; /* if not NULL, the least significant byte of the 24bit sample data, loaded in ram */ From ce6c5cadcb939002f551784aa1207b2c0ba4bc0e Mon Sep 17 00:00:00 2001 From: derselbst Date: Wed, 29 Nov 2017 13:56:05 +0100 Subject: [PATCH 07/13] fix build --- src/sfloader/fluid_defsfont.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index 270f2060..8a63c6fc 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -386,7 +386,7 @@ static int fluid_cached_sampledata_load(char *filename, if (loaded_sample24data == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory when allocating 24bit sample, ignoring"); } - else if (fcbs->fread(loaded_sample24data, 1, sample24size, fd) == FLUID_FAILED) { + else if (fcbs->fread(loaded_sample24data, sample24size, fd) == FLUID_FAILED) { FLUID_LOG(FLUID_ERR, "Failed to read sample24 data"); FLUID_FREE(loaded_sample24data); loaded_sample24data = NULL; From 9a21e10e10f6883be454ccee6c60c1c7acf6838b Mon Sep 17 00:00:00 2001 From: derselbst Date: Fri, 8 Dec 2017 18:23:18 +0100 Subject: [PATCH 08/13] add 24bit sample support to rvoice_dsp interpolation functions --- src/rvoice/fluid_rvoice_dsp.c | 190 +++++++++++++++++++--------------- 1 file changed, 109 insertions(+), 81 deletions(-) diff --git a/src/rvoice/fluid_rvoice_dsp.c b/src/rvoice/fluid_rvoice_dsp.c index 7931c812..c3a49072 100644 --- a/src/rvoice/fluid_rvoice_dsp.c +++ b/src/rvoice/fluid_rvoice_dsp.c @@ -119,6 +119,27 @@ void fluid_rvoice_dsp_config (void) fluid_check_fpe("interpolation table calculation"); } +/* + * Combines the most significant 16 bit part of a sample with a potentially present + * least sig. 8 bit part in order to create a 24 bit sample. + */ +static int32_t fluid_rvoice_get_sample(const short int* dsp_msb, const char* dsp_lsb, unsigned int idx) +{ + /* cast sample to unsigned type, so we can safely shift and bitwise or + * without relying on undefined behaviour (should never happen anyway ofc...) */ + uint32_t msb = (uint32_t)dsp_msb[idx]; + uint8_t lsb = 0U; + + /* most soundfonts have 16 bit samples, assume that it's unlikely we + * experience 24 bit samples here */ + if(G_UNLIKELY(dsp_lsb != NULL)) + { + lsb = (uint8_t)dsp_lsb[idx]; + } + + return (int32_t)((msb << 8) | lsb); +} + /* No interpolation. Just take the sample, which is closest to * the playback pointer. Questionable quality, but very * efficient. */ @@ -128,6 +149,7 @@ fluid_rvoice_dsp_interpolate_none (fluid_rvoice_dsp_t *voice) fluid_phase_t dsp_phase = voice->phase; fluid_phase_t dsp_phase_incr; short int *dsp_data = voice->sample->data; + char *dsp_data24 = voice->sample->data24; fluid_real_t *dsp_buf = voice->dsp_buf; fluid_real_t dsp_amp = voice->amp; fluid_real_t dsp_amp_incr = voice->amp_incr; @@ -151,7 +173,7 @@ fluid_rvoice_dsp_interpolate_none (fluid_rvoice_dsp_t *voice) /* interpolate sequence of sample points */ for ( ; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++) { - dsp_buf[dsp_i] = dsp_amp * dsp_data[dsp_phase_index]; + dsp_buf[dsp_i] = dsp_amp * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -189,13 +211,14 @@ fluid_rvoice_dsp_interpolate_linear (fluid_rvoice_dsp_t *voice) fluid_phase_t dsp_phase = voice->phase; fluid_phase_t dsp_phase_incr; short int *dsp_data = voice->sample->data; + char *dsp_data24 = voice->sample->data24; fluid_real_t *dsp_buf = voice->dsp_buf; fluid_real_t dsp_amp = voice->amp; fluid_real_t dsp_amp_incr = voice->amp_incr; unsigned int dsp_i = 0; unsigned int dsp_phase_index; unsigned int end_index; - short int point; + int32_t point; fluid_real_t *coeffs; int looping; @@ -209,8 +232,8 @@ fluid_rvoice_dsp_interpolate_linear (fluid_rvoice_dsp_t *voice) end_index = (looping ? voice->loopend - 1 : voice->end) - 1; /* 2nd interpolation point to use at end of loop or sample */ - if (looping) point = dsp_data[voice->loopstart]; /* loop start */ - else point = dsp_data[voice->end]; /* duplicate end for samples no longer looping */ + if (looping) point = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopstart); /* loop start */ + else point = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->end); /* duplicate end for samples no longer looping */ while (1) { @@ -220,8 +243,8 @@ fluid_rvoice_dsp_interpolate_linear (fluid_rvoice_dsp_t *voice) for ( ; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++) { coeffs = interp_coeff_linear[fluid_phase_fract_to_tablerow (dsp_phase)]; - dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index] - + coeffs[1] * dsp_data[dsp_phase_index+1]); + dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[1] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1)); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -238,8 +261,8 @@ fluid_rvoice_dsp_interpolate_linear (fluid_rvoice_dsp_t *voice) for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++) { coeffs = interp_coeff_linear[fluid_phase_fract_to_tablerow (dsp_phase)]; - dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index] - + coeffs[1] * point); + dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[1] * point); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -278,13 +301,14 @@ fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice) fluid_phase_t dsp_phase = voice->phase; fluid_phase_t dsp_phase_incr; short int *dsp_data = voice->sample->data; + char *dsp_data24 = voice->sample->data24; fluid_real_t *dsp_buf = voice->dsp_buf; fluid_real_t dsp_amp = voice->amp; fluid_real_t dsp_amp_incr = voice->amp_incr; unsigned int dsp_i = 0; unsigned int dsp_phase_index; unsigned int start_index, end_index; - short int start_point, end_point1, end_point2; + int32_t start_point, end_point1, end_point2; fluid_real_t *coeffs; int looping; @@ -300,23 +324,23 @@ fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice) if (voice->has_looped) /* set start_index and start point if looped or not */ { start_index = voice->loopstart; - start_point = dsp_data[voice->loopend - 1]; /* last point in loop (wrap around) */ + start_point = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopend - 1); /* last point in loop (wrap around) */ } else { start_index = voice->start; - start_point = dsp_data[voice->start]; /* just duplicate the point */ + start_point = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->start); /* just duplicate the point */ } /* get points off the end (loop start if looping, duplicate point if end) */ if (looping) { - end_point1 = dsp_data[voice->loopstart]; - end_point2 = dsp_data[voice->loopstart + 1]; + end_point1 = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopstart); + end_point2 = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopstart + 1); } else { - end_point1 = dsp_data[voice->end]; + end_point1 = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->end); end_point2 = end_point1; } @@ -328,10 +352,11 @@ fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice) for ( ; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++) { coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)]; - dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * start_point - + coeffs[1] * dsp_data[dsp_phase_index] - + coeffs[2] * dsp_data[dsp_phase_index+1] - + coeffs[3] * dsp_data[dsp_phase_index+2]); + dsp_buf[dsp_i] = dsp_amp * + ( coeffs[0] * start_point + + coeffs[1] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[2] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[3] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2)); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -343,10 +368,11 @@ fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice) for ( ; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++) { coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)]; - dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index-1] - + coeffs[1] * dsp_data[dsp_phase_index] - + coeffs[2] * dsp_data[dsp_phase_index+1] - + coeffs[3] * dsp_data[dsp_phase_index+2]); + dsp_buf[dsp_i] = dsp_amp * + ( coeffs[0] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[1] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[2] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[3] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2)); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -363,10 +389,11 @@ fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice) for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++) { coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)]; - dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index-1] - + coeffs[1] * dsp_data[dsp_phase_index] - + coeffs[2] * dsp_data[dsp_phase_index+1] - + coeffs[3] * end_point1); + dsp_buf[dsp_i] = dsp_amp * + ( coeffs[0] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[1] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[2] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[3] * end_point1); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -380,10 +407,11 @@ fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice) for (; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++) { coeffs = interp_coeff[fluid_phase_fract_to_tablerow (dsp_phase)]; - dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * dsp_data[dsp_phase_index-1] - + coeffs[1] * dsp_data[dsp_phase_index] - + coeffs[2] * end_point1 - + coeffs[3] * end_point2); + dsp_buf[dsp_i] = dsp_amp * + ( coeffs[0] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[1] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[2] * end_point1 + + coeffs[3] * end_point2); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -402,7 +430,7 @@ fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice) { voice->has_looped = 1; start_index = voice->loopstart; - start_point = dsp_data[voice->loopend - 1]; + start_point = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopend-1); } } @@ -428,14 +456,14 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) fluid_phase_t dsp_phase = voice->phase; fluid_phase_t dsp_phase_incr; short int *dsp_data = voice->sample->data; + char *dsp_data24 = voice->sample->data24; fluid_real_t *dsp_buf = voice->dsp_buf; fluid_real_t dsp_amp = voice->amp; fluid_real_t dsp_amp_incr = voice->amp_incr; unsigned int dsp_i = 0; unsigned int dsp_phase_index; unsigned int start_index, end_index; - short int start_points[3]; - short int end_points[3]; + int32_t start_points[3], end_points[3]; fluid_real_t *coeffs; int looping; @@ -455,14 +483,14 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) if (voice->has_looped) /* set start_index and start point if looped or not */ { start_index = voice->loopstart; - start_points[0] = dsp_data[voice->loopend - 1]; - start_points[1] = dsp_data[voice->loopend - 2]; - start_points[2] = dsp_data[voice->loopend - 3]; + start_points[0] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopend - 1); + start_points[1] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopend - 2); + start_points[2] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopend - 3); } else { start_index = voice->start; - start_points[0] = dsp_data[voice->start]; /* just duplicate the start point */ + start_points[0] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->start); /* just duplicate the start point */ start_points[1] = start_points[0]; start_points[2] = start_points[0]; } @@ -470,13 +498,13 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) /* get the 3 points off the end (loop start if looping, duplicate point if end) */ if (looping) { - end_points[0] = dsp_data[voice->loopstart]; - end_points[1] = dsp_data[voice->loopstart + 1]; - end_points[2] = dsp_data[voice->loopstart + 2]; + end_points[0] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopstart); + end_points[1] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopstart + 1); + end_points[2] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopstart + 2); } else { - end_points[0] = dsp_data[voice->end]; + end_points[0] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->end); end_points[1] = end_points[0]; end_points[2] = end_points[0]; } @@ -494,10 +522,10 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) * (coeffs[0] * (fluid_real_t)start_points[2] + coeffs[1] * (fluid_real_t)start_points[1] + coeffs[2] * (fluid_real_t)start_points[0] - + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] - + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1] - + coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2] - + coeffs[6] * (fluid_real_t)dsp_data[dsp_phase_index+3]); + + coeffs[3] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[4] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[5] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2) + + coeffs[6] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+3)); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -515,11 +543,11 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * (fluid_real_t)start_points[1] + coeffs[1] * (fluid_real_t)start_points[0] - + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1] - + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] - + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1] - + coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2] - + coeffs[6] * (fluid_real_t)dsp_data[dsp_phase_index+3]); + + coeffs[2] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[3] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[4] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[5] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2) + + coeffs[6] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+3)); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -536,12 +564,12 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) dsp_buf[dsp_i] = dsp_amp * (coeffs[0] * (fluid_real_t)start_points[0] - + coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2] - + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1] - + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] - + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1] - + coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2] - + coeffs[6] * (fluid_real_t)dsp_data[dsp_phase_index+3]); + + coeffs[1] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-2) + + coeffs[2] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[3] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[4] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[5] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2) + + coeffs[6] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+3)); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -558,13 +586,13 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * (fluid_real_t)dsp_data[dsp_phase_index-3] - + coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2] - + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1] - + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] - + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1] - + coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2] - + coeffs[6] * (fluid_real_t)dsp_data[dsp_phase_index+3]); + * (coeffs[0] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-3) + + coeffs[1] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-2) + + coeffs[2] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[3] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[4] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[5] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2) + + coeffs[6] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+3)); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -583,12 +611,12 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * (fluid_real_t)dsp_data[dsp_phase_index-3] - + coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2] - + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1] - + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] - + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1] - + coeffs[5] * (fluid_real_t)dsp_data[dsp_phase_index+2] + * (coeffs[0] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-3) + + coeffs[1] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-2) + + coeffs[2] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[3] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[4] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[5] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2) + coeffs[6] * (fluid_real_t)end_points[0]); /* increment phase and amplitude */ @@ -605,11 +633,11 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * (fluid_real_t)dsp_data[dsp_phase_index-3] - + coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2] - + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1] - + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] - + coeffs[4] * (fluid_real_t)dsp_data[dsp_phase_index+1] + * (coeffs[0] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-3) + + coeffs[1] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-2) + + coeffs[2] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[3] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[4] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) + coeffs[5] * (fluid_real_t)end_points[0] + coeffs[6] * (fluid_real_t)end_points[1]); @@ -627,10 +655,10 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * (fluid_real_t)dsp_data[dsp_phase_index-3] - + coeffs[1] * (fluid_real_t)dsp_data[dsp_phase_index-2] - + coeffs[2] * (fluid_real_t)dsp_data[dsp_phase_index-1] - + coeffs[3] * (fluid_real_t)dsp_data[dsp_phase_index] + * (coeffs[0] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-3) + + coeffs[1] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-2) + + coeffs[2] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[3] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + coeffs[4] * (fluid_real_t)end_points[0] + coeffs[5] * (fluid_real_t)end_points[1] + coeffs[6] * (fluid_real_t)end_points[2]); @@ -652,9 +680,9 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) { voice->has_looped = 1; start_index = voice->loopstart; - start_points[0] = dsp_data[voice->loopend - 1]; - start_points[1] = dsp_data[voice->loopend - 2]; - start_points[2] = dsp_data[voice->loopend - 3]; + start_points[0] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopend - 1); + start_points[1] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopend - 2); + start_points[2] = fluid_rvoice_get_sample(dsp_data, dsp_data24, voice->loopend - 3); } } From b130763545516f690a2d0c943e1576ac0da362bb Mon Sep 17 00:00:00 2001 From: derselbst Date: Fri, 8 Dec 2017 20:24:17 +0100 Subject: [PATCH 09/13] adjust voice gain for 24bit samples --- src/synth/fluid_voice.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/synth/fluid_voice.c b/src/synth/fluid_voice.c index ae39e756..5163c0bb 100644 --- a/src/synth/fluid_voice.c +++ b/src/synth/fluid_voice.c @@ -438,7 +438,11 @@ void fluid_voice_start(fluid_voice_t* voice) */ static fluid_real_t fluid_voice_calculate_gain_amplitude(const fluid_voice_t* voice, fluid_real_t gain) { - return gain * voice->synth_gain / 32768.0f; + /* we use 24bit samples in fluid_rvoice_dsp. in order to normalize float + * samples to [0.0;1.0] divide samples by the max. value of an int24 and + * amplify them with the gain */ + const fluid_real_t INT24_MAX = (1 << (16+8-1)) * 1.0f; + return gain * voice->synth_gain / INT24_MAX; } void From 0619f103ea607c1451f329ccc84bec8d1dcdfe40 Mon Sep 17 00:00:00 2001 From: derselbst Date: Sat, 9 Dec 2017 17:50:06 +0100 Subject: [PATCH 10/13] update API docs about 24bit sample support --- TODO | 1 - doc/fluidsynth-v11-devdoc.txt | 1 + include/fluidsynth/sfont.h | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 9b0bfcb9..c5a519dd 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,5 @@ New features ------------ -- 24 bit sample support - Non-realtime MIDI file rendering - Sample streaming, load/unload sample on demand - Synth sample rate change after initial creation diff --git a/doc/fluidsynth-v11-devdoc.txt b/doc/fluidsynth-v11-devdoc.txt index 37c68e39..836a9d79 100644 --- a/doc/fluidsynth-v11-devdoc.txt +++ b/doc/fluidsynth-v11-devdoc.txt @@ -113,6 +113,7 @@ Changes in FluidSynth 2.0.0 concerning developers: - add file callback struct to _fluid_sfloader_t and expose new_fluid_defsfloader() to enable soundfont loading from memory ( see fluid_sfload_mem.c ) - add seek support to midi-player, see fluid_player_seek() - expose functions to manipulate the ladspa effects unit (see ladspa.h) +- add 24 bit sample support, see _fluid_sample_t::data24 \section NewIn1_1_9 Whats new in 1.1.9? diff --git a/include/fluidsynth/sfont.h b/include/fluidsynth/sfont.h index 6fcff58b..98c6355b 100644 --- a/include/fluidsynth/sfont.h +++ b/include/fluidsynth/sfont.h @@ -298,7 +298,7 @@ struct _fluid_sample_t int sampletype; /**< Specifies the type of this sample as indicated by the #fluid_sample_type enum */ int valid; /**< Should be TRUE if sample data is valid, FALSE otherwise (in which case it will not be synthesized) */ short* data; /**< Pointer to the sample's 16 bit PCM data */ - char* data24; /**< If not NULL, pointer to the sample's contains the least significant byte counterparts to each sample data point */ + char* data24; /**< If not NULL, pointer to the least significant byte counterparts of each sample data point in order to create 24 bit audio samples */ int amplitude_that_reaches_noise_floor_is_valid; /**< Indicates if \a amplitude_that_reaches_noise_floor is valid (TRUE), set to FALSE initially to calculate. */ double amplitude_that_reaches_noise_floor; /**< The amplitude at which the sample's loop will be below the noise floor. For voice off optimization, calculated automatically. */ From 0dde0c1affcfc65e80433d0123f0fc758fa30c11 Mon Sep 17 00:00:00 2001 From: derselbst Date: Tue, 12 Dec 2017 20:54:40 +0100 Subject: [PATCH 11/13] mark voice helper functions inline fluid_voice_calculate_gain_amplitude() fluid_rvoice_get_sample() --- src/rvoice/fluid_rvoice_dsp.c | 3 ++- src/synth/fluid_voice.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/rvoice/fluid_rvoice_dsp.c b/src/rvoice/fluid_rvoice_dsp.c index c3a49072..5083ca17 100644 --- a/src/rvoice/fluid_rvoice_dsp.c +++ b/src/rvoice/fluid_rvoice_dsp.c @@ -123,7 +123,8 @@ void fluid_rvoice_dsp_config (void) * Combines the most significant 16 bit part of a sample with a potentially present * least sig. 8 bit part in order to create a 24 bit sample. */ -static int32_t fluid_rvoice_get_sample(const short int* dsp_msb, const char* dsp_lsb, unsigned int idx) +static FLUID_INLINE int32_t +fluid_rvoice_get_sample(const short int* dsp_msb, const char* dsp_lsb, unsigned int idx) { /* cast sample to unsigned type, so we can safely shift and bitwise or * without relying on undefined behaviour (should never happen anyway ofc...) */ diff --git a/src/synth/fluid_voice.c b/src/synth/fluid_voice.c index 5163c0bb..6f4c4f38 100644 --- a/src/synth/fluid_voice.c +++ b/src/synth/fluid_voice.c @@ -436,7 +436,8 @@ void fluid_voice_start(fluid_voice_t* voice) * @param gain The gain value in the range [0.0 ; 1.0] * @return An amplitude used by rvoice_mixer's buffers */ -static fluid_real_t fluid_voice_calculate_gain_amplitude(const fluid_voice_t* voice, fluid_real_t gain) +static FLUID_INLINE fluid_real_t +fluid_voice_calculate_gain_amplitude(const fluid_voice_t* voice, fluid_real_t gain) { /* we use 24bit samples in fluid_rvoice_dsp. in order to normalize float * samples to [0.0;1.0] divide samples by the max. value of an int24 and From 05a4989498022ab3211a1b7dd7e0153cdaef911b Mon Sep 17 00:00:00 2001 From: derselbst Date: Tue, 12 Dec 2017 21:02:21 +0100 Subject: [PATCH 12/13] avoid bad function cast warnings --- src/rvoice/fluid_rvoice_dsp.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/rvoice/fluid_rvoice_dsp.c b/src/rvoice/fluid_rvoice_dsp.c index 5083ca17..b7746637 100644 --- a/src/rvoice/fluid_rvoice_dsp.c +++ b/src/rvoice/fluid_rvoice_dsp.c @@ -123,7 +123,7 @@ void fluid_rvoice_dsp_config (void) * Combines the most significant 16 bit part of a sample with a potentially present * least sig. 8 bit part in order to create a 24 bit sample. */ -static FLUID_INLINE int32_t +static FLUID_INLINE fluid_real_t fluid_rvoice_get_sample(const short int* dsp_msb, const char* dsp_lsb, unsigned int idx) { /* cast sample to unsigned type, so we can safely shift and bitwise or @@ -138,7 +138,7 @@ fluid_rvoice_get_sample(const short int* dsp_msb, const char* dsp_lsb, unsigned lsb = (uint8_t)dsp_lsb[idx]; } - return (int32_t)((msb << 8) | lsb); + return (fluid_real_t)((int32_t)((msb << 8) | lsb)); } /* No interpolation. Just take the sample, which is closest to @@ -219,7 +219,7 @@ fluid_rvoice_dsp_interpolate_linear (fluid_rvoice_dsp_t *voice) unsigned int dsp_i = 0; unsigned int dsp_phase_index; unsigned int end_index; - int32_t point; + fluid_real_t point; fluid_real_t *coeffs; int looping; @@ -309,7 +309,7 @@ fluid_rvoice_dsp_interpolate_4th_order (fluid_rvoice_dsp_t *voice) unsigned int dsp_i = 0; unsigned int dsp_phase_index; unsigned int start_index, end_index; - int32_t start_point, end_point1, end_point2; + fluid_real_t start_point, end_point1, end_point2; fluid_real_t *coeffs; int looping; @@ -464,7 +464,7 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) unsigned int dsp_i = 0; unsigned int dsp_phase_index; unsigned int start_index, end_index; - int32_t start_points[3], end_points[3]; + fluid_real_t start_points[3], end_points[3]; fluid_real_t *coeffs; int looping; From f231df560862556fd2dda9b7bece361c7e6906f4 Mon Sep 17 00:00:00 2001 From: derselbst Date: Tue, 12 Dec 2017 21:06:11 +0100 Subject: [PATCH 13/13] remove redundant fluid_real_t casts in rvoice_dsp --- src/rvoice/fluid_rvoice_dsp.c | 98 +++++++++++++++++------------------ 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/src/rvoice/fluid_rvoice_dsp.c b/src/rvoice/fluid_rvoice_dsp.c index b7746637..db399c20 100644 --- a/src/rvoice/fluid_rvoice_dsp.c +++ b/src/rvoice/fluid_rvoice_dsp.c @@ -520,13 +520,13 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * (fluid_real_t)start_points[2] - + coeffs[1] * (fluid_real_t)start_points[1] - + coeffs[2] * (fluid_real_t)start_points[0] - + coeffs[3] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) - + coeffs[4] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) - + coeffs[5] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2) - + coeffs[6] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+3)); + * (coeffs[0] * start_points[2] + + coeffs[1] * start_points[1] + + coeffs[2] * start_points[0] + + coeffs[3] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[4] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[5] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2) + + coeffs[6] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+3)); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -542,13 +542,13 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * (fluid_real_t)start_points[1] - + coeffs[1] * (fluid_real_t)start_points[0] - + coeffs[2] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) - + coeffs[3] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) - + coeffs[4] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) - + coeffs[5] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2) - + coeffs[6] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+3)); + * (coeffs[0] * start_points[1] + + coeffs[1] * start_points[0] + + coeffs[2] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[3] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[4] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[5] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2) + + coeffs[6] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+3)); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -564,13 +564,13 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * (fluid_real_t)start_points[0] - + coeffs[1] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-2) - + coeffs[2] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) - + coeffs[3] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) - + coeffs[4] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) - + coeffs[5] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2) - + coeffs[6] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+3)); + * (coeffs[0] * start_points[0] + + coeffs[1] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-2) + + coeffs[2] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[3] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[4] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[5] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2) + + coeffs[6] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+3)); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -587,13 +587,13 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-3) - + coeffs[1] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-2) - + coeffs[2] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) - + coeffs[3] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) - + coeffs[4] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) - + coeffs[5] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2) - + coeffs[6] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+3)); + * (coeffs[0] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-3) + + coeffs[1] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-2) + + coeffs[2] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[3] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[4] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[5] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2) + + coeffs[6] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+3)); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -612,13 +612,13 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-3) - + coeffs[1] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-2) - + coeffs[2] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) - + coeffs[3] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) - + coeffs[4] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) - + coeffs[5] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2) - + coeffs[6] * (fluid_real_t)end_points[0]); + * (coeffs[0] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-3) + + coeffs[1] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-2) + + coeffs[2] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[3] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[4] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[5] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+2) + + coeffs[6] * end_points[0]); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -634,13 +634,13 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-3) - + coeffs[1] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-2) - + coeffs[2] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) - + coeffs[3] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) - + coeffs[4] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) - + coeffs[5] * (fluid_real_t)end_points[0] - + coeffs[6] * (fluid_real_t)end_points[1]); + * (coeffs[0] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-3) + + coeffs[1] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-2) + + coeffs[2] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[3] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[4] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index+1) + + coeffs[5] * end_points[0] + + coeffs[6] * end_points[1]); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr); @@ -656,13 +656,13 @@ fluid_rvoice_dsp_interpolate_7th_order (fluid_rvoice_dsp_t *voice) coeffs = sinc_table7[fluid_phase_fract_to_tablerow (dsp_phase)]; dsp_buf[dsp_i] = dsp_amp - * (coeffs[0] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-3) - + coeffs[1] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-2) - + coeffs[2] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) - + coeffs[3] * (fluid_real_t)fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) - + coeffs[4] * (fluid_real_t)end_points[0] - + coeffs[5] * (fluid_real_t)end_points[1] - + coeffs[6] * (fluid_real_t)end_points[2]); + * (coeffs[0] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-3) + + coeffs[1] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-2) + + coeffs[2] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index-1) + + coeffs[3] * fluid_rvoice_get_sample(dsp_data, dsp_data24, dsp_phase_index) + + coeffs[4] * end_points[0] + + coeffs[5] * end_points[1] + + coeffs[6] * end_points[2]); /* increment phase and amplitude */ fluid_phase_incr (dsp_phase, dsp_phase_incr);