Starting up - no float ?

New to XMOS and XCore? Get started here.
Post Reply
User avatar
williamk
Experienced Member
Posts: 114
Joined: Fri Oct 01, 2010 7:47 pm

Starting up - no float ?

Post by williamk »

Guys, I'm starting a bit late, but wish to do some tests with the XC1A kit.

I see from the Xmos docs that there's no float support. But how do I convert my filter codes that are float based? I'm a bit lost on this...

Also, is there any code to showcase how to output sound using the XC1A buz speaker? What's the resolution and max sample-rate it supports?

In any event, I will read more and research more, just asking here first to avoid loosing too much time. ;-) (I'm doing my first tests on my free time, for now)

Best Regards, WilliamK


Wusik Dot Com (http://www.Wusik.com)
William-K.com (http://www.William-K.com)
User avatar
segher
XCore Expert
Posts: 844
Joined: Sun Jul 11, 2010 1:31 am
Contact:

Post by segher »

In C, floating point is supported just fine (via software floating point). You'll
get much faster code if you convert to fixed point, of course (or even an
alternative floating point representation).

The speaker on the XC-1A is a single 1-bit port, with some filtering on it.
You can drive it as PWM, at lots of MHz; or perhaps you're content with
block waves, if you like bleeps.
User avatar
williamk
Experienced Member
Posts: 114
Joined: Fri Oct 01, 2010 7:47 pm

Post by williamk »

Thanks.

Now, I bet this is a stupid question, but if I wanted to do the following, how would I do this with fixed-point? (XC compiler gives me an error with any number that has a . in it....)

int test = 449383 * 6.82233;

Could I just do it in the following way?

int test = 449383 * (682233/10000);

Or something like that, just trying to understand things out...

Another thing is how I will manage fractional hz values for an object rate. One variable for integer and one for fractions? I'm really lost on those things, as its the first time I program in such way. :oops:

Wk
Wusik Dot Com (http://www.Wusik.com)
William-K.com (http://www.William-K.com)
User avatar
segher
XCore Expert
Posts: 844
Joined: Sun Jul 11, 2010 1:31 am
Contact:

Post by segher »

williamk wrote:Now, I bet this is a stupid question, but if I wanted to do the following, how would I do this with fixed-point? (XC compiler gives me an error with any number that has a . in it....)
XC does not support floating point at all as far as I know. You could put those routines
in a C file, and call them from XC, that works fine.
int test = 449383 * (682233/10000);
Not quite. It's better without the parentheses already: what you wrote computes 449383*68,
not what you want.

The next issue is that the multiply will overflow (the result won't fit in a 32-bit int). And XC
does not have a 64-bit type either I believe. In C, you would write
int test = 449383LL * 682233 / 10000;

You could figure out the scaling so that nothing will ever overflow, if that gives you enough
precision.

It's probably easiest to start with the floating point routine, in C.
Another thing is how I will manage fractional hz values for an object rate.
It is usually easiest if you use the number of (100MHz) clock ticks per interval.
User avatar
williamk
Experienced Member
Posts: 114
Joined: Fri Oct 01, 2010 7:47 pm

Post by williamk »

I'm trying to understand the XMOS chip a bit more. So some kind-stupid questions. :oops:

Does the chip have non-integer process? Or all floating/fractional stuff is done in software and uses the regular integer calls of the chip?

So far I couldn't get anything to work, as I'm not a big coder, and I think I got too much used to the Arduino IDE and the Xmos IDE is making me nuts... :cry:

Wk
Wusik Dot Com (http://www.Wusik.com)
William-K.com (http://www.William-K.com)
Heater
Respected Member
Posts: 296
Joined: Thu Dec 10, 2009 10:33 pm

Post by Heater »

williamk,

The XMOS device do not have hardware support for floating point arithmetic. That is to say there are no floating point instructions in the instruction set.

If you write C code that uses floating point types then the compiler will generate code that uses the XMOS integer ops to perform the floating point calcs. Perhaps inserting calls to builtin library functions to do so.

This of course is slower than having floating point in hardware but may be fast enough anyway.

If not you will need to write your code using integers with some appropriate scaling to get the fractional precision you want.

For example you may be working with sine values from 1.0 to -1.0 as floats but in your integer code you may want to scale it so that 1.0 is 65535 and -1 is -65535. That is to say you have scaled everything by 65535 and you now have 16 bits of integer and 16 bits of fraction in each value.

Then you will have to take care that you don't overflow 32 bits.

When multiplying such scaled values remember to scale them back down afterwards.

Oh yes, the Eclipse IDE is a pain.
User avatar
williamk
Experienced Member
Posts: 114
Joined: Fri Oct 01, 2010 7:47 pm

Post by williamk »

Heater, thank you so much for such detailed information. :D

I get it now. But I wonder, for instance, bear with me, just brainstorming a bit... ;-)

I want to create a Sawtooth waveform that is HZ set via MIDI. Each MIDI Note is set to a HZ value. The problem is that its not integer HZ.

I would do like this:

// rate = the midi note hz value
Wave = -65535;

//main
Wave += rate;
If (Wave == 65535) Wave = -65535;

The problem is if the rate is not integer.

I know that the solution for this would be simple, but I'm having a hard time figuring things out.

Wk
Wusik Dot Com (http://www.Wusik.com)
William-K.com (http://www.William-K.com)
Heater
Respected Member
Posts: 296
Joined: Thu Dec 10, 2009 10:33 pm

Post by Heater »

williamk,

OK. The problem here is that you have a variable "rate" that is an integer and you have decided that it has units of Hertz. So of course the values it contains represent 0Hz, 1Hz, 2Hz 3Hz etc.

But what if instead you decided that "rate" is not representing units of Hz but milli-hertz. Then as it's binary value goes up 1, 2, 3, 4, etc it is actually representing 0.001Hz, 0.002Hz, 0.003Hz etc.

What you would have done here is to apply a scale factor of 1000 to your rate.

Now as computers work nicely in binary it would be better to use a scale factor that is a power of 2, like 1024. Then you can do the scaling with shifts by 10 bits rather a multiply by 1024. On many processors that may be a lot quicker.

As an example. I have just written a Fast Fourier Transform for a micro-controller. In an FFT you end up doing a lot of multiplies by cos and sine. Cos and sin of course have max value of 1.0 and a min value of -1.0 so using integers straight off is not possible. My sines would only have values 1, 0, and -1.

So, I scaled the sin/cos results, and all other vars in the FFT, such that max is 4096 and min is -4096 now I can multiply things by my sin and cos values and get a 1 in 8000 resolution. I have to remember to divide by 8192 after a multiply to scale the result back correctly. That's just a shift operation.
Heater
Respected Member
Posts: 296
Joined: Thu Dec 10, 2009 10:33 pm

Post by Heater »

Forgot to say, In your "rate" example, having scaled "rate" by 1000, or 1024 or whatever, you will also have to scale your other vars like "Wav" such that addition etc works correctly. Scale the results back down when required.

All in all this scaling thing is rather like your bank working with your money calculations in cents rather than dollars. Or perhaps 1/10th or 1/100th cents. All the time using integers to hold the numbers.
Post Reply