Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package schismtracker for openSUSE:Factory 
checked in at 2023-09-07 21:13:39
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/schismtracker (Old)
 and      /work/SRC/openSUSE:Factory/.schismtracker.new.1766 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "schismtracker"

Thu Sep  7 21:13:39 2023 rev:25 rq:1109458 version:20230906

Changes:
--------
--- /work/SRC/openSUSE:Factory/schismtracker/schismtracker.changes      
2022-12-02 13:13:28.217961755 +0100
+++ /work/SRC/openSUSE:Factory/.schismtracker.new.1766/schismtracker.changes    
2023-09-07 21:15:12.646602617 +0200
@@ -1,0 +2,11 @@
+Thu Sep  7 06:29:42 UTC 2023 - Jan Engelhardt <jeng...@inai.de>
+
+- Update to release 20230906
+  * Add FLAC loading support
+  * Fix improper playback of note-without-instrument after
+    instrument-without-note
+  * Fix for initial instrument-without-note
+  * MIDI note-off events that don't match the last note are now dropped
+  * Detect S3M files made with Graoumf Tracker
+
+-------------------------------------------------------------------

Old:
----
  20221201.tar.gz

New:
----
  20230906.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ schismtracker.spec ++++++
--- /var/tmp/diff_new_pack.1JeNel/_old  2023-09-07 21:15:13.934648662 +0200
+++ /var/tmp/diff_new_pack.1JeNel/_new  2023-09-07 21:15:13.934648662 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package schismtracker
 #
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           schismtracker
-Version:        20221201
+Version:        20230906
 Release:        0
 Summary:        Music editor that matches the look and feel of Impulse Tracker
 License:        GPL-2.0-or-later
@@ -31,6 +31,7 @@
 BuildRequires:  alsa-devel
 BuildRequires:  autoconf
 BuildRequires:  automake
+BuildRequires:  fdupes
 BuildRequires:  freeglut-devel
 BuildRequires:  gcc-c++
 BuildRequires:  libtool
@@ -65,6 +66,7 @@
 done
 install -Dm 0644 icons/schism-icon.svg \
        "$b/%_datadir/icons/hicolor/scalable/apps/%name.svg"
+%fdupes %buildroot/%_prefix
 # install desktop file
 %suse_update_desktop_file -i %name
 

++++++ 20221201.tar.gz -> 20230906.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schismtracker-20221201/.github/workflows/build.yml 
new/schismtracker-20230906/.github/workflows/build.yml
--- old/schismtracker-20221201/.github/workflows/build.yml      2022-12-01 
17:04:39.000000000 +0100
+++ new/schismtracker-20230906/.github/workflows/build.yml      2023-09-07 
02:58:17.000000000 +0200
@@ -14,7 +14,7 @@
         include:
           - { sys: mingw32, env: i686, win: win32 }
           - { sys: mingw64, env: x86_64, win: win64 }
-    name: ${{ matrix.win }}
+    name: build-${{ matrix.win }}
     defaults:
       run:
         shell: msys2 {0}
@@ -36,11 +36,11 @@
       with:
         msystem: ${{ matrix.sys }}
         update: true
-        install: git mingw-w64-${{ matrix.env }}-toolchain libtool autoconf 
automake make mingw-w64-${{ matrix.env }}-SDL2 zip dos2unix
+        install: git mingw-w64-${{ matrix.env }}-toolchain mingw-w64-${{ 
matrix.env }}-flac libtool autoconf automake make mingw-w64-${{ matrix.env 
}}-SDL2 zip dos2unix
   
     - name: 'Get current date'
       id: date
-      run: echo "::set-output name=date::$(date +%Y%m%d)"
+      run: echo "date=$(date +%Y%m%d)" >> $GITHUB_OUTPUT
 
     - name: 'Build package'
       run: |
@@ -51,15 +51,15 @@
         make
         strip -g schismtracker.exe
         cp schismtracker.exe ..
+        cd ..
         if [ ${{ matrix.win }} == "win32" ]
         then
-          cp /mingw32/bin/SDL2.dll ..
-          cp /mingw32/bin/libgcc_s_dw2-1.dll ..
-          cp /mingw32/bin/libwinpthread-1.dll ..
-        else
-          cp /mingw64/bin/SDL2.dll ..
+          cp /mingw32/bin/libgcc_s_dw2-1.dll .
+          cp /mingw32/bin/libwinpthread-1.dll .
         fi
-        cd ..
+        cp /${{ matrix.sys }}/bin/SDL2.dll .
+        cp /${{ matrix.sys }}/bin/libFLAC.dll .
+        cp /${{ matrix.sys }}/bin/libogg-0.dll .
         cp docs/configuration.md .
         unix2dos COPYING README.md configuration.md
 
@@ -71,6 +71,8 @@
         path: |
           schismtracker.exe
           SDL2.dll
+          libFLAC.dll
+          libogg-0.dll
           libgcc_s_dw2-1.dll
           libwinpthread-1.dll
           COPYING
@@ -85,6 +87,8 @@
         path: |
           schismtracker.exe
           SDL2.dll
+          libFLAC.dll
+          libogg-0.dll
           COPYING
           README.md
           configuration.md
@@ -97,7 +101,7 @@
     steps:
       - name: 'Get current date'
         id: date
-        run: echo "::set-output name=date::$(date +%Y%m%d)"
+        run: echo "date=$(date +%Y%m%d)" >> $GITHUB_OUTPUT
 
       - name: 'chown SDK directory'
         id: chown
@@ -122,23 +126,45 @@
 
       - name: 'Install dependencies'
         run: |
-          brew install automake zip
+          brew install automake zip cmake
 
       - name: 'Checkout'
         uses: actions/checkout@v3
 
+        # Since Homebrew doesn't provide binaries for old versions, we have to 
compile our own:
       - name: 'Download SDL2 sources'
         run: |
-          curl https://www.libsdl.org/release/SDL2-2.24.2.tar.gz | tar xvf -
+          curl https://www.libsdl.org/release/SDL2-2.26.1.tar.gz | tar xvf -
 
       - name: 'Build SDL2'
         run: |
-          cd SDL2-2.24.2
+          cd SDL2-2.26.1
           ./configure CC="sh ../scripts/build-uni.sh"
           make
-          sudo make install
+          make install
           rm -rf arm64 x64
           cd ..
+      
+      - name: 'Download libflac and libogg sources'
+        run: |
+          curl https://ftp.osuosl.org/pub/xiph/releases/flac/flac-1.4.2.tar.xz 
| tar -xvf -
+          curl 
https://ftp.osuosl.org/pub/xiph/releases/ogg/libogg-1.3.5.tar.gz | tar -xvf -
+
+      - name: 'Build libflac'
+        run: |
+          cd libogg-1.3.5
+          mkdir build
+          cd build
+          ../configure CC="sh $PWD/../../scripts/build-uni.sh" 
LDFLAGS="-L/usr/local/lib"
+          make
+          make install
+          cd ../../flac-1.4.2
+          mkdir build
+          cd build
+          ../configure CC="sh $PWD/../../scripts/build-uni.sh" 
LDFLAGS="-L/usr/local/lib"
+          make
+          make install
+          cd ../..
 
       - name: 'Build package'
         run: |
@@ -146,11 +172,11 @@
           mkdir -p build
           cd build
           ../configure
-          make CFLAGS="-isysroot 
/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk 
-I/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/Tk.framework/Versions/8.5/Headers"
+          make CFLAGS="-isysroot 
/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk -I/usr/local/include 
-I/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/Tk.framework/Versions/8.5/Headers"
           mkdir -p ../buildarm
           cd ../buildarm
           ../configure
