|
Tabula Sonora 0.1.0
A native C++20 implementation of the Roland Sound Canvas VA synth voice
|
Everything the Sound Canvas VA engine needs — the wave ROM, every synth curve and key-follow table, and the patch directory — lives inside SCCore.dll. This page and the offset map are the reason a downstream implementation can read the static data straight from the DLL and never re-reverse an offset.
In this repository the offset map is assets/manifest.json, embedded into the library at build time and read by ts::TableManifest. It is the same map the spec repository publishes as tables/manifest.json; the spec copy is canonical, and this one tracks it.
The tables are version-specific. This work was done against exactly this file:
| field | value |
|---|---|
| filename | SCCore.dll |
| size | 27,347,456 bytes |
| SHA-256 | 117E6AA147A96FBDE5E10D2CAF16C89965ACC1E44235FD245992216CC620BDB1 |
| SHA-1 | CF9DCE5A0CABEE06792E884673B8BEEF806F1AED |
| MD5 | DBD9A30C168EFEF577D40A28D9ADF37D |
| PE timestamp | 1572416468 = 2019-10-30 06:21:08 UTC |
| file mtime | 2020-01-19 UTC |
| product | Roland VS Sound Canvas VA |
The Win32 version resource is empty (no FileVersion), so identify the build by hash + PE timestamp + size. A different SC-VA build may move tables. ts::RomImage enforces exactly this, and ts::DllIdentity records what it checked.
The DLL's preferred image base is 0x180000000. Symbol VAs (as seen in a disassembler) map to raw file offsets by a per-section constant:
| region | mapping |
|---|---|
| .rdata curve / key-follow tables | file_offset = VA − 0x180000000 − 0x1000 |
| resample-kernel section (g_interp_coef_table) | file_offset = VA − 0x180000000 − 0x1400 |
| data section — wave ROM + patch directory | own base offsets, one per region (see the manifest) |
This engine reads the raw file positionally, so it uses file offsets directly. If instead you read the loaded/relocated image (for example via the spec repository's scdec dumpmem), use loaded_base + (VA − 0x180000000) — the virtual RVA, which differs from the file offset by the section skew above.
The spec repository regenerates the map itself with python tools/gen_manifest.py <SCCore.dll>, which locates every table in the DLL by byte-exact content match and re-emits the manifest with fresh hashes. That is how the map is produced.
Here, the map is already embedded, and the equivalent local operation is to slice the tables out of your own DLL:
Each output is a byte-for-byte slice of the DLL at the offset the manifest records — size bytes at file_offset. All 50 cached tables match the DLL byte-for-byte at these offsets. One, kf_tvfenv, is an over-read whose used rows 0–15 match; the unused high rows differ and are never indexed.