I added some debug code to sdrplay_source_c.cc to see how the packets were being handled.
Here are the changes to the unmodified (current) sdrplay_source_c.cc:
Download:
http://www.transmitter.com/sdrplay/sdrp ... -debug.txt
The modified sdrplay_source_cc::work :
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;
int grChanged;
int rfChanged;
int fsChanged;
if (_uninit)
{
return WORK_DONE;
}
if (!_running)
{
reinit_device();
_running = true;
}
_buf_mutex.lock();
if (_buf_offset)
{
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) );
}
cnt -= (_dev->samplesPerPacket - _buf_offset);
std::cerr << "cnt after first IF = " << cnt << std::endl;
}
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 -= _dev->samplesPerPacket;
}
if (cnt)
{
_buf_offset = cnt;
}
std::cerr << "cnt before return = " << cnt << " noutput_items = " << noutput_items << " buffer_offset = " << _buf_offset << std::endl;
_buf_mutex.unlock();
return noutput_items;
}
When this code is used with my test program large spikes are visible on the output waveform and the amplitude is unstable. The console output from GQRX provides some clues as to where the problem might be. Notice the line where the buffer_offset goes negative. Is this what is causing the large spikes?
Download full log:
http://www.transmitter.com/sdrplay/sdrp ... dified.txt
Sample of GQRX console output:
Code: Select all
cnt after first IF = 822
cnt before return = 66 noutput_items = 1016 buffer_offset = 66
cnt after first IF = 2886
cnt before return = 114 noutput_items = 3072 buffer_offset = 114
cnt after first IF = 3958
cnt before return = 178 noutput_items = 4096 buffer_offset = 178
cnt after first IF = -67
cnt before return = -67 noutput_items = 7 buffer_offset = -67
cnt after first IF = 698
cnt before return = 194 noutput_items = 1017 buffer_offset = 194
cnt after first IF = 4038
cnt before return = 6 noutput_items = 4096 buffer_offset = 6
cnt after first IF = 2825
cnt before return = 53 noutput_items = 3071 buffer_offset = 53
cnt after first IF = 3897
cnt before return = 117 noutput_items = 4096 buffer_offset = 117
cnt after first IF = 889
cnt before return = 133 noutput_items = 1024 buffer_offset = 133
cnt after first IF = 3977
cnt before return = 197 noutput_items = 4096 buffer_offset = 197
cnt after first IF = 3016
cnt before return = 244 noutput_items = 3071 buffer_offset = 244
cnt after first IF = 4088
cnt before return = 56 noutput_items = 4096 buffer_offset = 56
cnt after first IF = 828
cnt before return = 72 noutput_items = 1024 buffer_offset = 72
cnt after first IF = 3916
I tried some different variations and it looked the the problem was being caused by this code:
Code: Select all
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;
}
After much experimentation, I ended up removing it. I also increased the SDRPLAY_MAX_BUF_SIZE to 8208. Changing the buffer size didn't seem to make much difference, although a larger buffer seemed more stable than the original 504 value. With the original code, the larger buffer seemed to delay the time before the spikes started appearing in the waveform.
Download code without debug:
http://www.transmitter.com/sdrplay/sdrp ... 904-22.txt
Download code with debug:
http://www.transmitter.com/sdrplay/sdrp ... bug-22.txt
The modified sdrplay_source_cc::work :
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;
int grChanged;
int rfChanged;
int fsChanged;
if (_uninit)
{
return WORK_DONE;
}
if (!_running)
{
reinit_device();
_running = true;
}
_buf_mutex.lock();
if (_buf_offset)
{
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) );
}
cnt -= (_dev->samplesPerPacket - _buf_offset);
std::cerr << "cnt after first IF = " << cnt << std::endl;
}
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 -= _dev->samplesPerPacket;
}
std::cerr << "cnt before return = " << cnt << " noutput_items = " << noutput_items << " buffer_offset = " << _buf_offset << std::endl;
_buf_mutex.unlock();
return noutput_items;
}
In the test program, with this code the spikes were gone. The console output from GQRX was also more stable. Note that with the removal of that last IF statement, the first IF statement condition is never satisfied. The buffer_offset never goes negative, always ending at "0".
Download full console output:
http://www.transmitter.com/sdrplay/sdrp ... 904-22.txt
Sample of GQRX console output:
Code: Select all
cnt before return = 63 noutput_items = 4095 buffer_offset = 0
cnt before return = 64 noutput_items = 4096 buffer_offset = 0
cnt before return = 64 noutput_items = 4096 buffer_offset = 0
cnt before return = 52 noutput_items = 4084 buffer_offset = 0
cnt before return = 11 noutput_items = 11 buffer_offset = 0
cnt before return = 64 noutput_items = 4096 buffer_offset = 0
cnt before return = 21 noutput_items = 2037 buffer_offset = 0
cnt before return = 32 noutput_items = 2048 buffer_offset = 0
cnt before return = 64 noutput_items = 4096 buffer_offset = 0
cnt before return = 10 noutput_items = 10 buffer_offset = 0
cnt before return = 22 noutput_items = 2038 buffer_offset = 0
cnt before return = 32 noutput_items = 2048 buffer_offset = 0
cnt before return = 64 noutput_items = 4096 buffer_offset = 0
cnt before return = 32 noutput_items = 2048 buffer_offset = 0
cnt before return = 32 noutput_items = 2048 buffer_offset = 0
cnt before return = 64 noutput_items = 4096 buffer_offset = 0
cnt before return = 32 noutput_items = 2048 buffer_offset = 0
cnt before return = 32 noutput_items = 2048 buffer_offset = 0
cnt before return = 64 noutput_items = 4096 buffer_offset = 0
cnt before return = 32 noutput_items = 2048 buffer_offset = 0
cnt before return = 24 noutput_items = 2040 buffer_offset = 0
cnt before return = 64 noutput_items = 4096 buffer_offset = 0
cnt before return = 7 noutput_items = 7 buffer_offset = 0
cnt before return = 57 noutput_items = 4089 buffer_offset = 0
cnt before return = 64 noutput_items = 4096 buffer_offset = 0
cnt before return = 63 noutput_items = 4095 buffer_offset = 0
cnt before return = 64 noutput_items = 4096 buffer_offset = 0
cnt before return = 64 noutput_items = 4096 buffer_offset = 0
cnt before return = 63 noutput_items = 4095 buffer_offset = 0
cnt before return = 64 noutput_items = 4096 buffer_offset = 0
cnt before return = 64 noutput_items = 4096 buffer_offset = 0
cnt before return = 63 noutput_items = 4095 buffer_offset = 0
cnt before return = 64 noutput_items = 4096 buffer_offset = 0
cnt before return = 64 noutput_items = 4096 buffer_offset = 0
cnt before return = 64 noutput_items = 4096 buffer_offset = 0
cnt before return = 63 noutput_items = 4095 buffer_offset = 0
cnt before return = 64 noutput_items = 4096 buffer_offset = 0
While this works, the demodulator output from GQRX is distorted and the sample rate appears to vary, resulting in a "warble" on cw signals. I don't understand why this output, which is more stable that that produced by the original code, produces the warble or alias on the demodulated signal. Perhaps some data is being dropped? If someone can figure out why that's happening and come up with a fix, I think we'll have a solution!
My final attempt to remove the "warble" was to add back in the final IF statement, but leave it to "WHILE" to pull the packets from the SDRPlay. I ended up with an SDRPLAY_MAX_BUF_SIZE 4112 in this version but as noted that didn't appear to make any difference (better or worse).
Download code without debug:
http://www.transmitter.com/sdrplay/sdrp ... 904-23.txt
Download code with debug:
http://www.transmitter.com/sdrplay/sdrp ... 904-23.txt
The modified sdrplay_source_cc::work :
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;
int grChanged;
int rfChanged;
int fsChanged;
if (_uninit)
{
return WORK_DONE;
}
if (!_running)
{
reinit_device();
_running = true;
}
_buf_mutex.lock();
if (_buf_offset)
{
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) );
}
cnt -= (_dev->samplesPerPacket - _buf_offset);
std::cerr << "cnt after first IF = " << cnt << std::endl;
}
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 -= _dev->samplesPerPacket;
}
if (cnt)
{
_buf_offset = cnt;
}
std::cerr << "cnt before return = " << cnt << " noutput_items = " << noutput_items << " buffer_offset = " << _buf_offset << std::endl;
_buf_mutex.unlock();
return noutput_items;
}
With this modification, the spikes returned on the scope in the test program. In GQRX there was some distortion, although not as bad as with 22. Note that in the GQRX console output, the negative buffer offset has returned, possibly indicating where the spikes are occurring.
Download full console output:
http://www.transmitter.com/sdrplay/sdrp ... 904-23.txt
Sample of GQRX console output:
Code: Select all
cnt before return = 14 noutput_items = 4095 buffer_offset = 14
cnt after first IF = 3858
cnt before return = 78 noutput_items = 4096 buffer_offset = 78
cnt after first IF = 3910
cnt before return = 130 noutput_items = 4084 buffer_offset = 130
cnt after first IF = 3974
cnt before return = 194 noutput_items = 4096 buffer_offset = 194
cnt after first IF = -47
cnt before return = -47 noutput_items = 11 buffer_offset = -47
cnt after first IF = 3786
cnt before return = 6 noutput_items = 4085 buffer_offset = 6
cnt after first IF = 3850
cnt before return = 70 noutput_items = 4096 buffer_offset = 70
cnt after first IF = 3914
cnt before return = 134 noutput_items = 4096 buffer_offset = 134
cnt after first IF = 3978
cnt before return = 198 noutput_items = 4096 buffer_offset = 198
cnt after first IF = 4042
cnt before return = 10 noutput_items = 4096 buffer_offset = 10
cnt after first IF = 3854
cnt before return = 74 noutput_items = 4096 buffer_offset = 74
cnt after first IF = 3918
cnt before return = 138 noutput_items = 4096 buffer_offset = 138
cnt after first IF = 3982
cnt before return = 202 noutput_items = 4096 buffer_offset = 202
cnt after first IF = 4038
I'm not sure if these problems can be fixed using the current method reading packets in sdrplay_source_c::work. I'm hoping that there may be one change to the conditions in the IF statements or WHILE loop that will resolve the issues, but I haven't found it yet. I'm still examining the SDR-J code to see if it provides any clues. The Mirics API documentation example code isn't detailed enough to be useful, at least for me.
I hope my experiments help someone else find a way to get SDRplay working with gr-osmosdr. Once that's cracked it shouldn't be difficult to get ADSB and Meteor M2 LRPT reception working as well as making GQRX more usable for general radio reception.
Any ideas?
73...
...Doug AH6DL