- SoundController rebuilt around idle+rev loop crossfading (real racing game approach): idle layer barely pitch-shifts (keeps engine character), rev layer carries the speed range; crossfade window 5%-45% of top speed - Per-car CAR_SOUNDS table so the RX-7 gets real 13B rotary loops while other cars keep the generic set - docs/ROTARY_SOUND.md: full record->loop->upload pipeline for capturing the owner's REAL RX-7 (extract audio from video, zero-crossing cut + equal-power crossfade seam, normalize, ogg, Studio upload, wire IDs) - Toolbox rotary rips evaluated and rejected: unauditionabe off-platform, short/unloopable, murky rights; the real car beats any rip
3.2 KiB
Real 13B rotary engine sound (rx7_fc)
The RX-7 must sound like a rotary. The pipeline: the owner's own recordings →
processed into two seamless loops on this workstation → uploaded in Studio →
IDs pasted into SoundController.CAR_SOUNDS.
What the game needs (two loops)
| Loop | Content | Length |
|---|---|---|
| Idle | Engine idling, steady. The rotary lope/brap at rest. | 5–10 s |
| Rev | Held at steady mid-high RPM (~4–6k), NOT a sweep. | 5–10 s |
Steady-state matters: the game pitch-shifts and crossfades these, so a loop recorded during rising RPM will "wander" audibly. A long recording containing steady sections is fine — the good seconds get cut out in processing.
Step 1 — Record (or use existing video)
Any source works: phone video, GoPro footage, a Zoom H5 recording. Existing videos of the car are fine — audio gets extracted. Best results:
- Record OUTSIDE the car, mic a few feet from the exhaust.
- Get ≥10 s of steady idle and ≥5 s of held revs.
- Avoid wind over the mic and people talking.
Drop the files on the NAS next to the reference photos:
unraid-1:/mnt/user/data/yy-roblox-games/0-fast-n-furious-sim/001-1993 Mazda RX-7/sound/
Step 2 — Process into seamless loops (this workstation)
Hermes does this — the box already has ffmpeg + numpy/scipy (avsync-research
venv). Ask and it happens; for reference the recipe is:
- Extract audio:
ffmpeg -i clip.mp4 -vn -ac 1 -ar 48000 raw.wav - Find a steady window (visually via spectrogram, or scripted RMS/pitch scan).
- Cut the loop at zero-crossings and apply a short equal-power crossfade from the tail onto the head so the seam is inaudible: loop-body + (last ~150 ms faded out, overlaid on first ~150 ms faded in).
- Normalize to about -3 dBFS peak, export
.ogg(smaller upload, Roblox-native):ffmpeg -i loop.wav -c:a libvorbis -q:a 6 rx7_idle_loop.ogg - Verify: play the file on repeat (
ffplay -loop 0) — no click, no wander.
Outputs: rx7_idle_loop.ogg + rx7_rev_loop.ogg, copied back to the NAS
sound/ folder and kept in assets/audio/ locally (small enough to commit).
Step 3 — Upload in Studio (owner)
- Studio → View → Asset Manager → Import (or the Creator Dashboard →
Development Items → Audio) → upload both
.oggfiles. - Audio uploads require an ID/phone-verified account; private audio uploaded to YOUR account is playable in YOUR experiences — exactly our case.
- Copy each asset ID after moderation clears (usually minutes).
Step 4 — Wire in
In src/client/SoundController.luau, uncomment and fill:
local CAR_SOUNDS: { [string]: EngineSounds } = {
rx7_fc = {
Idle = "rbxassetid://<idle id>",
Rev = "rbxassetid://<rev id>",
},
}
Rebuild, playtest, adjust IDLE_PITCH_* / REV_PITCH_* / CROSSFADE_* to
taste. Done — the RX-7 braps.
Why not a toolbox rotary?
Searched; candidates exist (e.g. "13B ROTARY ENGINE SOUND", id 118059219867199) but can't be auditioned outside Roblox (asset downloads require auth), most are short unloopable rips, and rights are murky. The owner HAS the real car — its actual engine is strictly better than any stranger's rip. Toolbox is the fallback only if recording proves impractical: audition in Studio before committing to one.