-          make LDFLAGS="-arch arm64 -isysroot 
/Library/Developer/CommandLineTools/SDKs/MacOSX11.sdk" CFLAGS="-arch arm64 
-isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX11.sdk 
-I/Library/Developer/CommandLineTools/SDKs/MacOSX11.sdk/System/Library/Frameworks/Tk.framework/Versions/8.5/Headers"
 OBJCFLAGS="-arch arm64 -isysroot 
/Library/Developer/CommandLineTools/SDKs/MacOSX11.sdk 
-I/Library/Developer/CommandLineTools/SDKs/MacOSX11.sdk/System/Library/Frameworks/Tk.framework/Versions/8.5/Headers"
+          make LDFLAGS="-arch arm64 -isysroot 
/Library/Developer/CommandLineTools/SDKs/MacOSX11.sdk" CFLAGS="-arch arm64 
-isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX11.sdk 
-I/usr/local/include 
-I/Library/Developer/CommandLineTools/SDKs/MacOSX11.sdk/System/Library/Frameworks/Tk.framework/Versions/8.5/Headers"
 OBJCFLAGS="-arch arm64 -isysroot 
/Library/Developer/CommandLineTools/SDKs/MacOSX11.sdk 
-I/Library/Developer/CommandLineTools/SDKs/MacOSX11.sdk/System/Library/Frameworks/Tk.framework/Versions/8.5/Headers"
           cd ..
           lipo -create -o schismtracker buildarm/schismtracker 
build/schismtracker
           strip -S schismtracker
@@ -158,10 +184,14 @@
           sed -i .bak "s;<string>CFBundle.*Version.*</string>;<string>$(date 
+%Y%m%d)</string>;" Info.plist
           rm Info.plist.bak
           mkdir MacOS
+          cp ../../../../schismtracker MacOS
+          cp /usr/local/lib/libSDL2-2.0.0.dylib Resources
+          cp /usr/local/lib/libFLAC.12.dylib Resources
+          cp /usr/local/lib/libogg.0.dylib Resources
           cd MacOS
-          cp ../../../../../schismtracker .
-          cp /usr/local/lib/libSDL2-2.0.0.dylib ../Resources
           install_name_tool -change /usr/local/lib/libSDL2-2.0.0.dylib 
@executable_path/../Resources/libSDL2-2.0.0.dylib schismtracker
+          install_name_tool -change /usr/local/lib/libFLAC.12.dylib 
@executable_path/../Resources/libFLAC.12.dylib schismtracker
+          install_name_tool -change /usr/local/lib/libogg.0.dylib 
@executable_path/../Resources/libogg.0.dylib schismtracker
           cd ../../../../..
           cp -r sys/macosx/Schism_Tracker.app Schism\ Tracker.app
           cp docs/configuration.md .
@@ -180,14 +210,14 @@
       - name: 'Install dependencies'
         run: |
           sudo apt-get update
-          sudo apt-get install --fix-missing build-essential automake autoconf 
autoconf-archive libx11-dev libxext-dev libxv-dev libxxf86vm-dev libsdl2-dev 
libasound2-dev git libtool zip
+          sudo apt-get install --fix-missing build-essential automake autoconf 
autoconf-archive libx11-dev libxext-dev libxv-dev libxxf86vm-dev libsdl2-dev 
libasound2-dev libflac-dev git libtool zip
 
       - name: 'Checkout'
         uses: actions/checkout@v3
 
       - name: 'Get current date'
         id: date
-        run: echo "::set-output name=date::$(date +%Y%m%d)"
+        run: echo "date=$(date +%Y%m%d)" >> $GITHUB_OUTPUT
 
       - name: 'autoreconf -i'
         run: autoreconf -i
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schismtracker-20221201/Makefile.am 
new/schismtracker-20230906/Makefile.am
--- old/schismtracker-20221201/Makefile.am      2022-12-01 17:04:39.000000000 
+0100
+++ new/schismtracker-20230906/Makefile.am      2023-09-07 02:58:17.000000000 
+0200
@@ -220,6 +220,13 @@
 cflags_macosx=
 endif
 
+if USE_FLAC
+files_flac = \
+       fmt/flac.c
+cflags_flac=-DUSE_FLAC
+libs_flac=-lFLAC
+endif
+
 if USE_NETWORK
 cflags_network=-DUSE_NETWORK
 endif
@@ -354,7 +361,8 @@
        $(files_stdlib)                 \
        $(files_mmap)                   \
        $(files_wii)                    \
-       $(files_windres)
+       $(files_windres)                \
+       $(files_flac)
 
 # have version.o rely on all files
 schism/version.$(OBJEXT): $(filter-out 
schism/version.$(OBJEXT),$(schismtracker_OBJECTS)) $(HEADERS)
@@ -365,8 +373,8 @@
 AM_CFLAGS = $(SDL_CFLAGS) $(cflags_alsa) $(cflags_oss) \
        $(cflags_network) $(cflags_x11) $(cflags_fmopl) \
        $(cflags_version) $(cflags_win32) $(cflags_wii) \
-       $(cflags_macosx)
+       $(cflags_macosx) $(cflags_flac)
 AM_OBJCFLAGS = $(AM_CFLAGS)
 
 schismtracker_DEPENDENCIES = $(files_windres)
-schismtracker_LDADD = $(lib_asound) $(lib_win32) $(SDL_LIBS) $(LIBM)
+schismtracker_LDADD = $(lib_asound) $(lib_win32) $(libs_flac) $(SDL_LIBS) 
$(LIBM)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schismtracker-20221201/configure.ac 
new/schismtracker-20230906/configure.ac
--- old/schismtracker-20221201/configure.ac     2022-12-01 17:04:39.000000000 
+0100
+++ new/schismtracker-20230906/configure.ac     2023-09-07 02:58:17.000000000 
+0200
@@ -63,7 +63,7 @@
 dnl Check for SDL libs
 AC_CHECK_TOOL([SDL_CONFIG], [sdl2-config])
 AC_SUBST(SDL_CONFIG)
-if test "x$SDL_CONFIG" == "x"; then
+if test "x$SDL_CONFIG" = "x"; then
         AC_MSG_ERROR([*** sdl2-config not found.])
 fi
 AS_VERSION_COMPARE([$($SDL_CONFIG --version)], [2.0.5], [AC_MSG_ERROR([*** SDL 
version >= 2.0.5 not found.])])
@@ -301,6 +301,11 @@
         ADD_FORTIFY=$enableval,
         ADD_FORTIFY=no)
 
+AC_ARG_WITH([flac],
+               [AS_HELP_STRING([--without-flac],[Build without FLAC support 
@<:@default=no@:>@])],
+               [],
+               [with_flac=yes])
+
 dnl fortify needs -O; do this early so ADD_OPT can override with higher -O 
level
 if test x$ADD_FORTIFY \!= xno; then
         CFLAGS="$CFLAGS -O -D_FORTIFY_SOURCE=2"
@@ -321,6 +326,14 @@
         CFLAGS="$CFLAGS -Werror"
 fi
 
+AM_CONDITIONAL([USE_FLAC], false)
+if test "x$with_flac" = "xyes"; then
+               AC_CHECK_HEADER(FLAC/stream_decoder.h, libflac_found=yes, 
libflac_found=no)
+               if test x"$libflac_found" = "xyes"; then
+                               AM_CONDITIONAL([USE_FLAC], true)
+               fi
+fi
+
 dnl ... but put the warnings first, to make it possible to quiet certain
 dnl warnings if necessary, while still providing most of the benefit
 if test x$ADD_WARN \!= xno; then
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schismtracker-20221201/docs/building_on_linux.md 
new/schismtracker-20230906/docs/building_on_linux.md
--- old/schismtracker-20221201/docs/building_on_linux.md        2022-12-01 
17:04:39.000000000 +0100
+++ new/schismtracker-20230906/docs/building_on_linux.md        2023-09-07 
02:58:17.000000000 +0200
@@ -12,16 +12,18 @@
 
     sudo apt update
        sudo apt install build-essential automake autoconf-archive libsdl2-dev \
