Skip to content

Added support for the E-mu Emulator IV bank format (E4B) - not yet tested on hardware#220

Open
douglas-carmichael wants to merge 6 commits into
git-moss:mainfrom
douglas-carmichael:e4b-format
Open

Added support for the E-mu Emulator IV bank format (E4B) - not yet tested on hardware#220
douglas-carmichael wants to merge 6 commits into
git-moss:mainfrom
douglas-carmichael:e4b-format

Conversation

@douglas-carmichael

@douglas-carmichael douglas-carmichael commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

This adds a detector and creator for the banks of the E-mu Emulator IV series (Emulator 4, E4X, E4XT, E4K, e-Synth, e-6400 and the other EOS samplers): *.e4b.

Reading

Every preset of a bank becomes one multi-sample and every voice becomes a group. Mapped: names, key and velocity ranges, root keys, tuning (transpose + coarse + fine), volume, sample-level forward loops, the amplitude envelope (attack/hold/decay/sustain/release plus its velocity modulation from the cord table) and the filter (type/poles, cutoff, resonance, key tracking and the filter envelope with its depth). The EOS effect filter types (phasers, flangers, vocal formants, EQ morphs) have no model equivalent; such voices are converted without a filter. Banks written by older EOS versions (no EMSt chunk, oversized FORM size) are read as well.

Banks are also read directly from CD-ROM and hard disk images of the EOS samplers (.iso, .img, .hda), either from the E4B source format or through the ISO/IMG one. The EOS samplers read no standard filesystem from CD-ROM at all, so nearly all Emulator IV content in circulation exists as images of E-mu's proprietary filesystem. The geometry is taken from the superblock, so the CD and the hard disk variant are both read; EIII banks on discs of the older samplers are skipped.

Writing

Each multi-sample becomes one preset; a library collects all sources into a single bank (up to 1000 presets and 1000 samples, the format limits). Every zone is written as its own voice, which keeps all per-zone settings. Samples are stored as 16-bit mono PCM at their original sample rate (stereo sources are mixed down with a note in the log) and are de-duplicated by content. Rates above 48 kHz, the EOS maximum, are down-sampled with the zone and loop positions moved along. Since the sampler always plays a sample back at 44.1 kHz, the pitch offset which transposes a sample stored at any other rate back into tune is written with it. The root note is appended to the sample name (e.g. _C3) as the hardware browsers show it.

The destination can additionally write the bank as a ready-to-use CD-ROM image for SCSI CD-ROM emulators such as the ZuluSCSI, as a checkbox next to the bank output. Only EOS 4.7+ reads FAT hard disks, so for anyone on an older EOS version an image with the proprietary filesystem is the only way to get banks onto the sampler, and even on 4.7 the CD-ROM route is the most common workflow.

Format knowledge and attribution

