shithub: sf2mid

Download patch

ref: 268f8e86c3d78d9d165c1605ae0e0e04c575598c
parent: b9a4de3b3b29fe03e52c6d0a5853353fa2c5e21f
author: Bernhard Schelling <schellingb@gmail.com>
date: Tue Oct 24 19:29:50 EDT 2017

Correctly stop notes with note_off
The previous commit introduced a bug where multiple calls to note_off stopped the same notes as they were deemed active even during their release

--- a/tsf.h
+++ b/tsf.h
@@ -80,10 +80,10 @@
 	// Custom data given to the functions as the first parameter
 	void* data;
 
-	// Function pointer will be called to read 'size' bytes into ptr
+	// Function pointer will be called to read 'size' bytes into ptr (returns number of read bytes)
 	int (*read)(void* data, void* ptr, unsigned int size);
 
-	// Function pointer will be called to skip ahead over 'count' bytes
+	// Function pointer will be called to skip ahead over 'count' bytes (returns 1 on success, 0 on error)
 	int (*skip)(void* data, unsigned int count);
 };
 
@@ -1241,7 +1241,7 @@
 	for (; v != vEnd; v++)
 	{
 		//Find the first and last entry in the voices list with matching preset, key and look up the smallest play index
-		if (v->playingPreset != preset_index || v->playingKey != key) continue;
+		if (v->playingPreset != preset_index || v->playingKey != key || v->ampenv.segment >= TSF_SEGMENT_SUSTAIN) continue;
 		else if (!vMatchFirst || v->playIndex < vMatchFirst->playIndex) vMatchFirst = vMatchLast = v;
 		else if (v->playIndex == vMatchFirst->playIndex) vMatchLast = v;
 	}
@@ -1249,7 +1249,8 @@
 	for (v = vMatchFirst; v <= vMatchLast; v++)
 	{
 		//Stop all voices with matching preset, key and the smallest play index which was enumerated above
-		if (v->playIndex != vMatchFirst->playIndex || v->playingPreset != preset_index || v->playingKey != key) continue;
+		if (v != vMatchFirst && v != vMatchLast &&
+			(v->playIndex != vMatchFirst->playIndex || v->playingPreset != preset_index || v->playingKey != key || v->ampenv.segment >= TSF_SEGMENT_SUSTAIN)) continue;
 		tsf_voice_end(v, f->outSampleRate);
 	}
 }