Bug 218625 - EMU10K1 sequencer MIDI playback corruption
Summary: EMU10K1 sequencer MIDI playback corruption
Status: RESOLVED CODE_FIX
Alias: None
Product: Linux
Classification: Unclassified
Component: Kernel (show other bugs)
Hardware: All Linux
: P3 normal
Assignee: Virtual assignee for kernel bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-03-22 11:05 UTC by Arthur Marsh
Modified: 2024-04-18 06:14 UTC (History)
3 users (show)

See Also:
Kernel Version: 6.5.0-rc1
Subsystem: Sound
Regression: Yes
Bisected commit-id: df335e9a8bcb58be3b7388cff556f06eeb3d024f


Attachments
MIDI file exhibiting the problem (152.47 KB, application/octet-stream)
2024-03-23 11:51 UTC, Arthur Marsh
Details

Description Arthur Marsh 2024-03-22 11:05:06 UTC
Using kernel 6.5.0-rc1 and later, multi-voice hardware MIDI playback on my Soundblaster Audigy 2ZS (PCI ID 1102:0004) was corrupted.

I git-bisected the problem:

git bisect start
# status: waiting for both good and bad commits
# bad: [06c2afb862f9da8dc5efa4b6076a0e48c3fbaaa5] Linux 6.5-rc1
git bisect bad 06c2afb862f9da8dc5efa4b6076a0e48c3fbaaa5
# status: waiting for good commit(s), bad commit known
# good: [6995e2de6891c724bfeb2db33d7b87775f913ad1] Linux 6.4
git bisect good 6995e2de6891c724bfeb2db33d7b87775f913ad1
# bad: [1b722407a13b7f8658d2e26917791f32805980a2] Merge tag 'drm-next-2023-06-29' of git://anongit.freedesktop.org/drm/drm
git bisect bad 1b722407a13b7f8658d2e26917791f32805980a2
# good: [3a8a670eeeaa40d87bd38a587438952741980c18] Merge tag 'net-next-6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next
git bisect good 3a8a670eeeaa40d87bd38a587438952741980c18
# good: [901bdf5ea1a836400ee69aa32b04e9c209271ec7] Merge tag 'amd-drm-next-6.5-2023-06-09' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
git bisect good 901bdf5ea1a836400ee69aa32b04e9c209271ec7
# bad: [d6048fdc870240e5020343f8af0c825829c232bd] Merge tag 'asoc-v6.5' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
git bisect bad d6048fdc870240e5020343f8af0c825829c232bd
# good: [e8181a895b05b264883288c4043ff83f893b56b0] ASoC: add N cpus to M codecs dai link support
git bisect good e8181a895b05b264883288c4043ff83f893b56b0
# bad: [508b662b6928808d1af3887f4adc20fb0cd315df] Merge branch 'topic/midi20' into for-next
git bisect bad 508b662b6928808d1af3887f4adc20fb0cd315df
# bad: [7195fb46dafb8750ed4055804cb131f376eb854e] ALSA: emu10k1: pass raw FX send config to snd_emu10k1_pcm_init_voice()
git bisect bad 7195fb46dafb8750ed4055804cb131f376eb854e
# good: [511cbe8f59e30cd09a04c1dbafe6337d9111e88a] ALSA: emu10k1: un-hardcode E-MU mixer control callbacks somewhat
git bisect good 511cbe8f59e30cd09a04c1dbafe6337d9111e88a
# good: [016027741f97457087b81bf304f1cb807bdeffe0] ALSA: emu10k1: simplify interrupt handler, part 2
git bisect good 016027741f97457087b81bf304f1cb807bdeffe0
# bad: [f26a4cf087cbfc9dc71bb3812e8e11ccac0d4d61] ALSA: emu10k1: simplify freeing synth voices
git bisect bad f26a4cf087cbfc9dc71bb3812e8e11ccac0d4d61
# good: [816967d55f425a647137ef884d8e92f2baf541dc] ALSA: emu10k1: set variables emu1010_routing_info and emu1010_pads_info storage-class-specifier to static
git bisect good 816967d55f425a647137ef884d8e92f2baf541dc
# bad: [5c2664cc09f94ba11c61908d5c7dac1c35d6dee8] ALSA: emu10k1: fix terminating synthesizer voices
git bisect bad 5c2664cc09f94ba11c61908d5c7dac1c35d6dee8
# bad: [df335e9a8bcb58be3b7388cff556f06eeb3d024f] ALSA: emu10k1: fix synthesizer sample playback position and caching
git bisect bad df335e9a8bcb58be3b7388cff556f06eeb3d024f
# first bad commit: [df335e9a8bcb58be3b7388cff556f06eeb3d024f] ALSA: emu10k1: fix synthesizer sample playback position and caching

By removing the first bad commit from Linus' git head kernel and rebuilding the kernel, the playback problem was removed.

