USRP Audio Rate versus Sample Rate of Soundcard

Hello!

I am current transmitting an audio stream from my sound card (SB
Audigy2) to the USRP and it is transmitting at an FM frequency. The
problem I am facing is that my sound card supports 44100Hz sample rate
however, since the USRP audio rate is an integer factor of 128MS/s When
I receive the signal on a regular FM radio it sounds funny depending on
the audio rate I set (either sounds high pitched if i set audio rate to
high or sounds low pitched and slow if I choose a lower sample rate).

If I change the sample rate for the audio_source (sound card) it gives
me an error that the sound card requests 44100Hz.

I am including the lines I am using to rectrieve the audio data:

" self.fg = gr.flow_graph()
src = audio.source(44100, options.audio_input)
fmtx = blks.wfm_tx(self.fg, self.audio_rate, self.usrp_rate)
self.fg.connect(src, fmtx, gain, self.u)"

Thank you for the previous help and Thanks for this one in advance.

Omer


This message was sent on behalf of [email protected] at
openSubscriber.com
http://www.opensubscriber.com/messages/[email protected]/topic.html

Omer - You should really read through a few “how to do DSP” books - as
well as review the GNU Radio code for filtering ( gnuradio-core/src/
lib/filter ) - since all of those books I’ve ever heard of cover
changes in sampling rate. That said, here’s some info that will
hopefully be useful to the list. These techniques have worked for me
for other sample rate changes, though I hope I remembered them
correctly here … someone please correct me if I didn’t. - MLD

On Feb 12, 2008, at 9:33 PM, [email protected] wrote:

 self.fg = gr.flow_graph()
       src = audio.source(44100, options.audio_input)
       fmtx = blks.wfm_tx(self.fg, self.audio_rate,  

self.usrp_rate)
self.fg.connect(src, fmtx, gain, self.u)"

The input sample rate must be 44100 = (235*7)^2
The output sample rate must be any one of 128M/[4:4:512].
Stream must be resampled in software somewhere along the DSP chain.

3 possible solutions or approximations … listed roughly in order of
“goodness” or “precision”:

  1. rational resampler: There’s a resampling block that can do up then
    down resampling by integer values. You’ll need to find:

hw_interp=[4:4:512];
usb_tx_rate =128e+6./hw_interp;
% find just the integer usb_rate’s:
ff=find(abs(usb_tx_rate - round(usb_tx_rate)) < eps);
X=lcm(44100*ones(size(ff)), usb_tx_rate(ff));
[Y,ndx]=min(X);
sw_interp_up=Y / 44100
sw_interp_down=Y / usb_tx_rate(ff(ndx))
hw_interp=hw_interp(ff(ndx))
usb_tx_rate=usb_tx_rate(ff(ndx))

From the above script, it looks like:

hw_interp = 512
usb_tx_rate = 250000
sw_interp_up = 2500
sw_interp_down = 441

I have no idea if these parameters will work with the rational
resampler block, but you can try them and see. I have no idea what
the CPU load of this block will be, but if you are running on an Intel
CPU with SSE then that will help reduce the load.

  1. fractional resampler: Provides samples between the inputs.
    Probably best to keep the sample rates at a minimum for filtering
    purposes:

hw_interp=512
usb_tx_rate=128e+6 / hw_interp
sw_interp= usb_tx_rate / 44100

which results in a fractional interpolation rate of sw_interp =
5.6689. I think the output samples will be the MMSE estimate to the
nearest 32nd of a time-slot to the actual sample - which is hopefully
good enough. I have no idea what the CPU load of this block will be,
but if you are running on an Intel CPU with SSE then that will help
reduce the load.

  1. Get “close enough” … note that because the sample rates are not
    exact, there will be an occasional overflow or underrun. in my
    experience, these have no real impact except an audio glitch.

hw_interp=[4:4:512];
usb_tx_rate =128e+6./hw_interp;
X= usb_tx_rate./44100;
[Y,ndx]=min(abs(X-round(X)));
sw_interp=round(X(ndx))
hw_interp=hw_interp(ndx)
usb_tx_rate=usb_tx_rate(ndx)
fg_rate=usb_tx_rate/sw_interp

then use the resulting ‘sw_interp’ in a software up-sampling block,
and ‘hw_interp’ for the USRP sink block.

Running this through MATLAB, I get:

sw_interp = 6
hw_interp = 484
usb_tx_rate = 264462.81
fg_rate = 44077.135

The output signal will be off by a little bit, but maybe it would be
close enough. For integer rates:

hw_interp=[4:4:512];
usb_tx_rate =128e+6./hw_interp;
% find just the integer usb_rate’s:
ff=find(abs(usb_tx_rate - round(usb_tx_rate)) < eps);
X=usb_tx_rate(ff)./44100;
[Y,ndx]=min(abs(X-round(X)));
sw_interp=round(X(ndx))
hw_interp=hw_interp(ndx)
usb_tx_rate=usb_tx_rate(ff(ndx))
fg_rate=usb_tx_rate/sw_interp

and I get:

sw_interp = 29
hw_interp = 36
usb_tx_rate = 1280000
fg_rate = 44138

Again, the output signal will be off by a little bit, but maybe it
would be close enough.

If you’re using alsa, try using plughw:0,0 as the input device.
It’s got a resampler built into it.

The plughw should do the trick.

You could also try sampling the audio with USRP and LFRX. I’ve never
tried it, but I don’t see why it wouldn’t work. It’s just the same as
sampling the ULF+VLF band, the input and output samples would be
coherently timed and you don’t need a sound card. Another reason for
the clicking might be buffer over/underflows. Do you see any of the
letters in the set {U,a,O,u} while running your app? If you do, you
can try increasing buffer sizes using the fusb_nblocks and
fusb_block_size parameters in the usrp sink.

juha

Thanks a lot everyone!

I am using an alsa_source however when using “plughw:0,4”, or
“plughw:0,0” instead of “hw:0,4” (which I am currently using) I get the
following message:

audio_alsa_source[plughw:0,0]: set_periods failed: Invalid argument
Traceback (most recent call last):
File “./fm_transmit_temp_sc.py”, line 134, in
wfm_tx()
File “./fm_transmit_temp_sc.py”, line 107, in init
src = audio.source(44100, options.audio_input)
File “/usr/local/lib/python2.5/site-packages/gnuradio/audio_alsa.py”,
line 219, in source
return _audio_alsa.source(*args)
RuntimeError: audio_alsa_source

What could cause this? My alsa drivers seem to be updated.

Juha : “You could also try sampling the audio with USRP and LFRX. I’ve
never
tried it, but I don’t see why it wouldn’t work.”

I have yet to try this. I plan on doing this if the other method doesn’t
work at all.

Juha : “Do you see any of the letters in the set {U,a,O,u} while running
your app?”

I was seeing them before. however as I made the audio_rate closer to
44.1K they have disappeared so looks like I am ok there.


This message was sent on behalf of [email protected] at
openSubscriber.com
http://www.opensubscriber.com/message/[email protected]/8600989.html

On Tue, Feb 12, 2008 at 09:33:11PM -0500, [email protected] wrote:

        fmtx = blks.wfm_tx(self.fg, self.audio_rate, self.usrp_rate)
        self.fg.connect(src, fmtx, gain, self.u)"

Thank you for the previous help and Thanks for this one in advance.

Omer

If you’re using alsa, try using plughw:0,0 as the input device.
It’s got a resampler built into it.

Eric