SDRPLAY linux commandline tools?

Add useful snippets of code or links to entire SDR projects.
0815
Posts: 45
Joined: Sat Jan 30, 2016 3:07 pm

Re: SDRPLAY linux commandline tools?

Post by 0815 » Fri Mar 11, 2016 6:44 pm

well, i do not see that the rsp is initializing....

do a sudo cp play_sdr /usr/bin

and give it a try again.

if not working try to

play_sdr -s 2400000 -f 89.3 -g 50 -

if working you should see a lot of ASCII in the display which means it works but i think the above should to its job....
Last edited by 0815 on Thu Jan 01, 1970 12:00 am, edited 0 times in total.
Reason: No reason

sdrplay
Posts: 978
Joined: Wed Jan 07, 2015 7:58 am

Re: SDRPLAY linux commandline tools?

Post by sdrplay » Fri Mar 11, 2016 7:20 pm

I just checked the code and forgot that I use 78-gain to produce the gain reduction value for the RSP.

So you are actually applying a gain value - if you needed a lower value then you are probably overloading the RSP.

Best regards,

SDRplay Support
Last edited by sdrplay on Thu Jan 01, 1970 12:00 am, edited 0 times in total.
Reason: No reason

IW2DHW
Posts: 59
Joined: Wed Sep 23, 2015 7:33 pm

Re: SDRPLAY linux commandline tools?

Post by IW2DHW » Fri Mar 11, 2016 7:38 pm

Please give me some info.

I am using a frequency of 89.3 MHz, so gain table is table at point 5.3 of API documentation, valid from 60 to 120 MHz
There are 102 values for gain reduction in this table. In your code, calling mir_sdr_Init, the first parameter is 78-gain.

So, using a gain value of 10 I use a gain reduction of 68 and, using a gain of 40, a gain reduction of 38?
This make sense. With CubicSDR I use a gain reduction of 50-70.
Using this code, how can I use a gain reduction greater of 78?

Can we do a test on frequency and use a "gain reduction" of 102-gain if freq in less than 420 MHz and 85-gain for greater freq.?

Is this correct?

Regards
Franco Spinelli
IW2DHW
Last edited by IW2DHW on Thu Jan 01, 1970 12:00 am, edited 0 times in total.
Reason: No reason

sdrplay
Posts: 978
Joined: Wed Jan 07, 2015 7:58 am

Re: SDRPLAY linux commandline tools?

Post by sdrplay » Fri Mar 11, 2016 8:56 pm

The RTL device has about 50dB of gain so as a rough approximation I just threw in 78-gain to get something working without having to specifically work in gain reduction.

The gain reduction is different in different bands, so that's why I stuck with 78. The LNA switching also affects the overall system gain reduction, again I didn't really take that into account to get something quickly working.

If this is something that is going to be used and the decoding is working correctly, then a better gain implementation needs to be coded.

I'll leave the current coarse gain reduction calculation as the default, but I'll add two new command line options...

-R = RSP Mode (interprets -g as gain reduction in dB)
-L = LNA (1 = on / 0 = off)

Best regards,

SDRplay Support
Last edited by sdrplay on Thu Jan 01, 1970 12:00 am, edited 0 times in total.
Reason: No reason

0815
Posts: 45
Joined: Sat Jan 30, 2016 3:07 pm

Re: SDRPLAY linux commandline tools?

Post by 0815 » Sat Mar 12, 2016 7:51 am

@sdrplay,

all functions on the rtl_sdr libary are demending on this:

rtlsdr_read_async(dev, rtlsdr_callback, (void *)(NULL),
DEFAULT_ASYNC_BUF_NUMBER,
DEFAULT_BUF_LENGTH);

please let me know how i can change it to use the callback function, in playsdr you are not using as you coded the file output directly, but for rtl_fm and rtl_adsb or dump 1090 and so on it would be great to have a workaround.

thanks in advance!

regards
Last edited by 0815 on Thu Jan 01, 1970 12:00 am, edited 0 times in total.
Reason: No reason

rgood123
Posts: 15
Joined: Fri Dec 18, 2015 9:55 pm

Re: SDRPLAY linux commandline tools?

Post by rgood123 » Sat Mar 12, 2016 4:20 pm

