hikari-no-yume / dream-sparer

Simple tool for extracting chunks from RIFX files.
1 stars 1 forks source link

Missing some 'snd ' type sound chunks #1

Open gingerbeardman opened 1 year ago

gingerbeardman commented 1 year ago

Firstly, thanks for this tool!

Background

I'm extracting sounds from Thoru Yamamoto's old .dcr (converted to .dir using ProjectorRays), to use in a new - free - remake of one of his projects for the Playdate handheld gaming system. Thread: https://twitter.com/gingerbeardman/status/1688938619287789568

Problem

I am seeing that some .dir files have 'snd ' chunks that your tool does not pickup.

I can export the chunks using ProjectorRays, and try to figure out the sample settings manually by trial and error (I do not know enough about their included headers)... but, maybe this tool can do it?

These .dir files are too old to be opened in Director 2004 and so cannot be processed with CastRipperTool.

Thoughts appreciated!

Examples

More dir files

'snd '?

The second part of my query is "what to do with 'snd ' type files?", I would need to convert them somehow. I thought they might be Apple .snd format sounds, but no immediate success so I still need to investigate that.

hikari-no-yume commented 1 year ago

Oh, what a pleasant surprise to get an issue on this. I'm glad this ended up being useful to someone else!

I've seen the snd chunks before but I haven't tried to export them because, so far as I could tell, they didn't contain anything useful; the header was in sndH and the samples were in sndS. That's why the example in the README just ignores the snd chunks.

What I do know is that pairs of sndS and sndH chunks are not the only format used for audio; those chunks are only used for PCM audio data, whereas other chunks (whose names I don't remember) are used for other audio formats.

I'll look at your Director files later, but my suggestion for now is to run my tool without passing any options, just the filename. Then see what kind of chunk immediately follows the snd chunks you're interested in. That's probably going to be a chunk for some non-PCM audio format, and dumping that might get you further.

hikari-no-yume commented 1 year ago

Oh, there's an example of this in the README: ediM type chunks are used sometimes.

hikari-no-yume commented 1 year ago

Ah okay, I thought this was about exporting, but I can see indeed that there's a strangely small number of snd chunks listed in the first of those files. I'll investigate a bit…

hikari-no-yume commented 1 year ago

This part of the output for bambam.dir looked suspicious:

Chunk #9 of type 'ord', size 29743 bytes at offset 22506 bytes
(skipping)
Chunk #10 of type [255, 0, 50, 254], size 4278521358 bytes at offset 52258 bytes
(skipping)

A size that large can't possibly be correct, and suggests a bug where the file is being misread.

The only thing I could think of was that it might be the chunk padding. That is, this line:

        // RIFF pads chunk sizes to be 2-byte-aligned (the era of “DWORDs”…)
        let seek_size = chunk_size + (chunk_size & 1);

If I change it to just let seek_size = chunk_size;, now all the snd chunks appear! I'll have to investigate that.

To my surprise, the snd chunks are large enough that they presumably contain actual sound data! But I'm not sure what the format is.

gingerbeardman commented 1 year ago

Nice findings!

The snd files contain unsigned raw PCM.

But I am yet to figure out its header (there is one)

This header is from a snd that turned out to be 8-bit, mono, at 11025 KHz.

image

A corresponding wav header seems to be

image

Sound data starts 8382...

hikari-no-yume commented 1 year ago

Aha, I was about to comment about this. Yes, there's some kind of header, and the data must be 8-bit mono linear PCM (not µ-law or a-law) at some sample rate.

Alas, the format isn't the same as the sndH chunks…

hikari-no-yume commented 1 year ago

Seems like they all begin with exactly this sequence (xxd output):

00000000: 0002 0000 0001 8051 0000 0000 000e 0000  .......Q........
00000010: 0000 0000 1550 2b77 45d2 0000 0000 0000  .....P+wE.......

All the rest of the bytes vary by file. Not sure if that's where the header ends or not.

hikari-no-yume commented 1 year ago

Bytes 0x26 and 0x27 seem to correspond to the size of the audio data. Presumably a 32-bit integer, so bytes 0x24 through 0x27 in that case.

hikari-no-yume commented 1 year ago

Based on comparing the sizes of the audio data to the file sizes for the dumped chunks, the header is 78 bytes. :)

