RX-7 audio v2: turbo whistle + exhaust from the action-cam library
CI / quality (push) Successful in 1m4s
CI / quality (push) Successful in 1m4s
- Scanned b-action-cam-footage/clipchamp (99GB, 5 videos of the FD): extracted audio NAS-side via linuxserver/ffmpeg container (stream-copy), scanned 69min return drive per-second for engine tonality + whistle prominence (1.5-9kHz peak vs band median) - New rev loop: 985-993s highway pull — 0.0Hz pitch drift over 8s, whistle ~1.7kHz at +33dB, exhaust + turbo captured together (seam 0.001) - New whistle-only loop: same pull high-passed 1.2kHz — isolated spool - SoundController: optional per-car Whistle layer that rides boost (throttle held at speed): fades in past 25% speed, pitch 0.9->1.35 - ROTARY_SOUND.md updated; three .ogg uploads needed in Studio now
This commit is contained in:
Binary file not shown.
Binary file not shown.
+15
-11
@@ -1,23 +1,27 @@
|
||||
## Status: loops are BUILT ✅ — awaiting Studio upload
|
||||
|
||||
Real 13B loops were extracted from the owner's own drive footage
|
||||
(`/mnt/user/data/c-finished-videos/2026-07-10/`, same car) and processed on the
|
||||
workstation. They live at:
|
||||
Real 13B loops extracted from the owner's own footage. **v2**: rev + turbo
|
||||
whistle now come from the action-cam library
|
||||
(`/mnt/user/data/b-action-cam-footage/clipchamp/`, 99 GB scanned — same car),
|
||||
which captured the turbo + exhaust together far better than the first source.
|
||||
|
||||
- `assets/audio/rx7_idle_loop.ogg` — 15.9 s steady idle (~99 Hz fundamental,
|
||||
scanned as the most tonally stable stretch of the session; seam jump 0.001)
|
||||
- `assets/audio/rx7_rev_loop.ogg` — 7.4 s held higher-RPM pull (~105 Hz,
|
||||
louder section; seam jump 0.005)
|
||||
from the 2026-07-10 session; seam jump 0.001)
|
||||
- `assets/audio/rx7_rev_loop.ogg` — 7.9 s whistle-rich highway pull (~124 Hz,
|
||||
from 20260510-Return..., window 985-993 s: 0.0 Hz pitch drift across 8 s,
|
||||
turbo whistle ~1.7 kHz riding +33 dB over the band; seam jump 0.001)
|
||||
- `assets/audio/rx7_whistle_loop.ogg` — the SAME pull high-passed at 1.2 kHz:
|
||||
isolated turbo whistle, layered in-game on top of the rev loop and faded
|
||||
in/up with "boost" (throttle held at speed) for the authentic spool sound
|
||||
- Masters (`.wav` + `.ogg`) mirrored to the NAS:
|
||||
`.../001-1993 Mazda RX-7/sound/`
|
||||
|
||||
**Remaining (owner, in Studio): upload the two `.ogg` files** (Asset Manager →
|
||||
Import, or Creator Dashboard → Audio), wait for moderation, then paste the two
|
||||
**Remaining (owner, in Studio): upload the three `.ogg` files** (Asset Manager →
|
||||
Import, or Creator Dashboard → Audio), wait for moderation, then paste the three
|
||||
asset IDs into `CAR_SOUNDS.rx7_fc` in `src/client/SoundController.luau`.
|
||||
|
||||
If a longer/angrier rev is wanted later, more source material exists in the
|
||||
other sessions under `c-finished-videos/` — the extraction is repeatable
|
||||
(method below).
|
||||
More source material exists in the other clipchamp sessions — the extraction is
|
||||
repeatable (method below).
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -34,19 +34,26 @@ local player = Players.LocalPlayer
|
||||
|
||||
local SoundController = {}
|
||||
|
||||
type EngineSounds = { Idle: string, Rev: string }
|
||||
type EngineSounds = { Idle: string, Rev: string, Whistle: string? }
|
||||
|
||||
-- Default (generic) sounds --------------------------------------------------
|
||||
local DEFAULT_SOUNDS: EngineSounds = {
|
||||
Idle = "rbxassetid://80317022777602", -- Roblox Resources engine loop
|
||||
Rev = "rbxassetid://80317022777602", -- same loop until real rev samples exist
|
||||
Whistle = nil, -- most cars have no turbo layer
|
||||
}
|
||||
local SQUEAL_ID = "rbxassetid://9120399077" -- ProSoundEffects tyre squeal
|
||||
|
||||
-- Per-car engine sounds. Fill rx7_fc with the owner's real 13B recordings
|
||||
-- once uploaded (docs/ROTARY_SOUND.md). Cars not listed use DEFAULT_SOUNDS.
|
||||
-- Per-car engine sounds. The rx7_fc loops are cut from the owner's REAL FD
|
||||
-- footage (docs/ROTARY_SOUND.md): idle + whistle-rich rev + an isolated
|
||||
-- >1.2kHz turbo whistle layer that rides boost. Fill the IDs after the
|
||||
-- Studio upload of assets/audio/*.ogg.
|
||||
local CAR_SOUNDS: { [string]: EngineSounds } = {
|
||||
-- rx7_fc = { Idle = "rbxassetid://<13B_IDLE>", Rev = "rbxassetid://<13B_REV>" },
|
||||
-- rx7_fc = {
|
||||
-- Idle = "rbxassetid://<rx7_idle_loop>",
|
||||
-- Rev = "rbxassetid://<rx7_rev_loop>",
|
||||
-- Whistle = "rbxassetid://<rx7_whistle_loop>",
|
||||
-- },
|
||||
}
|
||||
|
||||
-- Tunables --------------------------------------------------------------------
|
||||
@@ -63,6 +70,13 @@ local SLIP_START = 14 -- studs/sec lateral slip where squeal begins
|
||||
local SLIP_FULL = 34 -- lateral slip for max squeal volume
|
||||
local SQUEAL_MAX_VOLUME = 0.5
|
||||
local RESPONSIVENESS = 8 -- volume/pitch smoothing (1/sec)
|
||||
-- Turbo whistle layer (cars with Whistle set): rides "boost" = throttle
|
||||
-- held at speed. Fades in above BOOST_START speedFrac when on throttle.
|
||||
local WHISTLE_MAX_VOLUME = 0.45
|
||||
local BOOST_START = 0.25 -- speedFrac where boost can begin
|
||||
local BOOST_FULL = 0.8 -- speedFrac of max whistle
|
||||
local WHISTLE_PITCH_MIN = 0.9
|
||||
local WHISTLE_PITCH_MAX = 1.35
|
||||
|
||||
local heartbeatConn: RBXScriptConnection? = nil
|
||||
local seatedConn: RBXScriptConnection? = nil
|
||||
@@ -104,9 +118,16 @@ local function startAudio(seat: VehicleSeat)
|
||||
local idle = makeSound("EngineIdle", engineSet.Idle, ENGINE_BASE_VOLUME, bodyPart)
|
||||
local rev = makeSound("EngineRev", engineSet.Rev, 0, bodyPart)
|
||||
local squeal = makeSound("TyreSqueal", SQUEAL_ID, 0, bodyPart)
|
||||
local whistle: Sound? = nil
|
||||
if engineSet.Whistle then
|
||||
whistle = makeSound("TurboWhistle", engineSet.Whistle, 0, bodyPart)
|
||||
end
|
||||
idle:Play()
|
||||
rev:Play()
|
||||
squeal:Play() -- all loops run constantly; we fade volumes (no start/stop pops)
|
||||
if whistle then
|
||||
whistle:Play()
|
||||
end
|
||||
|
||||
heartbeatConn = RunService.Heartbeat:Connect(function(dt)
|
||||
if not bodyPart.Parent then
|
||||
@@ -138,6 +159,16 @@ local function startAudio(seat: VehicleSeat)
|
||||
local braking = (seat.ThrottleFloat == 0 and speed > tuning.MaxSpeed * 0.5) and 0.25 or 0
|
||||
local squealTarget = math.max(slipFrac, braking) * SQUEAL_MAX_VOLUME
|
||||
squeal.Volume += (squealTarget - squeal.Volume) * a
|
||||
|
||||
-- Turbo whistle: spools with throttle held at speed ("on boost").
|
||||
if whistle then
|
||||
local boost = math.clamp((speedFrac - BOOST_START) / (BOOST_FULL - BOOST_START), 0, 1)
|
||||
* math.abs(seat.ThrottleFloat)
|
||||
local whistleVolTarget = WHISTLE_MAX_VOLUME * boost
|
||||
local whistlePitchTarget = WHISTLE_PITCH_MIN + (WHISTLE_PITCH_MAX - WHISTLE_PITCH_MIN) * boost
|
||||
whistle.Volume += (whistleVolTarget - whistle.Volume) * a
|
||||
whistle.PlaybackSpeed += (whistlePitchTarget - whistle.PlaybackSpeed) * a
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user