OP25 OP 25 multi_rx.py help

Status
Not open for further replies.
Joined
Sep 15, 2010
Messages
41
Ok, nevermind that last question.. I currently have two rtl-sdr's running with multi_rx...

I can hear audio but only from one channel.. Is there any way for me to listen to all channels simultaneously in order to verify that they are working? Also, Is there a way to configure two heads? Lastly, am I seeing that "fine tune" is not included in multi_rx?

Second lastly, how exactly do I run two instances of rx.py instead of multi?

-C
 

maus92

Member
Premium Subscriber
Joined
Jun 23, 2004
Messages
8,534
Location
OCMD
Ok, nevermind that last question.. I currently have two rtl-sdr's running with multi_rx...

I can hear audio but only from one channel.. Is there any way for me to listen to all channels simultaneously in order to verify that they are working? Also, Is there a way to configure two heads? Lastly, am I seeing that "fine tune" is not included in multi_rx?

Second lastly, how exactly do I run two instances of rx.py instead of multi?

-C
Wrt two instances of rx.py, two terminal windows?
 
Joined
Sep 15, 2010
Messages
41
Wrt two instances of rx.py, two terminal windows?
It's a bit more complex than that I suspect.. Different udp, different trunk files, different whitelist, etc...

What I'm having trouble with now is udp... I keep getting [Errno98] Address already in use

I'm able to specify the port number to listen on by using -u but I'm not sure why I keep getting this error... Maybe because I can't listen to two streams on the same audio device?
 
Joined
Sep 15, 2010
Messages
41
Here's the contents of stder

Using Python /usr/bin/python3
gr-osmosdr 0.2.0.0 (0.2.0) gnuradio 3.8.1.0
built-in source types: file osmosdr fcd rtl rtl_tcp uhd miri hackrf bladerf rfspace airspy airspyhf soapy redpitaya freesrp
Using device #1 Realtek RTL2838UHIDIR SN: 00000001
Found Rafael Micro R820T tuner
[R82XX] PLL not locked!
gain: name: LNA range: start 0 stop 0 step 0
setting gain lna to 36
supported sample rates 250000-2560000 step 24000
[R82XX] PLL not locked!
Using two-stage decimator for speed=960000, decim=10/4 if1=96000 if2=24000
op25_audio::eek:pen_socket(): enabled udp host(127.0.0.1), wireshark(23458), audio(23458)
p25_frame_assembler_impl: do_imbe[1], do_output[0], do_audio_output[1], do_phase2_tdma[1], do_nocrypt[1]
10/04/21 17:44:31.217269 Reading whitelist file
metadata update not enabled
using ALSA sound system
audio device: default
Listening on 127.0.0.1:23458
Traceback (most recent call last):
File "./rx.py", line 1074, in <module>
rx = rx_main()
File "./rx.py", line 980, in __init__
self.tb = p25_rx_block(self.options)
File "./rx.py", line 275, in __init__
self.audio = audio_thread("127.0.0.1", self.options.wireshark_port, self.options.audio_output, False, self.options.audio_gain)
File "/home/sezumaga/op25/op25/gr-op25_repeater/apps/sockaudio.py", line 545, in __init__
self.sock_audio = socket_audio(udp_host, udp_port, pcm_device, two_channels, audio_gain, dest_stdout, **kwds)
File "/home/sezumaga/op25/op25/gr-op25_repeater/apps/sockaudio.py", line 409, in __init__
self.setup_sockets(udp_host, udp_port)
File "/home/sezumaga/op25/op25/gr-op25_repeater/apps/sockaudio.py", line 509, in setup_sockets
self.sock_a.bind((udp_host, udp_port))
OSError: [Errno 98] Address already in use
 

maus92

Member
Premium Subscriber
Joined
Jun 23, 2004
Messages
8,534
Location
OCMD
It's a bit more complex than that I suspect.. Different udp, different trunk files, different whitelist, etc...

What I'm having trouble with now is udp... I keep getting [Errno98] Address already in use