Hi to all.
examples-master has no installion instructions ,followed all post above.
As root compiled "CSDR"
than copied play_sdr.c to /usr/bin/.

root termial csdr-fm 89.3 40 works with rtl_sdr but when i change
rtl_sdr to play_sdr i get play_sdr: command not found.
Help What did i miss ? how about a HOW To
Thank You for you help.

user# csdr-fm 89.3 40
fir_decimate_cc: taps_length = 79
deemphasis_wfm_ff: tau = 5e-05, sample_rate = 48000
fractional_decimator_ff: window = HAMMING
fractional_decimator_ff: taps_length = 133
Found 2 device(s):
0: Realtek, RTL2838UHIDIR, SN: 00000001
1: Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM
MPlayer2 2.0-728-g2c378c7-4+b1 (C) 2000-2012 MPlayer Team
Cannot open file '/root/.mplayer/input.conf': No such file or directory
Failed to open /root/.mplayer/input.conf.
Cannot open file '/etc/mplayer/input.conf': No such file or directory
Failed to open /etc/mplayer/input.conf.

Playing -.
Reading from stdin...
Cache size set to 1024 KiB
Cache fill: 0.00% (0 bytes) Found Rafael Micro R820T tuner
Cache fill: 0.00% (0 bytes) [R82XX] PLL not locked!
Sampling at 2400000 S/s.
Cache fill: 0.00% (0 bytes) Tuned to 89300000 Hz.
Tuner gain set to 40.20 dB.
Reading samples in async mode...
Cache fill: 18.36% (192512 bytes)
Detected file format: rawaudio
Load subtitles in .
Cache not responding!
Selected audio codec: Uncompressed PCM [pcm]
AUDIO: 48000 Hz, 1 ch, s16le, 768.0 kbit/100.00% (ratio: 96000->96000)
AO: [pulse] 48000Hz 1ch s16le (2 bytes per sample)
Video: no video
Starting playback...
========================================================================

user# play_sdr -fm 89.3 40
bash: play_sdr: command not found
Last edited by rgood123 on Thu Jan 01, 1970 12:00 am, edited 0 times in total.
Reason: No reason

0815
Posts: 45
Joined: Sat Jan 30, 2016 3:07 pm

Re: SDRPLAY linux commandline tools?

Post by 0815 » Sun Mar 13, 2016 5:20 am

you have to compile play_sdr.c first:

Makefile:

Code: Select all

CFLAGS?=-O2 -g -Wall -W
LDLIBS+= -lpthread -lm -lmirsdrapi-rsp
CC?=gcc
PROGNAME=play_sdr

all: play_sdr

%.o: %.c
   $(CC) $(CFLAGS) -c $<

play_sdr: play_sdr.o
   $(CC) -g -o play_sdr play_sdr.o $(LDFLAGS) $(LDLIBS)

clean:
   rm -f *.o play_sdr
copypaste this code into "Makefile" where Makefile has to be in the same folder as your sdr_play.c
then type into console at the directory where both files are "make"
then it should run through, with warnings but no errors -> check it by typing "ls" and you should have a green file named play_sdr which is executable now and which you can copy to/usr/bin
Last edited by 0815 on Thu Jan 01, 1970 12:00 am, edited 0 times in total.
Reason: No reason

0815
Posts: 45
Joined: Sat Jan 30, 2016 3:07 pm

Re: SDRPLAY linux commandline tools?

Post by 0815 » Sun Mar 13, 2016 6:31 pm

well i have tried a lot of hours to get a working function equal to rtlsdr_read_async but it wont work. mainly i get memory overflows and so on, i cant get the RAW IQ Data into rtlsdrcallback....

simmilar to this

Code: Select all

rtlsdr_read_async(Modes.dev, rtlsdrCallback, NULL,
                              MODES_ASYNC_BUF_NUMBER,
                              MODES_DATA_LEN);

Code: Select all