gingerbeardman commented 1 year ago

Some header variations

00000000: 0002 0000 0001 8051 0000 0000 000e 0000  .......Q........
00000010: 0000 0000 0001 2b77 45d2 0000 0000 0000  ......+wE.......
00000000: 0002 0000 0001 8051 0000 0000 000e 0000  .......Q........
00000010: 0000 0000 2b78 2b77 45d2 0000 0000 0000  ....+x+wE.......
00000000: 0002 0000 0001 8051 0000 0000 000e 0000  .......Q........
00000010: 0000 0000 0001 56ee 8ba3 0000 0000 0000  ......V.........

bytes that vary:

0x14 and 0x15 0x16 and 0x17 (seems to be sample rate?) 0x18 and 0x19

gingerbeardman commented 1 year ago

The later part of the header can sometimes be empty and other times be very busy, so I wonder if that is describing some sort of manipulation that has been done to the wave, such as volume envelopes etc?

hikari-no-yume commented 1 year ago

Ohh, so that is the sample rate. I was expecting something common like 44.1kHz or an integer fraction of that, but 0x2b77 for example is 11127Hz. Well, turns out the early Macintosh had a weird hardware sample rate!

gingerbeardman commented 1 year ago

Confirming sample rate as 0x16 and 0x17, because Apple used some slightly odd rates:

https://whitefiles.org/dta/pgs/c08.htm (final column added by me)

Rate ​(Hz) kHz Resp ​(kHz) Application Hex
5,563​ .6363 5.5 2 Telephone ​quality ​speech ?
7,418​ .1818 7.4 3 Telephone ​quality ​speech 0x1cfa
11,127​ .27272 11.1 5 Medium ​quality ​speech 0x2b77
22,254​ .54546 22.2 10 Low ​quality ​music 0x56ee
44​ .1000 44.1 20 CD ​quality ​music ?

(I've also seen 0x5622 which is 22050)

gingerbeardman commented 1 year ago

Summary of all samples I've dumped using ProjectorRays:

Rate (Hz) Hex Quantity
7,418 0x1cfa 1
11,127 0x2b77 616
22,254 0x56ee 515
22,050 0x5622 31
gingerbeardman commented 1 year ago

I created this little bash script https://gist.github.com/gingerbeardman/1e6170d2652352bf30623b2a6c8d12fd

  1. extracts the sample rate
  2. creates a trimmed raw pcm file without the header
  3. uses sox to add a new wav header with the correct sample rate

Call it like this: find . -iname "*.bin" -exec ./bin2wav.sh {} \;

Somrlik commented 11 months ago

Good work, I just wanted to add that I found chunks with signed 16-bit PCM BE mono with 16000 sample rate with the following 78-byte headers

00000000: 0002 0000 0001 8051 0000 0000 000e 0000  .......Q........
00000010: 0000 0000 0001 3e80 0000 0000 0000 0000  ......>.........
00000020: 0000 ff3c 0000 13b5 400e bb80 0000 0000  ...<....@.......
00000030: 0000 0000 0000 0000 0000 0000 0000 0010  ................
00000040: 0000 0000 0000 0000 0000 0000 0000       ..............
00000000: 0002 0000 0001 8051 0000 0000 000e 0000  .......Q........
00000010: 0000 0000 0001 3e80 0000 0000 0000 0000  ......>.........
00000020: 0000 ff3c 0000 178e 400e ac44 0000 0000  ...<....@..D....
00000030: 0000 0000 0000 0000 0000 0000 0000 0010  ................
00000040: 0000 0000 0000 0000 0000 0000 0000       ..............

Observations:

Dropping this off here for future Director archeologists. Maybe we will decode the whole header in a few years.