oversampling coefficient specification, lib_dsp

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post by infiniteimprobability »

I'm not sure I get you?
If I do the following command:

Code: Select all

gnuplot -p -e  'plot "Filterdata/firos3_144.dat" with lines'
on lib_dsp 3.0.0, I get the following, which looks fine to me with no coefficient overflow:

Image


woodsb
Experienced Member
Posts: 79
Joined: Thu Nov 17, 2016 11:24 pm

Post by woodsb »

What does it look like if you plot the full filter, instead of the three different phases?
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post by infiniteimprobability »

I see your point. The coeffs should be multiplied by the number of phases to compensate for the loss of energy when moving to polyphase, but I don't initially understand the shape of the curve as that is a pure scaling step normally. Let me double check the derivation of the coefficients..
Image

Code: Select all

import matplotlib.pyplot as plt
import os.path as path

with open(path.expanduser("~/apps/views/swapps/lib_dsp/lib_dsp/src/os3/FilterData/firos3_144.dat"), "r") as coeffs:
	text = coeffs.readlines()	
	text = text[:-1]
	data = [int(line.strip(",\n")) for line in text]
	reordered = []
	filter_length = len(data)
	for index in range(filter_length/3):
		reordered.append(data[index])
		reordered.append(data[index + filter_length/3])
		reordered.append(data[index + filter_length*2/3])
	plt.plot(reordered)
	plt.ylabel('coeffs')
	plt.show()
woodsb
Experienced Member
Posts: 79
Joined: Thu Nov 17, 2016 11:24 pm

Post by woodsb »

Okay, glad I was able to indicate my confusion clearly. Look forward to the denouement.

-Bill
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post by infiniteimprobability »

Ok - I can confirm after talking to someone who knows a lot more about DSP than me that the way we were building the normal FIR from the polyphase banks was incorrect. The correct ordering is as follows:

Code: Select all

import matplotlib.pyplot as plt
import os.path as path

with open(path.expanduser("~/apps/views/swapps/lib_dsp/lib_dsp/src/os3/FilterData/firos3_144.dat"), "r") as coeffs:
	text = coeffs.readlines()	
	text = text[:-1] #lose last 
	data = [int(line.strip(",\n"))/3 for line in text]
	reordered = []
	filter_length = len(data)
	print "filter_length:", filter_length
	for index in range(filter_length/3):
		reordered.append(data[index + filter_length*2/3])
		reordered.append(data[index + filter_length/3])
		reordered.append(data[index])
	plt.plot(reordered, marker="o")
	plt.ylabel('coeffs')
	plt.show()
Basically lines 12 and 14 are swapped. This results in the following impulse response:

Image

I am sure the details are in the maths, which is probably why I missed it. So there is nothing to worry about and the coefficients are fine!
woodsb
Experienced Member
Posts: 79
Joined: Thu Nov 17, 2016 11:24 pm

Post by woodsb »

Hi Again,

I still think there is something amiss somewhere.

While I believe it is possible to "unwrap" the coefficients to get a reasonable impulse response as you show in your post of Tue Apr 11, 2017 12:13 am, if I actually use the coefficients with the lib_src code to generate an impulse response I do not get a reasonable impulse response, but, rather, one that looks like the plot shown in your post of Mon Apr 10, 2017 6:18 am.

I wrote a small routine to run a large positive number followed by zeros through the poly-phase filter using lib_src, and print out the filter output. The code pasted below is the lib_src-usage portion. I get the truncated response of the earlier post, not the clean response of the later post.

Can you check to see if perhaps I am using the library incorrectly?

Thanks,
Bill

#define NUM_PHASES_IN_POLYPHASE 3
int32_t us_dataLeft[NUM_TAPS_PER_PHASE] = {0}; // global mem for upsampling
void DataGenRoutine(void)
{
unsigned sample_idx = 0;
unsigned phase_index = 0;
int32_t sample;

// initialize with one
sample = src_us3_voice_input_sample(us_dataLeft, src_ff3v_fir_coefs[phase_index++], 1 << 31); // large positive number is first sample into filter.
printf("%d\n", sample);

// continue with zeros
for(sample_idx = 1; sample_idx < 75; sample_idx++) // loop with zeros into filter.
{
if(phase_index == 0)
sample = src_us3_voice_input_sample(us_dataLeft, src_ff3v_fir_coefs[phase_index++], 0); // zero into filter
else
sample = src_us3_voice_get_next_sample(us_dataLeft, src_ff3v_fir_coefs[phase_index++]);

printf("%d\n", sample);

phase_index %= NUM_PHASES_IN_POLYPHASE;
}
// after output is done plot the "sample" values to show impulse response.
}
woodsb
Experienced Member
Posts: 79
Joined: Thu Nov 17, 2016 11:24 pm

Post by woodsb »

Realized I had a small error in the code in the previous post that did not change the perspective on the issue but wanted to correct. Instead of a shift by 31 I meant to shift by 30.

Also wanted to post the impulse response as that (corrected) code generates it. Please see attached png file.

-Bill
Attachments
SrcImpResp.png
Plot of impulse response generated by code in previous post.
(28.43 KiB) Not downloaded yet
SrcImpResp.png
Plot of impulse response generated by code in previous post.
(28.43 KiB) Not downloaded yet
woodsb
Experienced Member
Posts: 79
Joined: Thu Nov 17, 2016 11:24 pm

Post by woodsb »

Hello,

Are any XCORE experts monitoring this anymore? I do not believe the issue is resolved and would like to do so.

Thanks,
Bill
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post by infiniteimprobability »

The main concern from our side was
am led to believe that something is wrong with the library data files
.. However, am pretty sure this is not the case. The libraries have been used in commercial products (where poor filtering would have become apparent) and the algos were originally tested end to end for SNR and THD etc when developed in SFP. There is a bit perfect equivalence test run nightly on the xcore implementation against the golden reference which is passing.

Also, I made a very simple change to app_os3 in the examples (to supply a mono impulse) and get this output..

Code: Select all

#define NUM_CHANNELS  1
#define NUM_OUTPUT_SAMPLES  144
const int32_t impulse[1024] = {0x7fffffff};
Can't see anything wrong with this!?


Image
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post by infiniteimprobability »

Hang on - just realised. The original thread was about lib_dsp but the code you just posted is lib_src. Have you switched which src module you are using? I have been talking about OS3 which is the higher quality version using 144 tap FIR. us3 is a lighter-weight voice version which is 72 taps but more than twice as fast.
Post Reply