www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Casting a vector operation

reply Andrej Mitrovic <none none.none> writes:
So, I need to convert a float[] to an int[] for some use with audio. The
conversion operation is to multiply each sample (the value) with 0x7FFF_0000,
and decrement with .5f, round this operation to an int and store it as the new
sample.

So here's how a float>int conversion looks like:

http://codepad.org/bqINREKG


Now, I wanted to replace the foreach loop with a vector op. So first I've tried
this:

writeTo[] = to!int((data[] * 0x7FFF_0000) - 0.5f)

This won't work. I've tried to do a simple cast:

writeTo[] = cast(int[])((data[] * 0x7FFF_0000) - 0.5f);

floatToInt.d(26): Error: Array operation data[] * 0x1.fffcp+30F - 0.5F not
implemented

Same thing if I use to!int[]. I'm not sure what this error means.

Unfortunately I have little understanding of vector ops. Is there any way to
use a vector op that operates on floats but stores each result as an int?

Btw, the *actual* definition of a single channel is:
void*[2] buffers;

These are two "half-buffers", meaning that the soundcard reads from one
half-buffer while the client fills the other half. 

Should I be worried that these are typed as void*? I mean I've read something
about a GC problem where the GC could interpret the value stored in a void* as
a pointer to random data in the heap, which could lead to memory leaks, or
something of that sort.
Apr 27 2011
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Andrej Mitrovic:

 So here's how a float>int conversion looks like:
 
 http://codepad.org/bqINREKG

Just a cast(int) for each item array is probably enough.
Is there any way to use a vector op that operates on floats but stores each
result as an int?

Not yet, as far as I know. But the feature you look for may be implemented later. Don wants to vectorize even sin, cos, etc functions.
 Should I be worried that these are typed as void*? I mean I've read something
about a GC problem where the GC could interpret the value stored in a void* as
a pointer to random data in the heap, which could lead to memory leaks, or
something of that sort.

If you use a type that can't contain pointers, like a ubyte[] the situation probably improves (no outbound pointers are followed) but inbound pointers are followed still by the GC, and they cause troubles when arrays are large (the array is never deallocated). Bye, bearophile
Apr 27 2011
prev sibling parent Jesse Phillips <jessekphillips+D gmail.com> writes:
Andrej Mitrovic Wrote:

 So, I need to convert a float[] to an int[] for some use with audio. The
conversion operation is to multiply each sample (the value) with 0x7FFF_0000,
and decrement with .5f, round this operation to an int and store it as the new
sample.
 
 So here's how a float>int conversion looks like:
 
 http://codepad.org/bqINREKG
 
 
 Now, I wanted to replace the foreach loop with a vector op. So first I've
tried this:
 
 writeTo[] = to!int((data[] * 0x7FFF_0000) - 0.5f)
 
 This won't work. I've tried to do a simple cast:
 
 writeTo[] = cast(int[])((data[] * 0x7FFF_0000) - 0.5f);
 
 floatToInt.d(26): Error: Array operation data[] * 0x1.fffcp+30F - 0.5F not
implemented

Well if the error is correct, this should mean you are doing it right, but the feature doesn't exist yet. While it won't get you the performance gain, there is also map, auto writeTo = array(map!"a*0x7FFF_0000 - 0.5f"(data));
Apr 27 2011