-                        git libtool
+                        git libtool libflac-dev
 
 On Arch Linux:
 
        sudo pacman -Syu
-       sudo pacman -S base-devel git sdl2 alsa-lib libxv libxxf86vm
+       sudo pacman -S base-devel git sdl2 alsa-lib libxv libxxf86vm flac
 
 Git is not strictly required, but if you don't need it you'll need to download
 a tarball manually, and your build won't have a proper version string.
 
+FLAC libraries are optional and only used for FLAC sample loading support.
+
 On other distros, the package names may be different. In particular, note that
 `build-essential` includes the packages `gcc` and `make` on Debian-based
 systems.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schismtracker-20221201/docs/building_on_osx.md 
new/schismtracker-20230906/docs/building_on_osx.md
--- old/schismtracker-20221201/docs/building_on_osx.md  2022-12-01 
17:04:39.000000000 +0100
+++ new/schismtracker-20230906/docs/building_on_osx.md  2023-09-07 
02:58:17.000000000 +0200
@@ -15,6 +15,9 @@
 
     sudo port install automake autoconf libtool libsdl2 git
 
+For FLAC sample loading support, you will also need development versions of the
+`flac` and `libogg` libraries.
+
 In this case, you may have to open a new terminal shell, or else you may get
 warnings about the version of autoconf/automake you're using.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schismtracker-20221201/docs/building_on_windows.md 
new/schismtracker-20230906/docs/building_on_windows.md
--- old/schismtracker-20221201/docs/building_on_windows.md      2022-12-01 
17:04:39.000000000 +0100
+++ new/schismtracker-20230906/docs/building_on_windows.md      2023-09-07 
02:58:17.000000000 +0200
@@ -54,6 +54,10 @@
 Also, you need the following specific dependency:
 
        pacman -S mingw-w64-x86_64-SDL2
+
+For FLAC sample loading, you'll also need the following dependency:
+
+       pacman -S mingw-w64-x86_64-flac
        
 Once you have installed these packages, close all your MSYS2 windows 
 before continuing with the instructions.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schismtracker-20221201/fmt/flac.c 
