ADSP-BF533, Problem with dividing signal

Status
Not open for further replies.

Wojtek

Newbie level 5
Joined
Aug 31, 2011
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,347
Hi everyone!

I'm working on a guitar effect at ADSP-BF533 Ez-Kit Lite, and I have a problem with processing the incoming samples:
From the output I take an integer value, then I convert it to float by simple 'sample_float = (float)sample_int;', after that I process the sample and convert it back to integer the same way and send it to output.
Problem is that when I try to multiply a sample by any value less than 1, it causes a distortion. I try to deal with it for several weeks but I can't think of anything.
I know blackfin processors have a fixed-point architecture and it would be easier to switch to a SHARK processor, but it's impossible, it has to be ADSP-BF533. Is there any way to do it anyway?
I hope I gave you enough details about my project, if not, please let me know what other informations you need to help me find the solution, it's very important to me.

Regards!
Wojte
 

Hi Wojte,

Are you are programming in C?
If your convert back from float to int without other processing, is there still distortion?
Can you post the piece of code?
Regards

Z
 
Reactions: Wojtek

    Wojtek

    Points: 2
    Helpful Answer Positive Rating
Hi Zorro,

I'm programming in C. If I just convert sample from int to float and then back from float to int without modifying
it's value, there's no distortion. I'm able to multiply it for example by 2, problem is only when I try to multiply sample by something less than 1. Even if I skip converting to float and try to multiply an integer sample by 0.5 (or divide by 2), there's z distortion.
My code is very simple, if you use VisualDSP++, it's based on the C_Talkthrough_I2S example project. Every new sample at the input causes an interrupt when function Process_Data() is called.
That's an original Process_Data() function:

Code:
void Process_Data(void)
{
	iChannel0LeftOut = iChannel0LeftIn;
	iChannel0RightOut = iChannel0RightIn;
	iChannel1LeftOut = iChannel1LeftIn;
	iChannel1RightOut = iChannel1RightIn;
}

That's the function with my changes:


Code:
void Process_Data(void)
{
	float sample;
	sample = (float)iChannel1RightIn;	//there's only one channel I'm using

	sample *= 0.5f;	//without this line everything is fine
	
	iChannel1RightOut = (int)sample;
}

Regards
Wojtek
 

Hi Wojtek

The code seems ok. iChannel1RightIn and iChannel1RightOut are declared as type int, right?
Are you sure that your signal level is enough? I mean that it is not so weak that, for example, it spans only 2 bits, and losing the least significant bit (as when you divide by 2) thee signal becomes more noticeably distorted.
Regards

Z
 
Reactions: Wojtek

    Wojtek

    Points: 2
    Helpful Answer Positive Rating
Hi,

Signal level should be okay, when I display the value of iChannel1RightIn/Out on the debug window, it's between 0 and 0xFFFFFF9. Multiplication by 0.9 also causes distortion, so that's not the problem, I think.
I've contacted the Analog Devices Processor support and described my problem, I've got following answer:


Regards,
Wojtek
 

when I display the value of iChannel1RightIn/Out on the debug window, it's between 0 and 0xFFFFFF9.
Do you mean that it ranges is between 0 and -7 ?
Or in decimal are there values of +/- hundreds at least?
Regards

Z
 
Last edited:
Reactions: Wojtek

    Wojtek

    Points: 2
    Helpful Answer Positive Rating
That would be strange, when I display it in decimal it's 16 777 209, sample converted to float has the same value and the range is between 0 and 16 777 209, so I'm not sure there are any negative values.

Best!
Wojtek
 

The value decimal 16 777 209 is equivalent to hexadecimal 0xFFFFFF9, but interpreted as unsigned.
You must use signed arithmetic.
iChannel1RightIn must be declared as int (i.e. signed int).
Please check its type in all the places it is declared.
Regards

Z
 
Last edited:
Reactions: Wojtek

    Wojtek

    Points: 2
    Helpful Answer Positive Rating
Hi,

iChannel1RightIn is declared as int.

Best!
Wojtek
 

Hi Wojtek,

Strange. Can be the way the values are displayed? In that case you should get only very small or very big numbers. Does this happen?
If in the your code shown in post #3, i.e:

sample = (float)iChannel1RightIn; //there's only one channel I'm using
sample *= 0.5f; //without this line everything is fine
iChannel1RightOut = (int)sample;

you display iChannel1RightOut, what values do you get?
Regards

Z
 
Reactions: Wojtek

    Wojtek

    Points: 2
    Helpful Answer Positive Rating
Hi!

When I display iChannel1RightOut value after dividing sample by 2 I get half of iChannel1RightIn, so it should be okay, problem is with the sound.

Best,
Wojtek
 

Hi,

I mean: for example consider iChannel1RightIn is 0xFFFFFF9 (equivalent to 16,777,209 unsigned decimal or -7 signed). When you divide it by 2 the result is either decimal 8,388,604 = 0x7FFFFC (if it is considered an unsigned variable prior to division) or decimal -3 = 0xFFFFFD (if it is considered signed).
In the first case, taken it as signed (after division) has a big error and the result has a very high level and distortion.
Regards

Z
 

Hi,

forgive the lateness of my reply - I had to focus on something else for a while.

I've tried to declare samples as unsigned int and int (unless there's other way to do it), but it doesn't matter - every time there was a distortion on the output.

My professor has suggested that the problem may be in converting from int to float. I use simple (sorry, but I don't know the English name of that operation)
float_input = (float)int_input;
(...)
int_output = (int)float_input;

Is there other way to convert between int and float? I've only found libraries with functions to convert between float and fract, but I can't find anything about conversion between int and float.

Best!
Wojtek
 

Hi Wojtek,
I use simple (sorry, but I don't know the English name of that operation)
float_input = (float)int_input;
(...)
int_output = (int)float_input;
This way of type conversion is called "cast" or "casting". It should work. It is a part of standard C language and calls specific functions if needed.
Regards

Z
 

Hi,

Problem solved, thanks for your advices.
The problem was that incoming samples were between 0 and FFFFFF (24 b), and I had to convert it to 32 b. I shift 8 bits left and cast it to float. After that I'm able to perform all necessary operations. Finally I cast float sample back to int and shift 8 bits right. It's that simple. If only I thought about it few months ago..

Thanks for your help Z!
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…