Linux

Add useful snippets of code or links to entire SDR projects.
AH6DL
Posts: 49
Joined: Sun Jun 14, 2015 7:24 am

Re: Linux - Working!!

Post by AH6DL » Sun Sep 20, 2015 8:00 am

After much testing using the debug code in my previous post, I think I now have a version of the gr-osmosdr library sdrplay_source_c_cc that will work as well as it can without major code modification such as using a FIFO buffer to allow fixed output packet size. I'm not seeing any dropped packets, the static is gone, and the baseband display is stable.

I'm still "hearing" (they aren't visible on the display) a few minor fluctuations in a test signal on GQRX that I think is due to variable packet size. Normal packets contain 4096 samples. However, output packets smaller than the sample packet size occur regularly, with a few under 10 samples. This must be having some impact on the receiver's processing. A FIFO buffer would eliminate this variance. I'm working on it, but it has turned out to be much more difficult than I originally thought to integrate with the existing sdrplay source code as the I and Q signals need to be combined in the FIFO when read from the SDRplay and then separated again on output to the receiver.

As I suspected, the main problem was in the if (_buf_offset) code. The original code couldn't handle cases where the requested number of samples was less than one packet (varies with sample rate -- usually 336 samples) from the sdrplay. My code resolves the problem in a somewhat inelegant fashion, with another "if", but it works. I also added a test at the end of sdrplay_source_c::work to flag any errors.

Here is the modified sdrplay_source_c::work code:

Code: Select all

int sdrplay_source_c::work( int noutput_items,
                            gr_vector_const_void_star &input_items,
                            gr_vector_void_star &output_items )
{
   gr_complex *out = (gr_complex *)output_items[0];
   int cnt = noutput_items;
   unsigned int sampNum;
   unsigned int sampNumStart;
   int grChanged;
   int rfChanged;
   int fsChanged;
   if (_uninit)
   {
      return WORK_DONE;
   }

   if (!_running)
   {
      reinit_device();
      _running = true;
   }

   _buf_mutex.lock();
   sampNumStart = sampNum;
   int first_offset = _buf_offset;
   if (_buf_offset > 0)
   {
      for (int i = _buf_offset; i <  _dev->samplesPerPacket; i++)
      {
         *out++ = gr_complex( float(_bufi[i]) * (1.0f/2048.0f), float(_bufq[i]) * (1.0f/2048.0f) );
      }
      if (cnt > ( _dev ->samplesPerPacket - _buf_offset ))
      {    
          cnt = cnt - (_dev->samplesPerPacket - _buf_offset);
      }
      else
      {
          _buf_offset = _buf_offset + cnt;
          cnt = 0;
      }
   }

   while ((cnt - _dev->samplesPerPacket) > 0)
   {
      mir_sdr_ReadPacket(_bufi.data(), _bufq.data(), &sampNum, &grChanged, &rfChanged, &fsChanged);
      for (int i = 0; i < _dev->samplesPerPacket; i++)
      {
         *out++ = gr_complex( float(_bufi[i]) * (1.0f/2048.0f), float(_bufq[i]) * (1.0f/2048.0f) );
      }
      cnt = cnt - _dev->samplesPerPacket;
   }
    
   if (cnt)
   {
      mir_sdr_ReadPacket(_bufi.data(), _bufq.data(), &sampNum, &grChanged, &rfChanged, &fsChanged);
      for (int i = 0; i < cnt; i++)
      {
         *out++ = gr_complex( float(_bufi[i]) * (1.0f/2048.0f), float(_bufq[i]) * (1.0f/2048.0f) );
      }
       _buf_offset = cnt;

   }
   int items = sampNum - sampNumStart;
   if ( (items + _dev->samplesPerPacket - first_offset - noutput_items) != (_dev->samplesPerPacket - _buf_offset))
   {
       std::cerr << "Sampling Error! " << "cnt before return = " << cnt << " noutput_items = " << noutput_items << " first_offset = " << first_offset << " buffer_offset = " << _buf_offset << " Items = " << items << " SpP - _buf_offset = " << _dev->samplesPerPacket -  _buf_offset << std::endl; 
   } 
   _buf_mutex.unlock();   
   return noutput_items;
}
Download the complete source code from:
http://www.transmitter.com/sdrplay/sdrp ... 919-49.txt