commit df335e9a8bcb58be3b7388cff556f06eeb3d024f
Author: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Date:   Thu May 18 16:03:38 2023 +0200

    ALSA: emu10k1: fix synthesizer sample playback position and caching
    
    Compensate for the cache delay, and actually populate the cache.
    Without these, the playback would start with garbage (which would be
    (mostly?) masqueraded by the attack phase).
    
    Unlike for the PCM voices, this doesn't try to compensate for the
    interpolator read-ahead, because it's pointless to be super-exact here.
    
    Note that this code is probably still broken for particularly short
    samples, because we ignore the loop-related parts of CCR. But I'm not
    going to reverse-engineer that now ...
    
    Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
    Link: https://lore.kernel.org/r/20230518140339.3722308-1-oswald.buddenhagen@gmx.de
    Signed-off-by: Takashi Iwai <tiwai@suse.de>

diff --git a/sound/pci/emu10k1/emu10k1_callback.c b/sound/pci/emu10k1/emu10k1_callback.c
index 06440b97b5d7..aab8d64fd708 100644
--- a/sound/pci/emu10k1/emu10k1_callback.c
+++ b/sound/pci/emu10k1/emu10k1_callback.c
@@ -253,7 +253,7 @@ lookup_voices(struct snd_emux *emu, struct snd_emu10k1 *hw,
 		/* check if sample is finished playing (non-looping only) */
 		if (bp != best + V_OFF && bp != best + V_FREE &&
 		    (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_SINGLESHOT)) {
-			val = snd_emu10k1_ptr_read(hw, CCCA_CURRADDR, vp->ch);
+			val = snd_emu10k1_ptr_read(hw, CCCA_CURRADDR, vp->ch) - 64;
 			if (val >= vp->reg.loopstart)
 				bp = best + V_OFF;
 		}
@@ -360,7 +360,7 @@ start_voice(struct snd_emux_voice *vp)
 
 	map = (hw->silent_page.addr << hw->address_mode) | (hw->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
 
-	addr = vp->reg.start;
+	addr = vp->reg.start + 64;
 	temp = vp->reg.parm.filterQ;
 	ccca = (temp << 28) | addr;
 	if (vp->apitch < 0xe400)
@@ -428,40 +428,14 @@ start_voice(struct snd_emux_voice *vp)
 		/* Q & current address (Q 4bit value, MSB) */
 		CCCA, ccca,
 
+		/* cache */
+		CCR, REG_VAL_PUT(CCR_CACHEINVALIDSIZE, 64),
+
 		/* reset volume */
 		VTFT, vtarget | vp->ftarget,
 		CVCF, vtarget | CVCF_CURRENTFILTER_MASK,
 
 		REGLIST_END);
-#if 0
-	/* cache */
-	{
-		unsigned int val, sample;
-		val = 32;
-		if (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_8BITS)
-			sample = 0x80808080;
-		else {
-			sample = 0;
-			val *= 2;
-		}
-
-		/* cache */
-		snd_emu10k1_ptr_write(hw, CCR, ch, 0x1c << 16);
-		snd_emu10k1_ptr_write(hw, CDE, ch, sample);
-		snd_emu10k1_ptr_write(hw, CDF, ch, sample);
-
-		/* invalidate maps */
-		temp = ((unsigned int)hw->silent_page.addr << hw_address_mode) | (hw->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
-		snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
-		snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
-		
-		/* fill cache */
-		val -= 4;
-		val <<= 25;
-		val |= 0x1c << 16;
-		snd_emu10k1_ptr_write(hw, CCR, ch, val);
-	}
-#endif
 
 	return 0;
 }

End.
Comment 1 Oswald Buddenhagen 2024-03-23 11:11:18 UTC
please be more specific.
how does the distortion sound? a short recording (ideally loopback from the device itself) might be useful.
how many is "many"?
can you provide a midi file that reproduces the problem?
what sound font did you use?
Comment 2 Arthur Marsh 2024-03-23 11:51:06 UTC
Created attachment 306030 [details]
MIDI file exhibiting the problem
Comment 3 Arthur Marsh 2024-03-23 11:57:56 UTC
I tried a few MIDI files but the distortion was only present on the attached file harehareyukai.mid, evident from early on but most evident at the 13-14 second mark.

I'm not familiar with doing a loopback recording but if you can detail how to do so, I'd be happy to provide a sample.

I purchased the card secondhand without software and the soundfont I've been using is a file 8mbgmsfx.sf2 described by the file command as "RIFF (little-endian) data, SoundFont/Bank" file size 7557598 bytes dated 26 December 2005.
Comment 4 Arthur Marsh 2024-03-23 12:23:34 UTC
Trying to decipher the distortion by playing back individual channels with Rosegarded, it appears the problem is when multiple notes are played at the same time on the one instrument. 

Channel 4 "Saw Lead" exhibits the problem most clearly.
Comment 5 Oswald Buddenhagen 2024-03-23 15:17:42 UTC
yeah, there is some serious "farting" going on.
Comment 6 Takashi Iwai 2024-04-18 06:14:25 UTC
The regression fix (the revert) was included in Linus tree and stable trees.  Let's close.

Note You need to log in before you can comment on or make changes to this bug.