Michael Wolf
Projects and thoughts from Cincinnati San Jose Oakland an undisclosed location in Grass Valley
Home Projects Photos Github Mastodon Nullbrook RSS
Setting Up SDRTrunk and Icecast Streaming to Pass the Time
Last edited - 2020-06-02

Oakland has been a whole lot quieter today as opposed to this weekend. The curfew has gone into effect and the police have proven they are serious about arresting people intentionally staying out past 8pm.

That said, I still wanted to get a decent P25 decoder set up running for my own curiosity as well as recording for public transparency. This is certainly not the end of the protests and there's much to be gained from dispatch communications, especially since, as stated before, I'm not on social media.

My investigation here stemmed from conversations I had with coworkers about my last post regarding ADS-B decoding. When I'd moved out here, I realized that most of the public safety stations were not broadcasting over FM voice. That pretty much prevented me from digging any deeper. However confidence with the last little project led me to look into these systems again.

Radio Reference, always helpful, shows the East Bay Regional Communications System (EBRCS) is a P25 encoded channel including police, fire, ambulances, BART and helicopters. The ALCO Northwest Simulcast matches my region pretty well! If you don't care about the details and just want the stream, click here

Project 25 (P25) is a digital radio encoding standard which has been widely adopted by public safety organizations around the country. It's trunked, which means that a control channel must be received in order to determine what frequencies should be listened to. The protocol can support encryption (though certainly not /great/ encryption) however on systems that are shared between departments/agencies messages are often left in clear text.

That's indeed the case with the East Bay Regional Communications System! The system runs P25 phase 1 (the older standard) and uses the following frequencies for control:

These will be necessary later for setting up the scanner

The Scanner! In order to handle the bit-more-complex task of handling digital radio signals and decoding P25, we'll be using SDRTrunk, a lovely Java application that will thus run on about any machine. Combined with an RTL-SDR or other SDR dongle, we'll be able to receive the P25-encoded stream and make sense of it.

The setup for SDRTrunk is fairly straightforward, but John's great guide does a fantastic job of laying out the steps for installing both SDRTrunk and the required JMBE library is installed. Upon opening up SDRTrunk for the first time, make sure to go to the configuration and point to the JMBE libray we've compiled.

Once set up and SDRTrunk is showing the radio waterfall, we'll set up four channels. One for each of the control frequencies listed above. For each channel, the Source tab should be set to the frequency and the Decoder tab should be set to P25 Phase 1 with Simulcast(LSM) modulation. Setting the channels to autostart makes dealing with occasional memory exhaustion less painful. After starting the channels, the UI should look a little like:

Note the inventive naming scheme

Hearing anything? I hope so. This is going to be a dang lazy blog post where I greatly rely on other peoples work.


I chose to set up an Icecast server because it's free, open-source and runs on FreeBSD (neat). Lucky for me, many brave souls have gone before me to set this business and it's xml-based config file up:

Once configured and reachable at localhost:8000 or wherever we may wish to host it, the next step is setting up SDRTrunk's streaming feature.

The SDRTrunk wiki does a great job explaining the steps but here's an overview.

Set up the Stream

  1. Go to the Streaming Tab
  2. Add a New Stream of type Icecast v2
  3. Give it a name, put in the server and the port
  4. Enter the mount that we've defined in the icecast xml
  5. The username will be 'source'
  6. The password will be what we defined for 'source-password' in the icecast.xml
  7. Select public
  8. Select enabled
  9. Save

If all goes well, the status should be Connected. If not, check the logs of SDRTrunk. The hexdump contains the HTTP response from the Icecast server. In order to properly stream anything, we'll need to set up an alias.

Set up the Alias

  1. Make an alias in the Aliases tab.
  2. Give it a name
  3. Go to Audio Identifier and add
    1. Audio Broadcast Channel -> our stream name
    2. Talkgroup Range (or Radio Range) -> a subset of the talk groups that can be looked up on radio reference or if we want everything min:1 max:16777215
    3. Save
  4. Add each of the channels to the alias
  5. Restart

At this point the audio should be streaming and our streaming status should look like the image below with queued and streamed being non-zero:

Finally to reap the sweer rewards and make sure it works, visit the icecast server webpage (default localhost:8000), find the stream and pull down the M3U.

In my case, the M3U for the East Bay Regional Communications System (EBRCS) is here

What' Next?

Well that was fun. I by no-means feel like I'm doing something cutting edge but it has taught me a bit about digital mode radio. It's as if I had actually paid attention to the UC Radio Club president when I was hanging out in the shack playing Paperboy on the club's Commodore.

Maybe I'll checkout the other systems and see if I can crack the encypted ones. Just kidding! I could barely get the unencrypted one to work and that has nice tutorials!

More likely the future of this project will be a constantly streaming radio station of DJ mixes and stuff. I'm sure my DSL connection can handle it...