I'm able to specify the port number to listen on by using -u but I'm not sure why I keep getting this error... Maybe because I can't listen to two streams on the same audio device?
Whitelist and trunk files can be named anything. What's the command line(s) look like?
 
Joined
Sep 15, 2010
Messages
41
Nope, correction values are set in the json config. You can fine tune manually.
Thanks...

This is the primary reason why I want to run multiple instances of rx.py instead of multi.. However, I want to be able to (listen) to the audio of all for channels for QC purposes. I think I can get the multiple instances running but if someone could post an example of what the commands need to look like and also, how I can listen to the audio of multiple channels that would help me a lot...

Code:
./rx.py --nocrypt --args "rtl=0" --gains 'lna:36' -S 960000 -X -q -0 -v 1 -2 -V -U -T north.tsv -u 23456 -l http:0.0.0.0:8081 2> stderrn.2

./rx.py --nocrypt --args "rtl=1" --gains 'lna:36' -S 960000 -X -q -0 -v 1 -2 -V -U -T central.tsv -u 23458 -l http:0.0.0.0:8083 2> stderrc.2

./rx.py --nocrypt --args "rtl=2" --gains 'lna:36' -S 960000 -X -q -0 -v 1 -2 -V -U -T west.tsv -u 23460 -l http:0.0.0.0:8085 2> stderrw.2

./rx.py --nocrypt --args "rtl=3" --gains 'lna:36' -S 960000 -X -q -0 -v 1 -2 -V -U -T south.tsv -u 23462 -l http:0.0.0.0:8087 2> stderrs.2

These would all be run from separate terminals obviously...

Alternatively, I would love to run multi_rx instead but I find that the audio is not quite as crisp as auto tune... Also, how do I listen to the audio for the other channels and how do I open a head via http for each... I'm so lost... I'm sorry...
 

boatbod

Member
Joined
Mar 3, 2007
Messages
3,539
Location
Talbot Co, MD
Hello again!

If I wanted to use multi_rx.py to test my configuration by sending audio from multiple rtls to the local speakers, would that be as simple as changing config.json "device_name" in "audio" "instances" from "pulse" to "ALSA" ?
If you have multiple RTLs supporting multiple 'channels' then presumably each channel has it's own UDP destination. For local audio to work properly you'll need multiple instances of the udp receiver (one for each channel) and all these can output via "pulse" or a sharable alsa device.