new/schismtracker-20230906/fmt/flac.c
--- old/schismtracker-20221201/fmt/flac.c       1970-01-01 01:00:00.000000000 
+0100
+++ new/schismtracker-20230906/fmt/flac.c       2023-09-07 02:58:17.000000000 
+0200
@@ -0,0 +1,378 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <stor...@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.bri...@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef USE_FLAC
+#include <FLAC/stream_decoder.h>
+#define NEED_BYTESWAP
+#include "headers.h"
+#include "fmt.h"
+#include "it.h"
+#include "disko.h"
+#include "sndfile.h"
+#include "log.h"
+#include <stdint.h>
+
+struct flac_file {
+       FLAC__StreamMetadata_StreamInfo streaminfo;
+       struct {
+               char *name;
+               int32_t sample_rate;
+               uint8_t pan;
+               uint8_t vol;
+               struct {
+                       uint32_t type;
+                       uint32_t start;
+                       uint32_t end;
+               } loop;
+       } flags;
+       struct {
+               const uint8_t* data;
+               size_t len;
+       } raw_data;
+       uint8_t* uncomp_buf;
+};
+static uint32_t samples_decoded = 0, samples_read = 0;
+static size_t total_size = 0;
+
+static void on_meta(const FLAC__StreamDecoder *decoder, const 
FLAC__StreamMetadata *metadata, void *client_data) {
+       struct flac_file* flac_file = (struct flac_file*)client_data;
+       int32_t loop_start = -1, loop_length = -1;
+       switch (metadata->type) {
+               case FLAC__METADATA_TYPE_STREAMINFO:
+                       flac_file->streaminfo = metadata->data.stream_info;
+                       break;
+               case FLAC__METADATA_TYPE_VORBIS_COMMENT:
+                       for (FLAC__uint32 i = 0; i < 
metadata->data.vorbis_comment.num_comments; i++) {
+                               const char *tag = (const 
char*)metadata->data.vorbis_comment.comments[i].entry;
+                               const FLAC__uint32 length = 
metadata->data.vorbis_comment.comments[i].length;
+                               if (length > 6 && !strncasecmp(tag, "TITLE=", 
6) && flac_file->flags.name)
+                                       strncpy(flac_file->flags.name, tag + 6, 
32);
+                               else if (length > 11 && !strncasecmp(tag, 
"SAMPLERATE=", 11))
+                                       flac_file->flags.sample_rate = 
strtol(tag + 11, NULL, 10);
+                               else if (length > 10 && !strncasecmp(tag, 
"LOOPSTART=", 10))
+                                       loop_start = strtol(tag + 10, NULL, 10);
+                               else if (length > 11 && !strncasecmp(tag, 
"LOOPLENGTH=", 11))
+                                       loop_length = strtol(tag + 11, NULL, 
10);
+                       }
+                       if (loop_start > 0 && loop_length > 1) {
+                               flac_file->flags.loop.type = 0;
+                               flac_file->flags.loop.start = loop_start;
+                               flac_file->flags.loop.end = loop_start + 
loop_length - 1;
+                       }
+                       break;
+               case FLAC__METADATA_TYPE_APPLICATION: {
+                       const uint8_t *data = (const uint8_t 
*)metadata->data.application.data;
+
+                       uint32_t chunk_id  = *(uint32_t *)data; data += 4;
+                       uint32_t chunk_len = *(uint32_t *)data; data += 4;
+
+                       if (chunk_id == 0x61727478 && chunk_len >= 8) { // 
"xtra"
+                               uint32_t xtra_flags = *(uint32_t *)data; data 
+= 4;
+
+                               // panning (0..256)
+                               if (xtra_flags & 0x20) {
+                                       uint16_t tmp_pan = *(uint16_t *)data;
+                                       if (tmp_pan > 255)
+                                               tmp_pan = 255;
+
+                                       flac_file->flags.pan = (uint8_t)tmp_pan;
+                               }
+                               data += 2;
+
+                               // volume (0..256)
+                               uint16_t tmp_vol = *(uint16_t *)data;
+                               if (tmp_vol > 256)
+                                       tmp_vol = 256;
+
+                               flac_file->flags.vol = (uint8_t)((tmp_vol + 2) 
/ 4); // 0..256 -> 0..64 (rounded)
+                       }
+
+                       if (chunk_id == 0x6C706D73 && chunk_len > 52) { // 
"smpl"
+                               data += 28; // seek to first wanted byte
+
+                               uint32_t num_loops = *(uint32_t *)data; data += 
4;
+                               if (num_loops == 1) {
+                                       data += 4+4; // skip "samplerData" and 
"identifier"
+
+                                       flac_file->flags.loop.type  = 
*(uint32_t *)data; data += 4;
+                                       flac_file->flags.loop.start = 
*(uint32_t *)data; data += 4;
+                                       flac_file->flags.loop.end   = 
*(uint32_t *)data; data += 4;
+                               }
+                       }
+                       break;
+               }
+               default:
+                       break;
+       }
+
+       (void)client_data;
+       (void)decoder;
+}
+
+static FLAC__StreamDecoderReadStatus on_read(const FLAC__StreamDecoder 
*decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) {
+       struct flac_file* flac_file = (struct flac_file*)client_data;
+
+       if (samples_read < flac_file->raw_data.len) {
+               if (*bytes > (flac_file->raw_data.len-samples_read))
+                       *bytes = flac_file->raw_data.len-samples_read;
+               memcpy(buffer, flac_file->raw_data.data+samples_read, *bytes);
+               samples_read += *bytes;
+               return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
+       } else {
+               *bytes = 0;
+               return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
+       }
+
+       (void)decoder;
+}
+
+static void on_error(const FLAC__StreamDecoder *decoder, 
FLAC__StreamDecoderErrorStatus status, void *client_data)
+{
+       (void)decoder, (void)client_data;
+
+       log_appendf(4, "Error loading FLAC: %s", 
FLAC__StreamDecoderErrorStatusString[status]);
+}
+
+static FLAC__StreamDecoderWriteStatus on_write(const FLAC__StreamDecoder 
*decoder, const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void 
*client_data) {
+       struct flac_file* flac_file = (struct flac_file*)client_data;
+
+       if (!flac_file->streaminfo.total_samples || 
!flac_file->streaminfo.channels)
+               return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
+
+       if (flac_file->streaminfo.channels > 2)
+               return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
+
+       switch (flac_file->streaminfo.bits_per_sample) {
+               case 8:  case 12: case 16:
+               case 20: case 24: case 32:
+                       break;
+               default:
+                       return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
+       }
+
+       if (frame->header.number.sample_number == 0)
+       {
+               total_size = (size_t)(flac_file->streaminfo.total_samples * 
flac_file->streaminfo.channels * flac_file->streaminfo.bits_per_sample/8);
+               flac_file->uncomp_buf = (uint8_t*)malloc(total_size * 
((flac_file->streaminfo.bits_per_sample == 8) ? sizeof(int8_t) : 
sizeof(int16_t)));
+               if (flac_file->uncomp_buf == NULL) {
+                       log_appendf(4, "Error loading FLAC: Out of memory!");
+                       return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
+               }
+
+               samples_decoded = 0;
+       }
+
+       /* this isn't true, but it works fine for what we do */
+       uint32_t block_size = 
frame->header.blocksize*flac_file->streaminfo.channels;
+
+       const uint32_t samples_allocated = 
flac_file->streaminfo.total_samples*flac_file->streaminfo.channels;
+       if (samples_decoded+block_size > samples_allocated)
+               block_size = samples_allocated - samples_decoded;
+
+       uint32_t i = 0, j = 0;
+       switch (flac_file->streaminfo.bits_per_sample) {
+               case 8: {
+                       int8_t *buf_ptr = flac_file->uncomp_buf + 
samples_decoded;
+                       for (i = 0, j = 0; i < block_size; j++) {
+                               buf_ptr[i++] = (int8_t)buffer[0][j];
+                               if (flac_file->streaminfo.channels == 2)
+                                       buf_ptr[i++] = (int8_t)buffer[1][j];
+                       }
+                       break;
+               }
+               /* here we cheat by just increasing 12-bit to 16-bit */
+               case 12: case 16: {
+                       int16_t *buf_ptr = (int16_t*)flac_file->uncomp_buf + 
samples_decoded;
+                       uint32_t bit_shift = 16 - 
flac_file->streaminfo.bits_per_sample;
+                       for (i = 0, j = 0; i < block_size; j++) {
+                               buf_ptr[i++] = buffer[0][j] << bit_shift;
+                               if (flac_file->streaminfo.channels == 2)
+                                       buf_ptr[i++] = buffer[1][j] << 
bit_shift;
+                       }
+                       break;
+               }
+               /* here we just make everything 16-bit, we don't support
+                  24-bit anyway */
+               case 20: case 24: case 32: {
+                       int16_t *buf_ptr = (int16_t*)flac_file->uncomp_buf + 
samples_decoded;
+                       uint32_t bit_shift = 
flac_file->streaminfo.bits_per_sample - 16;
+                       for (i = 0, j = 0; i < block_size; j++) {
+                               buf_ptr[i++] = buffer[0][j] >> bit_shift;
+                               if (flac_file->streaminfo.channels == 2)
+                                       buf_ptr[i++] = buffer[1][j] >> 
bit_shift;
+                       }
+                       break;
+               }
+       }
+
+       samples_decoded += block_size;
+
+       return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
+
+       (void)decoder;
+}
+
+#define FLAC_ERROR(x) \
+       if (decoder != NULL) FLAC__stream_decoder_delete(decoder); \
+       return x
+static int flac_load(struct flac_file* flac_file, size_t len, int meta_only) {
+       if (memcmp(flac_file->raw_data.data, "fLaC", 4))
+               return 0;
+       FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new();
+       if (decoder == NULL)
+               return 0;
+
+       FLAC__stream_decoder_set_metadata_respond_all(decoder);
+
+       FLAC__StreamDecoderInitStatus initStatus =
+               FLAC__stream_decoder_init_stream
+               (
+                       decoder,
+                       on_read, NULL,
+                       NULL, NULL,
+                       NULL, on_write,
+                       on_meta, on_error,
+                       flac_file
+               );
+
+       if (meta_only) {
+               if 
(!FLAC__stream_decoder_process_until_end_of_metadata(decoder)) {
+                       FLAC_ERROR(0);
+               }
+       } else {
+               if (!FLAC__stream_decoder_process_until_end_of_stream(decoder)) 
{
+                       FLAC_ERROR(0);
+               }
+       }
+
+       FLAC__stream_decoder_finish(decoder);
+       FLAC__stream_decoder_delete(decoder);
+       return 1;
+}
+#undef FLAC_ERROR
+
+int fmt_flac_load_sample(const uint8_t *data, size_t len, song_sample_t *smp) {
+       samples_read = 0;
+       samples_decoded = 0;
+       total_size = 0;
+       struct flac_file flac_file;
+       flac_file.raw_data.data = data;
+       flac_file.raw_data.len = len;
+       flac_file.flags.name = smp->name;
+       flac_file.flags.sample_rate = -1;
+       flac_file.flags.loop.type = -1;
+       if (!flac_load(&flac_file, len, 0))
+               return 0;
+
+       smp->volume        = 64 * 4;
+       smp->global_volume = 64;
+       smp->c5speed       = flac_file.streaminfo.sample_rate;
+       smp->length        = flac_file.streaminfo.total_samples;
+       if (flac_file.flags.loop.type != -1) {
+               smp->loop_start    = flac_file.flags.loop.start;
+               smp->loop_end      = flac_file.flags.loop.end+1;
+               smp->flags |= (flac_file.flags.loop.type ? (CHN_LOOP | 
CHN_PINGPONGLOOP) : CHN_LOOP);
+       }
+       if (flac_file.flags.sample_rate > 0) {
+               smp->c5speed = flac_file.flags.sample_rate;
+       }
+
+       // endianness
+       uint32_t flags = SF_LE;
+       // channels
+       flags |= (flac_file.streaminfo.channels == 2) ? SF_SI : SF_M;
+       // bit width
+       switch (flac_file.streaminfo.bits_per_sample) {
+       case 8:  flags |= SF_8;  break;
+       case 12:
+       case 16:
+       case 20:
+       case 24:
+       case 32: flags |= SF_16; break;
+       default:
+               free(flac_file.uncomp_buf);
+               return 0;
+       }
+       // libFLAC always returns signed
+       flags |= SF_PCMS;
+       int ret = csf_read_sample(smp, flags, flac_file.uncomp_buf, total_size);
+       free(flac_file.uncomp_buf);
+
+       return ret;
+}
+
+int fmt_flac_read_info(dmoz_file_t *file, const uint8_t *data, size_t len)
+{
+       samples_read = 0;
+       samples_decoded = 0;
+       total_size = 0;
+       struct flac_file flac_file;
+       flac_file.raw_data.data = data;
+       flac_file.raw_data.len = len;
+       flac_file.flags.name = NULL;
+       flac_file.flags.loop.type = -1;
+       if (!flac_load(&flac_file, len, 1)) {
+               return 0;
+       }
+
+       file->smp_flags = 0;
+
+       /* don't even attempt */
+       if (flac_file.streaminfo.channels > 2 || 
!flac_file.streaminfo.total_samples ||
+               !flac_file.streaminfo.channels)
+               return 0;
+
+       switch (flac_file.streaminfo.bits_per_sample) {
+               case 12:
+               case 16:
+               case 20:
+               case 24:
+               case 32:
+                       file->smp_flags |= CHN_16BIT;
+               case 8:
+                       break;
+               default:
+                       return 0;
+       }
+
+       if (flac_file.streaminfo.channels == 2)
+               file->smp_flags |= CHN_STEREO;
+
+       file->smp_speed      = flac_file.streaminfo.sample_rate;
+       file->smp_length     = flac_file.streaminfo.total_samples;
+       if (flac_file.flags.loop.type != -1) {
+               file->smp_loop_start = flac_file.flags.loop.start;
+               file->smp_loop_end   = flac_file.flags.loop.end+1;
+               file->smp_flags    |= (flac_file.flags.loop.type ? (CHN_LOOP | 
CHN_PINGPONGLOOP) : CHN_LOOP);
+       }
+       if (flac_file.flags.sample_rate > 0) {
+               file->smp_speed = flac_file.flags.sample_rate;
+       }
+
+       file->description  = "FLAC Audio File";
+       file->type         = TYPE_SAMPLE_COMPR;
+       file->smp_filename = file->base;
+
+       return 1;
+}
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schismtracker-20221201/fmt/s3m.c 
new/schismtracker-20230906/fmt/s3m.c
--- old/schismtracker-20221201/fmt/s3m.c        2022-12-01 17:04:39.000000000 
+0100
+++ new/schismtracker-20230906/fmt/s3m.c        2023-09-07 02:58:17.000000000 
+0200
@@ -441,7 +441,9 @@
                        ver_decode_cwtv(trkvers, reserved, song->tracker_id + 
strlen(song->tracker_id));
                        break;
                case 5:
-                       if (trkvers >= 0x5129 && reserved)
+                       if (trkvers == 0x5447)
+                               strcpy(song->tracker_id, "Graoumf Tracker");
+                       else if (trkvers >= 0x5129 && reserved)
                                sprintf(song->tracker_id, "OpenMPT 
%d.%02x.%02x.%02x", (trkvers & 0xf00) >> 8, trkvers & 0xff, (reserved >> 8) & 
0xff, reserved & 0xff);
                        else
                                tid = "OpenMPT %d.%02x";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schismtracker-20221201/include/fmt-types.h 
new/schismtracker-20230906/include/fmt-types.h
--- old/schismtracker-20221201/include/fmt-types.h      2022-12-01 
17:04:39.000000000 +0100
+++ new/schismtracker-20230906/include/fmt-types.h      2023-09-07 
02:58:17.000000000 +0200
@@ -106,6 +106,9 @@
 READ_INFO(au)   LOAD_SAMPLE(au)   SAVE_SAMPLE(au)
 READ_INFO(aiff) LOAD_SAMPLE(aiff) SAVE_SAMPLE(aiff) EXPORT(aiff)
 READ_INFO(wav)  LOAD_SAMPLE(wav)  SAVE_SAMPLE(wav)  EXPORT(wav)
+#ifdef USE_FLAC
+READ_INFO(flac) LOAD_SAMPLE(flac)
+#endif
 READ_INFO(iti)  LOAD_INSTRUMENT(iti)
 READ_INFO(xi)   LOAD_INSTRUMENT(xi)
 READ_INFO(pat)  LOAD_INSTRUMENT(pat)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schismtracker-20221201/include/sndfile.h 
new/schismtracker-20230906/include/sndfile.h
--- old/schismtracker-20221201/include/sndfile.h        2022-12-01 
17:04:39.000000000 +0100
+++ new/schismtracker-20230906/include/sndfile.h        2023-09-07 
02:58:17.000000000 +0200
@@ -62,7 +62,7 @@
 #define CHN_PANENV              0x400000 // pan envelope is active
 #define CHN_PITCHENV            0x800000 // pitch/filter envelope is active
 #define CHN_FASTVOLRAMP         0x1000000 // ramp volume very fast (XXX this 
is a dumb flag)
-//#define CHN_EXTRALOUD         0x2000000
+#define CHN_NEWNOTE             0x2000000 // note was triggered, reset filter
 //#define CHN_REVERB            0x4000000
 //#define CHN_NOREVERB          0x8000000
 #define CHN_NNAMUTE             0x10000000 // turn off mute, but have it reset 
later
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schismtracker-20221201/include/util.h 
new/schismtracker-20230906/include/util.h
--- old/schismtracker-20221201/include/util.h   2022-12-01 17:04:39.000000000 
+0100
+++ new/schismtracker-20230906/include/util.h   2023-09-07 02:58:17.000000000 
+0200
@@ -53,9 +53,6 @@
 # ifndef UNUSED
 #  define UNUSED __attribute__((unused))
 # endif
-# ifndef NORETURN
-#  define NORETURN __attribute__((noreturn))
-# endif
 # ifndef PACKED
 #  define PACKED __attribute__((packed))
 # endif
@@ -69,9 +66,6 @@
 # ifndef PACKED
 #  define PACKED
 # endif
-# ifndef NORETURN
-#  define NORETURN
-# endif
 # ifndef LIKELY
 #  define LIKELY(x)
 # endif
Binary files old/schismtracker-20221201/libs/libSDL-1.2.0.dylib and 
new/schismtracker-20230906/libs/libSDL-1.2.0.dylib differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schismtracker-20221201/player/csndfile.c 
new/schismtracker-20230906/player/csndfile.c
--- old/schismtracker-20221201/player/csndfile.c        2022-12-01 
17:04:39.000000000 +0100
+++ new/schismtracker-20230906/player/csndfile.c        2023-09-07 
02:58:17.000000000 +0200
@@ -451,6 +451,7 @@
        song_voice_t *v = csf->voices;
        for (uint32_t i = 0; i < MAX_VOICES; i++, v++) {
                memset(v, 0, sizeof(*v));
+               v->note = v->new_note = 1;
                v->cutoff = 0x7F;
                v->volume = 256;
                if (i < MAX_CHANNELS) {
@@ -474,7 +475,8 @@
                song_voice_t *v = csf->voices + j;
 
                v->frequency = 0;
-               v->note = v->new_note = v->new_instrument = 0;
+               v->note = v->new_note = 1;
+               v->new_instrument = 0;
                v->portamento_target = 0;
                v->n_command = 0;
                v->cd_patloop = 0;
@@ -1206,7 +1208,8 @@
                return;
        for (int i = 0; i < MAX_VOICES; i++, v++) {
                if (v->ptr_sample == smp || v->current_sample_data == 
smp->data) {
-                       v->note = v->new_note = v->new_instrument = 0;
+                       v->note = v->new_note = 1;
+                       v->new_instrument = 0;
                        v->fadeout_volume = 0;
                        v->flags |= CHN_KEYOFF | CHN_NOTEFADE;
                        v->frequency = 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schismtracker-20221201/player/effects.c 
new/schismtracker-20230906/player/effects.c
--- old/schismtracker-20221201/player/effects.c 2022-12-01 17:04:39.000000000 
+0100
+++ new/schismtracker-20230906/player/effects.c 2023-09-07 02:58:17.000000000 
+0200
@@ -1178,7 +1178,7 @@
        uint32_t note = chan->new_note;
 
        if (note == NOTE_NONE) {
-               /* nothing to see here */
+               return;
        } else if (NOTE_IS_CONTROL(note)) {
                /* nothing here either */
        } else if (penv) {
@@ -1214,9 +1214,12 @@
                }
        }
 
-       if(penv && !inst_changed && psmp != oldsmp && chan->current_sample_data 
&& !NOTE_IS_NOTE(note)) {
+       if (penv && !inst_changed && psmp != oldsmp && 
chan->current_sample_data && !NOTE_IS_NOTE(note)) {
                return;
        }
+       if (!penv && psmp != oldsmp && porta) {
+               chan->flags |= CHN_NEWNOTE;
+       }
 
        // Reset envelopes
 
@@ -1347,7 +1350,7 @@
        if (NOTE_IS_CONTROL(note)) {
                // hax: keep random sample numbers from triggering notes (see 
csf_instrument_change)
                // NOTE_OFF is a completely arbitrary choice - this could be 
anything above NOTE_LAST
-               chan->new_note = NOTE_OFF;
+               chan->note = chan->new_note = NOTE_OFF;
                switch (note) {
                case NOTE_OFF:
                        fx_key_off(csf, nchan);
@@ -1434,7 +1437,7 @@
                chan->vu_meter = 0x0;
                chan->strike = 4; /* this affects how long the initial hit on 
the playback marks lasts (bigger dot in instrument and sample list windows)*/
                chan->flags &= ~CHN_FILTER;
-               chan->flags |= CHN_FASTVOLRAMP;
+               chan->flags |= CHN_FASTVOLRAMP | CHN_NEWNOTE;
                if (!retrig) {
                        chan->autovib_depth = 0;
                        chan->autovib_position = 0;
@@ -1450,9 +1453,6 @@
                } else {
                        chan->vol_swing = chan->pan_swing = 0;
                }
-
-               if (chan->cutoff < 0x7F)
-                       setup_channel_filter(chan, 1, 256, csf->mix_frequency);
        }
 }
 
@@ -2049,7 +2049,7 @@
                               || volcmd == VOLFX_TONEPORTAMENTO);
                int start_note = csf->flags & SONG_FIRSTTICK;
 
-               chan->flags &= ~CHN_FASTVOLRAMP;
+               chan->flags &= ~(CHN_FASTVOLRAMP | CHN_NEWNOTE);
 
                // set instrument before doing anything else
                if (instr && start_note) chan->new_instrument = instr;
@@ -2095,6 +2095,15 @@
                                        if (instr < MAX_SAMPLES)
                                                chan->volume = 
csf->samples[instr].volume;
                                }
+
+                               if (csf->flags & SONG_INSTRUMENTMODE) {
+                                       if (instr < MAX_INSTRUMENTS && 
(chan->ptr_instrument != csf->instruments[instr] || !chan->increment))
+                                               note = chan->note;
+                               } else
+                               {
+                                       if (instr < MAX_SAMPLES && 
(chan->ptr_sample != &csf->samples[instr] || !chan->increment))
+                                               note = chan->note;
+                               }
                        }
                        // Invalid Instrument ?
                        if (instr >= MAX_INSTRUMENTS) instr = 0;
