OP25 Question regarding whitelist/blacklist and multiple voice channels

Status
Not open for further replies.

jschmall

Member
Premium Subscriber
Joined
Jul 15, 2017
Messages
79
Location
Anderson, CA
I'm monitoring a Smartnet system with 2 SDR's with perfect results. I have the audio piped directly from the pi to speakers as well as being piped to BCFY using liquidsoap. I have blacklisted all talkgroups EXCEPT 1 for streaming to BCFY in order to meet their requirements, which is no problem.

What I'd like to know is it it's possible to listen to talkgroups other than the one I have whitelisted for BCFY, locally, through the speakers. I assume it would require another SDR to add another voice channel? But it doesn't seem like I could isolate that third SDR from the audio stream unless I could specify a different UDP port in the destination line in the json file for my system?

Any ideas or leads I could chase would be helpful, thank you!
 

wgbecks

Active Member
Joined
Jan 17, 2005
Messages
916
Location
NE Wisconsin
You have it correct. Add another SDR and Voice Channel using a separate UDP port for the new channel's destination then comes the fun part.
Are you by chance using Liquidsoap to stream the audio to BCFY for your feed? With liquidsoap you have some options available in that you can configure separates Input Ports and Output Ports (Streams or Audio Devices).

For you local speaker audio (single audio device) you could make it a stereo output using audio from the first voice channel as the left output and audio from the second voice channel as the right output. This give you local speaker audio from both channels as stereo. Alternatively, you could install Icecast and stream the second voice channel to the Icecast server whereby you connect to it using a media player on your LAN devices such as PC's, Tablets, WiFi Connected Cell Phones.

I'd be happy to lend a had to craft your op25.liq script. Just decide if you want/need local audio from both Smartnet voice channels or just from the second voice channel for private use. You can apply audio to the local speaker as well as to a private Icecast stream as well.

Feel free to PM me to establish an offline contact via email or telephone.

Bill
 

jschmall

Member
Premium Subscriber
Joined
Jul 15, 2017
Messages
79
Location
Anderson, CA
You have it correct. Add another SDR and Voice Channel using a separate UDP port for the new channel's destination then comes the fun part.
Are you by chance using Liquidsoap to stream the audio to BCFY for your feed? With liquidsoap you have some options available in that you can configure separates Input Ports and Output Ports (Streams or Audio Devices).

For you local speaker audio (single audio device) you could make it a stereo output using audio from the first voice channel as the left output and audio from the second voice channel as the right output. This give you local speaker audio from both channels as stereo. Alternatively, you could install Icecast and stream the second voice channel to the Icecast server whereby you connect to it using a media player on your LAN devices such as PC's, Tablets, WiFi Connected Cell Phones.

I'd be happy to lend a had to craft your op25.liq script. Just decide if you want/need local audio from both Smartnet voice channels or just from the second voice channel for private use. You can apply audio to the local speaker as well as to a private Icecast stream as well.

Feel free to PM me to establish an offline contact via email or telephone.

Bill
Bill,

I think I’m on the right path. I kind of assumed it would require a second SDR.

I am using liquidsoap. I figured that would be key to make this all work.

Thank your for the information, looks like it’s time to order my 4th SDR!

If I have any questions I will message you directly. Thanks again!
 

wgbecks

Active Member
Joined
Jan 17, 2005
Messages
916
Location
NE Wisconsin
Sounds good! I whipped up an example op25.liq script to accomplish sending one feed (channel) to BCFY, the other to an optional Icecast server to setup for private use while processing both channels (sources) into a stereo output to drive the local speaker.

I' am posting the script below, but I don't know how well the formatting will work out. Please feel free to PM me with your contact info and I will be glad to email you the the actual file. Good Luck!

Bill


Example (multi_channel.liq)

Code:
#!/usr/bin/liquidsoap

# Example liquidsoap streaming from op25 to icecast
# (c) 2019-2021 gnorbury@bondcar.com, wllmbecks@gmail.com
#

set("log.stdout", true)
set("log.file.path", "/home/pi/op25/op25/gr-op25_repeater/apps/liquidsoap.log")
set("log.file", true)
set("log.level", 2)


# Make the native sample rate compatible with op25
set("frame.audio.samplerate", 8000)

input_A = mksafe(input.external(buffer=0.25, channels=2, samplerate=8000, restart_on_error=false, "./audio.py -u 23450 -x 1.25 -s"))
input_B = mksafe(input.external(buffer=0.25, channels=2, samplerate=8000, restart_on_error=false, "./audio.py -u 23460 -x 1.25 -s"))

# Consider increasing the buffer value on slow systems such as RPi3. e.g. buffer=0.25
# Longer buffer results in less choppy audio but at the expense of increased latency.


# OPTIONAL AUDIO SIGNAL PROCESSING BLOCKS
# Uncomment to enable
#
# High pass filter
#input_A = filter.iir.butterworth.high(frequency = 200.0, order = 4, input_A)
#input_B = filter.iir.butterworth.high(frequency = 200.0, order = 4, input_B)

# Low pass filter
#input_A = filter.iir.butterworth.low(frequency = 3250.0, order = 4, input_A)
#input_B = filter.iir.butterworth.low(frequency = 3250.0, order = 4, input_B)

# Compand
input_A = compand(input_A, mu = 0.5)
input_B = compand(input_B, mu = 0.5)

# Process "Input_A" & "Input_B" into "Left" & "Right" channel components
left = audio_to_stereo(input_A)
left = stereo.pan(pan=1., input_A)

right = audio_to_stereo(input_B)
right = stereo.pan(pan=-1., input_B)

# Combine "Left" & "Right" channel components into stereo output to local speaker
speaker = mksafe(add(normalize=false, [left,right]))


# LOCAL AUDIO OUTPUT
# Uncomment the appropriate line below to enable local sound
#
# Default audio subsystem
#out (speaker)
#
# PulseAudio
#output.pulseaudio(speaker)
#
# ALSA
output.alsa(speaker)


# ICECAST STREAMING
# Uncomment to enable output to an icecast server
# Change the "host", "password", and "mount" strings appropriately first!
# For metadata to work properly, the host address given here MUST MATCH the address in op25's meta.json file
#

# Stream to broadcastify.com
output.icecast(%mp3(bitrate=16, samplerate=22050, stereo=false), description="op25", genre="Public Safety", url="", fallible=false,
icy_metadata="true", host="audiox.broadcastify.com", port=80, mount="BCFY_Mount, password="BCFY_Password",mean(input_A))

# Stream to local icecast server
output.icecast(%mp3(bitrate=16, samplerate=22050, stereo=false), description="op25", genre="Public Safety", url="", fallible=false,
icy_metadata="true", host="localhost", port=8000, mount="op25", password="hackme",mean(input_B))
 

jschmall

Member
Premium Subscriber
Joined
Jul 15, 2017
Messages
79
Location
Anderson, CA
Sounds good! I whipped up an example op25.liq script to accomplish sending one feed (channel) to BCFY, the other to an optional Icecast server to setup for private use while processing both channels (sources) into a stereo output to drive the local speaker.

I' am posting the script below, but I don't know how well the formatting will work out. Please feel free to PM me with your contact info and I will be glad to email you the the actual file. Good Luck!

Bill


Example (multi_channel.liq)

Code:
#!/usr/bin/liquidsoap

# Example liquidsoap streaming from op25 to icecast
# (c) 2019-2021 gnorbury@bondcar.com, wllmbecks@gmail.com
#

set("log.stdout", true)
set("log.file.path", "/home/pi/op25/op25/gr-op25_repeater/apps/liquidsoap.log")
set("log.file", true)
set("log.level", 2)


# Make the native sample rate compatible with op25
set("frame.audio.samplerate", 8000)

input_A = mksafe(input.external(buffer=0.25, channels=2, samplerate=8000, restart_on_error=false, "./audio.py -u 23450 -x 1.25 -s"))
input_B = mksafe(input.external(buffer=0.25, channels=2, samplerate=8000, restart_on_error=false, "./audio.py -u 23460 -x 1.25 -s"))

# Consider increasing the buffer value on slow systems such as RPi3. e.g. buffer=0.25
# Longer buffer results in less choppy audio but at the expense of increased latency.


# OPTIONAL AUDIO SIGNAL PROCESSING BLOCKS
# Uncomment to enable
#
# High pass filter
#input_A = filter.iir.butterworth.high(frequency = 200.0, order = 4, input_A)
#input_B = filter.iir.butterworth.high(frequency = 200.0, order = 4, input_B)

# Low pass filter
#input_A = filter.iir.butterworth.low(frequency = 3250.0, order = 4, input_A)
#input_B = filter.iir.butterworth.low(frequency = 3250.0, order = 4, input_B)

# Compand
input_A = compand(input_A, mu = 0.5)
input_B = compand(input_B, mu = 0.5)

# Process "Input_A" & "Input_B" into "Left" & "Right" channel components
left = audio_to_stereo(input_A)
left = stereo.pan(pan=1., input_A)

right = audio_to_stereo(input_B)
right = stereo.pan(pan=-1., input_B)

# Combine "Left" & "Right" channel components into stereo output to local speaker
speaker = mksafe(add(normalize=false, [left,right]))


# LOCAL AUDIO OUTPUT
# Uncomment the appropriate line below to enable local sound
#
# Default audio subsystem
#out (speaker)
#
# PulseAudio
#output.pulseaudio(speaker)
#
# ALSA
output.alsa(speaker)


# ICECAST STREAMING
# Uncomment to enable output to an icecast server
# Change the "host", "password", and "mount" strings appropriately first!
# For metadata to work properly, the host address given here MUST MATCH the address in op25's meta.json file
#

# Stream to broadcastify.com
output.icecast(%mp3(bitrate=16, samplerate=22050, stereo=false), description="op25", genre="Public Safety", url="", fallible=false,Ba
icy_metadata="true", host="audiox.broadcastify.com", port=80, mount="BCFY_Mount, password="BCFY_Password",mean(input_A))

# Stream to local icecast server
output.icecast(%mp3(bitrate=16, samplerate=22050, stereo=false), description="op25", genre="Public Safety", url="", fallible=false,
icy_metadata="true", host="localhost", port=8000, mount="op25", password="hackme",mean(input_B))
Bill,

Thank you so much for this! I really appreciate you taking time and putting this together for me. I will make a few modifications to match my system and implement this as soon as my SDR arrives.

I do have a separate question though. Since I'll be using liquidsoap to pipe audio to my speakers, should I disable/remove the audio instance from the json file for my system? Or does it really not matter?

Thanks again.
 

boatbod

Member
Joined
Mar 3, 2007
Messages
3,338
Location
Talbot Co, MD
I do have a separate question though. Since I'll be using liquidsoap to pipe audio to my speakers, should I disable/remove the audio instance from the json file for my system? Or does it really not matter?

If the sockaudio instance name is null ("") op25 will not start the internal player.
 

wgbecks

Active Member
Joined
Jan 17, 2005
Messages
916
Location
NE Wisconsin
Bill,

Thank you so much for this! I really appreciate you taking time and putting this together for me. I will make a few modifications to match my system and implement this as soon as my SDR arrives.

I do have a separate question though. Since I'll be using liquidsoap to pipe audio to my speakers, should I disable/remove the audio instance from the json file for my system? Or does it really not matter?

Thanks again.

See @boatbod Post #6 to disable the sockaudio instance in your json file.

Bill
 

dlchicago

Member
Feed Provider
Joined
May 31, 2007
Messages
25
Location
Chicago, IL
Sorry to butt in here! I have a similar setup - but was wondering how to send the metadata (alphatags) to my local stream. Is there a way to accomplish this?

In order to send metadata to broadcastify the meta.json file needs to match what's in the liq file in the output.icecast section...does the meta.json file allow for 2 outputs there?

I've tried using this:

Code:
{
    "icecastPass": "pass",
    "icecastMountpoint": "mount",
    "icecastServerAddress": "broadcastify URL",
    "delay": "0.0", "icecastMountExt": ".mp3",
    "meta_format_idle": "Scanning...",
    "meta_format_tgid": "[%TGID%]",
    "meta_format_tag":  "%TAG%"
},
{
    "icecastPass": "pass",
    "icecastMountpoint": "mount",
    "icecastServerAddress": "LOCAL IP",
    "delay": "0.0", "icecastMountExt": ".mp3",
    "meta_format_idle": "Scanning...",
    "meta_format_tgid": "[%TGID%]",
    "meta_format_tag":  "%TAG%"
}

But it throws an error...

Thank you in advance!
 

wgbecks

Active Member
Joined
Jan 17, 2005
Messages
916
Location
NE Wisconsin
Indeed you can send metatags from multi_rx.py but you first have to create a tag file who's file name is specified within the "Trunking" section
of your json file.

I'll have to assume that your voice channels destinations are being sent as UDP over to Liquidsoap for processing of the audio steams up to your BCFY mount points while you configure and use the icemeta.py streams associated with each of your voice channels to handle the transmission of your metatags.

With this bit of information, you should now be able to take another look at the example json files provided to see how it all comes together.
Note that it would be very helpful to post your entire json file should you come back to request additional help in debugging the metadata functionality in your configuration.

Bill
 

boatbod

Member
Joined
Mar 3, 2007
Messages
3,338
Location
Talbot Co, MD
Sorry to butt in here! I have a similar setup - but was wondering how to send the metadata (alphatags) to my local stream. Is there a way to accomplish this?

In order to send metadata to broadcastify the meta.json file needs to match what's in the liq file in the output.icecast section...does the meta.json file allow for 2 outputs there?

The stand-alone meta.json file is used only by rx.py. If you are using multi-rx.py, all the configuration goes in cfg.json with the exception of tgid_tags_file and rid_tags_file which can be specified as in the trunking section as noted by wgbecks. For the metadata you can define multiple stream instances and then refer to them by stream name from the channels section.
Code:
    "metadata": {
        "module": "icemeta.py",
        "streams": [
            {
                "stream_name": "stream0",
                "icecastServerAddress": "audio3.broadcastify.com:80",
                "icecastMountpoint": "aaaaaaaa",
                "icecastMountExt": ".xspf",
                "icecastPass": "xxxxxxxx",
                "delay": 0.0
            },
            {
                "stream_name": "stream1",
                "icecastServerAddress": "audio9.broadcastify.com:80",
                "icecastMountpoint": "bbbbbbbb",
                "icecastMountExt": ".xspf",
                "icecastPass": "xxxxxxxx",
                "delay": 0.0
            },
            {
                "stream_name": "stream2",
                "icecastServerAddress": "audio1.broadcastify.com:80",
                "icecastMountpoint": "cccccccc",
                "icecastMountExt": ".xspf",
                "icecastPass": "xxxxxxxx",
                "delay": 0.0
            }
        ]
    },
 

dlchicago

Member
Feed Provider
Joined
May 31, 2007
Messages
25
Location
Chicago, IL
Thanks wgbecks & boatbod!

I've read through and tried multi_rx.py but I think I am misunderstanding the logic there.

I've got a JSON file set up for multi_rx.py to use; I am trying to send the same stream to both broadcastify and to a local IP. I wasn't getting any audio and was only seeing metadata updates on broadcastify (but again, no audio).

Do you mind if I post my multi_rx.py here for you to take a peek at?

Thank you again!
 

wgbecks

Active Member
Joined
Jan 17, 2005
Messages
916
Location
NE Wisconsin
Thanks wgbecks & boatbod!

I've read through and tried multi_rx.py but I think I am misunderstanding the logic there.

I've got a JSON file set up for multi_rx.py to use; I am trying to send the same stream to both broadcastify and to a local IP. I wasn't getting any audio and was only seeing metadata updates on broadcastify (but again, no audio).

Do you mind if I post my multi_rx.py here for you to take a peek at?

Thank you again!
Sure, please post and explain exactly what you desire in terms of what goes to BCFY and what is intended for the local IP that we can better understand and make any suggestions after reviewing your json. Please also include a copy of your op25.liq file with the BCFY mount point and password removed or dummied for security.

Bill
 

jschmall

Member
Premium Subscriber
Joined
Jul 15, 2017
Messages
79
Location
Anderson, CA
Hate to bring up an old thread but I have a question for you Bill, am I able to tune two SDR's to the same talkgroup simultaneously? I'd like to stream 1 (and only that one) talkgroup to Broadcastify, which I currently am with no issues. I'd like to include that same talkgroup, in addition to more talkgroups, in a stream to my private Icecast server, that way I don't have to access 2 streams.

If it's possible to do with a liquidsoap config I will happily do it that way. I assume it would involve a mixer configuration of sorts?
 

wgbecks

Active Member
Joined
Jan 17, 2005
Messages
916
Location
NE Wisconsin
If I remember, you're monitoring a Smartnet system configured with a single voice channel. So, you can certainly configure another voice channel and stream it separately to your private Icecast server using it's own whitelist of TGID's, but it will mean that you'll have to add a third SDR. Of course, doing so will also increase the loading on CPU and USB resources. So, it will ultimately depend upon the capabilities of the specific hardware platform employed to run Smartnet.

Bill
 

jschmall

Member
Premium Subscriber
Joined
Jul 15, 2017
Messages
79
Location
Anderson, CA
If I remember, you're monitoring a Smartnet system configured with a single voice channel. So, you can certainly configure another voice channel and stream it separately to your private Icecast server using it's own whitelist of TGID's, but it will mean that you'll have to add a third SDR. Of course, doing so will also increase the loading on CPU and USB resources. So, it will ultimately depend upon the capabilities of the specific hardware platform employed to run Smartnet.

Bill
Yes I am monitoring a Smartnet system. I currently have 3 SDR’s, 1 for control, 1 for a single talkgroup (dedicated for BCFY) and 1 for the other talk groups I’m interested in. I’m hoping to combine the audio feeds, either at the multi-rx level, or at the liquidsoap level, to a single stream so I don’t have to monitor 2 streams when I’m monitoring.

Would it be helpful if I uploaded all of my relevant config files?
 

wgbecks

Active Member
Joined
Jan 17, 2005
Messages
916
Location
NE Wisconsin
Yes I am monitoring a Smartnet system. I currently have 3 SDR’s, 1 for control, 1 for a single talkgroup (dedicated for BCFY) and 1 for the other talk groups I’m interested in. I’m hoping to combine the audio feeds, either at the multi-rx level, or at the liquidsoap level, to a single stream so I don’t have to monitor 2 streams when I’m monitoring.

Would it be helpful if I uploaded all of my relevant config files?

Yes, it would be helpful to look at your configs. I have had good success configuring liquidsoap to process multiple audio channels in various combinations of streams and local speaker audio.
 

boatbod

Member
Joined
Mar 3, 2007
Messages
3,338
Location
Talbot Co, MD
Yes I am monitoring a Smartnet system. I currently have 3 SDR’s, 1 for control, 1 for a single talkgroup (dedicated for BCFY) and 1 for the other talk groups I’m interested in. I’m hoping to combine the audio feeds, either at the multi-rx level, or at the liquidsoap level, to a single stream so I don’t have to monitor 2 streams when I’m monitoring.
With 3 SDR and multi_rx in a smartnet environment you need 1 sdr dedicated to the control channel and 2 sdrs dedicated to voice decode. You'd then need two separate whitelist file - one linked to each of the two voice channels - with the associated tgids in them that you want to decode. Liquidsoap would run two streams, one for each voice channel.

There is unfortunately no way for liquidsoap to dissect a single stream based on metadata content. You can add streams together, but that doesn't save you much in terms of processing power since you'd still need 3 sdr devices.
 

jschmall

Member
Premium Subscriber
Joined
Jul 15, 2017
Messages
79
Location
Anderson, CA
Yes, it would be helpful to look at your configs. I have had good success configuring liquidsoap to process multiple audio channels in various combinations of streams and local speaker audio.
I am unable to attach files it appears so here's a link to my personal cloud server to download the files: rpd.zip

With 3 SDR and multi_rx in a smartnet environment you need 1 sdr dedicated to the control channel and 2 sdrs dedicated to voice decode. You'd then need two separate whitelist file - one linked to each of the two voice channels - with the associated tgids in them that you want to decode. Liquidsoap would run two streams, one for each voice channel.

There is unfortunately no way for liquidsoap to dissect a single stream based on metadata content. You can add streams together, but that doesn't save you much in terms of processing power since you'd still need 3 sdr devices.

I believe that's how I have things set up but it's only tuning to the one Talkgroup on the first SDR and not on the second even though it's whitelisted on both. Unless there's no way to tune a Talkgroup on BOTH voice SDR's?
 

boatbod

Member
Joined
Mar 3, 2007
Messages
3,338
Location
Talbot Co, MD
I am unable to attach files it appears so here's a link to my personal cloud server to download the files: rpd.zip
Thanks.
Looking at the .json I would recommend moving the UDP ports further apart (i.e. 23456 and 23466) because internally op25 uses ports in pairs regardless of whether you are listening to single or dual channel. Separating them by 10 is easy and guarantees they won't conflict.


I believe that's how I have things set up but it's only tuning to the one Talkgroup on the first SDR and not on the second even though it's whitelisted on both. Unless there's no way to tune a Talkgroup on BOTH voice SDR's?
I think you might run into a problem there. Internally the talkgroups dictionary object is shared among all receivers; one of the checks performed prior to assigning a receiver to a call in progress is to make ensure no other receiver is already assigned to that call. This works fine as long as you don't duplicate tgids across multiple whitelist files but it's not going to work as intended where you genuinely do want the same call decoded simultaneously. I will have to figure out how to address that without breaking something else.
 
Status
Not open for further replies.
Top