Ambient tracks

Ambient tracks are music tracks, longer than sound effects. There are two 3 minute tracks for the base version of MechWarrior 3, and one 9.5 minute track for the Pirate's Moon expansion. They are never installed, and so must be retrieved from the CD. They are used as background music during missions.

Investigation

When I insert a MechWarrior 3 CD into a Mac, iTunes opens. When I insert a MechWarrior 3 CD into a Windows PC, this message shows:

"Select to choose what happens with enhanced audio CDs."

An enhanced audio CD contains data and audio on the same disk. So the ambient tracks are simply CD audio, which are presumably streamed from the CD during gameplay. A re-implementation should also be able to do this.

There are only two ambient/background tracks, roughly three minutes earch. Using a tool such as ExactAudioCopy (EAC)1, it is possible to copy the audio tracks as Waveform Audio files (WAV, *.wav) where it is legal to do so.

For individuals wanting to enjoy these tracks, it's worth noting these WAV files are rather large. For preservation, a lossless compression like FLAC uses about ~40% of the storage space. Since the tracks slightly differ between the different versions, for general use a lossy format like AAC with a bitrate of 128 kilobytes or above should be plenty. This produces file sizes around 10% of the original.

1

EAC is Windows only. Options on macOS are RIP, Max, XLD, or iTunes. There are many options on Linux, I suggest Morituri.

In-game use

To my knowledge, the ambient tracks do not play in the menus, only during gameplay. I don't know how the engine uses these tracks:

  1. Does the engine select a random track, or always starts on the first (audio) track?
  2. Does the engine loop the tracks once they finish playing, or is there simply slience after a mission time of over six minutes?

Appendix 1: Detailed version comparison

Between the versions, all the tracks had different CRC codes. Another oddity is the fact the tracks aren't in the same order on different versions. I'm unsure why this is. The difference in the audio data could be the result of the manufacturing process. For the German version, it could be due to the SafeDisc DRM (is 2 seconds longer). But they all sound indistinguishable for me, and the waveforms look the same, so it's probably fine.

A waveform plot of the shorter tracks, showing virtually indistinguishable waveforms. The data was resampled to mono, but the amplitude is not re-normalised. It may appear slightly quieter than it would be in stereo.

These are the detailed track information of all MechWarrior 3 versions I own:

v1.0 US

TrackStartLengthStart sectorEnd sectorSizeCRC
10:00.0059:12.450266444597.64 MiB
259:12.453:11.6926644528083832.28 MiB515BECAE
362:24.393:06.0628083929479431.30 MiB45D64143

CTDB TOCID: hUJiDDh7s2IYPP1GpLfGVYpIWxE-

v1.0 DE

TrackStartLengthStart sectorEnd sectorSizeCRC
10:00.0062:48.560282655634.00 MiB
262:48.563:06.0628265629661131.30 MiBEDCC302C
365:54.623:13.6929661231115532.62 MiBA262C28B

CTDB TOCID: vPmoaaMWAdaLNkVSMLqK2HZxmaE-

v1.1 US

TrackStartLengthStart sectorEnd sectorSizeCRC
10:00.0059:12.200266419597.59 MiB
259:12.203:06.0626642028037531.30 MiB825686B5
362:18.263:11.6928037629476932.28 MiB21627377

CTDB TOCID: WJdZLalC42N4VOtU.QQx5GDfvqI-

v1.2 US

TrackStartLengthStart sectorEnd sectorSizeCRC
10:00.0059:12.340266433597.62 MiB
259:12.343:06.0626643428038931.30 MiBDB5F6872
362:18.403:11.6928039029478332.28 MiB61502511

CTDB TOCID: WJdZLalC42N4VOtU.QQx5GDfvqI-

v1.2 PM

TrackStartLengthStart sectorEnd sectorSizeCRC
10:00.0022:18.110100360
222:18.119:22.61100361142571535BD032

CTDB TOCID: Y1qrr8eDEKTsSDhgyfHah6MGKzA-

Appendix 2: How the waveform plots were made

I used SciPy to read WAV file data, and matplotlib to plot them:

import numpy as np
from scipy.io import wavfile
from scipy.signal import resample

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker


def time_ticker_format(x, pos=None):
    mins, secs = divmod(x, 60)
    return "{:.0f}:{:02.0f}".format(abs(mins), secs)


def plot_waveforms(tracks, save_name=None, resample_factor=40):
    """This function makes assumptions about the input data: stereo 44100 Hz 16-bit signed PCM"""
    data = []
    rates = []
    for track in tracks:
        rate, stereo = wavfile.read(track, mmap=True)
        samples, channels = stereo.shape
        assert channels == 2, "expecting stereo"
        mono = stereo.mean(1)
        # this is to make the data more resonable to plot
        resampled = resample(mono, int(np.ceil(mono.size / resample_factor)))
        data.append(resampled)
        rates.append(rate)

    rate = rates[0]
    assert all(rate == r for r in rates)

    count = len(tracks)
    fig, axis = plt.subplots(count, 1, figsize=(16, 4 * count))

    for ax, mono, name in zip(axis, data, tracks):
        samples = mono.size
        length = samples / rate
        time = np.linspace(0, length, num=samples)

        ax.plot(time, mono)
        ax.set_xlim(0, length)
        ax.xaxis.set_major_formatter(ticker.FuncFormatter(time_ticker_format))
        ax.xaxis.set_major_locator(ticker.MultipleLocator(20))
        ax.set_ylim(-(1 << 15), (1 << 15))  # signed 16-bit
        ax.yaxis.set_major_locator(ticker.NullLocator())
        ax.xaxis.set_label_text(name)

    fig.tight_layout()
    if save_name:
        plt.savefig(save_name)
        plt.close(fig)