Sound card channel delay half sampling period

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Sound card channel delay half sampling period

neil_450658
I have a Roland DUO-Capture sound card which samples at 48 kHz being used with a Softrock Ensemble RXTX.  After noticing huge I/Q imbalance images, I began playing with the rx phase correction.  I discovered that there is an I/Q delay between the stereo channels of exactly half of a sampling period for this sound card(0.5/48000 ~ 1.04e-5 s).

I have working(but ugly and unsuitable for public consumption) proof-of-concept patch to quisk in which I upsample to 96 kHz by adding an extra zero sample for every sample collected then use the existing "channel_delay" option to align the samples.  It works very well at removing images.

I want something like this fix for the source card added to quisk.  I am willing to do the coding work, but I would need suggestions on a better approach or how to elegantly make such changes such that they would be suitable for being added to quisk.
Reply | Threaded
Open this post in threaded view
|

Re: Sound card channel delay half sampling period

ahlstromjc
Administrator
Thanks for studying this problem.  I never heard of a half-sample delay before.  Your solution seems to be a good one, but I will look for alternatives.  I will work on this right after the next release.

Jim
N2ADR
Reply | Threaded
Open this post in threaded view
|

Re: Sound card channel delay half sampling period

ahlstromjc
Administrator
In reply to this post by neil_450658
One possibility is to add another function to Quisk
   nSamples = process_raw_samples(complex cSamples, int nSamples)
that alters the samples in place.  For the Quisk distribution, this is a dummy function.  But you (or I) can write a replacement function that implements your up/down conversion logic.  To use it, you would have to copy your function to the distribution process_raw_samples.c and re-compile.  That is no problem on Linux, but if you use Windows, you would have to install a compiler.

I can do this quickly if it helps.

Jim
N2ADR
Reply | Threaded
Open this post in threaded view
|

Re: Sound card channel delay half sampling period

neil_450658
On 02/17/2014 10:04 AM, ahlstromjc [via quisk] wrote:
> One possibility is to add another function to Quisk
>    nSamples = process_raw_samples(complex cSamples, int nSamples)
> that alters the samples in place.

I am using Debian GNU/Linux.  So access to a compiler is never a problem.

I might not know enough about your program to tell you if your idea can
easily work.  So I will add some more detail on what I did for receive.

Note that while I have tested the receive, and it appears to let me do a
proper I/Q balance over the whole -24 kHz to +24 kHz(less than a degree
needed for balance), I have not yet attempted to implement a transmit
fix which appears to require exactly the same number of changes as
receive in my approach.

In first draft hack, I hooked into quisk_read_alsa() in sound_alsa.c  
This was the convenient spot mostly because it occurred before
delay_sample() was called.

The adding of zero samples was done in quisk_read_alsa() when initially
processing the frames from the sound card.  Since my sound card has 24
bit resolution, I just added a line in the case 3 block of the
dev->sample_bytes switch.

Right after the cSamples[nSamples] = ii + I * qq, I added a
cSamples[nSamples + 1] = 0.0 + I*0.0.



Reply | Threaded
Open this post in threaded view
|

Re: Sound card channel delay half sampling period

ahlstromjc
Administrator
I don't think this works because the next loop iteration over-writes the zero:

Right after the cSamples[nSamples] = ii + I * qq, I added a
cSamples[nSamples + 1] = 0.0 + I*0.0.

But maybe you meant:

cSamples[++nSamples] = 0.0;

But then there are twice as many samples as indicated by the sample_rate, so you must have decimated by two later in the code.

I didn't know you needed to correct the transmit side too.  Have you thought about a different USB sound device?  A 48ksps device is cheap.

Jim
N2ADR
Reply | Threaded
Open this post in threaded view
|

Re: Sound card channel delay half sampling period

neil_450658
I had avoided overwriting my zero sample by editing the for loop to get the correct amount of loops.  

But you are correct in that the changes begin to snowball.  Everything in quisk refers to sample_rate, and everything is hardwired to expect some multiple or fraction of sample_rate.  So changing the sample_rate means having to change everything else.

I dug out one of my old math books from college.  I think there might be a way to fix this problem without changing the sample rate.  The approach is to just do a multiplication on the Q signal similar to how the mixing multiplication is done with rxTuneVector in quisk_process_samples().  Though I might have to split cSamples into two signals.

Unfortunately I have not had the opportunity to test this idea yet.  Perhaps this weekend.
Reply | Threaded
Open this post in threaded view
|

Re: Sound card channel delay half sampling period

ahlstromjc
Administrator
Let me know how multiplying the Q signal works.

An alternative is to add a module to sound.c right after sound_read_alsa().  It zero-stuffs cSamples, shifts by one sample time, and decimates by two all in the same module.  Then the sample rate never changes.

I am leaving on a ski trip today.  I can answer email but not work on code.

Jim
N2ADR