diff --git a/fluidsynth/AUTHORS b/fluidsynth/AUTHORS index 1c0dcf2f..6b930c5b 100644 --- a/fluidsynth/AUTHORS +++ b/fluidsynth/AUTHORS @@ -115,5 +115,5 @@ Rui Nuno Capela Frieder Bürzele Henri Manson Mihail Zenkov -Paul Miller +Paul Millar Nick Daly diff --git a/fluidsynth/ChangeLog b/fluidsynth/ChangeLog index 53e09e84..e29068bd 100644 --- a/fluidsynth/ChangeLog +++ b/fluidsynth/ChangeLog @@ -1,3 +1,12 @@ +2007-01-14 Josh Green + + * src/fluid_alsa.c: Fixed evil bugs in ALSA driver where return value + of new fluid_alsa_handle_write_error() was not being checked correctly + causing successfully handled ALSA errors (underruns for example) to + terminate audio thread. + * src/fluid_synth.c: Using an inline roundi function to replace roundf + as per suggestion by Mihail Zenkov, 16 bit for dithering. + 2006-12-10 Josh Green Lots of documentation updates. @@ -13,7 +22,7 @@ * src/fluid_aufile.c: Now also doing 16 bit dithering. * src/fluid_cmd.c: Removed use of old tokenizer instance. * src/fluid_coreaudio.c: User defined callback function is now honored. - * src/fluid_defsfont.c: More leaks plugged (thanks to Paul Miller for + * src/fluid_defsfont.c: More leaks plugged (thanks to Paul Millar for the patch), removed sfont_free_data() since sfont_close() should be used instead (don't want to leak a file handle). * src/fluid_midi_router.c: Took out uses of fflush() since sending a @@ -24,7 +33,7 @@ other improvements. * src/fluid_synth.c (delete_fluid_synth): Turning off all voices so that SoundFont data will be freed correctly (thanks to patch from - Paul Miller). + Paul Millar). * src/fluid_sys.c (fluid_strtok): New function to replace old tokenizing functions which required a token instance. * src/fluidsynth.c: Warning message printed if a non option is not a diff --git a/fluidsynth/src/fluid_alsa.c b/fluidsynth/src/fluid_alsa.c index 57d9f7ba..fa58b0f2 100644 --- a/fluidsynth/src/fluid_alsa.c +++ b/fluidsynth/src/fluid_alsa.c @@ -478,7 +478,7 @@ static void* fluid_alsa_audio_run_float(void* d) if (n < 0) /* error occurred? */ { - if (!fluid_alsa_handle_write_error (dev->pcm, n)) + if (fluid_alsa_handle_write_error (dev->pcm, n) != FLUID_OK) goto error_recovery; } else offset += n; /* no error occurred */ } /* while (offset < buffer_size) */ @@ -498,7 +498,7 @@ static void* fluid_alsa_audio_run_float(void* d) if (n < 0) /* error occurred? */ { - if (!fluid_alsa_handle_write_error (dev->pcm, n)) + if (fluid_alsa_handle_write_error (dev->pcm, n) != FLUID_OK) goto error_recovery; } else offset += n; /* no error occurred */ } /* while (offset < buffer_size) */ @@ -563,7 +563,7 @@ static void* fluid_alsa_audio_run_s16(void* d) if (n < 0) /* error occurred? */ { - if (!fluid_alsa_handle_write_error (dev->pcm, n)) + if (fluid_alsa_handle_write_error (dev->pcm, n) != FLUID_OK) goto error_recovery; } else offset += n; /* no error occurred */ } /* while (offset < buffer_size) */ @@ -580,7 +580,7 @@ static void* fluid_alsa_audio_run_s16(void* d) if (n < 0) /* error occurred? */ { - if (!fluid_alsa_handle_write_error (dev->pcm, n)) + if (fluid_alsa_handle_write_error (dev->pcm, n) != FLUID_OK) goto error_recovery; } else offset += n; /* no error occurred */ } /* while (offset < buffer_size) */ diff --git a/fluidsynth/src/fluid_dll.c b/fluidsynth/src/fluid_dll.c index 011a1ef2..fbf7e648 100644 --- a/fluidsynth/src/fluid_dll.c +++ b/fluidsynth/src/fluid_dll.c @@ -95,4 +95,5 @@ HWND fluid_win32_get_window(void) { return fluid_wnd; } -#endif + +#endif // #ifdef WIN32 diff --git a/fluidsynth/src/fluid_strtok.c b/fluidsynth/src/fluid_strtok.c deleted file mode 100644 index 6f115ca6..00000000 --- a/fluidsynth/src/fluid_strtok.c +++ /dev/null @@ -1,123 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -#include "fluid_strtok.h" -#include "fluidsynth_priv.h" - -/* - * new_fluid_strtok - */ -fluid_strtok_t* new_fluid_strtok(char* s, char* d) -{ - fluid_strtok_t* st; - st = FLUID_NEW(fluid_strtok_t); - if (st == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - /* Careful! the strings are not copied for speed */ - st->string = s; - st->delimiters = d; - st->offset = 0; - st->len = (s == NULL)? 0 : strlen(s); - return st; -} - -int delete_fluid_strtok(fluid_strtok_t* st) -{ - if (st == NULL) { - FLUID_LOG(FLUID_ERR, "Null pointer"); - return 0; - } - free(st); - return 0; -} - -int fluid_strtok_set(fluid_strtok_t* st, char* s, char* d) -{ - /* Careful! the strings are not copied for speed */ - st->string = s; - st->delimiters = d; - st->offset = 0; - st->len = (s == NULL)? 0 : strlen(s); - return 0; -} - -char* fluid_strtok_next_token(fluid_strtok_t* st) -{ - int start = st->offset; - int end; - if ((st == NULL) || (st->string == NULL) || (st->delimiters == NULL)) { - FLUID_LOG(FLUID_ERR, "Null pointer"); - return NULL; - } - if (start >= st->len) { - return NULL; - } - while (fluid_strtok_char_index(st->string[start], st->delimiters) >= 0) { - if (start == st->len) { - return NULL; - } - start++; - } - end = start + 1; - while (fluid_strtok_char_index(st->string[end], st->delimiters) < 0) { - if (end == st->len) { - break; - } - end++; - } - st->string[end] = 0; - st->offset = end + 1; - return &st->string[start]; -} - -int fluid_strtok_has_more(fluid_strtok_t* st) -{ - int cur = st->offset; - if ((st == NULL) || (st->string == NULL) || (st->delimiters == NULL)) { - FLUID_LOG(FLUID_ERR, "Null pointer"); - return -1; - } - while (cur < st->len) { - if (fluid_strtok_char_index(st->string[cur], st->delimiters) < 0) { - return -1; - } - cur++; - } - return 0; -} - -int fluid_strtok_char_index(char c, char* s) -{ - int i; - if (s == NULL) { - FLUID_LOG(FLUID_ERR, "Null pointer"); - return -1; - } - for (i = 0; s[i] != 0; i++) { - if (s[i] == c) { - return i; - } - } - return -1; -} - diff --git a/fluidsynth/src/fluid_strtok.h b/fluidsynth/src/fluid_strtok.h deleted file mode 100644 index 07649058..00000000 --- a/fluidsynth/src/fluid_strtok.h +++ /dev/null @@ -1,44 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -#ifndef _FLUID_STRTOK_H -#define _FLUID_STRTOK_H - -#include "fluidsynth_priv.h" - - -/** string tokenizer */ -typedef struct { - char* string; - char* delimiters; - int offset; - int len; -} fluid_strtok_t; - -fluid_strtok_t* new_fluid_strtok(char* s, char* d); -int delete_fluid_strtok(fluid_strtok_t* st); -int fluid_strtok_set(fluid_strtok_t* st, char* s, char* d); -char* fluid_strtok_next_token(fluid_strtok_t* st); -int fluid_strtok_has_more(fluid_strtok_t* st); -int fluid_strtok_char_index(char c, char* s); - - -#endif /* _FLUID_STRTOK_H */ diff --git a/fluidsynth/src/fluid_synth.c b/fluidsynth/src/fluid_synth.c index 2f830026..d5a54d3e 100644 --- a/fluidsynth/src/fluid_synth.c +++ b/fluidsynth/src/fluid_synth.c @@ -1722,6 +1722,16 @@ static void init_dither(void) } } +/* A portable replacement for roundf(), seems it may actually be faster too! */ +static inline int +roundi (float x) +{ + if (x >= 0.0f) + return (int)(x+0.5f); + else + return (int)(x-0.5f); +} + /* * fluid_synth_write_s16 */ @@ -1740,6 +1750,7 @@ fluid_synth_write_s16(fluid_synth_t* synth, int len, fluid_real_t right_sample; double time = fluid_utime(); int di = synth->dither_index; + double prof_ref_on_block; /* make sure we're playing */ if (synth->state != FLUID_SYNTH_PLAYING) { @@ -1752,8 +1763,7 @@ fluid_synth_write_s16(fluid_synth_t* synth, int len, /* fill up the buffers as needed */ if (cur == FLUID_BUFSIZE) { - - double prof_ref_on_block = fluid_profile_ref(); + prof_ref_on_block = fluid_profile_ref(); fluid_synth_one_block(synth, 0); cur = 0; @@ -1761,8 +1771,8 @@ fluid_synth_write_s16(fluid_synth_t* synth, int len, fluid_profile(FLUID_PROF_ONE_BLOCK, prof_ref_on_block); } - left_sample = left_in[cur] * 32767.0f + rand_table[0][di]; - right_sample = right_in[cur] * 32767.0f + rand_table[1][di]; + left_sample = roundi (left_in[cur] * 32766.0f + rand_table[0][di]); + right_sample = roundi (right_in[cur] * 32766.0f + rand_table[1][di]); di++; if (di >= DITHER_SIZE) di = 0; @@ -1815,8 +1825,8 @@ fluid_synth_dither_s16(fluid_synth_t* synth, int len, float* lin, float* rin, for (i = 0, j = loff, k = roff; i < len; i++, j += lincr, k += rincr) { - left_sample = lin[i] * 32767.0f + rand_table[0][di]; - right_sample = rin[i] * 32767.0f + rand_table[1][di]; + left_sample = roundi (lin[i] * 32766.0f + rand_table[0][di]); + right_sample = roundi (rin[i] * 32766.0f + rand_table[1][di]); di++; if (di >= DITHER_SIZE) di = 0;