I just got this working this evening and will do more testing over the next few days. I've been fooled before into thinking I had a solution but it in reality I'd just moved the problem to a spot where I wasn't looking. With extensive debug code and the gnuradio-companion test receiver, a steady signal source from my Ettus B200, and spot checks with GQRX I feel more confident in this version. Please compile it and let me know you experience with it. I'd be especially interested in hearing from anyone building this on OS-X -- it should solve the gr-osmosdr problems there as well.

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

amish
Posts: 6
Joined: Wed Sep 02, 2015 6:17 am

Re: Linux

Post by amish » Mon Sep 21, 2015 12:12 pm

Hi Doug,

I compiled your code but did not have much time to test. Reaching net is a big issue here.

I wanted to send you the gqrx output from my compiled source. But will have to find a way to attach the file.
Last edited by amish on Thu Jan 01, 1970 12:00 am, edited 0 times in total.
Reason: No reason
73
VU2AIE

AH6DL
Posts: 49
Joined: Sun Jun 14, 2015 7:24 am

Re: Linux

Post by AH6DL » Mon Sep 21, 2015 6:02 pm

Thanks Amish --

I don't need the I/Q output, just the console output when you run GQRX from a terminal and maybe a screen shot if you see anything odd. You should be able to cut and paste it using the code button above. The key thing I'm looking for is whether any packet handling errors (from the code I added) are showing up as well as any USB buffer overflow/underflow. I haven't seen any USB buffer issues here but haven't tried all sampling rates/bandwidth combinations. I have seen GQRX get into unstable states, requiring a restart, and also times when I've had to unplug and replug the SDRplay, but that was primarily while testing modifications that didn't work.

I tested this code a lot yesterday and am pretty happy with it. Now that the corrupted packets are fixed I can look into some other tweaks to do things like improve DC removal and perhaps enable hardware AGC -- the Mirics API has an example showing how to do that.

...Doug
Last edited by AH6DL 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: Linux

Post by sdrplay » Tue Sep 22, 2015 12:52 am

Mirics have been evaluating your modifications Doug and have made some further changes.

Here is the latest code...

https://github.com/SDRplay/gr-osmosdr/t ... ay_support

Only the sdrplay_source_c.cc file has changed in lib/sdrplay

They will continue to look at it but if you have any feedback on how this works please let us know.

Best regards,

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

AH6DL
Posts: 49
Joined: Sun Jun 14, 2015 7:24 am

Re: Linux

Post by AH6DL » Tue Sep 22, 2015 2:53 pm

I looked at the Mirics code and it's good to see they removed the last bits of debug code and streamlined it a bit. I'd expanded some of the code to make it easier for me to understand and modify during my testing.

I won't have a chance to test it until after work today but I have a few concerns with the Mirics "if (cnt > (_dev->samplesPerPacket - _buf_offset))" statement based on what I learned during my testing.

Miric's code

Code: Select all

 if (cnt > (_dev->samplesPerPacket - _buf_offset))
      {
         cnt -= (_dev->samplesPerPacket - _buf_offset);
         _buf_offset = 0;
      }
      else
      {
         cnt = 0;
         _buf_offset += cnt; 
      }
My code:

Code: Select all

      if (cnt > ( _dev ->samplesPerPacket - _buf_offset ))
      {    
          cnt = cnt - (_dev->samplesPerPacket - _buf_offset);
      }
      else
      {
          _buf_offset = _buf_offset + cnt;
          cnt = 0;
      }
   }
I didn't find any need for the first "_buf_offset =0;" and recall that it caused problems under some conditions, for example if the number of packets requested by nonoutput_items was less than the number of items in the buffer. You don't want to lose those samples. If everything is working as it should, there is no reason to set _buf_offset to zero.

It looks like the "else" might be the place to fix that, but if cnt is set to "0" before the "_buf_offset += cnt;" , it would appear that "_buf_offset += cnt" wouldn't do anything.