The layout was reverse-engineered by the mpc2emu project (GPL, hardware-saved E4XT banks, commercial EOS CD-ROMs, the emu3bm sample struct and Phil's E4 notes); this implementation is an independent one based on that documentation. A distilled spec with the byte layouts and the hardware-calibrated envelope rate law lives in documentation/design/E4B_FORMAT.md.

Validation

  • Banks written by the creator pass the mpc2emu reference parser plus structural checks (EMU FORM-size convention, trailing EMSt master setup, TOC offsets); the EMSt/E4Ma blocks are byte-identical to hardware-captured defaults.
  • Three hardware-created third-party banks (Ian Wilson's free EOS banks, 198 presets / 1980 zones / 317 sample chunks) read completely: every zone resolves and all 165 unique sample PCMs are byte-identical to the reference parser's output.
  • A 66-preset bank round-tripped through detector and creator re-parses with identical zone mapping, envelopes and filters.
  • Two defects which the mpc2emu project found on real hardware after this PR was opened are fixed here as well: the sample pitch offset, without which a sample not stored at 44.1 kHz plays transposed, and a CD-ROM image directory entry which could describe a bank one block short so that the sampler refuses to load it. The image change leaves every already-correct entry byte-identical; see the discussion below for the verification of both.

I do not own an Emulator IV, so written banks have not been loaded on real hardware yet - same caveat as the MC-707 support. Happy to adjust anything.

@douglas-carmichael

Copy link
Copy Markdown
Contributor Author

Added the feature matrix rows for the format to SupportedFeaturesSampleFormats.ods (Read/Write pair between discoDSP Bliss and Elektron Tonverk). While filling it in I also tightened the creator: written samples are now limited to 48 kHz (the maximum EOS playback rate) - higher-rate sources are down-sampled with the zone/loop positions moved accordingly.

@douglas-carmichael

Copy link
Copy Markdown
Contributor Author

Two additions since the initial version, both aimed at making the format actually usable on real hardware - especially for owners of older units:

Reading EOS CD-ROM and hard disk images (.iso, .img, .hda). The EOS samplers read no standard filesystem from CD-ROM at all, so nearly all Emulator IV content in circulation exists as images of E-mu's proprietary disk filesystem (dumps of the commercial CD-ROM libraries, images for SCSI emulators like the ZuluSCSI). Banks are now read directly from such images, following the existing house pattern for sampler disk images: the endings on the E4B source format itself plus an EMU3 entry in the ISO/IMG format identifier which dispatches to the E4B detector (like the Ensoniq and Roland handling there). The filesystem geometry is taken from the superblock, so the CD and the hard disk variant are both read; EIII banks on discs of the older samplers are skipped.

Writing a CD-ROM image as a destination option, following the DecentSampler 'Create Bundle' checkbox pattern. The rationale: only EOS 4.7+ can read FAT hard disks, so for anyone running an older EOS version an image with the proprietary filesystem is the only way to get banks onto the sampler - and even on 4.7 the CD-ROM route via ZuluSCSI is the most common workflow. The written images are byte-identical to those of the mpc2emu reference builder for the same bank content, whose images are verified to load on a real E4XT, so the filesystem layer inherits that hardware validation (the bank content itself remains untested on hardware, as noted above).

I had briefly opened the image reading as a stacked PR (#222) but folded it in here so the format can be reviewed as one piece.

@lentferj

lentferj commented Jul 25, 2026

Copy link
Copy Markdown

Check my latest update, especially
lentferj/mpc2emu@e6b85b8
lentferj/mpc2emu@2d5f832
lentferj/mpc2emu@c40b7ee

Reads and writes Emulator 4/E4X/E4XT/E4K (EOS) .e4b banks. Every preset
of a bank becomes one multi-sample (voices become groups); writing turns
each multi-sample into a preset of a bank, with library support for up
to 1000 presets/1000 samples per bank and content-based sample
de-duplication. Mapped: names, key/velocity ranges, root keys, tuning,
volume, forward loops, amplitude envelope (incl. hold and velocity
modulation), filter type/cutoff/resonance/key tracking and the filter
envelope with its depth. Stereo samples are mixed down to mono on write.

The layout follows the reverse-engineering of the mpc2emu project (see
documentation/design/E4B_FORMAT.md). Validated against the mpc2emu
reference parser and hardware-created third-party banks (198 presets,
1980 zones, all sample PCM byte-identical on read; written banks
re-parse with identical mapping). Not yet tested on real hardware.
…ample rates to the 48 kHz EOS maximum

The Read/Write row pair in SupportedFeaturesSampleFormats.ods documents the
supported features. Written samples with a higher sample rate are now
down-sampled to 48 kHz (the maximum EOS playback rate) with the zone and
loop positions moved accordingly; lower rates are kept as before.
…mages

The EOS samplers use a proprietary disk filesystem on their CD-ROMs and
hard disks (they read no standard filesystem from CD at all). Banks can
now be read directly from such images (.iso, .img, .hda - e.g. dumps of
commercial E-mu CD-ROM libraries or images for SCSI emulators like the
ZuluSCSI), both via the E4B source format and via the generic ISO/IMG
source format. All geometry is taken from the superblock, so both the
CD-ROM and the hard disk variant of the filesystem are read. Files which
are not Emulator IV banks (e.g. EIII banks on discs of the older
samplers, which use the same filesystem) are skipped.

Validated against images generated by the mpc2emu reference builder
(3 banks each as CD and as 1 GB hard disk image): all 198 presets read
through both source formats with sample PCM byte-identical to reading
the plain bank files.
… CD-ROM emulators

The EOS samplers read no standard filesystem from CD-ROM and only EOS 4.7
or later reads FAT hard disks, so for units running older EOS versions an
image with the proprietary E-mu disk filesystem is the only way to load
banks at all. With the new destination option (house pattern of the
DecentSampler 'Create Bundle' checkbox) the created bank is wrapped into
such a CD-ROM image (*.iso) which can be copied to the SD card of a SCSI
emulator (e.g. as CD1.iso for a ZuluSCSI in CD-ROM mode) and loaded from
the emulated CD-ROM drive on any EOS version.

The written images are byte-identical to those of the hardware-verified
mpc2emu reference builder for the same bank content (verified with a
Roland MV-8000 source converted both ways), and they round-trip through
the image reading added before.
…1 kHz play in tune

The sampler plays every sample back at its fixed 44100 Hz rate and takes the
transposition of a sample stored at a different rate from a signed 1/64
semitone offset at byte 58 of the sample struct, which the creator left at
zero. The sample rate field at byte 54, which was the only one written, is
informational and inherited from the EOS 3 struct; the firmware does not use
it for the pitch. Any written sample not at exactly 44100 Hz therefore played
back transposed by the ratio of the two rates - a 22050 Hz sample sounded a
full octave too high.

The offset is round(768 * log2(rate / 44100)), reverse-engineered from E4XT
hardware captures by the mpc2emu project (accurate within +/-2 units over
11025-48000 Hz) and confirmed there on hardware.

This was not visible in a conversion round-trip because the detector reads the
rate back from the informational field, which was written correctly all along.
…load

The 'bytes used in the last block' of a written file entry was derived with a
plain remainder of the block size, which is zero whenever the data in a file's
last cluster happens to be an exact multiple of 512 bytes. The entry then
describes the file one block short and the sampler aborts its load with an end
of file error, while every other bank of the same image loads normally.

The value is now derived from the block count instead, so it is always in the
range of 1 to 512. Every entry which was already correct keeps its exact value
- only the case which produced a zero changes.

Found and confirmed on an E4XT by the mpc2emu project. The reader keeps
accepting a zero as a full block, since images written by other tools can
contain it.
@douglas-carmichael

Copy link
Copy Markdown
Contributor Author

Thank you for the pointer - both of those were present here too, and both are now fixed on the branch.

Sample pitch offset (2d5f832). The creator wrote only the sample rate at [54-57] and left [58-59] at zero, so every sample not stored at exactly 44100 Hz played back transposed. Implemented as round(768 * log2(rate / 44100)), which reproduces your captured values: 22050 → -768 (exactly one octave), 11025 → -1536, 44100 → 0, 48000 → +94.

Worth recording why this survived my testing: the detector reads the rate back from the informational field at [54-57], which was written correctly all along, so a detector → creator → detector round-trip reproduced every rate exactly and looked clean. Only hardware - or your capture - would have shown it.

CD-ROM image directory entry (c40b7ee). Same derivation and so the same bug: the bytes used in the last block came from lastClusterBytes % 512 and was therefore 0 whenever the last cluster was an exact multiple of 512. It is now derived from the ceiling block count and is always 1..512. On a test image of seven files with sizes chosen around the boundary (512, 513, 1023, 1024, 100000, 524288, 524800), four of the seven entries were 0 before the change and none after, while the three that were already correct keep their exact values (1, 511, 160).

That does mean I have to correct what I wrote further up this thread: the images are byte-identical to the pre-fix builder. After c40b7ee they agree with yours again for every file whose last cluster is not an exact multiple of 512, and in that one case both now write the same corrected value.

Docs (e6b85b8). I mirrored the [58-59] field and the 1..512 rule into documentation/design/E4B_FORMAT.md, with the attribution for both.

Much appreciated - a port is only as good as the spec it comes from, and these two were not findable from this side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants