Skip to content

Race Engineer (voice callouts)

Race Engineer watches your telemetry and speaks the things a real engineer would tell you over the radio: lap times, personal bests, fuel range, pit windows, engine warnings and — once it knows the track — where you are losing time.

"New personal best, one minute thirty-one point eight." "Fuel remaining, five point two laps." "Pit window opens next lap." "Repeated front-left lockups into turn four."

Speech is generated by the browser, not the server. The datalogger never needs an audio device, PulseAudio, Bluetooth, a desktop, a TTS package, or a cloud API — which is what makes this work identically on a Raspberry Pi, in Docker, on a NAS, or on a Windows PC. Nothing is uploaded, and no microphone permission is requested.

Turning it on

  1. Open the driver dashboard (/dash) or the standalone page (/engineer).
  2. Click Enable Race Engineer.
  3. You should hear "Race engineer enabled."

The click matters: browsers only allow audio after a user interaction, and a saved preference does not carry that permission across a browser restart. Race Engineer therefore always waits for one click per page load before it speaks.

The panel distinguishes four separate things, which is usually enough to diagnose a silent setup:

Row Meaning
Voice preference you have enabled voice on this device
Browser audio speech synthesis exists and the test utterance went through
Active speaker this device is the one allowed to speak
Connection the WebSocket to the datalogger is up
Server callouts the backend is generating callouts
Coaching whether enough laps have been driven for lap-vs-lap coaching (Coach mode only)

One speaker at a time

You may have the dashboard open on a laptop, a phone, an OBS browser source and the admin page at once. Only one browser speaks — the one that claimed voice output (Use this device for voice output). Everything else still receives the callouts and can show them as on-screen captions, but stays silent.

Only /dash and /engineer may claim voice at all. The OBS overlay (/overlay) never speaks, so adding overlay sources can't turn your stream into a chorus.

If the speaking browser disappears (tab closed, laptop asleep), the claim is released. Reopening the same page takes it back; another device never picks it up on its own.

The /engineer page

/engineer is a minimal standalone surface: connection state, the voice controls, and a running list of recent callouts. It is intended for

  • a phone or tablet propped next to the wheel,
  • an OBS browser source that provides stream audio,
  • troubleshooting voice output without the dashboard in the way.

What it says, and how much

Verbosity is a preset over the callout categories:

Mode Speaks
Minimal critical engine warnings, fuel shortage, pit window, final lap
Race everything in Minimal, plus lap times, personal bests, positions, fuel range, race progress
Coach everything in Race, plus repeated lockups and wheelspin, tire balance, bottoming, corner time loss

Pace and corner feedback are always measured against your best lap of the session — the pace you have already proven in this car, on this track.

Default is Race, which averages one to three spoken messages per lap.

Individual categories can be switched off on top of that (system, lap, pace, race, position, fuel, strategy, engine, tires, chassis, coaching).

Braking points and speeds are spoken in meters and km/h by default; switch to feet and mph in Admin → Race Engineer (GT7_RACE_ENGINEER_UNITS). This is a server setting rather than a per-device one, because the callout is worded before it reaches a browser.

The server has its own verbosity and category settings in Admin → Race Engineer, and they are a ceiling, not a default: a category the server does not produce never reaches any browser, so a device set to Coach hears nothing extra if the server is capped at Race. Out of the box the server is set to Coach — it produces everything and each device decides what it wants — and the panel dims (with the reason) any category the server has been capped below.

What each category says

Every callout belongs to one category, and every category can be switched off. The same table is in the Race Engineer panel under What each category says, so you never have to guess what a toggle controls.

Category Says Example
system status messages from Race Engineer itself "Race engineer enabled."
lap your lap time, every completed lap "Lap time, one minute thirty-two point five. Two tenths slower."
pace personal bests, and pace slipping away from them "New personal best, one minute thirty-one point eight." / "Your pace is dropping, eight tenths off your best."
race where you are in the race distance "Final lap." / "Halfway through the race."
position places gained and lost "Position gained. You are now position four."
fuel how much further the tank will take you "Fuel remaining, five point two laps." / "Fuel critical, one point two laps remaining."
strategy pit decisions "Pit window opens next lap." / "Fuel will be short by one point two laps."
engine mechanical warnings — on at every verbosity "Water temperature critical." / "Oil pressure low."
tires tire temperature and balance "Rear tires are running eight degrees hotter than the fronts."
chassis setup feedback: what the car is doing, not you "The car is bottoming out at turn four."
coaching driving feedback against your best lap "You are braking early into turn four, about fifteen meters." / "Repeated front-left lockups into turn four." / "You lost three tenths in turn six. You braked eighteen meters earlier and carried five kilometers per hour less at the apex."

