Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package fluidsynth for openSUSE:Factory checked in at 2022-07-12 11:12:00 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/fluidsynth (Old) and /work/SRC/openSUSE:Factory/.fluidsynth.new.1523 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "fluidsynth" Tue Jul 12 11:12:00 2022 rev:67 rq:988281 version:2.2.8 Changes: -------- --- /work/SRC/openSUSE:Factory/fluidsynth/fluidsynth.changes 2022-05-12 22:57:36.396574965 +0200 +++ /work/SRC/openSUSE:Factory/.fluidsynth.new.1523/fluidsynth.changes 2022-07-12 11:12:04.339669618 +0200 @@ -1,0 +2,9 @@ +Sun Jul 10 16:25:37 UTC 2022 - Tom Mbrt <tom.m...@googlemail.com> + +- Update to 2.2.8: + * ALSA and WinMIDI drivers now pass system real-time messages on to user callback + * Fix FPU division by zero in `fluid_player_set_tempo()` + * Fix system-wide config file not loaded + * Pluseaudio driver now honors `audio.periods` setting + +------------------------------------------------------------------- Old: ---- fluidsynth-2.2.7.tar.gz New: ---- fluidsynth-2.2.8.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ fluidsynth.spec ++++++ --- /var/tmp/diff_new_pack.roFT09/_old 2022-07-12 11:12:05.071670576 +0200 +++ /var/tmp/diff_new_pack.roFT09/_new 2022-07-12 11:12:05.075670581 +0200 @@ -18,7 +18,7 @@ %define sover 3 Name: fluidsynth -Version: 2.2.7 +Version: 2.2.8 Release: 0 Summary: A Real-Time Software Synthesizer That Uses Soundfont(tm) License: LGPL-2.1-or-later ++++++ fluidsynth-2.2.7.tar.gz -> fluidsynth-2.2.8.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.2.7/.azure/azure-pipelines-android.yml new/fluidsynth-2.2.8/.azure/azure-pipelines-android.yml --- old/fluidsynth-2.2.7/.azure/azure-pipelines-android.yml 2022-04-25 20:18:10.000000000 +0200 +++ new/fluidsynth-2.2.8/.azure/azure-pipelines-android.yml 2022-07-10 00:05:56.000000000 +0200 @@ -52,6 +52,7 @@ # This is a symlink pointing to the real Android NDK # Must be the same as $ANDROID_NDK_HOME see: # https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-README.md + # We cannot use $ANDROID_NDK_HOME because this is an environment variable, but here, we need a compile-time constant. NDK: '/usr/local/lib/android/sdk/ndk-bundle' # All the built binaries, libs and their headers will be installed here @@ -198,6 +199,11 @@ condition: and(succeeded(), ne(variables.CACHE_RESTORED, 'true')) - script: | + set -ex + ln -sfn $ANDROID_SDK_ROOT/ndk/21.4.7075529 $ANDROID_NDK_ROOT + displayName: 'Use NDK r22' + + - script: | set -e # The cross-compile toolchain we use diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.2.7/.azure/azure-pipelines-mac.yml new/fluidsynth-2.2.8/.azure/azure-pipelines-mac.yml --- old/fluidsynth-2.2.7/.azure/azure-pipelines-mac.yml 2022-04-25 20:18:10.000000000 +0200 +++ new/fluidsynth-2.2.8/.azure/azure-pipelines-mac.yml 2022-07-10 00:05:56.000000000 +0200 @@ -13,8 +13,14 @@ - '.cirrus.yml' - 'README.md' +parameters: +- name: UseCache + displayName: Use Dependency Cache + type: boolean + default: true + jobs: -- job: macOS +- job: macOS_brew strategy: matrix: UnixLibs: @@ -26,6 +32,9 @@ 11_0: imageName: 'macos-11' CMakeFlags: '' + 12_0: + imageName: 'macos-12' + CMakeFlags: '' pool: vmImage: $(imageName) @@ -67,3 +76,124 @@ cmake -DCMAKE_INSTALL_PREFIX=$(Build.ArtifactStagingDirectory) .. make install displayName: 'Install fluidsynth to artifact dir' + + +- job: macOS_ports + timeoutInMinutes: 300 + strategy: + matrix: + # SDL2/SDL_cpuinfo.h includes some x86 specific headers, which ofc doesn't work when cross compiling for arm64 + # And this universal build thingy doesn't work on Mac10.15 for some reason... + # Furthermore, there is a problem when restoring the cache on Mac11, so disable this job as well + #11_0_universal_unixlibs: + # macPortsUrl: 'https://github.com/macports/macports-base/releases/download/v2.7.2/MacPorts-2.7.2-11-BigSur.pkg' + # imageName: 'macos-11' + # CMakeFlags: '-Denable-sdl2=0 -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" -Denable-framework=0 -DLIB_SUFFIX=""' + 12_0_universal_unixlibs: + macPortsUrl: 'https://github.com/macports/macports-base/releases/download/v2.7.2/MacPorts-2.7.2-12-Monterey.pkg' + imageName: 'macos-12' + CMakeFlags: '-Denable-sdl2=0 -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" -Denable-framework=0 -DLIB_SUFFIX=""' + pool: + vmImage: $(imageName) + steps: + - script: | + set -ex + brew install wget pkg-config + wget $(macPortsUrl) + sudo installer -pkg *.pkg -target / + rm -f *.pkg + sudo chown -R $(id -u):$(id -g) /opt/local + sudo chflags nouchg /opt/local + displayName: 'Prerequisites' + workingDirectory: $(Agent.TempDirectory) + - task: Cache@2 + continueOnError: true + displayName: "Cache macPort packages" + condition: and(not(in(variables['Build.Reason'], 'Schedule')), ${{ parameters.useCache }}) + inputs: + key: '"$(Agent.OS)" | "$(imageName)" | "$(macPortsUrl)" | "versionalways"' + path: '/opt/local' + cacheHitVar: CACHE_RESTORED + - script: | + set -ex + export PATH=$PATH:/opt/local/bin + echo $PATH + which codesign + which port + cmake --version || true + + echo "+universal" | sudo tee -a /opt/local/etc/macports/variants.conf + + sudo sh -c 'cat << EOF >> /opt/local/etc/macports/macports.conf + buildfromsource always + universal_archs arm64 x86_64 + ui_interactive no + EOF' + + sudo port install glib2-devel libsndfile dbus-glib readline + # fixup permissions to allow non-priv pipeline user access every directory, to make the caching step succeed at the end + sudo chown -R $(id -u):$(id -g) /opt/local + # remove all extended attributes, as they cannot be restored when restoring the pipeline cache + #sudo xattr -rcv /opt/local + displayName: 'Port install universal' + condition: and(succeeded(), ne(variables.CACHE_RESTORED, 'true')) + - script: | + set -ex + export PATH=$PATH:/opt/local/bin + export PKG_CONFIG_PATH="/opt/local/lib/pkgconfig" + mkdir build && cd build + cmake -Werror=dev $(CMakeFlags) -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_VERBOSE_MAKEFILE=1 -DNO_GUI=1 .. + make -j3 + displayName: 'Compile fluidsynth' + - script: | + export PATH=$PATH:/opt/local/bin + sudo port -v install fluidsynth +universal + displayName: 'port install fluidsynth +universal' + condition: failed() + enabled: false + - script: | + set -x + cat /opt/local/var/macports/logs/*cmake-bootstrap/cmake-bootstrap/main.log + cat /opt/local/var/macports/build/*cmake-bootstrap/cmake-bootstrap/work/cmake-3.9.4-arm64/Bootstrap.cmk/*.log + cat /opt/local/var/macports/logs/*_fluidsynth/fluidsynth/main.log + condition: failed() + displayName: 'Print fluidsynth error log' + - script: | + set -ex + cd build + make -j3 check + displayName: 'Execute Unittests' + - script: | + set -ex + cd build + make -j3 demo + displayName: 'Compile demos' + - script: | + set -ex + cd build + sudo make install + rm -f install_manifest.txt + displayName: 'Install fluidsynth to default location' + - script: | + set -ex + cd build + cmake -DCMAKE_INSTALL_PREFIX=$(Build.ArtifactStagingDirectory) .. + make install + cd /opt/local/lib/ + cp -a libgthread*.dylib libglib*.dylib libintl*.dylib libsndfile*.dylib libdbus-*.dylib libreadline*.dylib $(Build.ArtifactStagingDirectory)/lib + file /opt/local/lib/libglib-2.0.dylib $(Build.ArtifactStagingDirectory)/bin/fluidsynth $(Build.ArtifactStagingDirectory)/lib/libfluidsynth*.dylib + displayName: 'Install fluidsynth to artifact dir' + - task: PublishBuildArtifacts@1 + displayName: 'Publish fluidsynth artifacts' + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)' + ArtifactName: 'fluidsynth-$(imageName)' + publishLocation: 'Container' + - task: PublishBuildArtifacts@1 + displayName: 'Publish macPorts deps' + enabled: false + condition: and(succeeded(), ne(variables.CACHE_RESTORED, 'true')) + inputs: + PathtoPublish: '/opt/local/lib' + ArtifactName: 'macports-$(imageName)' + publishLocation: 'Container' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.2.7/.github/workflows/linux.yml new/fluidsynth-2.2.8/.github/workflows/linux.yml --- old/fluidsynth-2.2.7/.github/workflows/linux.yml 2022-04-25 20:18:10.000000000 +0200 +++ new/fluidsynth-2.2.8/.github/workflows/linux.yml 2022-07-10 00:05:56.000000000 +0200 @@ -62,7 +62,6 @@ echo Can execute `nproc` make jobs in parallel cmake --version cmake -E make_directory ${{github.workspace}}/build - sudo ln -s /usr/bin/clang-tidy-10 /usr/bin/clang-tidy which clang-tidy || true ls -la `which clang-tidy` || true echo $PATH diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.2.7/CMakeLists.txt new/fluidsynth-2.2.8/CMakeLists.txt --- old/fluidsynth-2.2.7/CMakeLists.txt 2022-04-25 20:18:10.000000000 +0200 +++ new/fluidsynth-2.2.8/CMakeLists.txt 2022-07-10 00:05:56.000000000 +0200 @@ -38,7 +38,7 @@ # FluidSynth package version set ( FLUIDSYNTH_VERSION_MAJOR 2 ) set ( FLUIDSYNTH_VERSION_MINOR 2 ) -set ( FLUIDSYNTH_VERSION_MICRO 7 ) +set ( FLUIDSYNTH_VERSION_MICRO 8 ) set ( VERSION "${FLUIDSYNTH_VERSION_MAJOR}.${FLUIDSYNTH_VERSION_MINOR}.${FLUIDSYNTH_VERSION_MICRO}" ) set ( FLUIDSYNTH_VERSION "\"${VERSION}\"" ) @@ -53,7 +53,7 @@ # This is not exactly the same algorithm as the libtool one, but the results are the same. set ( LIB_VERSION_CURRENT 3 ) set ( LIB_VERSION_AGE 1 ) -set ( LIB_VERSION_REVISION 0 ) +set ( LIB_VERSION_REVISION 1 ) set ( LIB_VERSION_INFO "${LIB_VERSION_CURRENT}.${LIB_VERSION_AGE}.${LIB_VERSION_REVISION}" ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.2.7/doc/examples/example.c new/fluidsynth-2.2.8/doc/examples/example.c --- old/fluidsynth-2.2.7/doc/examples/example.c 2022-04-25 20:18:10.000000000 +0200 +++ new/fluidsynth-2.2.8/doc/examples/example.c 2022-07-10 00:05:56.000000000 +0200 @@ -28,40 +28,55 @@ int main(int argc, char **argv) { - fluid_settings_t *settings; - fluid_synth_t *synth; - fluid_audio_driver_t *adriver; + fluid_settings_t *settings = NULL; + fluid_synth_t *synth = NULL; + fluid_audio_driver_t *adriver = NULL; int sfont_id; int i, key; /* Create the settings. */ settings = new_fluid_settings(); + if(settings == NULL) + { + puts("Failed to create the settings!"); + goto err; + } /* Change the settings if necessary*/ /* Create the synthesizer. */ synth = new_fluid_synth(settings); - - /* Create the audio driver. The synthesizer starts playing as soon - as the driver is created. */ - adriver = new_fluid_audio_driver(settings, synth); + if(synth == NULL) + { + puts("Failed to create the synth!"); + goto err; + } /* Load a SoundFont and reset presets (so that new instruments - * get used from the SoundFont) */ + * get used from the SoundFont) + * Depending on the size of the SoundFont, this will take some time to complete... + */ sfont_id = fluid_synth_sfload(synth, "example.sf2", 1); - if(sfont_id == FLUID_FAILED) { puts("Loading the SoundFont failed!"); goto err; } + /* Create the audio driver. The synthesizer starts playing as soon + as the driver is created. */ + adriver = new_fluid_audio_driver(settings, synth); + if(adriver == NULL) + { + puts("Failed to create the audio driver!"); + goto err; + } + /* Initialize the random number generator */ srand(getpid()); for(i = 0; i < 12; i++) { - /* Generate a random key */ key = 60 + (int)(12.0f * rand() / (float) RAND_MAX); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.2.7/doc/fluidsettings.xml new/fluidsynth-2.2.8/doc/fluidsettings.xml --- old/fluidsynth-2.2.7/doc/fluidsettings.xml 2022-04-25 20:18:10.000000000 +0200 +++ new/fluidsynth-2.2.8/doc/fluidsettings.xml 2022-07-10 00:05:56.000000000 +0200 @@ -418,7 +418,7 @@ <min>64</min> <max>8192</max> <desc> - The size of the audio buffers (in frames). + This is the number of audio samples most audio drivers will request from the synth at one time. In other words, it's the amount of samples the synth is allowed to render in one go when no state changes (events) are about to happen. Because of that, specifying too big numbers here may cause MIDI events to be poorly quantized (=untimed) when a MIDI driver or the synth's API directly is used, as fluidsynth cannot determine when those events are to arrive. This issue does not matter, when using the MIDI player or the MIDI sequencer, because in this case, fluidsynth does know when events will be received. </desc> </setting> <setting> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.2.7/doc/fluidsynth-v20-devdoc.txt new/fluidsynth-2.2.8/doc/fluidsynth-v20-devdoc.txt --- old/fluidsynth-2.2.7/doc/fluidsynth-v20-devdoc.txt 2022-04-25 20:18:10.000000000 +0200 +++ new/fluidsynth-2.2.8/doc/fluidsynth-v20-devdoc.txt 2022-07-10 00:05:56.000000000 +0200 @@ -8,8 +8,8 @@ \author David Henningsson \author Tom Moebert \author Copyright © 2003-2022 Peter Hanappe, Conrad Berh??rster, Antoine Schmitt, Pedro L??pez-Cabanillas, Josh Green, David Henningsson, Tom Moebert -\version Revision 2.2.7 -\date 2022-04-25 +\version Revision 2.2.8 +\date 2022-07-10 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 https://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 https://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.2.7/include/fluidsynth/synth.h new/fluidsynth-2.2.8/include/fluidsynth/synth.h --- old/fluidsynth-2.2.7/include/fluidsynth/synth.h 2022-04-25 20:18:10.000000000 +0200 +++ new/fluidsynth-2.2.8/include/fluidsynth/synth.h 2022-07-10 00:05:56.000000000 +0200 @@ -331,6 +331,18 @@ * render real-time audio, ensure that you call these functions from a high-priority * thread with little to no other duties other than calling the rendering functions. * + * @warning + * If a concurrently running thread calls any other sound affecting synth function + * (e.g. fluid_synth_noteon(), fluid_synth_cc(), etc.) it is unspecified whether the event triggered by such a call + * will be effective in the recently synthesized audio. While this is inaudible when only requesting small chunks from the + * synth with every call (cf. fluid_synth_get_internal_bufsize()), it will become evident when requesting larger sample chunks: + * With larger sample chunks it will get harder for the synth to react on those spontaneously occurring events in time + * (like events received from a MIDI driver, or directly made synth API calls). + * In those real-time scenarios, prefer requesting smaller + * sample chunks from the synth with each call, to avoid poor quantization of your events in the synthesized audio. + * This issue is not applicable when using the MIDI player or sequencer for event dispatching. Also + * refer to the documentation of \setting{audio_period-size}. + * * @{ */ FLUIDSYNTH_API int fluid_synth_write_s16(fluid_synth_t *synth, int len, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.2.7/src/drivers/fluid_adriver.c new/fluidsynth-2.2.8/src/drivers/fluid_adriver.c --- old/fluidsynth-2.2.7/src/drivers/fluid_adriver.c 2022-04-25 20:18:10.000000000 +0200 +++ new/fluidsynth-2.2.8/src/drivers/fluid_adriver.c 2022-07-10 00:05:56.000000000 +0200 @@ -310,8 +310,9 @@ * Otherwise the behaviour is undefined. * * @note As soon as an audio driver is created, the \p synth starts rendering audio. - * This means that all necessary sound-setup should be completed after this point, - * thus of all object types in use (synth, midi player, sequencer, etc.) the audio + * This means that all necessary initialization and sound-setup should have been + * completed before calling this function. + * Thus, of all object types in use (synth, midi player, sequencer, etc.) the audio * driver should always be the last one to be created and the first one to be deleted! * Also refer to the order of object creation in the code examples. */ @@ -322,7 +323,20 @@ if(def) { - fluid_audio_driver_t *driver = (*def->new)(settings, synth); + fluid_audio_driver_t *driver; + double srate, midi_event_latency; + int period_size; + + fluid_settings_getint(settings, "audio.period-size", &period_size); + fluid_settings_getnum(settings, "synth.sample-rate", &srate); + + midi_event_latency = period_size / srate; + if(midi_event_latency >= 0.05) + { + FLUID_LOG(FLUID_WARN, "You have chosen 'audio.period-size' to be %d samples. Given a sample rate of %.1f this results in a latency of %.1f ms, which will cause MIDI events to be poorly quantized (=untimed) in the synthesized audio (also known as the 'drunken-drummer' syndrome). To avoid that, you're strongly advised to increase 'audio.periods' instead, while keeping 'audio.period-size' small enough to make this warning disappear.", period_size, srate, midi_event_latency*1000.0); + } + + driver = (*def->new)(settings, synth); if(driver) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.2.7/src/drivers/fluid_alsa.c new/fluidsynth-2.2.8/src/drivers/fluid_alsa.c --- old/fluidsynth-2.2.7/src/drivers/fluid_alsa.c 2022-04-25 20:18:10.000000000 +0200 +++ new/fluidsynth-2.2.8/src/drivers/fluid_alsa.c 2022-07-10 00:05:56.000000000 +0200 @@ -553,7 +553,7 @@ { FLUID_MEMSET(left, 0, buffer_size * sizeof(*left)); FLUID_MEMSET(right, 0, buffer_size * sizeof(*right)); - + (*dev->callback)(dev->data, buffer_size, 0, NULL, 2, handle); /* convert floating point data to 16 bit (with dithering) */ @@ -1347,6 +1347,26 @@ } break; + case SND_SEQ_EVENT_START: + evt.type = MIDI_START; + break; + + case SND_SEQ_EVENT_CONTINUE: + evt.type = MIDI_CONTINUE; + break; + + case SND_SEQ_EVENT_STOP: + evt.type = MIDI_STOP; + break; + + case SND_SEQ_EVENT_CLOCK: + evt.type = MIDI_SYNC; + break; + + case SND_SEQ_EVENT_RESET: + evt.type = MIDI_SYSTEM_RESET; + break; + default: continue; /* unhandled event, next loop iteration */ } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.2.7/src/drivers/fluid_pulse.c new/fluidsynth-2.2.8/src/drivers/fluid_pulse.c --- old/fluidsynth-2.2.7/src/drivers/fluid_pulse.c 2022-04-25 20:18:10.000000000 +0200 +++ new/fluidsynth-2.2.8/src/drivers/fluid_pulse.c 2022-07-10 00:05:56.000000000 +0200 @@ -83,12 +83,12 @@ pa_sample_spec samplespec; pa_buffer_attr bufattr; double sample_rate; - int period_size, period_bytes, adjust_latency; + int period_size, period_bytes, adjust_latency, periods; char *server = NULL; char *device = NULL; char *media_role = NULL; int realtime_prio = 0; - int err; + int err = 0; float *left = NULL, *right = NULL, *buf = NULL; @@ -103,6 +103,7 @@ FLUID_MEMSET(dev, 0, sizeof(fluid_pulse_audio_driver_t)); + fluid_settings_getint(settings, "audio.periods", &periods); fluid_settings_getint(settings, "audio.period-size", &period_size); fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate); fluid_settings_dupstr(settings, "audio.pulseaudio.server", &server); /* ++ alloc server string */ @@ -143,7 +144,7 @@ samplespec.rate = sample_rate; period_bytes = period_size * sizeof(float) * 2; - bufattr.maxlength = adjust_latency ? -1 : period_bytes; + bufattr.maxlength = adjust_latency ? -1 : period_bytes * periods; bufattr.tlength = period_bytes; bufattr.minreq = -1; bufattr.prebuf = -1; /* Just initialize to same value as tlength */ @@ -155,9 +156,9 @@ &bufattr, &err); - if(!dev->pa_handle) + if(!dev->pa_handle || err != PA_OK) { - FLUID_LOG(FLUID_ERR, "Failed to create PulseAudio connection"); + FLUID_LOG(FLUID_ERR, "Failed to create PulseAudio connection, because pa_simple_new() failed with error: %s", pa_strerror(err)); goto error_recovery; } @@ -176,6 +177,7 @@ } buf = FLUID_ARRAY(float, period_size * 2); + if(buf == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory."); @@ -242,10 +244,8 @@ { fluid_pulse_audio_driver_t *dev = (fluid_pulse_audio_driver_t *) d; float *buf = dev->buf; - int buffer_size; - int err; - - buffer_size = dev->buffer_size; + int buffer_size = dev->buffer_size; + int err = 0; while(dev->cont) { @@ -254,9 +254,20 @@ if(pa_simple_write(dev->pa_handle, buf, buffer_size * sizeof(float) * 2, &err) < 0) { - FLUID_LOG(FLUID_ERR, "Error writing to PulseAudio connection."); + FLUID_LOG(FLUID_ERR, "Error writing to PulseAudio connection: %s", pa_strerror(err)); break; } + +#if 0 + { + pa_usec_t pa_latency = pa_simple_get_latency(dev->pa_handle, &err); + + if(err == PA_OK) + { + FLUID_LOG(FLUID_DBG, "PulseAudio latency: %d ms", (int) pa_latency / 1000); + } + } +#endif } /* while (dev->cont) */ return FLUID_THREAD_RETURN_VALUE; @@ -271,12 +282,10 @@ *right = dev->right, *buf = dev->buf; float *handle[2]; - int buffer_size; - int err; + int buffer_size = dev->buffer_size; + int err = 0; int i; - buffer_size = dev->buffer_size; - handle[0] = left; handle[1] = right; @@ -297,9 +306,20 @@ if(pa_simple_write(dev->pa_handle, buf, buffer_size * sizeof(float) * 2, &err) < 0) { - FLUID_LOG(FLUID_ERR, "Error writing to PulseAudio connection."); + FLUID_LOG(FLUID_ERR, "Error writing to PulseAudio connection: %s", pa_strerror(err)); break; } + +#if 0 + { + pa_usec_t pa_latency = pa_simple_get_latency(dev->pa_handle, &err); + + if(err == PA_OK) + { + FLUID_LOG(FLUID_DBG, "PulseAudio latency: %d ms", (int) pa_latency / 1000); + } + } +#endif } /* while (dev->cont) */ return FLUID_THREAD_RETURN_VALUE; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.2.7/src/drivers/fluid_wasapi.c new/fluidsynth-2.2.8/src/drivers/fluid_wasapi.c --- old/fluidsynth-2.2.7/src/drivers/fluid_wasapi.c 2022-04-25 20:18:10.000000000 +0200 +++ new/fluidsynth-2.2.8/src/drivers/fluid_wasapi.c 2022-07-10 00:05:56.000000000 +0200 @@ -803,6 +803,7 @@ { fluid_wasapi_finddev_data_t *d = (fluid_wasapi_finddev_data_t *)data; int nsz; + size_t id_len; char *name = NULL; wchar_t *id = NULL; IPropertyStore *prop = NULL; @@ -841,9 +842,15 @@ goto cleanup; } - nsz = wcslen(id); - d->id = FLUID_ARRAY(wchar_t, nsz + 1); - FLUID_MEMCPY(d->id, id, sizeof(wchar_t) * (nsz + 1)); + id_len = wcslen(id); + if(id_len >= UINT_MAX / sizeof(wchar_t)) + { + FLUID_LOG(FLUID_ERR, "wasapi: the returned device identifier was way too long"); + goto cleanup; + } + id_len++; + d->id = FLUID_ARRAY(wchar_t, id_len); + FLUID_MEMCPY(d->id, id, sizeof(wchar_t) * id_len); } cleanup: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.2.7/src/drivers/fluid_winmidi.c new/fluidsynth-2.2.8/src/drivers/fluid_winmidi.c --- old/fluidsynth-2.2.7/src/drivers/fluid_winmidi.c 2022-04-25 20:18:10.000000000 +0200 +++ new/fluidsynth-2.2.8/src/drivers/fluid_winmidi.c 2022-07-10 00:05:56.000000000 +0200 @@ -145,21 +145,28 @@ break; case MIM_DATA: - event.type = msg_type(msg_param); - event.channel = msg_chan(msg_param) + dev_infos->channel_map; + if(msg_param < 0xF0) /* Voice category message */ + { + event.type = msg_type(msg_param); + event.channel = msg_chan(msg_param) + dev_infos->channel_map; - FLUID_LOG(FLUID_DBG, "\ndevice at index %d sending MIDI message on channel %d, forwarded on channel: %d", - dev_infos->dev_idx, msg_chan(msg_param), event.channel); + FLUID_LOG(FLUID_DBG, "\ndevice at index %d sending MIDI message on channel %d, forwarded on channel: %d", + dev_infos->dev_idx, msg_chan(msg_param), event.channel); - if(event.type != PITCH_BEND) - { - event.param1 = msg_p1(msg_param); - event.param2 = msg_p2(msg_param); + if(event.type != PITCH_BEND) + { + event.param1 = msg_p1(msg_param); + event.param2 = msg_p2(msg_param); + } + else /* Pitch bend is a 14 bit value */ + { + event.param1 = (msg_p2(msg_param) << 7) | msg_p1(msg_param); + event.param2 = 0; + } } - else /* Pitch bend is a 14 bit value */ + else /* System message */ { - event.param1 = (msg_p2(msg_param) << 7) | msg_p1(msg_param); - event.param2 = 0; + event.type = msg_param; } (*dev->driver.handler)(dev->driver.data, &event); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.2.7/src/fluidsynth.c new/fluidsynth-2.2.8/src/fluidsynth.c --- old/fluidsynth-2.2.7/src/fluidsynth.c 2022-04-25 20:18:10.000000000 +0200 +++ new/fluidsynth-2.2.8/src/fluidsynth.c 2022-07-10 00:05:56.000000000 +0200 @@ -891,13 +891,13 @@ if(config_file == NULL) { config_file = fluid_get_userconf(buf, sizeof(buf)); - if(config_file == NULL) + if(config_file == NULL || !g_file_test(config_file, G_FILE_TEST_EXISTS)) { config_file = fluid_get_sysconf(buf, sizeof(buf)); } /* if the automatically selected command file does not exist, do not even attempt to open it */ - if(!g_file_test(config_file, G_FILE_TEST_EXISTS)) + if(config_file != NULL && !g_file_test(config_file, G_FILE_TEST_EXISTS)) { config_file = NULL; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.2.7/src/midi/fluid_midi.c new/fluidsynth-2.2.8/src/midi/fluid_midi.c --- old/fluidsynth-2.2.7/src/midi/fluid_midi.c 2022-04-25 20:18:10.000000000 +0200 +++ new/fluidsynth-2.2.8/src/midi/fluid_midi.c 2022-07-10 00:05:56.000000000 +0200 @@ -126,8 +126,13 @@ { fluid_midi_file *mf; - mf = FLUID_NEW(fluid_midi_file); + if(length > INT_MAX) + { + FLUID_LOG(FLUID_ERR, "Refusing to open a MIDI file which is bigger than 2GiB"); + return NULL; + } + mf = FLUID_NEW(fluid_midi_file); if(mf == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); @@ -140,7 +145,7 @@ mf->running_status = -1; mf->buffer = buffer; - mf->buf_len = length; + mf->buf_len = (int)length; mf->buf_pos = 0; mf->eof = FALSE; @@ -2331,6 +2336,12 @@ int tempo; /* tempo in micro seconds by quarter note */ float deltatime; + /* do nothing if the division is still unknown to avoid a div by zero */ + if(player->division == 0) + { + return; + } + if(fluid_atomic_int_get(&player->sync_mode)) { /* take internal tempo from MIDI file */ @@ -2395,6 +2406,10 @@ * #FLUID_PLAYER_TEMPO_INTERNAL will set the player to follow this internal * tempo. * + * @warning If the function is called when no MIDI file is loaded or currently playing, it + * would have caused a division by zero in fluidsynth 2.2.7 and earlier. Starting with 2.2.8, the + * new tempo change will be stashed and applied later. + * * @return #FLUID_OK if success or #FLUID_FAILED otherwise (incorrect parameters). * @since 2.2.0 */ @@ -2637,14 +2652,9 @@ * of another message. */ if(c >= 0xF8) { - if(c == MIDI_SYSTEM_RESET) - { - parser->event.type = c; - parser->status = 0; /* clear the status */ - return &parser->event; - } - - return NULL; + parser->event.type = c; + parser->status = 0; /* clear the status */ + return &parser->event; } /* Status byte? - If previous message not yet complete, it is discarded (re-sync). */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fluidsynth-2.2.7/src/synth/fluid_synth.c new/fluidsynth-2.2.8/src/synth/fluid_synth.c --- old/fluidsynth-2.2.7/src/synth/fluid_synth.c 2022-04-25 20:18:10.000000000 +0200 +++ new/fluidsynth-2.2.8/src/synth/fluid_synth.c 2022-07-10 00:05:56.000000000 +0200 @@ -3717,7 +3717,8 @@ * @param synth FluidSynth instance * @return Internal buffer size in audio frames. * - * Audio is synthesized this number of frames at a time. Defaults to 64 frames. + * Audio is synthesized at this number of frames at a time. Defaults to 64 frames. I.e. the synth can only react to notes, + * control changes, and other audio affecting events after having processed 64 audio frames. */ int fluid_synth_get_internal_bufsize(fluid_synth_t *synth)