Menu ▾ ▴

#538 Regression: Fails to load turboloader wav files. Worked fine at v1.7

future
open
nobody
None
5
6 days ago
2026-10-16
No

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

1 Attachments

Related

Bugs: #538

Discussion

  • Fredrick Meunier

    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
  • Daan Scherft

    Daan Scherft - 2026-10-17

    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.

     
  • Fredrick Meunier

    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

     
    • Sergio Baldoví

      Sergio Baldoví - 2026-10-19

      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?

      This build works for me. I think it could be related to an unpatched libaudiofile.

       
  • Daan Scherft

    Daan Scherft - 2026-10-18

    No, does not work; same issue.

     
  • Fredrick Meunier

    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?

     
    • Sergio Baldoví

      Sergio Baldoví - 2026-10-19

      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.

       
  • Fredrick Meunier

    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

     
    • Daan Scherft

      Daan Scherft - 6 days ago

      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:

      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
      https://www.dropbox.com/scl/fi/chfnvlmv5mp0l2q9wnsmy/fuse-1.10.0-win32-2.zip?rlkey=zamprew557qlz9gye173q3ciu&dl=0


      [bugs:#538] https://sourceforge.net/p/fuse-emulator/bugs/538/
      Regression: Fails to load turboloader wav files. Worked fine at v1.7

      Status: open
      Group: future
      Created: Fri Oct 16, 2026 08:09 PM UTC by Daan Scherft
      Last Updated: Wed Oct 21, 2026 10:07 AM UTC
      Owner: nobody
      Attachments:

      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


      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/fuse-emulator/bugs/538/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

       

      Related

      Bugs: #538

  • Fredrick Meunier

    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

     
    • Daan Scherft

      Daan Scherft - 5 hours ago

      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.


      > SampleToWav resets its elapsed-time accumulator after each pulse rather than carrying fractional timing residue
      forward...
      

      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.)

      > Its comparison is strictly >; liveSampleSender uses >=.
      

      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.

      > Code in upper RAM does not eliminate all contention: the trace includes bit-loop reads at port 0x63fe,
      whose high-byte address is in contended 48K RAM, and payload writes
      can also be contended.
      

      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

      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


      [bugs:#538] https://sourceforge.net/p/fuse-emulator/bugs/538/
      Regression: Fails to load turboloader wav files. Worked fine at v1.7

      Status: open
      Group: future
      Created: Fri Oct 16, 2026 08:09 PM UTC by Daan Scherft
      Last Updated: Thu Oct 22, 2026 11:40 AM UTC
      Owner: nobody
      Attachments:

      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


      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/fuse-emulator/bugs/538/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

       

      Related

      Bugs: #538


Log in to post a comment.