The following multi_rx configuration has 2 channels (running from a single Airspy) outputting local audio. It's from my test system running 24x7 on my laptop. The only time things get confusing is when both channels are talking simultaneously, but if you listen carefully it works!
Code:
{
    "channels": [
        {
            "name": "TB Fire", 
            "device": "sdr0",
            "trunking_sysname": "FiRST Talbot",
            "demod_type": "cqpsk", 
            "destination": "udp://127.0.0.1:23456", 
            "meta_stream_name": "",
            "#meta_stream_name": "stream1",
            "excess_bw": 0.2, 
            "filter_type": "rc", 
            "frequency": 773843750, 
            "if_rate": 24000, 
            "plot": "",
            "symbol_rate": 4800,
            "enable_analog": "off",
            "whitelist": "talbot-fire.wlist",
            "blacklist": ""
        },
        {
            "name": "DR Fire", 
            "device": "sdr0",
            "trunking_sysname": "FiRST Talbot",
            "demod_type": "cqpsk", 
            "destination": "udp://127.0.0.1:23466", 
            "meta_stream_name": "",
            "#meta_stream_name": "stream0",
            "excess_bw": 0.2, 
            "filter_type": "rc", 
            "frequency": 773843750, 
            "if_rate": 24000, 
            "plot": "",
            "symbol_rate": 4800,
            "enable_analog": "off",
            "blacklist": "",
            "whitelist": "dorc-fire.wlist"
        }
    ], 
    "devices": [
        {
            "args": "airspy", 
            "frequency": 772525000, 
            "gains": "LNA:15,MIX:15,IF:8", 
            "name": "sdr0", 
            "offset": 0, 
            "ppm": 0.429, 
            "usable_bw_pct": 0.85,
            "rate": 6000000, 
            "tunable": false
        }
    ],
    "trunking": {
        "module": "tk_p25.py",
        "chans": [
            {
                "nac": "0x4a6",
                "sysname": "FiRST Talbot",
                "control_channel_list": "773.84375",
                "whitelist": "",
                "tgid_tags_file": "first.tsv",
                "rid_tags_file": "first-rids.tsv",
                "tdma_cc": false,
                "crypt_behavior": 2
            }
        ]
    },
    "metadata": {
        "module": "icemeta.py",
        "streams": [
            {
                "stream_name": "stream0",
                "meta_format_idle": "[idle]",
                "meta_format_tgid": "[%TGID%]",
                "meta_format_tag":  "[%TGID%] %TAG%",
                "icecastServerAddress": "192.168.1.24:8000",
                "icecastMountpoint": "op25-0",
                "icecastMountExt": ".xspf",
                "icecastPass": "xxxxxx",
                "delay": 0.0
            },
            {
                "stream_name": "stream1",
                "icecastServerAddress": "192.168.1.24:8000",
                "icecastMountpoint": "op25-1",
                "icecastMountExt": ".xspf",
                "icecastPass": "xxxxxx",
                "delay": 0.0
            }
        ]
    },
    "audio": {
        "module": "sockaudio.py",
        "instances": [
            {
                "#instance_name": "",
                "instance_name": "audio0",
                "device_name": "pulse",
                "udp_port": 23456,
                "audio_gain": 1.0,
                "number_channels": 1
            },
            {
                "#instance_name": "",
                "instance_name": "audio1",
                "device_name": "pulse",
                "udp_port": 23466,
                "audio_gain": 1.0,
                "number_channels": 1
            }
        ]
    },
    "terminal": {
        "module": "terminal.py",
        "terminal_type": "curses",
        "curses_plot_interval": 0.1,
        "http_plot_interval": 1.0,
        "http_plot_directory": "../www/images",
        "tuning_step_large": 1200,
        "tuning_step_small": 100
    }
}
 
Joined
Sep 15, 2010
Messages
41
If you have multiple RTLs supporting multiple 'channels' then presumably each channel has it's own UDP destination. For local audio to work properly you'll need multiple instances of the udp receiver (one for each channel) and all these can output via "pulse" or a sharable alsa device.

The following multi_rx configuration has 2 channels (running from a single Airspy) outputting local audio. It's from my test system running 24x7 on my laptop. The only time things get confusing is when both channels are talking simultaneously, but if you listen carefully it works!
Thank you!

Does the json config use the trunk.tsv file in any capacity? I'm connecting to a system that is P25 Phase 2 Simulcast... Control channel can be any channel in the system..

This is what my json file looks like:

