Thanks!
It's a single QML file with two SoundEffect instances that do stop() → change source → play() on a timer,
the same way as in my game. No C++ or build step is needed.
Setup
soundeffect_repro/
Main.qml
sounds/tone_1.wav
sounds/tone_2.wav
Sorry, the WAV files (tone_1.wav and tone_2.wav) can't be uploaded, so you'll need to prepare two short WAV files yourself.
Two different short WAV files are needed. Mine are 16 bit PCM, stereo, 44.1 kHz sine waves of 0.5 s and 0.6 s.
Run
<Qt>/6.12.0/gcc_64/bin/qml Main.qml 2> err.txt
grep -m3 -n QSocketNotifier err.txt
I ran it 5 times, and it reproduced every time, after about 3 to 30 s.
13:QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread
14:QSocketNotifier: Invalid socket 60 and type 'Read', disabling...
15:QSocketNotifier: Invalid socket 60 and type 'Read', disabling...
When it reproduces:
err.txt fills up with QSocketNotifier: Invalid socket ... lines.
The square in the window stops rotating, the play count stops increasing, and no more sound is played
(see the screenshot below).
Note: once the issue starts, err.txt keeps growing by tens of MB per second.
Please stop the app (Ctrl+C) soon after it reproduces, or the file will get huge.
[image: 3750a5da-8208-4821-91b0-d6bd3f2443e9.png]
Main.qml
pragma ComponentBehavior: Bound
import QtQuick
import QtMultimedia
Window {
id: root
readonly property int playInterval: 800 // ms between plays of each SoundEffect
readonly property list<url> soundUrls: [
Qt.resolvedUrl("sounds/tone_1.wav"),
Qt.resolvedUrl("sounds/tone_2.wav")
]
property int playCount: 0
width: 360
height: 120
visible: true
title: "SoundEffect repro"
// Two SoundEffect instances, the second one starting half an interval later
Repeater {
model: 2
delegate: Item {
id: player
required property int index
property int nextSound: index // index into soundUrls
function playNext() {
effect.stop()
effect.source = root.soundUrls[player.nextSound] // a different file from the previous play
effect.play() // without waiting for SoundEffect.Ready
player.nextSound = (player.nextSound + 1) % root.soundUrls.length
root.playCount++
console.log("play " + root.playCount + " instance " + player.index + " "
+ effect.source.toString().split("/").pop())
}
SoundEffect {
id: effect
onStatusChanged: {
if (status === SoundEffect.Error)
console.log("instance " + player.index + ": Error " + source)
}
}
Timer {
interval: player.index * root.playInterval / 2
running: true
onTriggered: {
player.playNext()
repeatTimer.start()
}
}
Timer {
id: repeatTimer
interval: root.playInterval
repeat: true
onTriggered: player.playNext()
}
}
}
// Progress line every 10 s; it stops once the issue starts
Timer {
interval: 10000
running: true
repeat: true
onTriggered: console.log("progress: plays=" + root.playCount)
}
// Shows whether the GUI thread is still alive
Rectangle {
x: 20
y: 30
width: 60
height: 60
color: "steelblue"
RotationAnimation on rotation {
from: 0
to: 360
duration: 2000
loops: Animation.Infinite
}
}
Text {
x: 110
y: 50
text: "plays: " + root.playCount
}
}
Thanks again!