int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx,
			  uint32_t buf_num, uint32_t buf_len)
{
	unsigned int i;
	int r = 0;
	struct timeval tv = { 1, 0 };
	struct timeval zerotv = { 0, 0 };
	enum rtlsdr_async_status next_status = RTLSDR_INACTIVE;

	if (!dev)
		return -1;

	if (RTLSDR_INACTIVE != dev->async_status)
		return -2;

	dev->async_status = RTLSDR_RUNNING;
	dev->async_cancel = 0;

	dev->cb = cb;
	dev->cb_ctx = ctx;

	if (buf_num > 0)
		dev->xfer_buf_num = buf_num;
	else
		dev->xfer_buf_num = DEFAULT_BUF_NUMBER;

	if (buf_len > 0 && buf_len % 512 == 0) /* len must be multiple of 512 */
		dev->xfer_buf_len = buf_len;
	else
		dev->xfer_buf_len = DEFAULT_BUF_LENGTH;

	_rtlsdr_alloc_async_buffers(dev);

	for(i = 0; i < dev->xfer_buf_num; ++i) {
		libusb_fill_bulk_transfer(dev->xfer[i],
					  dev->devh,
					  0x81,
					  dev->xfer_buf[i],
					  dev->xfer_buf_len,
					  _libusb_callback,
					  (void *)dev,
					  BULK_TIMEOUT);

		r = libusb_submit_transfer(dev->xfer[i]);
		if (r < 0) {
			fprintf(stderr, "Failed to submit transfer %i!\n", i);
			dev->async_status = RTLSDR_CANCELING;
			break;
		}
	}

	while (RTLSDR_INACTIVE != dev->async_status) {
		r = libusb_handle_events_timeout_completed(dev->ctx, &tv,
							   &dev->async_cancel);
		if (r < 0) {
			/*fprintf(stderr, "handle_events returned: %d\n", r);*/
			if (r == LIBUSB_ERROR_INTERRUPTED) /* stray signal */
				continue;
			break;
		}

		if (RTLSDR_CANCELING == dev->async_status) {
			next_status = RTLSDR_INACTIVE;

			if (!dev->xfer)
				break;

			for(i = 0; i < dev->xfer_buf_num; ++i) {
				if (!dev->xfer[i])
					continue;

				if (LIBUSB_TRANSFER_CANCELLED !=
						dev->xfer[i]->status) {
					r = libusb_cancel_transfer(dev->xfer[i]);
					/* handle events after canceling
					 * to allow transfer status to
					 * propagate */
					libusb_handle_events_timeout_completed(dev->ctx,
									       &zerotv, NULL);
					if (r < 0)
						continue;

					next_status = RTLSDR_CANCELING;
				}
			}

			if (dev->dev_lost || RTLSDR_INACTIVE == next_status) {
				/* handle any events that still need to
				 * be handled before exiting after we
				 * just cancelled all transfers */
				libusb_handle_events_timeout_completed(dev->ctx,
								       &zerotv, NULL);
				break;
			}
		}
	}

	_rtlsdr_free_async_buffers(dev);

	dev->async_status = next_status;

	return r;
}
i wrote an extra function for collecting and converting the IQ but it fails.

would be great if we had a function like this so that the rtl_sdr source can be used, in my case for adsb
regards
Last edited by 0815 on Thu Jan 01, 1970 12:00 am, edited 0 times in total.
Reason: No reason

Bill_C
Posts: 3
Joined: Tue Mar 15, 2016 1:38 am

Re: SDRPLAY linux commandline tools?

Post by Bill_C » Tue Mar 15, 2016 6:08 am

I'm also keen to get a command line utility for data storage to a binary file. Both RTL dongles and USRPs come with these utility functions.

