Hello,
I am the author of zqloader; this is a turbo loader used to load games into a real unmodified ZX Spectrum at high speed. (see https://github.com/oxidaan/zqloader)
This tool can also create wav files, and I always used Fuse to test it with. These wav files could be loaded fine by fuse 1.7 but on more recent versions it suddenly fails. (other emulators like 'zxspin' and 'EightyOne' can also load these wav files.) It doesn't work at Fuse 1.8 and higher.
I realize this is not really a bug in Fuse, but still something happened between v1.7 and 1.8 - I just wonder what causes this problem.
Attachted is a sample wav file that loads fine with Fuse 1.7.
Thanks
It seems to work for me on Fuse 1.10.0? Can you provide some more information about Fuse and libspectrum versions, host OS etc.?
Last edit: Fredrick Meunier 2026-10-16
Weird, tried again to be sure with version 1.10 and for me it still only works at Fuse 1.7.
(That screenshot is when it went ok indeed- just a test pattern)
I am on Windows (maybe that explains it ;-) Windows 11 home 25h2.
Don't know it it is relevant but my audio hardware has a sample rate of 96000bps. MSI strealth a16 laptop; AMD Ryzen AI 9 HX 370
I installed fuse in Windows with windows installer fuse-1.10.0-win32-setup.exe (1.10 - not working) and fuse-1.7.0-win32-setup.exe (1.7 - working)
Btw I also noted that if the left and right channel are inverted, it never works, also not at Fuse 1.7. Inverting channels is however needed to get the wav file loaded in my real ZX spectrum...
Thanks.
We used a different build chain after 1.7.0 and it had an older WAV library. I've got an untested update here, could you give it a try? https://www.dropbox.com/scl/fi/d5xxjyr0ukqzxeu7436xz/fuse-1.10.0-win32.zip?rlkey=gqn5lsv6zy0hsx8wj2ricpoc7&dl=0
This build works for me. I think it could be related to an unpatched libaudiofile.
No, does not work; same issue.
Could you try replacing only libaudiofile-1.dll in a copy of the new build with the DLL from 1.7.0 and let me know what happens?
That won't work because of different entry point addresses.
Thanks Sergio.
Daan: could you try this one instead? It has a built-in WAV reader instead of the library https://www.dropbox.com/scl/fi/4r6hvo3te7h4adeaf28c8/fuse-1.10.0-win32.zip?rlkey=9n2wdhz44xbjbbou4xnzxtik7&dl=0
Hello,
This version immidiately gives this error:
Same wav file works fine with fuse 1.7 though.
Op 21-10-2026 om 12:07 schreef Fredrick Meunier:
Related
Bugs: #538
Thanks, I get the same results with the test WAV, I should have checked that first.
testdata.wav has an incorrect byte rate field in its WAV header.
For its format—48,000 Hz, stereo, 16-bit PCM—the correct value is:
48,000 × 2 channels × 2 bytes = 192,000 bytes/second
The header instead contains 1,536,000, which is the rate in bits/second, eight times too large.
The other PCM format fields are consistent. I guess libaudiofile tolerates this error, but stricter readers may reject the file. The WAV writer should store bytes per second, not bits per second, in the byte-rate field (nAvgBytesPerSec).
I've made the reader more tolerant and this version's code works for me on mac, could you check if this one does the trick?
https://www.dropbox.com/scl/fi/chfnvlmv5mp0l2q9wnsmy/fuse-1.10.0-win32-2.zip?rlkey=zamprew557qlz9gye173q3ciu&dl=0
Hello,
Thanks for finding the bug in my wav writer, already fixed it.
I found out that when I set the speed speed of my turbo loader
(zqloader) to the slowest possible setting, Fuse 1.10 can load the wav
file with the test pattern. But thats about it; any 'serious' game
fails. Fuse 1.7 and zxspin can handle much higher speeds and load 128K
snapshots created by ZQLoader.
However I think it has not much to do with wav files because with tzx
files I have more or less the same problem. Again works reasonable at
fuse 1.7 (albeit I need to slow it down a little) but with fuse 1.10 I
can barely load the test pattern at slowest possible speed. And ZXSpin
works with both wav and tzx files.
Can there be any timing difference in the z80 simulation between 1.7 and
higher versions?
In the mean time I'll try with other simulators next to Fuse and ZXSPin
but there is almost no simlator that can read txx-generalized data block
that I am using....
Thanks for the efforts!
Daan.
Op 22-10-2026 om 13:40 schreef Fredrick Meunier:
Related
Bugs: #538
Hi Daan, I did some more research on ZQLoader and created a PR with my findings and some improvements to address some of them https://github.com/oxidaan/zqloader/pull/7.
I don't see anything remaining that is different between 1.7 and 1.8 that could be relevant and on the code for the next release, the WAVs and WAV-equivalent TZXs produced by the PR load for me.
I hope that help,
Fred
Hello Fred,
I will merge your PR into ZQLoader. Thanks for the investigation.
Some remarks and questions:
When I was writing the TZX writer, I was already wondering: in TZX
files, is the general rule /'wait-then-edge'/or /'edge-then-wait'/?
The specification at https://worldofspectrum.net/TZXformat.html
https://worldofspectrum.net/TZXformat.htmlis not very clear, IMHO.
If it is /'edge-then-wait'/, what about the very last symbol (at the end
of the file)? If it ends with a wait and no edge follows, how does it
know whether the last symbol is a 0 or a 1? A final edge must follow the
wait, but why is there nothing about this in the documentation?
Because of this, I assumed /'wait-then-edge'/. This was easiest to
implement since the 'Pulsers' also used this approach, which also seems
more logical to me. And since it already worked in Fuse and ZXSpin, I
left it like that. Besides, does it actually matter if each pulse is
followed by an edge anyway?
You've spent quite some effort ensuring that the TZX durations produce
the same results as the WAV writer. However, unlike WAV files, TZX files
can preserve the exact timings used by the 'Pulsers' — that is, the
timings as intended.
When writing a WAV file, these timings are rounded because the sample
rate is not an exact multiple of the T-state duration. This is
unavoidable when writing WAV files. However, this is not the case with
TZX files, so I wonder whether it is wise to imitate this behaviour when
writing TZX files.
Ultimately, the purpose of writing a TZX file is to have it played back
as sound by another tool. The sound will then be sampled again anyway.
By the way, I could not find a tool that handles the 'Generalized Data
Block' correctly, apart from Fuse and ZXSpin. For example, Tzxtools (by
Shred) does not.
I tried doing otherwise — the code is still there, but commented out.
However, that produces irregular sound; even the leader tone sounds
irregular. (Maybe I made a mistake. I'll check again when I have time.)
I doubt it makes much difference because it compares double values, but
this is clearly not intentional. I guess I changed one and forgot the other.
For the payload, this is unavoidable (the Spectrum ROM does the same).
But yes, that IN is contended. I commented out the |ld A,$7F|; there is
still a TODO there...
My implementation of the end-of-byte delay after the last bit was
clearly wrong. Indeed, the duration of the last bit was extended, which
is not correct. I had already noticed that I had to set the 'End of Byte
Delay' to zero in the UI to get working TZX files (and then reduce the
overall speed to compensate). I was just about to investigate this when
your PR arrived...
I may adjust your code a little to match my coding style. For example, I
like to use |{}|even around single statements and follow the Allman
style. I also prefer member variables to start with |m_|rather than have
a trailing underscore, etc.
What about the copyright notice I have at the top of each file? I guess
I can add your name there?
Thanks for all your help,
Daan
Related
Bugs: #538