@@ -2140,9 +2149,11 @@
                                                
csf->instruments[instr]->midi_bank,
                                                
csf->instruments[instr]->midi_channel_mask);
 
-                               chan->new_instrument = 0;
-                               if (NOTE_IS_NOTE(note) && psmp != 
chan->ptr_sample) {
-                                       chan->position = chan->position_frac = 
0;
+                               if (NOTE_IS_NOTE(note)) {
+                                       chan->new_instrument = 0;
+                                       if (psmp != chan->ptr_sample) {
+                                               chan->position = 
chan->position_frac = 0;
+                                       }
                                }
                        }
                        // New Note ?
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schismtracker-20221201/player/filters.c 
new/schismtracker-20230906/player/filters.c
--- old/schismtracker-20221201/player/filters.c 2022-12-01 17:04:39.000000000 
+0100
+++ new/schismtracker-20230906/player/filters.c 2023-09-07 02:58:17.000000000 
+0200
@@ -82,14 +82,17 @@
        if (resonance > 255)
                resonance = 255;
 
-        // TODO: The enabling/disabling of channel filter is a bit more 
complex.
-        // More info in snd_flt.cpp in OpenMPT and filter-reset.it, 
filter-reset-carry.it
-        // and filter-nna.it from 
https://wiki.openmpt.org/Development:_Test_Cases/IT
-       // Should be 255, but Zxx cutoff is limited to 127, so...
-       if (cutoff < 254)
-               chan->flags |= CHN_FILTER;
-       else
-               cutoff = 255;
+       if (resonance == 0 && cutoff >= 254)
+       {
+               if (chan->flags & CHN_NEWNOTE)
+               {
+                       // Z7F next to a note disables the filter, however in 
other cases this should not happen.
+                       // Test cases: filter-reset.it, filter-reset-carry.it, 
filter-reset-envelope.it, filter-nna.it, FilterResetPatDelay.it, 
FilterPortaSmpChange.it, FilterPortaSmpChange-InsMode.it
+                       chan->flags &= ~CHN_FILTER;
+               }
+               return;
+       }
+       chan->flags |= CHN_FILTER;
 
        // 2 ^ (i / 24 * 256)
        frequency = 110.0 * powf(2.0, (float) cutoff * FREQ_PARAM_MULT + 0.25);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schismtracker-20221201/player/sndmix.c 
new/schismtracker-20230906/player/sndmix.c
--- old/schismtracker-20221201/player/sndmix.c  2022-12-01 17:04:39.000000000 
+0100
+++ new/schismtracker-20230906/player/sndmix.c  2023-09-07 02:58:17.000000000 
+0200
@@ -224,16 +224,17 @@
 }
 
 