Full detail, callout by callout, with when each one fires:

Callout Category When
Lap time lap every full lap, compared with your session best
Personal best pace a full lap beats your session best
Pace dropping pace three laps running average well off your best, none of them back on it
Final lap / halfway race race distance milestones, once each per race
Position gained / lost position a position change that holds for about a second
Fuel remaining fuel once a lap, when the tank is close to mattering
Fuel low / critical fuel range drops below 3 / 1.5 laps
Fuel shortage strategy two laps running project you cannot reach the finish
Pit window strategy the lap you must pit by comes into range
Water / oil temperature engine above the limit for 5 s, escalating to critical
Oil pressure engine below 2 bar for 1.5 s with the engine pulling
Tire temperature / balance tires tires running hot, or one axle/side 8 °C hotter
Bottoming out chassis the floor grounds in the same place lap after lap
Braking early / late coaching recent laps consistently brake off your best lap's marker
Repeated lockups / wheelspin coaching the same wheel, the same place, three times in recent laps
Corner time loss coaching after a slower lap: where the time went, and how

Which laps it trusts

A lap the logger only saw part of — capture started mid-lap, or you came out of the garage — still gets a lap time from GT7, and that time is short. Left alone it wins the session, becomes the reference every comparison is made against, and turns every coaching callout into fiction.

So laps are checked against how far recent laps ran. A lap covering materially less of the track cannot become the session best, is dropped from the fuel model, and is marked as partial in the Sessions view. The check is retroactive: a lap that looked fine on its own is retracted once later laps show how long a real lap is, and the fastest remaining full lap takes the best.

Coaching waits for this. Braking points, corner losses and repeated-mistake callouts compare laps by position on the track, which is meaningless until several laps agree on the distance — usually by lap three. Until then the coaching category is simply quiet, and the panel says Coaching: needs a few laps.

When it stays quiet

Race Engineer deliberately says nothing when the telemetry source is disconnected, the game is loading or paused, the session is not active, the message's category is off, the same thing was just said, or the message has gone stale. A late callout is worse than none: every message carries an expiry, and one that arrives after it is simply dropped.

When you hear nothing

Race Engineer reports where it stopped, so silence is diagnosable rather than mysterious. Check in this order:

  1. The panel's status rows. Browser audio says needs a click, armed, speaking, or N failed; Active speaker says whether this device is the one allowed to talk. If speech is failing, a red banner names the reason the speech engine gave.
  2. Admin → Race Engineer. Callouts emitted counts what the backend produced; Spoken acks and Speech failures count what the browser did with them. Emitted but failing means the problem is entirely in the browser; nothing emitted means the detectors have not fired yet.
  3. The server log logs a warning with the same reason on every failed callout.

What the common reasons mean:

Reason What to do
the browser blocked audio The click did not count as permission. Press Test voice.
no response from the speech engine The engine accepted the message and did nothing. The reason names how many voices the browser has: 0 voices means the browser has nothing to speak with (Chrome on Linux needs a speech engine such as speech-dispatcher); with voices present, reload the page — the engine can wedge.
no audio output device / the audio device is busy The browser's output device is unavailable — check the system output, and that the page is not muted in the OS mixer.
no voice installed for this language Pick a specific voice in the Voice dropdown.
this browser has no speech synthesis Use Chrome or Edge; captions still work.

To tell the app apart from the browser, paste this into the browser console:

speechSynthesis.speak(new SpeechSynthesisUtterance("test one two three"))

If that is silent too, the problem is the browser or the machine's audio, not Race Engineer.

After three failures in a row Race Engineer stops trying and shows captions only — each failed attempt otherwise blocks the queue long enough for the messages behind it to expire. Test voice clears that and tries again.

Browsers

Chrome and Edge are the best-supported. Safari (macOS and iOS) works, but loads its voices asynchronously and stops speech when the screen locks. On iOS, keep the page in the foreground.

The OBS embedded browser has historically had unreliable speech support; test it before relying on it for a stream, and fall back to a normal browser window on the same machine if it stays silent. Callout captions still render either way.

If speech is unavailable entirely, the dashboard keeps working normally and callouts appear as on-screen captions — nothing else degrades.

Testing without driving

Admin → Race Engineer → Send test callout pushes a callout to every connected browser, which is the quickest way to prove the whole path (server → WebSocket → queue → speech) works.

To exercise real detectors without a console, run the simulated source with a scenario:

GT7_SOURCE=sim GT7_SIM_SCENARIO=fuel_shortage ./dev.sh

Scenarios: practice (default), race, fuel_shortage, overheating, oil_pressure.