About NWI Scanner
nwiscanner.com  ·  Northwest Indiana Public Safety Scanner Archive
117 Total Runs
294235 Transmissions
117 Transcribed
26 Talkgroups
Last run active TGs
Jasper County Sheriff Dispatch Valparaiso Dispatch Porter Countywide Fire/EMS Talkaround Portage Dispatch Porter Sheriff Dispatch Portage/Valpo Fire - Talkaround Porter Chesterton Police Dispatch Starke County Sheriff Dispatch Portage Fire Fireground Valparaiso Fire Fireground Porter County Fire Dispatch La Porte County Sheriff Dispatch Michigan City Police Dispatch La Porte County Fire Dispatch Michigan City Fire Dispatch

The radio system never really sleeps. Fire departments get toned out, deputies run plates, trains stop traffic, ambulances get redirected mid-run, public works calls in a downed line. Most of it is routine. By the next day, it's forgotten.

NWI Scanner keeps the record. It's a publicly accessible archive of unencrypted public safety radio communications received via software-defined radio (SDR) in Northwest Indiana. The site captures transmissions from Porter, La Porte, Starke, Jasper, and Newton counties on the Indiana STARCOM21 P25 Phase II trunked radio system, transcribes them with local AI speech recognition, and makes all of it searchable.

Nothing here comes from an internet feed. Every recording starts with an antenna and two radios sitting quietly, listening. This is an independent, community-operated project with no affiliation with any government agency, public safety department, or commercial service.

Two RTL-SDR dongles and a whip antenna. That's the entire receive side — refreshingly simple. The dongles started life as cheap European TV tuners; someone figured out you could put them into a mode where they just hand you raw IQ samples and get out of the way. Everything past that point is software. The antenna sits elevated with line of sight toward the STARCOM21 tower infrastructure across Porter County. The machine running SDRTrunk spends most of its life doing absolutely nothing interesting until somebody keys a microphone — then everything happens in a fraction of a second before it quietly goes back to waiting. None of it is exotic: two sticks of hardware and a growing pile of scripts holding the rest together.

Receivers 2× RTL-SDR v3 dongles (Rafael Micro R820T2 tuner, 8-bit ADC, ~2.4 MHz usable bandwidth each)
Antenna Vertical whip, elevated mount — line of sight to the STARCOM21 tower infrastructure across Porter County
Host Ubuntu 22.04 LTS, running continuously. SDRTrunk handles decode; everything else is bash and Python.
Transcription A modest always-on ARM server — whisper.cpp with the large-v3-turbo-q8 model. Runs on CPU only, no GPU required. Scanner traffic isn't in a hurry.
Web server Same server as transcription. Nginx + Gunicorn + Flask. SQLite for the transcript index. No managed services, no cloud database.

Air to archive:

RF 860 MHz RTL-SDR dongle IQ samples (USB) SDRTrunk P25 decode WAV per transmission merge + log whisper.cpp dict correction this page

Scanner culture predates the internet. People built crystal sets and homebrew receivers to hear what was happening around them because the transmissions were there in the air and pulling them down felt like the obvious thing to do. That instinct hasn't changed. The gear just got cheaper.

There's a certain satisfaction in receiving something — not streaming it from someone else's server, but actually receiving it. Your antenna, your hardware, your software making sense of the signal. You own that.

Live scanner audio disappears the moment it's spoken. That always seemed like a waste. Searching for something that happened three months ago used to mean remembering roughly when it occurred, finding an archive, and listening through hours of recordings. Computers are good at remembering things. They should probably do that job instead.

Recording the audio turned into transcribing it. Transcribing it turned into indexing it. Indexing it turned into search. None of that was planned from the beginning — each piece simply made the next one seem like the obvious thing to build.

Whisper isn't perfect on scanner audio — it hears "Reportage" instead of "Portage," stumbles on phonetic-alphabet strings, and occasionally invents a word that's never existed. A correction dictionary helps close the gap. The audio is always there when the transcript fails; the transcript is simply another way to get back to it.

Most software tries to make decisions. This mostly tries to avoid them: record everything, timestamp everything, keep it together, make it searchable, get out of the way. The less opinion the software has about what's important today, the more useful it becomes six months from now.

This isn't a product. It's a machine someone built because they wanted it to exist.

The machine doesn't know what's important. A working structure fire gets logged exactly the same as someone asking if another unit is clear. One transmission is a jaw dislocation; the next is a stuck traffic gate; an hour later it's an ambulance headed to Camelot Manor. Most days aren't extraordinary. They're just Tuesday. After enough Tuesdays, a picture starts to emerge.

Indiana STARCOM21 is a statewide P25 trunked system. State police, county sheriff, fire, EMS, municipalities — all sharing the same tower infrastructure, separated by talkgroup. The control channel coordinates everything in real time: who's transmitting, which tower, which channel slot. SDRTrunk follows it like a map.

Some of it you can hear. Some of it you can't. Fire and EMS in Porter County mostly run unencrypted. Police is mixed — some agencies went AES a while back, others haven't. When a talkgroup encrypts, the control channel still shows activity but the audio is gone. A locked door. Those transmissions don't show up here.