I'll give this a try, but after all the time I spent mapping out how data is processed through "work" I think it is going to bring back some of the packet loss we had problems with. I tested my version on a NOAA-19 APT pass yesterday afternoon and got a perfect image -- something that wasn't possible before -- and it was better than any images I'd gotten with the Airspy or RTL SDRs due to the performance of receiver.

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

AH6DL
Posts: 49
Joined: Sun Jun 14, 2015 7:24 am

Re: Linux (new code)

Post by AH6DL » Tue Sep 22, 2015 11:08 pm

Congratulations! I think you've got it!

In spite of my reservations in the previous email, the github code is working fine!

I tested the github code after adding the same limited debug routine I used in my test-0919-49 version and I'm not seeing any sample errors, even during long runs.

Comparisons of the code in GQRX show identical performance between my test code and github code. Using my gnuradio-companion test program I was seeing a few differences in stability and noise but those could simply be due to restarting the SDRplay with the different code and needing to "bounce" the gain to get the DC removal to act. Certainly nothing substantial one way or the other.

Now on to porting some of those features in the new EXTIO code to Linux! This should be possible using device strings in gr-osmosdr.

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

mrj
Posts: 2
Joined: Sat Oct 03, 2015 5:26 pm

Re: Linux

Post by mrj » Sat Oct 03, 2015 10:11 pm

I'm a new SDRPlay owner. When I first used the Mac Port of gqrx, I applied the diff to the gr-osmosdr Portfile here (https://trac.macports.org/ticket/48451).

I saw the horizontal yellow line behavior in my waterfall display, the FFT display "jumping" periodically.

I applied the latest code from Doug and Mirics this morning, and it has fixed those problems for me -- thanks!


It looks like the code for other SDRs in gr-osmosdr may have an even better approach... For example, in lib/rfspace/rfspace_source_c.cc, they use a separate thread to call their usb_read_task function and populate their FIFO circular buffer.

It seems like a similar approach for the SDRPlay might solve the remaining issues Doug mentions above.


I could probably try to implement the above for SDRPlay... Doug, were you already working on something similar?

Mimics folks -- would a diff to implement a thread for reading from the device and add a FIFO circular buffer like some of the other SDR libs be welcome?
Last edited by mrj on Thu Jan 01, 1970 12:00 am, edited 0 times in total.
Reason: No reason

WyoDuner
Posts: 7
Joined: Fri Sep 18, 2015 11:36 pm

Re: Linux

Post by WyoDuner » Wed Oct 07, 2015 12:01 am

After a few attempts I have GNUradio working with the SDRplay on Ubuntu 14.04. But.... I can't get rid of the huge DC spike and that is causing problems. Even if I use a signal source and mix that with the output of the SDRplay source to move off from center frequency, I am still left with intermods on stronger signals.

Is there a cure for the DC spike?
Last edited by WyoDuner on Thu Jan 01, 1970 12:00 am, edited 0 times in total.
Reason: No reason

jazzkutya
Posts: 26
Joined: Wed Sep 23, 2015 8:50 pm

Re: Linux

Post by jazzkutya » Wed Oct 14, 2015 1:18 pm

Hi sdrplay,

Have you considered making the extio dll opensource? Not the API dll, just the extio dll.
It seems there is many important functionality in that dll, like closing the gap of 380-420MHz.
While an extio library is a very rare sight on linux, maybe totally non-existent, linrad does support an extio .so file, so it would be very easy for linrad and also it would be very helpful for developers of gr-osmosdr and soapysdrplay.

I would be glad to experiment with porting it to linux and try to help soapysdr get better with the help of the dll source code.

Thanks,
jazzkutya
Last edited by jazzkutya 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: Linux

Post by sdrplay » Thu Oct 15, 2015 4:34 pm

Hello Jazzkutya,

We liked your idea and have released the source code for the ExtIO plugin. It's on our github repository...

https://github.com/SDRplay/ExtIO_SDRplay

Please let us know how you get on. Please note that we will continue to develop the plugin with fixes and new features and we'll keep the repository updated when new releases are available.

Best regards,

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

Post Reply