Hello community, here is the log from the commit of package fluidsynth for openSUSE:Factory checked in at 2018-10-11 11:44:13 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/fluidsynth (Old) and /work/SRC/openSUSE:Factory/.fluidsynth.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "fluidsynth" Thu Oct 11 11:44:13 2018 rev:40 rq:640547 version:2.0.1 Changes: -------- --- /work/SRC/openSUSE:Factory/fluidsynth/fluidsynth.changes 2018-09-26 16:01:57.628437760 +0200 +++ /work/SRC/openSUSE:Factory/.fluidsynth.new/fluidsynth.changes 2018-10-11 11:44:52.286831127 +0200 @@ -1,0 +2,19 @@ +Sun Oct 7 15:31:52 UTC 2018 - [email protected] + +- Update to 2.0.1: + * implement auto-conntect for CoreMidi + * fix a build issue with cmake < 3.3 + * fix a crash when creating multiple jack drivers + * various fixes to dsound driver + * fix multiple potential NULL dereferences + * fix two memory leaks in the soundfont loader + * correct upper threshold of synth.chorus.depth +- Remove fluidsynth-last_client-reuse-fix.patch + +------------------------------------------------------------------- +Sat Sep 29 11:38:37 UTC 2018 - Luigi Baldoni <[email protected]> + +- Backported fluidsynth-last_client-reuse-fix.patch from master + (qsynth crashes without it) + +------------------------------------------------------------------- Old: ---- fluidsynth-2.0.0.tar.gz New: ---- fluidsynth-2.0.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ fluidsynth.spec ++++++ --- /var/tmp/diff_new_pack.m2a5v5/_old 2018-10-11 11:44:53.162830012 +0200 +++ /var/tmp/diff_new_pack.m2a5v5/_new 2018-10-11 11:44:53.166830007 +0200 @@ -12,7 +12,7 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # @@ -24,10 +24,10 @@ %endif Name: fluidsynth -Version: 2.0.0 +Version: 2.0.1 Release: 0 Summary: A Real-Time Software Synthesizer That Uses Soundfont(tm) -License: LGPL-2.1+ +License: LGPL-2.1-or-later Group: Productivity/Multimedia/Sound/Midi Url: http://www.fluidsynth.org/ Source: https://github.com/FluidSynth/%{name}/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz ++++++ fluidsynth-2.0.0.tar.gz -> fluidsynth-2.0.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.0.0/.travis.yml new/fluidsynth-2.0.1/.travis.yml --- old/fluidsynth-2.0.0/.travis.yml 2018-09-12 12:10:29.000000000 +0200 +++ new/fluidsynth-2.0.1/.travis.yml 2018-10-07 14:47:07.000000000 +0200 @@ -53,20 +53,6 @@ env: - MATRIX_EVAL="CC=gcc-4.8 && CXX=g++-4.8" - CMAKE_FLAGS="-Denable-floats=0" - - - os: linux - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-4.9 - - cmake-data - - cmake - - libglib2.0-0 - - ladspa-sdk - env: - - MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9" # works on Precise and Trusty - os: linux @@ -141,6 +127,12 @@ - cmake-data - cmake - libglib2.0-0 + - libsndfile-dev + - libasound2-dev + - libjack-dev + - portaudio19-dev + - libpulse-dev + - libdbus-glib-1-dev - ladspa-sdk env: - MATRIX_EVAL="CC=clang-3.8 && CXX=clang++-3.8" @@ -150,51 +142,62 @@ addons: apt: sources: - - llvm-toolchain-trusty-3.9 + - llvm-toolchain-trusty-4.0 packages: - - clang-3.9 + - clang-4.0 - cmake-data - cmake - libglib2.0-0 - - libsndfile-dev - - libasound2-dev - - libjack-dev - - portaudio19-dev - - libpulse-dev - - libdbus-glib-1-dev - ladspa-sdk env: - - MATRIX_EVAL="CC=clang-3.9 && CXX=clang++-3.9" + - MATRIX_EVAL="CC=clang-4.0 && CXX=clang++-4.0" # works on Trusty - os: linux addons: apt: sources: - - llvm-toolchain-trusty-4.0 + - llvm-toolchain-trusty-5.0 packages: - - clang-4.0 + - clang-5.0 - cmake-data - cmake - libglib2.0-0 - ladspa-sdk env: - - MATRIX_EVAL="CC=clang-4.0 && CXX=clang++-4.0" + - MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0" # works on Trusty - os: linux addons: apt: sources: - - llvm-toolchain-trusty-5.0 + - ubuntu-toolchain-r-test + - llvm-toolchain-trusty-6.0 packages: - - clang-5.0 + - clang-6.0 - cmake-data - cmake - libglib2.0-0 - ladspa-sdk env: - - MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0" + - MATRIX_EVAL="CC=clang-6.0 && CXX=clang++-6.0" + + # works on Trusty + - os: linux + addons: + apt: + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-trusty-7 + packages: + - clang-7 + - cmake-data + - cmake + - libglib2.0-0 + - ladspa-sdk + env: + - MATRIX_EVAL="CC=clang-7 && CXX=clang++-7" - os: osx osx_image: xcode8 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.0.0/CMakeLists.txt new/fluidsynth-2.0.1/CMakeLists.txt --- old/fluidsynth-2.0.0/CMakeLists.txt 2018-09-12 12:10:29.000000000 +0200 +++ new/fluidsynth-2.0.1/CMakeLists.txt 2018-10-07 14:47:07.000000000 +0200 @@ -29,7 +29,7 @@ # FluidSynth package version set ( FLUIDSYNTH_VERSION_MAJOR 2 ) set ( FLUIDSYNTH_VERSION_MINOR 0 ) -set ( FLUIDSYNTH_VERSION_MICRO 0 ) +set ( FLUIDSYNTH_VERSION_MICRO 1 ) set ( VERSION "${FLUIDSYNTH_VERSION_MAJOR}.${FLUIDSYNTH_VERSION_MINOR}.${FLUIDSYNTH_VERSION_MICRO}" ) set ( FLUIDSYNTH_VERSION "\"${VERSION}\"" ) @@ -44,7 +44,7 @@ # This is not exactly the same algorithm as the libtool one, but the results are the same. set ( LIB_VERSION_CURRENT 2 ) set ( LIB_VERSION_AGE 0 ) -set ( LIB_VERSION_REVISION 0 ) +set ( LIB_VERSION_REVISION 1 ) set ( LIB_VERSION_INFO "${LIB_VERSION_CURRENT}.${LIB_VERSION_AGE}.${LIB_VERSION_REVISION}" ) @@ -116,9 +116,11 @@ if ( NOT OS2 ) set ( CMAKE_C_VISIBILITY_PRESET hidden ) endif ( NOT OS2 ) -# enforce visibility control for all types of cmake targets -cmake_policy ( SET CMP0063 NEW ) +# enforce visibility control for all types of cmake targets +if ( POLICY CMP0063 ) + cmake_policy ( SET CMP0063 NEW ) +endif ( POLICY CMP0063 ) # Default install directory names include ( DefaultDirs ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.0.0/doc/Doxyfile new/fluidsynth-2.0.1/doc/Doxyfile --- old/fluidsynth-2.0.0/doc/Doxyfile 2018-09-12 12:10:29.000000000 +0200 +++ new/fluidsynth-2.0.1/doc/Doxyfile 2018-10-07 14:47:07.000000000 +0200 @@ -5,7 +5,7 @@ #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = libfluidsynth -PROJECT_NUMBER = 2.0.0 +PROJECT_NUMBER = 2.0.1 OUTPUT_DIRECTORY = api CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.0.0/doc/fluidsettings.xml new/fluidsynth-2.0.1/doc/fluidsettings.xml --- old/fluidsynth-2.0.0/doc/fluidsettings.xml 2018-09-12 12:10:29.000000000 +0200 +++ new/fluidsynth-2.0.1/doc/fluidsettings.xml 2018-10-07 14:47:07.000000000 +0200 @@ -47,7 +47,7 @@ <type>num</type> <def>8</def> <min>0</min> - <max>21</max> + <max>256</max> <desc> Specifies the modulation depth of the chorus.</desc> </setting> @@ -331,7 +331,7 @@ <name>sample-rate</name> <type>num</type> <def>44100.0</def> - <min>22050.0</min> + <min>8000.0</min> <max>96000.0</max> <desc> The sample rate of the audio generated by the synthesizer. @@ -584,7 +584,7 @@ <type>bool</type> <def>0 (FALSE)</def> <desc> - If 1 (TRUE), automatically connects FluidSynth to available MIDI input ports. alsa_seq is currently the only driver making use of this. + If 1 (TRUE), automatically connects FluidSynth to available MIDI input ports. alsa_seq and coremidi are currently the only drivers making use of this. </desc> </setting> <setting> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.0.0/doc/fluidsynth-v20-devdoc.txt new/fluidsynth-2.0.1/doc/fluidsynth-v20-devdoc.txt --- old/fluidsynth-2.0.0/doc/fluidsynth-v20-devdoc.txt 2018-09-12 12:10:29.000000000 +0200 +++ new/fluidsynth-2.0.1/doc/fluidsynth-v20-devdoc.txt 2018-10-07 14:47:07.000000000 +0200 @@ -8,8 +8,8 @@ \author David Henningsson \author Tom Moebert \author Copyright © 2003-2018 Peter Hanappe, Conrad Berhörster, Antoine Schmitt, Pedro López-Cabanillas, Josh Green, David Henningsson, Tom Moebert -\version Revision 2.0.0 -\date 2018-09-12 +\version Revision 2.0.1 +\date 2018-10-07 All the source code examples in this document are in the public domain; you can use them as you please. This document is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ . The FluidSynth library is distributed under the GNU Lesser General Public License. A copy of the GNU Lesser General Public License is contained in the FluidSynth package; if not, visit http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt or write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.0.0/doc/fluidsynth.1 new/fluidsynth-2.0.1/doc/fluidsynth.1 --- old/fluidsynth-2.0.0/doc/fluidsynth.1 2018-09-12 12:10:29.000000000 +0200 +++ new/fluidsynth-2.0.1/doc/fluidsynth.1 2018-10-07 14:47:07.000000000 +0200 @@ -13,7 +13,7 @@ .\" along with this program; see the file LICENSE. If not, write to .\" the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. .\" -.TH FluidSynth 1 "Sep 12, 2018" +.TH FluidSynth 1 "Oct 6, 2018" .\" Please update the above date whenever this man page is modified. .\" .\" Some roff macros, for reference: @@ -200,39 +200,36 @@ .TP .B REVERB .TP -.B reverb [0|1|on|off] +.B set synth.reverb.active [0|1] Turn the reverb on or off .TP -.B rev_preset num -Load preset num into the reverb unit -.TP -.B rev_setroomsize num +.B set synth.reverb.room-size num Change reverb room size .TP -.B rev_setdamp num +.B set synth.reverb.damp num Change reverb damping .TP -.B rev_setwidth num +.B set synth.reverb.width num Change reverb width .TP -.B rev_setlevel num +.B set synth.reverb.level num Change reverb level .TP .B CHORUS .TP -.B chorus [0|1|on|off] +.B set synth.chorus.active [0|1] Turn the chorus on or off .TP -.B cho_set_nr n +.B set synth.chorus.nr n Use n delay lines (default 3) .TP -.B cho_set_level num +.B set synth.chorus.level num Set output level of each chorus line to num .TP -.B cho_set_speed num +.B set synth.chorus.speed num Set mod speed of chorus to num (Hz) .TP -.B cho_set_depth num +.B set synth.chorus.depth num Set chorus modulation depth to num (ms) .TP .B MIDI ROUTER diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.0.0/doc/fluidsynth_sfload_mem.c new/fluidsynth-2.0.1/doc/fluidsynth_sfload_mem.c --- old/fluidsynth-2.0.0/doc/fluidsynth_sfload_mem.c 2018-09-12 12:10:29.000000000 +0200 +++ new/fluidsynth-2.0.1/doc/fluidsynth_sfload_mem.c 2018-10-07 14:47:07.000000000 +0200 @@ -19,14 +19,13 @@ return NULL; } - scanf("&%p", &p); + sscanf(filename, "&%p", &p); return p; } int my_read(void *buf, int count, void *handle) { - // not yet implemented - memset(buf, 0, count); + // NYI return FLUID_OK; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.0.0/src/bindings/fluid_cmd.c new/fluidsynth-2.0.1/src/bindings/fluid_cmd.c --- old/fluidsynth-2.0.0/src/bindings/fluid_cmd.c 2018-09-12 12:10:29.000000000 +0200 +++ new/fluidsynth-2.0.1/src/bindings/fluid_cmd.c 2018-10-07 14:47:07.000000000 +0200 @@ -1839,7 +1839,7 @@ { case FLUID_NO_TYPE: fluid_ostream_printf(out, "set: Parameter '%s' not found.\n", av[0]); - break; + return ret; case FLUID_INT_TYPE: if(fluid_settings_get_hints(handler->synth->settings, av[0], &hints) == FLUID_OK @@ -1879,7 +1879,7 @@ if(ret == FLUID_FAILED) { - fluid_ostream_printf(out, "set: Value out of range.\n"); + fluid_ostream_printf(out, "set: Value out of range. Try 'info %s' for valid ranges\n", av[0]); } if(!fluid_settings_is_realtime(handler->synth->settings, av[0])) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.0.0/src/drivers/fluid_coremidi.c new/fluidsynth-2.0.1/src/drivers/fluid_coremidi.c --- old/fluidsynth-2.0.0/src/drivers/fluid_coremidi.c 2018-09-12 12:10:29.000000000 +0200 +++ new/fluidsynth-2.0.1/src/drivers/fluid_coremidi.c 2018-10-07 14:47:07.000000000 +0200 @@ -57,7 +57,9 @@ fluid_midi_driver_t driver; MIDIClientRef client; MIDIEndpointRef endpoint; + MIDIPortRef input_port; fluid_midi_parser_t *parser; + int autoconn_inputs; } fluid_coremidi_driver_t; void fluid_coremidi_callback(const MIDIPacketList *list, void *p, void *src); @@ -67,6 +69,31 @@ fluid_settings_register_str(settings, "midi.coremidi.id", "pid", 0); } +static void fluid_coremidi_autoconnect(fluid_coremidi_driver_t *dev, MIDIPortRef input_port) +{ + int i; + int source_count = MIDIGetNumberOfSources(); + for(i = 0; i < source_count; ++i) + { + MIDIEndpointRef source = MIDIGetSource(i); + + CFStringRef externalName; + OSStatus result = MIDIObjectGetStringProperty(source, kMIDIPropertyName, &externalName); + const char *source_name = CFStringGetCStringPtr(externalName, kCFStringEncodingASCII); + CFRelease(externalName); + + result = MIDIPortConnectSource(input_port, source, NULL); + if(result != noErr) + { + FLUID_LOG(FLUID_ERR, "Failed to connect \"%s\" device to input port.", source_name); + } + else + { + FLUID_LOG(FLUID_DBG, "Connected input port to \"%s\".", source_name); + } + } +} + /* * new_fluid_coremidi_driver */ @@ -147,6 +174,7 @@ } OSStatus result = MIDIClientCreate(str_clientname, NULL, NULL, &client); + CFRelease(str_clientname); if(result != noErr) { @@ -166,6 +194,25 @@ goto error_recovery; } + CFStringRef str_input_portname = CFSTR("input"); + result = MIDIInputPortCreate(client, str_input_portname, + fluid_coremidi_callback, + (void *)dev, &dev->input_port); + CFRelease(str_input_portname); + + if(result != noErr) + { + FLUID_LOG(FLUID_ERR, "Failed to create input port."); + goto error_recovery; + } + + fluid_settings_getint(settings, "midi.autoconnect", &dev->autoconn_inputs); + + if(dev->autoconn_inputs) + { + fluid_coremidi_autoconnect(dev, dev->input_port); + } + dev->endpoint = endpoint; return (fluid_midi_driver_t *) dev; @@ -184,6 +231,11 @@ fluid_coremidi_driver_t *dev = (fluid_coremidi_driver_t *) p; fluid_return_if_fail(dev != NULL); + if(dev->input_port != NULL) + { + MIDIPortDispose(dev->input_port); + } + if(dev->client != NULL) { MIDIClientDispose(dev->client); @@ -227,4 +279,3 @@ } #endif /* COREMIDI_SUPPORT */ - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.0.0/src/drivers/fluid_dsound.c new/fluidsynth-2.0.1/src/drivers/fluid_dsound.c --- old/fluidsynth-2.0.0/src/drivers/fluid_dsound.c 2018-09-12 12:10:29.000000000 +0200 +++ new/fluidsynth-2.0.1/src/drivers/fluid_dsound.c 2018-10-07 14:47:07.000000000 +0200 @@ -30,9 +30,12 @@ #include <mmsystem.h> #include <dsound.h> -DWORD WINAPI fluid_dsound_audio_run(LPVOID lpParameter); +#define NOBITMAP +#include <mmreg.h> -char *fluid_win32_error(HRESULT hr); +static DWORD WINAPI fluid_dsound_audio_run(LPVOID lpParameter); + +static char *fluid_win32_error(HRESULT hr); typedef struct { @@ -40,12 +43,12 @@ LPDIRECTSOUND direct_sound; LPDIRECTSOUNDBUFFER prim_buffer; LPDIRECTSOUNDBUFFER sec_buffer; - WAVEFORMATEX *format; HANDLE thread; DWORD threadID; fluid_synth_t *synth; fluid_audio_callback_t write; - int cont; + HANDLE quit_ev; + int bytes_per_second; DWORD buffer_byte_size; DWORD queue_byte_size; DWORD frame_size; @@ -109,6 +112,7 @@ double sample_rate; int periods, period_size; fluid_dsound_devsel_t devsel; + WAVEFORMATEX format; /* create and clear the driver data */ dev = FLUID_NEW(fluid_dsound_audio_driver_t); @@ -121,42 +125,49 @@ FLUID_MEMSET(dev, 0, sizeof(fluid_dsound_audio_driver_t)); dev->synth = synth; - dev->cont = 1; fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate); fluid_settings_getint(settings, "audio.periods", &periods); fluid_settings_getint(settings, "audio.period-size", &period_size); + /* Clear the buffer format */ + ZeroMemory(&format, sizeof(WAVEFORMATEX)); + /* check the format */ - if(!fluid_settings_str_equal(settings, "audio.sample-format", "16bits")) + if(fluid_settings_str_equal(settings, "audio.sample-format", "float")) { - FLUID_LOG(FLUID_ERR, "Unhandled sample format"); - goto error_recovery; - } + FLUID_LOG(FLUID_DBG, "Selected 32 bit sample format"); - dev->frame_size = 2 * sizeof(short); - dev->buffer_byte_size = period_size * dev->frame_size; - dev->queue_byte_size = periods * dev->buffer_byte_size; - dev->write = fluid_synth_write_s16; + dev->frame_size = 2 * sizeof(float); + dev->write = fluid_synth_write_float; + + format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; + } + else if(fluid_settings_str_equal(settings, "audio.sample-format", "16bits")) + { + FLUID_LOG(FLUID_DBG, "Selected 16 bit sample format"); - /* create and initialize the buffer format */ - dev->format = (WAVEFORMATEX *) FLUID_MALLOC(sizeof(WAVEFORMATEX)); + dev->frame_size = 2 * sizeof(short); + dev->write = fluid_synth_write_s16; - if(dev->format == NULL) + format.wFormatTag = WAVE_FORMAT_PCM; + } + else { - FLUID_LOG(FLUID_ERR, "Out of memory"); + FLUID_LOG(FLUID_ERR, "Unhandled sample format"); goto error_recovery; } - ZeroMemory(dev->format, sizeof(WAVEFORMATEX)); + dev->buffer_byte_size = period_size * dev->frame_size; + dev->queue_byte_size = periods * dev->buffer_byte_size; + dev->bytes_per_second = sample_rate * dev->frame_size; - dev->format->wFormatTag = WAVE_FORMAT_PCM; - dev->format->nChannels = 2; - dev->format->wBitsPerSample = 16; - dev->format->nSamplesPerSec = (DWORD) sample_rate; - dev->format->nBlockAlign = (WORD) dev->frame_size; - dev->format->nAvgBytesPerSec = dev->format->nSamplesPerSec * dev->frame_size; - dev->format->cbSize = 0; + /* Finish to initialize the buffer format */ + format.nChannels = 2; + format.wBitsPerSample = dev->frame_size * 4; + format.nSamplesPerSec = (DWORD) sample_rate; + format.nBlockAlign = (WORD) dev->frame_size; + format.nAvgBytesPerSec = dev->bytes_per_second; devsel.devGUID = NULL; @@ -220,11 +231,11 @@ /* set the primary sound buffer to this format. if it fails, just print a warning. */ - hr = IDirectSoundBuffer_SetFormat(dev->prim_buffer, dev->format); + hr = IDirectSoundBuffer_SetFormat(dev->prim_buffer, &format); if(hr != DS_OK) { - FLUID_LOG(FLUID_WARN, "Can't set format of primary sound buffer", fluid_win32_error(hr)); + FLUID_LOG(FLUID_WARN, "Can't set format of primary sound buffer: %s", fluid_win32_error(hr)); } /* initialize the buffer description */ @@ -232,9 +243,8 @@ ZeroMemory(&desc, sizeof(DSBUFFERDESC)); desc.dwSize = sizeof(DSBUFFERDESC); desc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2; - desc.lpwfxFormat = dev->format; + desc.lpwfxFormat = &format; desc.dwBufferBytes = dev->queue_byte_size; - desc.dwReserved = 0; if(caps.dwFreeHwMixingStreamingBuffers > 0) { @@ -267,9 +277,16 @@ /* Unlock */ IDirectSoundBuffer_Unlock(dev->sec_buffer, buf1, bytes1, 0, 0); + /* Create object to signal thread exit */ + dev->quit_ev = CreateEvent(NULL, FALSE, FALSE, NULL); + + if(dev->quit_ev == NULL) + { + goto error_recovery; + } /* start the audio thread */ - dev->thread = CreateThread(NULL, 0, &fluid_dsound_audio_run, (LPVOID) dev, 0, &dev->threadID); + dev->thread = CreateThread(NULL, 0, fluid_dsound_audio_run, (LPVOID) dev, 0, &dev->threadID); if(dev->thread == NULL) { @@ -289,23 +306,30 @@ fluid_dsound_audio_driver_t *dev = (fluid_dsound_audio_driver_t *) d; fluid_return_if_fail(dev != NULL); - /* tell the audio thread to stop its loop */ - dev->cont = 0; - /* wait till the audio thread exits */ - if(dev->thread != 0) + if(dev->thread != NULL) { + /* tell the audio thread to stop its loop */ + SetEvent(dev->quit_ev); + if(WaitForSingleObject(dev->thread, 2000) != WAIT_OBJECT_0) { /* on error kill the thread mercilessly */ FLUID_LOG(FLUID_DBG, "Couldn't join the audio thread. killing it."); TerminateThread(dev->thread, 0); } + + /* Release the thread object */ + CloseHandle(dev->thread); } - /* release all the allocated ressources */ + /* Release the event object */ + if(dev->quit_ev != NULL) + { + CloseHandle(dev->quit_ev); + } - FLUID_FREE(dev->format); + /* release all the allocated resources */ if(dev->sec_buffer != NULL) { @@ -326,13 +350,14 @@ FLUID_FREE(dev); } -DWORD WINAPI fluid_dsound_audio_run(LPVOID lpParameter) +static DWORD WINAPI fluid_dsound_audio_run(LPVOID lpParameter) { fluid_dsound_audio_driver_t *dev = (fluid_dsound_audio_driver_t *) lpParameter; short *buf1, *buf2; DWORD bytes1, bytes2; DWORD cur_position, frames, play_position, write_position, bytes; HRESULT res; + int ms; cur_position = 0; @@ -341,9 +366,8 @@ IDirectSoundBuffer_Play(dev->sec_buffer, 0, 0, DSBPLAY_LOOPING); - while(dev->cont) + for(;;) { - IDirectSoundBuffer_GetCurrentPosition(dev->sec_buffer, &play_position, &write_position); if(cur_position <= play_position) @@ -395,19 +419,32 @@ cur_position -= dev->queue_byte_size; } + /* 1 ms of wait */ + ms = 1; } else { - Sleep(1); + /* Calculate how many milliseconds to sleep (minus 1 for safety) */ + ms = (dev->buffer_byte_size - bytes) * 1000 / dev->bytes_per_second - 1; + + if(ms < 1) + { + ms = 1; + } + } + + /* Wait quit event or timeout */ + if(WaitForSingleObject(dev->quit_ev, ms) == WAIT_OBJECT_0) + { + break; } } - ExitThread(0); - return 0; /* never reached */ + return 0; } -char *fluid_win32_error(HRESULT hr) +static char *fluid_win32_error(HRESULT hr) { char *s = "Don't know why"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.0.0/src/drivers/fluid_jack.c new/fluidsynth-2.0.1/src/drivers/fluid_jack.c --- old/fluidsynth-2.0.0/src/drivers/fluid_jack.c 2018-09-12 12:10:29.000000000 +0200 +++ new/fluidsynth-2.0.1/src/drivers/fluid_jack.c 2018-10-07 14:47:07.000000000 +0200 @@ -137,7 +137,7 @@ * then re-use the client. */ if(last_client && (last_client->server != NULL && server != NULL && FLUID_STRCMP(last_client->server, server) == 0) && - ((!isaudio && last_client->midi_driver != NULL) || (isaudio && last_client->audio_driver != NULL))) + ((!isaudio && last_client->midi_driver == NULL) || (isaudio && last_client->audio_driver == NULL))) { client_ref = last_client; last_client = NULL; /* No more pairing for this client */ @@ -670,7 +670,7 @@ } else { - fluid_audio_func_t callback = (audio_driver->callback != NULL) ? audio_driver->callback : fluid_synth_process; + fluid_audio_func_t callback = (audio_driver->callback != NULL) ? audio_driver->callback : (fluid_audio_func_t) fluid_synth_process; for(i = 0; i < audio_driver->num_output_ports; i++) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.0.0/src/midi/fluid_seq.c new/fluidsynth-2.0.1/src/midi/fluid_seq.c --- old/fluidsynth-2.0.0/src/midi/fluid_seq.c 2018-09-12 12:10:29.000000000 +0200 +++ new/fluidsynth-2.0.1/src/midi/fluid_seq.c 2018-10-07 14:47:07.000000000 +0200 @@ -156,6 +156,7 @@ /** * Free a sequencer object. + * @note Registered sequencer clients may not be fully freed by this function. Explicitly unregister them with fluid_sequencer_unregister_client(). * @param seq Sequencer to delete */ void diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.0.0/src/rvoice/fluid_chorus.c new/fluidsynth-2.0.1/src/rvoice/fluid_chorus.c --- old/fluidsynth-2.0.0/src/rvoice/fluid_chorus.c 2018-09-12 12:10:29.000000000 +0200 +++ new/fluidsynth-2.0.1/src/rvoice/fluid_chorus.c 2018-10-07 14:47:07.000000000 +0200 @@ -90,8 +90,8 @@ * Set through MAX_SAMPLES_LN2. * For example: * MAX_SAMPLES_LN2=12 - * => MAX_SAMPLES=pow(2,12)=4096 - * => MAX_SAMPLES_ANDMASK=4095 + * => MAX_SAMPLES=pow(2,12-1)=2048 + * => MAX_SAMPLES_ANDMASK=2047 */ #define MAX_SAMPLES_LN2 12 @@ -348,25 +348,27 @@ { fluid_log(FLUID_WARN, "chorus: Too high depth. Setting it to max (%d).", MAX_SAMPLES); modulation_depth_samples = MAX_SAMPLES; + // set depth to maximum to avoid spamming console with above warning + chorus->depth_ms = (modulation_depth_samples * 1000) / chorus->sample_rate; } /* initialize LFO table */ - if(chorus->type == FLUID_CHORUS_MOD_SINE) - { - fluid_chorus_sine(chorus->lookup_tab, chorus->modulation_period_samples, - modulation_depth_samples); - } - else if(chorus->type == FLUID_CHORUS_MOD_TRIANGLE) - { - fluid_chorus_triangle(chorus->lookup_tab, chorus->modulation_period_samples, - modulation_depth_samples); - } - else + switch(chorus->type) { + default: fluid_log(FLUID_WARN, "chorus: Unknown modulation type. Using sinewave."); chorus->type = FLUID_CHORUS_MOD_SINE; + /* fall-through */ + + case FLUID_CHORUS_MOD_SINE: fluid_chorus_sine(chorus->lookup_tab, chorus->modulation_period_samples, modulation_depth_samples); + break; + + case FLUID_CHORUS_MOD_TRIANGLE: + fluid_chorus_triangle(chorus->lookup_tab, chorus->modulation_period_samples, + modulation_depth_samples); + break; } for(i = 0; i < chorus->number_blocks; i++) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.0.0/src/sfloader/fluid_defsfont.c new/fluidsynth-2.0.1/src/sfloader/fluid_defsfont.c --- old/fluidsynth-2.0.0/src/sfloader/fluid_defsfont.c 2018-09-12 12:10:29.000000000 +0200 +++ new/fluidsynth-2.0.1/src/sfloader/fluid_defsfont.c 2018-10-07 14:47:07.000000000 +0200 @@ -833,42 +833,39 @@ { /* SF 2.01 section 8.5 page 58: If some generators are - * encountered at preset level, they should be ignored */ - 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)) - { + encountered at preset level, they should be ignored. + However this check is not necessary when the soundfont + loader has ignored invalid preset generators. + Actually load_pgen()has ignored these invalid preset + generators: + GEN_STARTADDROFS, GEN_ENDADDROFS, + GEN_STARTLOOPADDROFS, GEN_ENDLOOPADDROFS, + GEN_STARTADDRCOARSEOFS,GEN_ENDADDRCOARSEOFS, + GEN_STARTLOOPADDRCOARSEOFS, + GEN_KEYNUM, GEN_VELOCITY, + GEN_ENDLOOPADDRCOARSEOFS, + GEN_SAMPLEMODE, GEN_EXCLUSIVECLASS,GEN_OVERRIDEROOTKEY + */ - /* SF 2.01 section 9.4 'bullet' 9: A generator in a - * local preset zone supersedes a global preset zone - * generator. The effect is -added- to the destination - * summing node -> voice_gen_incr */ + /* SF 2.01 section 9.4 'bullet' 9: A generator in a + * local preset zone supersedes a global preset zone + * generator. The effect is -added- to the destination + * summing node -> voice_gen_incr */ - if(preset_zone->gen[i].flags) - { - fluid_voice_gen_incr(voice, i, preset_zone->gen[i].val); - } - else if((global_preset_zone != NULL) && global_preset_zone->gen[i].flags) - { - fluid_voice_gen_incr(voice, i, global_preset_zone->gen[i].val); - } - else - { - /* The generator has not been defined in this preset - * Do nothing, leave it unchanged. - */ - } - } /* if available at preset level */ + if(preset_zone->gen[i].flags) + { + fluid_voice_gen_incr(voice, i, preset_zone->gen[i].val); + } + else if((global_preset_zone != NULL) && global_preset_zone->gen[i].flags) + { + fluid_voice_gen_incr(voice, i, global_preset_zone->gen[i].val); + } + else + { + /* The generator has not been defined in this preset + * Do nothing, leave it unchanged. + */ + } } /* for all generators */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.0.0/src/sfloader/fluid_sffile.c new/fluidsynth-2.0.1/src/sfloader/fluid_sffile.c --- old/fluidsynth-2.0.0/src/sfloader/fluid_sffile.c 2018-09-12 12:10:29.000000000 +0200 +++ new/fluidsynth-2.0.1/src/sfloader/fluid_sffile.c 2018-10-07 14:47:07.000000000 +0200 @@ -489,9 +489,9 @@ static int chunkid(unsigned int id) { unsigned int i; - unsigned int *p; + const unsigned int *p; - p = (unsigned int *)&idlist; + p = (const unsigned int *)&idlist; for(i = 0; i < sizeof(idlist) / sizeof(int); i++, p += 1) { @@ -982,7 +982,11 @@ for(; i > 0; i--) { /* load all preset headers */ - preset = FLUID_NEW(SFPreset); + if((preset = FLUID_NEW(SFPreset)) == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + return FALSE; + } sf->preset = fluid_list_append(sf->preset, preset); preset->zone = NULL; /* In case of failure, fluid_sffile_close can cleanup */ READSTR(sf, &preset->name); /* possible read failure ^ */ @@ -1069,7 +1073,11 @@ return FALSE; } - z = FLUID_NEW(SFZone); + if((z = FLUID_NEW(SFZone)) == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + return FALSE; + } p2->data = z; z->gen = NULL; /* Init gen and mod before possible failure, */ z->mod = NULL; /* to ensure proper cleanup (fluid_sffile_close) */ @@ -1198,7 +1206,11 @@ return FALSE; } - m = FLUID_NEW(SFMod); + if((m = FLUID_NEW(SFMod)) == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + return FALSE; + } p3->data = m; READW(sf, m->src); READW(sf, m->dest); @@ -1350,7 +1362,11 @@ if(!dup) { /* if gen ! dup alloc new */ - g = FLUID_NEW(SFGen); + if((g = FLUID_NEW(SFGen)) == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + return FALSE; + } p3->data = g; g->id = genid; } @@ -1487,7 +1503,11 @@ for(i = 0; i < size; i++) { /* load all instrument headers */ - p = FLUID_NEW(SFInst); + if((p = FLUID_NEW(SFInst)) == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + return FALSE; + } sf->inst = fluid_list_append(sf->inst, p); p->zone = NULL; /* For proper cleanup if fail (fluid_sffile_close) */ p->idx = i; @@ -1568,7 +1588,11 @@ return FALSE; } - z = FLUID_NEW(SFZone); + if((z = FLUID_NEW(SFZone)) == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + return FALSE; + } p2->data = z; z->gen = NULL; /* In case of failure, */ z->mod = NULL; /* fluid_sffile_close can clean up */ @@ -1698,7 +1722,11 @@ return FALSE; } - m = FLUID_NEW(SFMod); + if((m = FLUID_NEW(SFMod)) == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + return FALSE; + } p3->data = m; READW(sf, m->src); READW(sf, m->dest); @@ -1839,7 +1867,11 @@ if(!dup) { /* if gen ! dup alloc new */ - g = FLUID_NEW(SFGen); + if((g = FLUID_NEW(SFGen)) == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + return FALSE; + } p3->data = g; g->id = genid; } @@ -1974,7 +2006,11 @@ /* load all sample headers */ for(i = 0; i < size; i++) { - p = FLUID_NEW(SFSample); + if((p = FLUID_NEW(SFSample)) == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + return FALSE; + } sf->sample = fluid_list_append(sf->sample, p); READSTR(sf, &p->name); READD(sf, p->start); @@ -2102,6 +2138,8 @@ } delete_fluid_list(preset->zone); + + FLUID_FREE(preset); } static void delete_inst(SFInst *inst) @@ -2124,6 +2162,8 @@ } delete_fluid_list(inst->zone); + + FLUID_FREE(inst); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.0.0/src/synth/fluid_mod.c new/fluidsynth-2.0.1/src/synth/fluid_mod.c --- old/fluidsynth-2.0.0/src/synth/fluid_mod.c 2018-09-12 12:10:29.000000000 +0200 +++ new/fluidsynth-2.0.1/src/synth/fluid_mod.c 2018-10-07 14:47:07.000000000 +0200 @@ -164,10 +164,10 @@ fluid_mod_get_source_value(const unsigned char mod_src, const unsigned char mod_flags, fluid_real_t *range, - const fluid_channel_t *chan, const fluid_voice_t *voice ) { + const fluid_channel_t *chan = voice->channel; fluid_real_t val; if(mod_flags & FLUID_MOD_CC) @@ -367,18 +367,13 @@ * fluid_mod_get_value */ fluid_real_t -fluid_mod_get_value(fluid_mod_t *mod, fluid_channel_t *chan, fluid_voice_t *voice) +fluid_mod_get_value(fluid_mod_t *mod, fluid_voice_t *voice) { extern fluid_mod_t default_vel2filter_mod; fluid_real_t v1 = 0.0, v2 = 1.0; fluid_real_t range1 = 127.0, range2 = 127.0; - if(chan == NULL) - { - return 0.0f; - } - /* 'special treatment' for default controller * * Reference: SF2.01 section 8.4.2 @@ -418,7 +413,7 @@ /* get the initial value of the first source */ if(mod->src1 > 0) { - v1 = fluid_mod_get_source_value(mod->src1, mod->flags1, &range1, chan, voice); + v1 = fluid_mod_get_source_value(mod->src1, mod->flags1, &range1, voice); /* transform the input value */ v1 = fluid_mod_transform_source_value(v1, mod->flags1, range1); @@ -437,7 +432,7 @@ /* get the second input source */ if(mod->src2 > 0) { - v2 = fluid_mod_get_source_value(mod->src2, mod->flags2, &range2, chan, voice); + v2 = fluid_mod_get_source_value(mod->src2, mod->flags2, &range2, voice); /* transform the second input value */ v2 = fluid_mod_transform_source_value(v2, mod->flags2, range2); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.0.0/src/synth/fluid_mod.h new/fluidsynth-2.0.1/src/synth/fluid_mod.h --- old/fluidsynth-2.0.0/src/synth/fluid_mod.h 2018-09-12 12:10:29.000000000 +0200 +++ new/fluidsynth-2.0.1/src/synth/fluid_mod.h 2018-10-07 14:47:07.000000000 +0200 @@ -43,7 +43,7 @@ fluid_mod_t *next; }; -fluid_real_t fluid_mod_get_value(fluid_mod_t *mod, fluid_channel_t *chan, fluid_voice_t *voice); +fluid_real_t fluid_mod_get_value(fluid_mod_t *mod, fluid_voice_t *voice); #ifdef DEBUG void fluid_dump_modulator(fluid_mod_t *mod); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.0.0/src/synth/fluid_synth.c new/fluidsynth-2.0.1/src/synth/fluid_synth.c --- old/fluidsynth-2.0.0/src/synth/fluid_synth.c 2018-09-12 12:10:29.000000000 +0200 +++ new/fluidsynth-2.0.1/src/synth/fluid_synth.c 2018-10-07 14:47:07.000000000 +0200 @@ -207,7 +207,7 @@ fluid_settings_register_int(settings, "synth.chorus.nr", FLUID_CHORUS_DEFAULT_N, 0, 99, 0); fluid_settings_register_num(settings, "synth.chorus.level", FLUID_CHORUS_DEFAULT_LEVEL, 0.0f, 10.0f, 0); fluid_settings_register_num(settings, "synth.chorus.speed", FLUID_CHORUS_DEFAULT_SPEED, 0.29f, 5.0f, 0); - fluid_settings_register_num(settings, "synth.chorus.depth", FLUID_CHORUS_DEFAULT_DEPTH, 0.0f, 21.0f, 0); + fluid_settings_register_num(settings, "synth.chorus.depth", FLUID_CHORUS_DEFAULT_DEPTH, 0.0f, 256.0f, 0); fluid_settings_register_int(settings, "synth.ladspa.active", 0, 0, 1, FLUID_HINT_TOGGLED); fluid_settings_register_int(settings, "synth.lock-memory", 1, 0, 1, FLUID_HINT_TOGGLED); @@ -3004,8 +3004,7 @@ /** * Set sample rate of the synth. - * @note This function is currently experimental and should only be - * used when no voices or notes are active, and before any rendering calls. + * @note This function should only be used when no voices or notes are active. * @param synth FluidSynth instance * @param sample_rate New sample rate (Hz) * @since 1.1.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.0.0/src/synth/fluid_voice.c new/fluidsynth-2.0.1/src/synth/fluid_voice.c --- old/fluidsynth-2.0.0/src/synth/fluid_voice.c 2018-09-12 12:10:29.000000000 +0200 +++ new/fluidsynth-2.0.1/src/synth/fluid_voice.c 2018-10-07 14:47:07.000000000 +0200 @@ -612,7 +612,7 @@ for(i = 0; i < voice->mod_count; i++) { fluid_mod_t *mod = &voice->mod[i]; - fluid_real_t modval = fluid_mod_get_value(mod, voice->channel, voice); + fluid_real_t modval = fluid_mod_get_value(mod, voice); int dest_gen_index = mod->dest; fluid_gen_t *dest_gen = &voice->gen[dest_gen_index]; dest_gen->mod += modval; @@ -1202,7 +1202,7 @@ { if(fluid_mod_has_dest(&voice->mod[k], gen)) { - modval += fluid_mod_get_value(&voice->mod[k], voice->channel, voice); + modval += fluid_mod_get_value(&voice->mod[k], voice); } } @@ -1251,7 +1251,7 @@ { if(fluid_mod_has_dest(&voice->mod[k], gen)) { - modval += fluid_mod_get_value(&voice->mod[k], voice->channel, voice); + modval += fluid_mod_get_value(&voice->mod[k], voice); } } @@ -1732,7 +1732,7 @@ || (mod->src2 == FLUID_MOD_PITCHWHEEL))) { - fluid_real_t current_val = fluid_mod_get_value(mod, voice->channel, voice); + fluid_real_t current_val = fluid_mod_get_value(mod, voice); fluid_real_t v = fabs(mod->amount); if((mod->src1 == FLUID_MOD_PITCHWHEEL) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.0.0/src/utils/fluid_hash.c new/fluidsynth-2.0.1/src/utils/fluid_hash.c --- old/fluidsynth-2.0.0/src/utils/fluid_hash.c 2018-09-12 12:10:29.000000000 +0200 +++ new/fluidsynth-2.0.1/src/utils/fluid_hash.c 2018-10-07 14:47:07.000000000 +0200 @@ -415,7 +415,13 @@ hashtable->key_destroy_func = key_destroy_func; hashtable->value_destroy_func = value_destroy_func; hashtable->nodes = FLUID_ARRAY(fluid_hashnode_t *, hashtable->size); - FLUID_MEMSET(hashtable->nodes, 0, hashtable->size * sizeof(fluid_hashnode_t *)); + if(hashtable->nodes == NULL) + { + delete_fluid_hashtable(hashtable); + FLUID_LOG(FLUID_ERR, "Out of memory"); + return NULL; + } + FLUID_MEMSET(hashtable->nodes, 0, hashtable->size * sizeof(*hashtable->nodes)); return hashtable; }