What does show up: a jaw dislocation at Camelot Manor, 9-year-old home alone. CSX gates stuck down after a train cleared. Rescue 4 getting bounced between two scenes. A plate run on a maroon '98 Chevy, expired, operator surrendered CDL. An air medical request — "we need angels" — at 8:57 in the morning. Ordinary day. All of it public, all of it broadcast, none of it going anywhere until now.

Fifteen minutes. Two talkgroups. Real run.

00:05:41Portage Dispatch144, Portage, OIC alert.
00:05:44Portage Dispatch1064, Camelot Manor. 25-year-old female, conscious and breathing.
00:05:57Portage DispatchShe dislocated her jaw. Unknown how. Home alone with her 9-year-old.
00:06:00Portage DispatchTrain has gone through. Gates are still down. CSX has been notified.
00:06:16Portage Dispatch10-4, they're clear.

00:07:58Portage/Valpo FireStation 2 will respond to Ameriplex. Have South Haven respond to Camelot.
00:08:43Portage/Valpo FireLighter 1 is going to head to Camelot for that traumatic injury.
00:08:57Portage/Valpo FireAffirmative. We need angels.
00:09:04Portage/Valpo FireRescue 4 responding to Ameriplex. South Haven dispatched to Camelot.

00:15:46Portage DispatchAffirmative, checking on mail, it's a business, 5349 US Army, sir.
00:17:51Portage DispatchLast name H-Henry, A-Adam, A-Adam, C-Charles, K-King. First name Allen, A-L-A-N.
00:18:43Portage DispatchTony returning, expired plate, Maroon 1998 Chevy GMT, 2953 May Street, Portage. Signal 43.
00:19:32Portage DispatchReturns valid, zero points, operator surrendered Class B CDL, now on lifetime permit. Signal 43.

Actual output from a recent run. Timestamps link to audio in the full archive. "We need angels" — air medical request.

1
Radio Reception SDRTrunk ↗ RTL-SDR ↗
Two RTL-SDR dongles receive the RF signal simultaneously. SDRTrunk decodes the Indiana STARCOM21 P25 Phase II trunked system in real time, following the control channel to track talkgroup grants and tuning each dongle to voice channels as transmissions occur. Every individual transmission is saved as a WAV file tagged with talkgroup ID, timestamp, and unit ID where available. The receiver runs continuously, 24 hours a day.
2
Audio Merging SoX ↗
Twice daily, a script collects all WAV clips recorded since the last run and merges them with SoX into a separate audio file per talkgroup, plus one continuous recording covering every talkgroup in chronological order. Audio is normalized to a consistent volume level, silence is trimmed from each clip, and a small gap is inserted between transmissions. A log file is produced alongside each audio file that maps every clip to its exact wall-clock timestamp, talkgroup, and audio offset — this is what powers the click-to-seek feature in the player.
3
Transcription whisper.cpp ↗
Each talkgroup's merged audio is passed independently through whisper.cpp — a fast local implementation of OpenAI's Whisper speech recognition model — producing a timestamped transcript for that talkgroup alone. The log file's audio offsets align each recognized segment back to its exact clip and wall-clock time, powering click-to-seek. Raw output is post-processed through a 2724-entry correction dictionary built specifically for this system, correcting common mishearings of 10-codes, agency names, unit identifiers, street names, and local place names. The continuous all-talkgroup recording is kept for uninterrupted listening across the full run but isn't separately transcribed, since every transmission it contains already has a transcript from its own talkgroup. Transcription runs entirely on-device. No audio leaves the server.
4
Sync & Publication Flask ↗ SQLite ↗
Completed runs are synced from the local recording machine to the public web server over SSH. Transcripts are parsed, annotated with talkgroup metadata, and indexed in a SQLite full-text search database. The Flask web app serves the archive, audio player, and search interface. Clicking any transcript line seeks the audio player to that exact moment in the recording. All transcript text is fully searchable across the entire archive.

Reception covers the Indiana STARCOM21 system serving Porter, La Porte, Starke, Jasper, and Newton counties, along with regional talkgroups for Indiana State Police, Indiana Toll Road, Indiana Dunes National Park, DNR, and air medical services.

Reception Area · NW Indiana
Porter County
9
Talkgroups
La Porte County
4
Talkgroups
Starke County
1
Talkgroups
Jasper County
1
Talkgroups
Newton County
1
Talkgroups
Regional / Statewide
10
Talkgroups

There isn't much mystery here. A couple of radios. An antenna. Some Linux machines. A growing pile of scripts. Eventually those pieces became something that didn't seem to exist anywhere else. So it kept growing.

All transmissions monitored and published on this site are unencrypted public safety communications broadcast on licensed radio frequencies. Reception of these signals is lawful under federal law. Publication of unencrypted radio communications is permitted under 47 U.S.C. § 605 and the Electronic Communications Privacy Act, which explicitly excludes unencrypted radio communications from its prohibitions.

This site is operated solely for educational, research, and public interest purposes. No private communications are intercepted or published. No encrypted transmissions are decoded or published.

Transcripts are generated by machine learning software and may contain errors, including misrecognized words, incorrect agency names, and inaccurate location information. Always verify transcript content against the original audio before relying on it for any purpose.

Do not use scanner audio or transcripts as a substitute for calling 911. If you witness an emergency, contact your local emergency services directly.