-static inline void rn_process_envelope(song_voice_t *chan, int *nvol)
-{
+static inline void rn_process_vol_env(song_voice_t* chan, int *nvol) {
        song_instrument_t *penv = chan->ptr_instrument;
        int vol = *nvol;
 
-       // Volume Envelope
-       if (chan->flags & CHN_VOLENV && penv->vol_env.nodes) {
-               int envpos = chan->vol_env_position;
+       if ((chan->flags & CHN_VOLENV || penv->flags & ENV_VOLUME) && 
penv->vol_env.nodes) {
+               int envpos = chan->vol_env_position - 1;
                unsigned int pt = penv->vol_env.nodes - 1;
 
+               if (chan->vol_env_position == 0)
+                       return;
+
                for (unsigned int i = 0; i < (unsigned int)(penv->vol_env.nodes 
- 1); i++) {
                        if (envpos <= penv->vol_env.ticks[i]) {
                                pt = i;
@@ -265,12 +266,21 @@
                envvol = CLAMP(envvol, 0, 256);
                vol = (vol * envvol) >> 8;
        }
+       
+       *nvol = vol;
+}
 
-       // Panning Envelope
-       if ((chan->flags & CHN_PANENV) && (penv->pan_env.nodes)) {
-               int envpos = chan->pan_env_position;
+
+static inline void rn_process_pan_env(song_voice_t* chan) {
+       song_instrument_t *penv = chan->ptr_instrument;
+
+       if ((chan->flags & CHN_PANENV || penv->flags & ENV_PANNING) && 
(penv->pan_env.nodes)) {
+               int envpos = chan->pan_env_position - 1;
                unsigned int pt = penv->pan_env.nodes - 1;
 
+               if (chan->pan_env_position == 0)
+                       return;
+
                for (unsigned int i=0; i<(unsigned int)(penv->pan_env.nodes-1); 
i++) {
                        if (envpos <= penv->pan_env.ticks[i]) {
                                pt = i;
@@ -308,8 +318,13 @@
 
                chan->final_panning = pan;
        }
+}
+
+
+static inline void rn_process_ins_fade(song_voice_t *chan, int *nvol) {
+       song_instrument_t *penv = chan->ptr_instrument;
+       int vol = *nvol;
 
-       // FadeOut volume
        if (chan->flags & CHN_NOTEFADE) {
                unsigned int fadeout = penv->fadeout;
 
@@ -324,11 +339,23 @@
                        vol = 0;
                }
        }
-
        *nvol = vol;
 }
 
 
+static inline void rn_process_envelope(song_voice_t *chan, int *nvol)
+{
+       // Volume Envelope
+       rn_process_vol_env(chan, nvol);
+
+       // Panning Envelope
+       rn_process_pan_env(chan);
+
+       // FadeOut volume
+       rn_process_ins_fade(chan, nvol);
+}
+
+
 static inline int rn_arpeggio(song_t *csf, song_voice_t *chan, int frequency)
 {
        int a;
@@ -356,56 +383,62 @@
        int *nenvpitch, int *nfrequency)
 {
        song_instrument_t *penv = chan->ptr_instrument;
-       int envpos = chan->pitch_env_position;
-       unsigned int pt = penv->pitch_env.nodes - 1;
-       int frequency = *nfrequency;
-       int envpitch = *nenvpitch;
-
-       for (unsigned int i = 0; i < (unsigned int)(penv->pitch_env.nodes - 1); 
i++) {
-               if (envpos <= penv->pitch_env.ticks[i]) {
-                       pt = i;
-                       break;
+
+       if ((chan->flags & CHN_PANENV || penv->flags & (ENV_PITCH | 
ENV_FILTER)) && (penv->pan_env.nodes)) {
+               int envpos = chan->pitch_env_position - 1;
+               unsigned int pt = penv->pitch_env.nodes - 1;
+               int frequency = *nfrequency;
+               int envpitch = *nenvpitch;
+
+               if (chan->pitch_env_position == 0)
+                       return;
+
+               for (unsigned int i = 0; i < (unsigned 
int)(penv->pitch_env.nodes - 1); i++) {
+                       if (envpos <= penv->pitch_env.ticks[i]) {
+                               pt = i;
+                               break;
+                       }
                }
-       }
 
-       int x2 = penv->pitch_env.ticks[pt];
-       int x1;
+               int x2 = penv->pitch_env.ticks[pt];
+               int x1;
 
-       if (envpos >= x2) {
-               envpitch = (((int)penv->pitch_env.values[pt]) - 32) * 8;
-               x1 = x2;
-       } else if (pt) {
-               envpitch = (((int)penv->pitch_env.values[pt - 1]) - 32) * 8;
-               x1 = penv->pitch_env.ticks[pt - 1];
-       } else {
-               envpitch = 0;
-               x1 = 0;
-       }
+               if (envpos >= x2) {
+                       envpitch = (((int)penv->pitch_env.values[pt]) - 32) * 8;
+                       x1 = x2;
+               } else if (pt) {
+                       envpitch = (((int)penv->pitch_env.values[pt - 1]) - 32) 
* 8;
+                       x1 = penv->pitch_env.ticks[pt - 1];
+               } else {
+                       envpitch = 0;
+                       x1 = 0;
+               }
+
+               if (envpos > x2)
+                       envpos = x2;
 
-       if (envpos > x2)
-               envpos = x2;
+               if (x2 > x1 && envpos > x1) {
+                       int envpitchdest = (((int)penv->pitch_env.values[pt]) - 
32) * 8;
+                       envpitch += ((envpos - x1) * (envpitchdest - envpitch)) 
/ (x2 - x1);
+               }
 
-       if (x2 > x1 && envpos > x1) {
-               int envpitchdest = (((int)penv->pitch_env.values[pt]) - 32) * 8;
-               envpitch += ((envpos - x1) * (envpitchdest - envpitch)) / (x2 - 
x1);
-       }
+               // clamp to -255/255?
+               envpitch = CLAMP(envpitch, -256, 256);
 
-       // clamp to -255/255?
-       envpitch = CLAMP(envpitch, -256, 256);
+               // Pitch Envelope
+               if (!(penv->flags & ENV_FILTER)) {
+                       int l = abs(envpitch);
 
-       // Pitch Envelope
-       if (!(penv->flags & ENV_FILTER)) {
-               int l = abs(envpitch);
+                       if (l > 255)
+                               l = 255;
 
-               if (l > 255)
-                       l = 255;
+                       int ratio = (envpitch < 0 ? linear_slide_down_table : 
linear_slide_up_table)[l];
+                       frequency = _muldiv(frequency, ratio, 0x10000);
+               }
 
-               int ratio = (envpitch < 0 ? linear_slide_down_table : 
linear_slide_up_table)[l];
-               frequency = _muldiv(frequency, ratio, 0x10000);
+               *nfrequency = frequency;
+               *nenvpitch = envpitch;
        }
-
-       *nfrequency = frequency;
-       *nenvpitch = envpitch;
 }
 
 
@@ -419,8 +452,6 @@
                return;
        }
 
-       (*position)++;
-
        if ((penv->flags & sus_flag) && !(chan->flags & CHN_KEYOFF)) {
                start = envelope->ticks[envelope->sustain_start];
                end = envelope->ticks[envelope->sustain_end] + 1;
@@ -440,6 +471,8 @@
                *position = start;
                chan->flags |= fade_flag; // only relevant for volume envelope
        }
+
+       (*position)++;
 }
 
 static inline void rn_increment_env_pos(song_voice_t *chan)
@@ -1126,6 +1159,8 @@
 
                        // Process Envelopes
                        if ((csf->flags & SONG_INSTRUMENTMODE) && 
chan->ptr_instrument) {
+                               /* OpenMPT test cases s77.it and EnvLoops.it */
+                               rn_increment_env_pos(chan);
                                rn_process_envelope(chan, &vol);
                        } else {
                                // No Envelope: key off => note cut
@@ -1176,6 +1211,10 @@
                        if (!(chan->flags & CHN_NOTEFADE))
                                rn_gen_key(csf, chan, cn, frequency, vol);
 
+                       if (chan->flags & CHN_NEWNOTE) {
+                               setup_channel_filter(chan, 1, 256, 
csf->mix_frequency);
+                       }
+
                        // Filter Envelope: controls cutoff frequency
                        if (chan && chan->ptr_instrument && 
chan->ptr_instrument->flags & ENV_FILTER) {
                                setup_channel_filter(chan,
@@ -1198,10 +1237,6 @@
                        chan->increment = (ninc + 1) & ~3;
                }
 
-               // Increment envelope position
-               if (csf->flags & SONG_INSTRUMENTMODE && chan->ptr_instrument)
-                       rn_increment_env_pos(chan);
-
                chan->final_panning = CLAMP(chan->final_panning, 0, 256);
 
                // Volume ramping
@@ -1232,6 +1267,8 @@
                        chan->left_volume = chan->right_volume = 0;
                        chan->length = 0;
                }
+
+               chan->flags &= ~CHN_NEWNOTE;
        }
 
        // Checking Max Mix Channels reached: ordering by volume
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schismtracker-20221201/schism/keyboard.c 
new/schismtracker-20230906/schism/keyboard.c
--- old/schismtracker-20221201/schism/keyboard.c        2022-12-01 
17:04:39.000000000 +0100
+++ new/schismtracker-20230906/schism/keyboard.c        2023-09-07 
02:58:17.000000000 +0200
@@ -360,8 +360,9 @@
                break;
        default:
                note--;
-               snprintf(buf, 4, "%.2s%.1d", note_names[note % 12],
-                        note / 12);
+               buf[0] = note_names[note % 12][0];
+               buf[1] = note_names[note % 12][1];
+               buf[2] = note / 12 + '0'; 
        }
        buf[3] = 0;
        return buf;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schismtracker-20221201/schism/main.c 
new/schismtracker-20230906/schism/main.c
--- old/schismtracker-20221201/schism/main.c    2022-12-01 17:04:39.000000000 
+0100
+++ new/schismtracker-20230906/schism/main.c    2023-09-07 02:58:17.000000000 
+0200
@@ -594,7 +594,6 @@
        kk->sy = start_y;
 }
 
-static void event_loop(void) NORETURN;
 static void event_loop(void)
 {
        SDL_Event event;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schismtracker-20221201/schism/page_patedit.c 
new/schismtracker-20230906/schism/page_patedit.c
--- old/schismtracker-20221201/schism/page_patedit.c    2022-12-01 
17:04:39.000000000 +0100
+++ new/schismtracker-20230906/schism/page_patedit.c    2023-09-07 
02:58:17.000000000 +0200
@@ -105,6 +105,7 @@
 static int panning_mode = 0;            /* for the volume column */
 int midi_bend_hit[64];
 int midi_last_bend_hit[64];
+int midi_last_note[64];
 
 /* blah; other forwards */
 static void pated_save(const char *descr);
@@ -2983,6 +2984,11 @@
        if (k->midi_note == -1) {
                /* nada */
        } else if (k->state == KEY_RELEASE) {
+               /* don't record noteoffs of non-matching notes */
+               if (k->midi_note != midi_last_note[c]) {
+                       return 0;
+               }
+
                c = song_keyup(KEYJAZZ_NOINST, KEYJAZZ_NOINST, k->midi_note);
 
                /* don't record noteoffs for no good reason... */
@@ -3006,7 +3012,7 @@
                if (!((song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP)) && 
playback_tracing)) {
                        tick = 0;
                }
-               n = k->midi_note;
+               midi_last_note[c] = n = k->midi_note;
                c = song_keydown(KEYJAZZ_NOINST, KEYJAZZ_NOINST, n, v, 
current_channel);
                cur_note = pattern + 64 * current_row + (c-1);
                patedit_record_note(cur_note, c, current_row, n, 0);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schismtracker-20221201/schism/sample-view.c 
new/schismtracker-20230906/schism/sample-view.c
--- old/schismtracker-20221201/schism/sample-view.c     2022-12-01 
17:04:39.000000000 +0100
+++ new/schismtracker-20230906/schism/sample-view.c     2023-09-07 
02:58:17.000000000 +0200
@@ -50,45 +50,31 @@
 static void _draw_sample_data_8(struct vgamem_overlay *r,
        signed char *data, unsigned long length, unsigned int inputchans, 
unsigned int outputchans)
 {
+       length /= inputchans;
+       const int nh = r->height / outputchans;
+       const int step = MAX(1, (length / r->width) >> 8);
+
        unsigned long pos;
        unsigned int cc, co;
-       int level, xs, ys, xe, ye, step;
-       int nh, np;
-       int chip;
-
-       nh = (r->height / outputchans);
-       np = r->height - (nh / 2);
-
-       length /= inputchans;
-       chip = (length < (unsigned int) r->width * 2);
+       int level, xs, ys, xe, ye;
+       int np = r->height - nh / 2;
 
        for (cc = 0; cc < outputchans; cc++) {
                pos = 0;
-               co = 0;
-               step = MAX(1, (length / r->width) >> 8);
-               level=0;
-               do {
-                       level+=ceil(data[(pos * inputchans) + cc+co] * nh / 
(float)(SCHAR_MAX - SCHAR_MIN + 1));
-               } while (co++ < inputchans-outputchans);
                xs = 0;
-               ys = (np - 1) - level;
-               ys = CLAMP(ys, 0, r->height - 1);
+               ys = 0;
                do {
-                       pos += step;
                        co = 0;
-                       level=0;
+                       level = 0;
                        do {
-                               level+=ceil(data[(pos * inputchans) + cc+co] * 
nh / (SCHAR_MAX - SCHAR_MIN + 1));
+                               level += ceil(data[(pos * inputchans) + cc+co] 
* nh / (float)UCHAR_MAX);
                        } while (co++ < inputchans-outputchans);
-                       xe = pos * r->width / length;
-                       ye = (np - 1) - level;
-                       xe = CLAMP(xe, 0, r->width - 1);
-                       ye = CLAMP(ye, 0, r->height - 1);
-                       // 'ye' is more or less useless for small samples, but 
this is much cleaner
-                       // code than writing nearly the same loop four 
different times :P
-                       vgamem_ovl_drawline(r, xs, ys, xe, chip ? ys : ye, 
SAMPLE_DATA_COLOR);
+                       xe = length <= 1 ? r->width - 1 : CLAMP(pos * r->width 
/ length, 0, r->width - 1);
+                       ye = CLAMP((np - 1) - level, 0, r->height - 1);
+                       vgamem_ovl_drawline(r, xs, !pos ? ye : ys, xe, ye, 
SAMPLE_DATA_COLOR);
                        xs = xe;
                        ys = ye;
+                       pos += step;
                } while (pos < length);
                np -= nh;
        }
@@ -97,43 +83,31 @@
 static void _draw_sample_data_16(struct vgamem_overlay *r,
         signed short *data, unsigned long length, unsigned int inputchans, 
unsigned int outputchans)
 {
+       length /= inputchans;
+       const int nh = r->height / outputchans;
+       const int step = MAX(1, (length / r->width) >> 8);
+
        unsigned long pos;
        unsigned int cc, co;
-       int level, xs, ys, xe, ye, step;
-       int nh, np;
-       int chip;
-
-       nh = (r->height / outputchans);
-       np = r->height - (nh / 2);
-
-       length /= inputchans;
-       chip = (length < (unsigned int) r->width * 2);
+       int level, xs, ys, xe, ye;
+       int np = r->height - nh / 2;
 
        for (cc = 0; cc < outputchans; cc++) {
                pos = 0;
-               co = 0;
-               step = MAX(1, (length / r->width) >> 8);
-               level=0;
-               do {
-                       level += ceil(data[(pos * inputchans) + cc+co] * nh / 
(float)(SHRT_MAX - SHRT_MIN + 1));
-               } while(co++ < inputchans-outputchans);
                xs = 0;
-               ys = (np - 1) - level;
-               ys = CLAMP(ys, 0, r->height - 1);
+               ys = 0;
                do {
-                       pos += step;
                        co = 0;
                        level = 0;
                        do {
-                               level = ceil(data[(pos * inputchans) + cc+co] * 
nh / (float)(SHRT_MAX - SHRT_MIN + 1));
+                               level += ceil(data[(pos * inputchans) + cc+co] 
* nh / (float)USHRT_MAX);
                        } while (co++ < inputchans-outputchans);
-                       xe = pos * r->width / length;
-                       ye = (np - 1) - level;
-                       xe = CLAMP(xe, 0, r->width - 1);
-                       ye = CLAMP(ye, 0, r->height - 1);
-                       vgamem_ovl_drawline(r, xs, ys, xe, chip ? ys : ye, 
SAMPLE_DATA_COLOR);
+                       xe = length <= 1 ? r->width - 1 : CLAMP(pos * r->width 
/ length, 0, r->width - 1);
+                       ye = CLAMP((np - 1) - level, 0, r->height - 1);
+                       vgamem_ovl_drawline(r, xs, !pos ? ye : ys, xe, ye, 
SAMPLE_DATA_COLOR);
                        xs = xe;
                        ys = ye;
+                       pos += step;
                } while (pos < length);
                np -= nh;
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schismtracker-20221201/schism/video.c 
new/schismtracker-20230906/schism/video.c
--- old/schismtracker-20221201/schism/video.c   2022-12-01 17:04:39.000000000 
+0100
+++ new/schismtracker-20230906/schism/video.c   2023-09-07 02:58:17.000000000 
+0200
@@ -190,6 +190,10 @@
 void video_setup(const char* quality)
 {
        SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, quality);
+
+       // Needed as of SDL2 so Ctrl-D SDL_SetWindowGrab will grab keyboard too,
+       // not just mouse.
+       SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "1");
 }
 
 static void set_icon(void)
@@ -250,6 +254,10 @@
 
        video_setup(cfg_video_interpolation);
 
+#ifndef SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR
+/* older SDL2 versions don't define this, don't fail the build for it */
+#define SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR 
"SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR"
+#endif
        SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
 
        video.x = SDL_WINDOWPOS_CENTERED;

Reply via email to