Having debugged Jill's sample caching code, it's becoming plain to me what the problem is:
The game caches four samples at a time. If all four slots are used up and a sample is requested that is not in the cache, the sample that has been used the least so far gets replaced by reading directly from JILLx.VCL into the respective sample cache slot memory. For this reason, the code counts the number each sample has been requested throughout the entire game session. So far, so good.
The problem is that each cache slot is exactly 6,144 (1800h) bytes large. If a sample is shorter than that, then fine. If it is longer than that, the memory that comes after the 1800h bytes reserved for that slot is overwritten and thus corrupted. 5 out of 24 samples in Episode 1, 3 out of 25 samples in Episode 2, and 1 out of 24 samples in Episode 3 are larger than 6,112 bytes (6,144 minus the "Creative Voice File" header that the program generates on-the-fly). The largest sample has 11518 bytes in Episode 1, 8160 bytes in Episode 2 and 11518 bytes long in Episode 3, each without the "Creative Voice File" header.
So, why does then does the game memory that follows the sample cache not get corrupted, leading to horrible crashes? Because the game allocates memory for five rather than four sample cache slots. Apparently the programmers did notice that the game would otherwise crash all the time. Doing so however only guards against corruption if a large sample is loaded into the *fourth* slot. If a large sample is loaded into slots one to three, the other samples still get corrupted. The reason this leads to dropouts rather than garbage sounds is that the "Creative Voice File" header gets overwritten as well, and without that header present, Worx will just refuse to play the file, leading to no sound at all. Since these large samples are only played at infrequent occasions in the game, most players don't even notice it. The solution is to increase the slot memory size from 6,144 to something like 12,048 bytes, and allocate memory for only four instead of five slots. That should not be too difficult, as the memory is allocated on the heap when the program starts.
Another bug in the sample cache code is that although it makes up a "Creative Voice File" header on the spot, it fails to include the sample rate byte in the header's block size field. That's actually a good thing, because it also forgets to add the final 00h byte indicating an "end-of-file" block in the Creative Voice File format. Instead, because of the incorrect block size field in the header, the last sample gets interpreted as a block type, and since Worx mercifully performs a range check and treats all block types above 9 as "end of file", and because that last sample almost always has a value above 09h, the game does not crash every single time.
Worx will freeze the game however if that last sample, that is interpreted as a block marker, should ever have the values 3 or 5-8, as Worx ignores them but fails to advance the file position. That does not seem to be the case at the end of any of the samples that the game uses, but is something that could arise from the the memory corruption bug mentioned above, and would lead to very occasional game freezes. The solution is to make the code that creates the "Creative Voice File" header put the correct sample size into the header and add a 00h byte after the file data.
Edit: Both errors are quite visible in the Xargon source code, file SOURCE\MUSIC.C.