I tried the rawIQ code provided above, with some minimal changes of writing 16 bit data samples to a file. (I don't want to truncate the samples to 8 bits -- the greater precision is one of the main benefits of this receiver compared to the RTLs!) It works fine up to about 40 packets, then I get a segmentation fault. If I run it with sudo ( eg "sudo ./rawIQ -g 40 -s 2 -b 1.536 -f 432.5") then it runs for a few hundred packets before crashing with a seg fault. By the way, the data seems fine -- I've used Octave to look at the power spectrum of the local 70 cm beacon from the above command and it is what we expect.

I also tried the play_sdr example code. It compiles under Ubuntu with various warnings. This code only collects a few hundred bytes of data, exiting with a "short read, samples lost" message.

I built cubicSDR for this system and that seems to run well. Any suggestions for getting command-line data collection working would be appreciated.

Bill
Last edited by Bill_C on Thu Jan 01, 1970 12:00 am, edited 0 times in total.
Reason: No reason

0815
Posts: 45
Joined: Sat Jan 30, 2016 3:07 pm

Re: SDRPLAY linux commandline tools?

Post by 0815 » Tue Mar 15, 2016 10:11 am

try this one for 16bit - and forget about the -b option!!

rawIQ:

Code: Select all

/*
 * rtl-sdr, turns your Realtek RTL2832 based DVB dongle into a SDR receiver
 * Copyright (C) 2012 by Steve Markgraf <steve@steve-m.de>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdint.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#ifndef _WIN32
#include <unistd.h>
#include "mirsdrapi-rsp.h"
#else
#include <windows.h>
#include <io.h>
#include <fcntl.h>
#include "getopt/getopt.h"
#include "mir_sdr.h"
#endif

#define DEFAULT_SAMPLE_RATE     2048000
#define DEFAULT_BUF_LENGTH      (336 * 2) // (16 * 16384)
#define MINIMAL_BUF_LENGTH      672 // 512
#define MAXIMAL_BUF_LENGTH      (256 * 16384)

static int do_exit = 0;
static uint32_t bytes_to_read = 0;

short *ibuf;
short *qbuf;
unsigned int firstSample;
int samplesPerPacket, grChanged, fsChanged, rfChanged;

double atofs(char *s)
/* standard suffixes */
{
    char last;
    int len;
    double suff = 1.0;
    len = strlen(s);
    last = s[len-1];
    s[len-1] = '\0';
    switch (last) {
        case 'g':
        case 'G':
            suff *= 1e3;
        case 'm':
        case 'M':
            suff *= 1e3;
        case 'k':
        case 'K':
            suff *= 1e3;
            suff *= atof(s);
            s[len-1] = last;
            return suff;
    }
    s[len-1] = last;
    return atof(s);
}

void usage(void)
{
    fprintf(stderr,
        "play_sdr, an I/Q recorder for SDRplay RSP receivers\n\n"
        "Usage:\t -f frequency_to_tune_to [Hz]\n"
        "\t[-s samplerate (default: 2048000 Hz)]\n"
        "\t[-g gain (default: 50)]\n"
        "\t[-ppm correct ppm errorvalue\n"
        "\t[-n number of samples to read (default: 0, infinite)]\n"
        "\tfilename (a '-' dumps samples to stdout)\n\n");
    exit(1);
}

#ifdef _WIN32
BOOL WINAPI
sighandler(int signum)
{
    if (CTRL_C_EVENT == signum) {
        fprintf(stderr, "Signal caught, exiting!\n");
        do_exit = 1;
        rtlsdr_cancel_async(dev);
        return TRUE;
    }
    return FALSE;
}
#else
static void sighandler(int signum)
{
    fprintf(stderr, "Signal caught, exiting!\n");
    do_exit = 1;
    mir_sdr_Uninit();
}
#endif


int main(int argc, char **argv)
{
#ifndef _WIN32
    struct sigaction sigact;
#endif
    char *filename = NULL;
    int n_read;
    mir_sdr_ErrT r;
    int opt;
    int gain = 50;
    int ppm_error = 0;
    FILE *file;
    short *buffer;
    uint32_t frequency = 100000000;
    uint32_t samp_rate = DEFAULT_SAMPLE_RATE;
    uint32_t out_block_size = DEFAULT_BUF_LENGTH;
    int i, j;

    while ((opt = getopt(argc, argv, "d:f:g:s:b:n:p:S")) != -1) {
        switch (opt) {
        case 'f':
            frequency = (uint32_t)atofs(optarg);
            break;
        case 'g':
            gain = (int)atof(optarg);
            break;
        case 's':
            samp_rate = (uint32_t)atofs(optarg);
            break;
//      case 'b':
//          out_block_size = (uint32_t)atof(optarg);
//          break;
        case 'n':
            bytes_to_read = (uint32_t)atofs(optarg) * 2;
            break;
        default:
            usage();
            break;
        }
    }

    if (argc <= optind) {
        usage();
    } else {
        filename = argv[optind];
    }

    if(out_block_size < MINIMAL_BUF_LENGTH ||
       out_block_size > MAXIMAL_BUF_LENGTH ){
        fprintf(stderr,
            "Output block size wrong value, falling back to default\n");
        fprintf(stderr,
            "Minimal length: %u\n", MINIMAL_BUF_LENGTH);
        fprintf(stderr,
            "Maximal length: %u\n", MAXIMAL_BUF_LENGTH);
        out_block_size = DEFAULT_BUF_LENGTH;
    }

    buffer = malloc(out_block_size * sizeof(short));

    r = mir_sdr_Init(40, 2.0, 100.00, mir_sdr_BW_1_536, mir_sdr_IF_Zero,
                        &samplesPerPacket);
    if (r != mir_sdr_Success) {
        fprintf(stderr, "Failed to open SDRplay RSP device.\n");
        exit(1);
    }
    mir_sdr_Uninit();
#ifndef _WIN32
    sigact.sa_handler = sighandler;
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    sigaction(SIGINT, &sigact, NULL);
    sigaction(SIGTERM, &sigact, NULL);
    sigaction(SIGQUIT, &sigact, NULL);
    sigaction(SIGPIPE, &sigact, NULL);
#else
    SetConsoleCtrlHandler( (PHANDLER_ROUTINE) sighandler, TRUE );
#endif

    if(strcmp(filename, "-") == 0) { /* Write samples to stdout */
        file = stdout;
#ifdef _WIN32
        _setmode(_fileno(stdin), _O_BINARY);
#endif
    } else {
        file = fopen(filename, "wb");
        if (!file) {
            fprintf(stderr, "Failed to open %s\n", filename);
            goto out;
        }
    }

    r = mir_sdr_Init((78-gain), (samp_rate/1e6), ((frequency+ppm_error)/1e6),
                       mir_sdr_BW_1_536, mir_sdr_IF_Zero, &samplesPerPacket );

    mir_sdr_SetDcMode(4,0);
    mir_sdr_SetDcTrackTime(63);

    ibuf = malloc(samplesPerPacket * sizeof(short));
    qbuf = malloc(samplesPerPacket * sizeof(short));

    fprintf(stderr, "Writing samples...\n");
    while (!do_exit) {
        r = mir_sdr_ReadPacket(ibuf, qbuf, &firstSample, &grChanged, &rfChanged,
                            &fsChanged);
        if (r != mir_sdr_Success) {
            fprintf(stderr, "WARNING: ReadPacket failed.\n");
            break;
        }

        j = 0;
	
	for (i=0; i < samplesPerPacket; i++)
        {
            buffer[j++] = ibuf[i];
            buffer[j++] = qbuf[i];
        }	

        n_read = (samplesPerPacket * 2);

        if ((bytes_to_read > 0) && (bytes_to_read <= (uint32_t)n_read)) {
            n_read = bytes_to_read;
            do_exit = 1;
        }

        if (fwrite(buffer, 1, n_read, file) != (size_t)n_read) {
            fprintf(stderr, "Short write FILE, samples lost, exiting!\n"); break;
        }

        if ((uint32_t)n_read < (uint32_t)n_read) {
            fprintf(stderr, "Short read, samples lost, exiting!\n");
            break;
        }

        if (bytes_to_read > 0)
            bytes_to_read -= n_read;
    }

    if (do_exit)
        fprintf(stderr, "\nUser cancel, exiting...\n");
    else
        fprintf(stderr, "\nLibrary error %d, exiting...\n", r);

    if (file != stdout)
        fclose(file);

    mir_sdr_Uninit();
    free (buffer);
out:
    return r >= 0 ? r : -r;
}
Makefile

Code: Select all

CFLAGS?=-O2 -g -Wall -W
LDLIBS+= -lpthread -lm -lmirsdrapi-rsp
CC?=gcc
PROGNAME=rawIQ

all:rawIQ

%.o:%.c
	$(CC) $(CFLAGS) -c $<

rawIQ: rawIQ.o
	$(CC) -g -o rawIQ rawIQ.o $(LDFLAGS) $(LDLIBS)

clean:
	rm -f *.o rawIQ
Last edited by 0815 on Thu Jan 01, 1970 12:00 am, edited 0 times in total.
Reason: No reason

Post Reply