Opened 16 years ago

Closed 7 years ago

Last modified 12 months ago

#7328 closed enhancement (fixed)

AUDIO: LOOM Mac music support

Reported by: SF/jamieson630 Owned by: SF/jamieson630
Priority: normal Component: Engine: SCUMM
Keywords: Cc:
Game: Loom

Description

I didn't find a bug or RFE anywhere else regarding Loom-
Mac music, so here's where I'm going to post notes
about the custom format as I discover things.

Ticket imported from: #824221. Ticket imported from: feature-requests/144.

Change History (11)

comment:1 by SF/jamieson630, 16 years ago

The Loom Mac music resources consist of a header and up to
5 streams. Here is what is known so far:

RESOURCE DATA
LE 2 bytes Resource size
2 bytes Unknown
2 bytes 'so'
24 bytes Unknown
BE 2 bytes Offset to Stream 1
BE 2 bytes Offset to Stream 2
BE 2 bytes Offset to Stream 3
BE 2 bytes Offset to Stream 4
BE 2 bytes Offset to Stream 5
? bytes The streams

STREAM DATA
BE 2 bytes Unknown (always 1?)
2 bytes Unknown (always 0?)
2 bytes Number of events in stream
? bytes Stream data

Each stream event is exactly 3 bytes, therefore one can
assert that numEvents == (streamSize - 6) / 3.

A stream can contain events for multiple "channels". There
are two types of events: channel and universal (or System
Common in MIDI terms).

UNIVERSAL EVENTS
1 byte 0x7F
1 byte ?
1 byte ?

CHANNEL EVENTS
1 byte Channel number (0-?)
1 byte Note duration or delay before next event?
1 byte Note number to play (0 = rest)

(The first event in the stream, presumably, has a delay of 0,
since the delay before an event is embedded in the previous
event.)

The second byte of the event appears to be a temporal
measure because sequences of these bytes, with multiple
channels active, appear to add up to patterns of summations
(something that would not happen if the byte carried
command data). However, a few events contain second bytes
that completely depart from this pattern.

comment:2 by SF/lechimp, 16 years ago

I would like to help with this jamieson. I forgot... was it you or
superqult that didn't have the resources but only the game data
files?

Anyway, I'd be happy to help with information on them,
remapping them to MIDI perhaps, like you did with Monkey 1.

There are 10 samples in the Loom application :

Res. ID Name Size(bytes) 'sounds like' in GM
1000 "Dual Harp" 5082 - Pizzicato Strings (46)
10895 "harp1" 7254 - Orchestral Harp (47)
11445 "strings1" 6493 - String ensemble (49)
11548 "silent" 50 - nothing
13811 "staff1" 7944 - music box (11)
15703 "brass1" 10463 - saw wave (82)
16324 "flute1" 8458 - flute (74)
25614 "accordion1" 8394 - accordion (22)
28110 "f horn1" 8121 - french horn (61)
29042 "bassoon1" 2423 - bassoon (71)

They are all sampled at C4 (MIDI 60). The GM values are
estimated by ear from singular sounds, not from the music mix.

Hopefully the resource IDs match some of the values in the
'unknown' fields. Else, just ask me for more information...

comment:3 by SF/lechimp, 16 years ago

sorry 'bout the table alignment or lack of same :o)

comment:4 by fingolfin, 16 years ago

Summary: LOOM Mac music supportAUDIO: LOOM Mac music support

comment:5 by SF/jamieson630, 15 years ago

lechimp, thanks for the resource information. Those do indeed
match up with information in the header -- 2 bytes for each
stream, corresponding apparently to which instrument that
stream is supposed to use.

Also, the channels-within-a-stream thing doesn't appear to
be correct. The streams themselves may very well be the
equivalent of simultaneous channels. If that's the case, then
what's interesting is that data from one channel seems to
show up in other channels, but there may be a flag I'm
missing that is used to mute those events so that they only
serve as timing references. I'm not sure yet.

So discard the information in my original notes, and here's the
new information:

RESOURCE DATA
LE 2 bytes Resource size
2 bytes Unknown
2 bytes 'so'
14 bytes Unknown
BE 2 bytes Instrument for Stream 1
BE 2 bytes Instrument for Stream 2
BE 2 bytes Instrument for Stream 3
BE 2 bytes Instrument for Stream 4
BE 2 bytes Instrument for Stream 5
BE 2 bytes Offset to Stream 1
BE 2 bytes Offset to Stream 2
BE 2 bytes Offset to Stream 3
BE 2 bytes Offset to Stream 4
BE 2 bytes Offset to Stream 5
? bytes The streams

STREAM DATA
BE 2 bytes Unknown (always 1?)
2 bytes Unknown (always 0?)
BE 2 bytes Number of events in stream
? bytes Stream data

Each stream event is exactly 3 bytes, therefore one can
assert that numEvents == (streamSize - 6) / 3. The
polyphony of a stream appears to be 1; in other words, only
one note at a time can be playing in each stream. The next
event is not executed until the current note (or rest) is
finished playing; therefore, note duration also serves as the
time delta between events.

FOR EACH EVENTS
BE 2 bytes Note duration
1 byte Note number to play (0 = rest/silent)

comment:6 by SF/jamieson630, 15 years ago

Oh, and quick speculation -- Stream 1 may be used for a
single-voice interleaved version of the music, where Stream 2-
5 represent a version of the music in up to 4-voice
polyphony, one voice per stream. I postulate thus because
the first stream of the Mac Loom theme music contains
interleaved voices, whereas the second stream seemed to
contain only the pizzicato bottom-end harp. Stream 5, in this
example, is empty, so if my speculation is correct, this
particular musical number supports 3-voice polyphony at
most. I must check out Streams 3 and 4 to see what they
contain.

comment:7 by SF/lechimp, 15 years ago

I am only happy to help :-)
Is there anything else short of hardcore programming or reverse
engineering I can help with?

I am looking forward to play Loom again and maybe I'll try to run it on
my old dusty LC II for which it was originally bought for. I could make
some comparison tests even...

comment:8 by eriktorbjorn, 7 years ago

I recently bought a used copy of Loom for the Mac, and using the information collected here I was able to get the Loom music playing. I don't know whether or not it sounds correct, but it sounds reasonable enough to me.

The current version can be found as a ScummVM pull request at https://github.com/scummvm/scummvm/pull/291

comment:9 by eriktorbjorn, 7 years ago

Resolution: fixed
Status: newclosed

comment:10 by eriktorbjorn, 7 years ago

The Mac MI1/Loom music patch was accepted a month ago. I just forgot to close this feature request. As I said, it's possible that it's still not quite right but it sounds reasonable enough to me.

Thanks to everyone who worked to figure out the music format and handling Macintosh instruments! All I had to do was to put the final pieces together.

comment:11 by digitall, 12 months ago

Component: Engine: SCUMM
Game: Loom
Note: See TracTickets for help on using tickets.