Opened 7 months ago

Last modified 7 months ago

#14558 new defect

SCI: Use the SCI32 SOL decoder for SCI 0-1.1 games

Reported by: ccawley2011 Owned by:
Priority: normal Component: Engine: SCI
Version: Keywords: performance
Cc: Game:


The SCI engine has two SOL decoders. As far as I can tell, these both handle the same format, but the SCI32 version streams the file off the disk as-needed, while the SCI0-1.1 decodes the entire file up front, which is likely to be slower and require more RAM.

Change History (2)

comment:1 by sluicebox, 7 months ago


  • SCI16 handles a SOL header format in QFG3 Demo (according to the comment), I assume the SCI32 code doesn't
  • SCI16 handles SOL flags that SCI32 doesn't and vice versa
  • SCI32 code makes audio decoding decisions based on interpreter runtime, those will need to be audited for SCI16 compatibility
  • SCI16 indeed decompresses SOLs up front, requiring a buffer twice the size of the SOL. Even with this change, the SOL will still require a buffer to be copied to for playback, but it would be half the current size. See comments in AudioPlayer::getAudioStream and df4bf9d5571fbffae88323c62469900c24b159a0

This would be a good change to eliminate the duplicate code. It looks like you'd have to adapt the SCI32 code to support all the SCI16 SOL versions. I don't know how many SOL versions are out there or in what games, but you'd want to find and test them all. I didn't know what "SOL" was until today, so I'm not exactly volunteering. =)

comment:2 by sluicebox, 7 months ago

More notes:

  • The two decoders don't use the same flag logic, even on flags they both handle. SCI16 can set FLAG_UNSIGNED on 16-bit audio, SCI32 doesn't.
  • The SCI32 decoder expects SOL data to be 32 bit aligned. I don't see that in the SCI16 decoder. I looked at an SCI16 AUDBLAST.DRV (LSL6 floppy) and saw some code that looks like it does this.
  • I tried using the SCI32 decoder on Brain2 1.1 and the sounds were noticeably different: volume, background noise (maybe that was just volume), and an occasional glitch. So they're doing different things. This was not due to the 32 bit alignment code; same results with and without.

I wrote a thing to scan my RESOURCE.AUD/SFX and RESAUD.0## files for the SOL header and parse out the header sizes (versions) and flag bytes and make a report to see who was using what. Some things I noticed:

  • QFG3 Demo appears to be the only game that uses header size 7
  • Some games use multiple header sizes (11 and 12) within the same version
  • The 16-bit flag and the signed flag are always both set or both clear. That explains why the SCI32 decoder can get away with ignoring the signed flag. Unclear if that was intentional. No comments!
  • LSL7 is the only game I see with the Stereo flag
  • There is an unknown flag 0x80 that appears in eco1-cd. Unclear if anything uses it; the AUDBLAST.DRV I looked at appears to set a variable when it's present but then doesn't use that.

Once we can explain the playback discrepancy, we can switch to the SCI32 stream-based decoder and remove the ancient one from the aughts. I've tried this and it cleans up AudioPlayer::getAudioStream, a frequent source of bugs, so I'm excited about that.

I'm stepping away from this particular rabbit hole though, at least for a while. I've got others!

Note: See TracTickets for help on using tickets.