Code:
{
    "channels": [
        {
            "name": "MiamiPDNorth",
            "device": "sdr0",
            "trunking_sysname": "MiamiPD",
            "demod_type": "cqpsk",
            "destination": "udp://127.0.0.1:23456",
            "meta_stream_name": "",
            "excess_bw": 0.2,
            "filter_type": "rc",
            "frequency": 854962500,
            "if_rate": 24000,
            "plot": "",
            "symbol_rate": 4800,
            "enable_analog": "off",
            "blacklist": "",
            "whitelist": "north.wlist"
        },
        {
            "name": "MiamiPDCentral",
            "device": "sdr1",
            "trunking_sysname": "MiamiPD",
            "demod_type": "cqpsk",
            "destination": "udp://127.0.0.1:23466",
            "meta_stream_name": "",
            "excess_bw": 0.2,
            "filter_type": "rc",
            "frequency": 854962500,
            "if_rate": 24000,
            "plot": "",
            "symbol_rate": 4800,
            "enable_analog": "off",
            "blacklist": "",
            "whitelist": "central.wlist"
        }
    ],
    "devices": [
        {
            "args": "rtl=0",
            "frequency": 854962500,
            "gains": "LNA:36",
            "name": "sdr0",
            "offset": 0,
            "ppm": 0.0,
            "rate": 2000000,
            "tunable": true
        },
        {
            "args": "rtl=1",
            "frequency": 854962500,
            "gains": "LNA:36",
            "name": "sdr1",
            "offset": 0,
            "ppm": 5.0,
            "rate": 2000000,
            "tunable": true
        }
    ],
    "trunking": {
        "module": "tk_p25.py",
        "chans": [
            {
                "nac": "0xa",
                "sysname": "MiamiPD",
                "control_channel_list": "857.712500,854.962500,855.212500,855.462500,855.712500,856.212500,856.462500,856.712500,856.962500,857.462500,857.962500,858.212500,858.712500,858.962500,859.212500,859.462500,859.962500,860.212500,860.462500,860.712500",
                "whitelist": "",
                "tgid_tags_file": "00a_35358_talkgroups.tsv",
                "crypt_behavior": 2
            }
        ]
    },
    "metadata": {
        "module": "icemeta.py",
        "streams": [
            {
                "stream_name": "stream0",
                "icecastServerAddress": "stream_host1:80",
                "icecastMountpoint": "stream1",
                "icecastMountExt": ".xspf",
                "icecastPass": "passwd",
                "delay": 0.0
            },
            {
                "stream_name": "stream1",
                "icecastServerAddress": "stream_host2:80",
                "icecastMountpoint": "stream1",
                "icecastMountExt": ".xspf",
                "icecastPass": "passwd",
                "delay": 0.0
            }
        ]
    },
    "audio": {
        "module": "sockaudio.py",
        "instances": [
            {
                "instance_name": "audio1",
                "device_name": "pulse",
                "udp_port": 23456,
                "audio_gain": 1.0,
                "number_channels": 1
            },
            {
                "instance_name": "audio2",
                "device_name": "pulse",
                "udp_port": 23466,
                "audio_gain": 1.0,
                "number_channels": 1
            }
        ]
    },
    "terminal": {
        "module": "terminal.py",
        "terminal_type": "http:0.0.0.0:8080",
        "curses_plot_interval": 0.1,
        "http_plot_interval": 1.0,
        "http_plot_directory": "../www/images"
    }

I tried to reference trunk.tsv in control_channel_list to no avail..

[remember i'm a noob...]
 

boatbod

Member
Joined
Mar 3, 2007
Messages
3,539
Location
Talbot Co, MD
No, trunk.tsv is used by rx.py only. If you want to specify a list of possible control channels you would place them in the trunking section "control_channel_list" much as you have done here. They will be searched in order of appearance until a working CC is identified.
Code:
    "trunking": {
        "module": "tk_p25.py",
        "chans": [
            {
                "nac": "0xa",
                "sysname": "MiamiPD",
                "control_channel_list": "857.712500,854.962500,855.212500,855.462500,855.712500,856.212500,856.462500,856.712500,856.962500,857.462500,857.962500,858.212500,858.712500,858.962500,859.212500,859.462500,859.962500,860.212500,860.462500,860.712500",
                "whitelist": "",
                "tgid_tags_file": "00a_35358_talkgroups.tsv",
                "crypt_behavior": 2
            }
        ]
    },

At log level 5 (-v 5) you should see something similar to this as CC hunting takes place. 3 timeouts until it tunes the next freq.
Code:
10/05/21 07:23:12.615602 [0] set control channel=773.000000
python version detected: 3.8.10 (default, Jun  2 2021, 10:49:15) 
[GCC 9.4.0]
10/05/21 07:23:13.614707 [1] control channel timeout
10/05/21 07:23:13.616835 [0] control channel timeout
10/05/21 07:23:13.616956 [0] set control channel=773.000000
10/05/21 07:23:14.616822 [1] control channel timeout
10/05/21 07:23:14.617733 [0] control channel timeout
10/05/21 07:23:14.617821 [0] set control channel=773.000000
10/05/21 07:23:15.619737 [1] control channel timeout
10/05/21 07:23:15.621225 [0] control channel timeout
10/05/21 07:23:15.621258 [0] set control channel=774.000000
10/05/21 07:23:16.626094 [1] control channel timeout
10/05/21 07:23:16.626902 [0] control channel timeout
10/05/21 07:23:16.626974 [0] set control channel=774.000000
10/05/21 07:23:17.631101 [0] control channel timeout
10/05/21 07:23:17.631228 [0] set control channel=774.000000
10/05/21 07:23:17.631862 [1] control channel timeout
10/05/21 07:23:18.636590 [1] control channel timeout
10/05/21 07:23:18.637503 [0] control channel timeout
10/05/21 07:23:18.637589 [0] set control channel=773.843750
10/05/21 07:23:19.484850 [FiRST Talbot] set tgid=7557, srcaddr=0
10/05/21 07:23:19.485034 [FiRST Talbot] new freq=773.593750
10/05/21 07:23:19.485112 [FiRST Talbot] set tgid=8226, srcaddr=0
10/05/21 07:23:19.485166 [FiRST Talbot] new freq=771.718750
10/05/21 07:23:19.633094 [FiRST Talbot] set tgid=8226, srcaddr=0
10/05/21 07:23:19.649911 [1] control channel timeout
10/05/21 07:23:19.782033 [FiRST Talbot] set tgid=11541, srcaddr=0
10/05/21 07:23:19.782135 [FiRST Talbot] set tgid=7557, srcaddr=0
10/05/21 07:23:19.938860 [FiRST Talbot] set tgid=7557, srcaddr=0
10/05/21 07:23:19.939138 [FiRST Talbot] set tgid=8226, srcaddr=0
10/05/21 07:23:20.156735 [FiRST Talbot] set tgid=8226, srcaddr=0
 
Last edited:
Joined
Sep 15, 2010
Messages
41
No, trunk.tsv is used by rx.py only. If you want to specify a list of possible control channels you would place them in the trunking section "control_channel_list" much as you have done here. They will be searched in order of appearance until a working CC is identified.
Yep! Seems about right… Thanks again!

I’m getting closer and closer to my goal here.. The next thing I need to figure out is how to grab each independent audio stream and make it an independent audio source in OBS Studio.

I haven’t given this a go yet as I am still familiarizing myself with pulse… Do you foresee any issues here? Also, is it absolutely necessary that the audio sent to pulse has to be routed to the pc speakers or can it just sit there in pulse waiting for me to pick it up as a source in OBS? The idea being that I can then choose which of these sources to “monitor” by using the audio mixer in OBS Studio. Is this the correct approach or should I be tapping these audio source before they hit pulse?

While we’re on a completely unrelated topic to the purpose of this thread, I’d like to learn more about the built-in, experimental tone detection algorithms for op25. Can you point me to a good resource for this? I want to be able to have tone-detector listen for a 1000Hz audio tone that lasts more than a certain amount of milliseconds, say 300ms. When it does “hear” this tone I would like to fire off another python script which I have already written. This script simply posts a message to a telegram channel notifying of the tone.

Your thoughts?

If you’d like to know more about the project I’m working on, just DM me. I don’t want to clutter up this thread with unrelated posts..

Again, thank you so much! I really appreciate you very very much!
 

boatbod

Member
Joined
Mar 3, 2007
Messages
3,539
Location
Talbot Co, MD
Yep! Seems about right… Thanks again!

I’m getting closer and closer to my goal here.. The next thing I need to figure out is how to grab each independent audio stream and make it an independent audio source in OBS Studio.

I haven’t given this a go yet as I am still familiarizing myself with pulse… Do you foresee any issues here? Also, is it absolutely necessary that the audio sent to pulse has to be routed to the pc speakers or can it just sit there in pulse waiting for me to pick it up as a source in OBS? The idea being that I can then choose which of these sources to “monitor” by using the audio mixer in OBS Studio. Is this the correct approach or should I be tapping these audio source before they hit pulse?
I'm not familiar with OBS Studio, but there are ways of integrating op25 with liquidsoap (savonet), which seems like a similar streaming application. If you can find a way to make OBY accept raw pcm data from stdin then there is a way to use the audio.py tool to receive the stream from op25 and pass it on to OBS. DM me and we can talk about this more offline.
While we’re on a completely unrelated topic to the purpose of this thread, I’d like to learn more about the built-in, experimental tone detection algorithms for op25. Can you point me to a good resource for this? I want to be able to have tone-detector listen for a 1000Hz audio tone that lasts more than a certain amount of milliseconds, say 300ms. When it does “hear” this tone I would like to fire off another python script which I have already written. This script simply posts a message to a telegram channel notifying of the tone.
Boatbod op25 does not have any native tone detection but it does have TDMA tone reproduction. (FDMA tones are sent as encoded audio, TDMA tones are sent in special tone frames that have to be turned into sine waves for playback). I've occasionally toyed with the idea of implementing a Minitor style tone detector in the codec but haven't got around to it yet. Conceivably you might be able to pass op25's decoded audio through the Two Tone Detect app as an adjunct.
 
Joined
Sep 15, 2010
Messages
41
I'm not familiar with OBS Studio, but there are ways of integrating op25 with liquidsoap (savonet), which seems like a similar streaming application. If you can find a way to make OBY accept raw pcm data from stdin then there is a way to use the audio.py tool to receive the stream from op25 and pass it on to OBS. DM me and we can talk about this more offline.

Boatbod op25 does not have any native tone detection but it does have TDMA tone reproduction. (FDMA tones are sent as encoded audio, TDMA tones are sent in special tone frames that have to be turned into sine waves for playback). I've occasionally toyed with the idea of implementing a Minitor style tone detector in the codec but haven't got around to it yet. Conceivably you might be able to pass op25's decoded audio through the Two Tone Detect app as an adjunct.
I'll look into adjunct... I'm also messing with qjackctl to see iff i can route audio that way.

I do have one more question for now..

I have all four of my rtl's installed and working as far as being recognized and such, however, when I run multi_rx, I'm getting an error..

* * * Channel 'MiamiPDWest' cannot share a tunable device - ignoring!
* * * Channel 'MiamiPDSouth' cannot share a tunable device - ignoring!

I feel like I've gone over the config file but I'm obviously missing something... Can you take a quick look at this?

Code:
{
    "channels": [
        {
            "name": "MiamiPDNorth",
            "device": "sdr0",
            "trunking_sysname": "MiamiPD",
            "demod_type": "cqpsk",
            "destination": "udp://127.0.0.1:23456",
            "meta_stream_name": "",
            "excess_bw": 0.2,
            "filter_type": "rc",
            "frequency": 854962500,
            "if_rate": 24000,
            "plot": "",
            "symbol_rate": 4800,
            "enable_analog": "off",
            "blacklist": "",
            "whitelist": "north.wlist"
        },
        {
            "name": "MiamiPDCentral",
            "device": "sdr1",
            "trunking_sysname": "MiamiPD",
            "demod_type": "cqpsk",
            "destination": "udp://127.0.0.1:23466",
            "meta_stream_name": "",
            "excess_bw": 0.2,
            "filter_type": "rc",
            "frequency": 854962500,
            "if_rate": 24000,
            "plot": "",
            "symbol_rate": 4800,
            "enable_analog": "off",
            "blacklist": "",
            "whitelist": "central.wlist"
        },
        {
            "name": "MiamiPDWest",
            "device": "sdr2",
            "trunking_sysname": "MiamiPD",
            "demod_type": "cqpsk",
            "destination": "udp://127.0.0.1:23476",
            "meta_stream_name": "",
            "excess_bw": 0.2,
            "filter_type": "rc",
            "frequency": 854962500,
            "if_rate": 24000,
            "plot": "",
            "symbol_rate": 4800,
            "enable_analog": "off",
            "blacklist": "",
            "whitelist": "west.wlist"
        },
        {
            "name": "MiamiPDSouth",
            "device": "sdr3",
            "trunking_sysname": "MiamiPD",
            "demod_type": "cqpsk",
            "destination": "udp://127.0.0.1:23486",
            "meta_stream_name": "",
            "excess_bw": 0.2,
            "filter_type": "rc",
            "frequency": 854962500,
            "if_rate": 24000,
            "plot": "",
            "symbol_rate": 4800,
            "enable_analog": "off",
            "blacklist": "",
            "whitelist": "south.wlist"
        }
    ],
    "devices": [
        {
            "args": "rtl=0",
            "frequency": 854962500,
            "gains": "LNA:36",
            "name": "sdr0",
            "offset": 0,
            "ppm": -1.185,
            "rate": 1000000,
            "tunable": true
        },
        {
            "args": "rtl=1",
            "frequency": 854962500,
            "gains": "LNA:36",
            "name": "sdr0",
            "offset": 0,
            "ppm": -0.169,
            "rate": 1000000,
            "tunable": true
        },
        {
            "args": "rtl=2",
            "frequency": 854962500,
            "gains": "LNA:36",
            "name": "sdr0",
            "offset": 0,
            "ppm": -0.169,
            "rate": 1000000,
            "tunable": true
        },
        {
            "args": "rtl=3",
            "frequency": 854962500,
            "gains": "LNA:36",
            "name": "sdr0",
            "offset": 0,
            "ppm": -0.169,
            "rate": 1000000,
            "tunable": true
        }
    ],
    "trunking": {
        "module": "tk_p25.py",
        "chans": [
            {
                "nac": "0xa",
                "sysname": "MiamiPD",
                "control_channel_list": "857.712500,854.962500,855.212500,855.462500,855.712500,856.212500,856.462500,856.712500,856.962500,857.462500,857.962500,858.212500,858.712500,858.962500,859.212500,859.462500,859.962500,860.212500,860.462500,860.712500",
                "whitelist": "",
                "tgid_tags_file": "00a_35358_talkgroups.tsv",
                "crypt_behavior": 2
            }
        ]
    },
    "metadata": {
        "module": "icemeta.py",
        "streams": [
            {
                "stream_name": "stream0",
                "icecastServerAddress": "stream_host1:80",
                "icecastMountpoint": "stream1",
                "icecastMountExt": ".xspf",
                "icecastPass": "passwd",
                "delay": 0.0
            },
            {
                "stream_name": "stream1",
                "icecastServerAddress": "stream_host2:80",
                "icecastMountpoint": "stream1",
                "icecastMountExt": ".xspf",
                "icecastPass": "passwd",
                "delay": 0.0
            },
            {
                "stream_name": "stream2",
                "icecastServerAddress": "stream_host3:80",
                "icecastMountpoint": "stream1",
                "icecastMountExt": ".xspf",
                "icecastPass": "passwd",
                "delay": 0.0
            },
            {
                "stream_name": "stream3",
                "icecastServerAddress": "stream_host4:80",
                "icecastMountpoint": "stream1",
                "icecastMountExt": ".xspf",
                "icecastPass": "passwd",
                "delay": 0.0
            }
        ]
    },
    "audio": {
        "module": "sockaudio.py",
        "instances": [
            {
                "instance_name": "audio1",
                "device_name": "pulse",
                "udp_port": 23456,
                "audio_gain": 0.2,
                "number_channels": 1
            },
            {
                "instance_name": "audio2",
                "device_name": "pulse",
                "udp_port": 23466,
                "audio_gain": 0.2,
                "number_channels": 1
            },
            {
                "instance_name": "audio3",
                "device_name": "pulse",
                "udp_port": 23476,
                "audio_gain": 0.2,
                "number_channels": 1
            },
            {
                "instance_name": "audio4",
                "device_name": "pulse",
                "udp_port": 23486,
                "audio_gain": 0.2,
                "number_channels": 1
            }
        ] 
    },
    
    "terminal": {
        "module": "terminal.py",
        "terminal_type": "http:0.0.0.0:8080",
        "curses_plot_interval": 0.1,
        "http_plot_interval": 1.0,
        "http_plot_directory": "../www/images"
    }
}
 

boatbod

Member
Joined
Mar 3, 2007
Messages
3,539
Location
Talbot Co, MD
Never mind.. I see it now...
In the Devices section each sdr needs it's own unique "name", and then each Channel needs to be assigned to a unique "device".
It is possible to have channels share a device, but only when the device is parked on a specific frequency and tunable=False. Practically this only works for wider bandwidth receivers which can cover an entire system's frequency range.
 
Joined
Sep 15, 2010
Messages
41
In the Devices section each sdr needs it's own unique "name", and then each Channel needs to be assigned to a unique "device".
It is possible to have channels share a device, but only when the device is parked on a specific frequency and tunable=False. Practically this only works for wider bandwidth receivers which can cover an entire system's frequency range.

Noted.. And thank you again..

BTW, I solved my audio problem by creating 4 null-sinks using pulseaudio.. I then "move" the sinks from OP25 to these new ones and done!

You basically just get the sink numbers by doing:

Code:
pacmd list-sink-inputs

after running multi_rx.py...

Then you create as many sinks as you need using:

Code:
pactl load-module module-null-sink sink_name=north sink_properties=device.description="north"
pactl load-module module-null-sink sink_name=central sink_properties=device.description="central"

Where "north" or "central" are whatever you want to call your new sinks.. Use sink properties and description at the end of the line to give each of your new sinks a distinct name, otherwise they all just show up as "null" in pulseaudio...

From there you just move your audio inputs to your new sinks using:

Code:
pactl move-sink-input $INDEX north
pactl move-sink-input $INDEX central

Where $INDEX is the index number you got from list-sink-inputs in the first step...
 
Joined
Sep 15, 2010
Messages
41
There is one thing that I need to figure out... The autotune / offset feature in rx.py is so wonderful at handling variances that it borders on perfection... Statically setting these values in multi_rx.py is not quite as great. Don't get me wrong, it works well enough but it simply doesn't match up with the quality observed with auto fine tune..

Is there a way that I can get the best of both worlds here? Been scratching my head about this for a few days now.
 
Joined
Sep 15, 2010
Messages
41
There is one thing that I need to figure out... The autotune / offset feature in rx.py is so wonderful at handling variances that it borders on perfection... Statically setting these values in multi_rx.py is not quite as great. Don't get me wrong, it works well enough but it simply doesn't match up with the quality observed with auto fine tune..

Is there a way that I can get the best of both worlds here? Been scratching my head about this for a few days now.

Well, I've got that working as well...

Basically all one has to do is structure the rx.py arguments properly and that's all folks!

What I did was create a variant of the op25.sh (op251, 252, 253, etc..) to suit each channel need and then I run them in separate shells.

The command with args looks like this for me..

Code:
./rx.py --nocrypt --args "rtl=2" --gains 'lna:36' -S 960000 -X -q -0 -v 1 -2 -V -U -w -W 127.0.0.1 -u 23476 -g 0.8 -T trunk5.tsv -l http:0.0.0.0:8085 2> stderr.2

Important the you change the rtl, -u [port] and -l host port values it would seem.. Now I've got the best of both worlds!! ;)

I do have another question as it pertains to audio though.. Is there a way to assign a name to the audio channel that is created? Currently, each new audio channel has "ALSA Playback" assigned to it, making it confusing which one is which..

I was looking within the rx.py script and I can see where the audio structuring takes place but it is not clear to me how the name property is set. I'm assuming this is because the name property is not set here?

Any guidance would be greatly appreciated.
 
Status
Not open for further replies.
Top