#Working with Elixir NIFS; need advice on types

20 messages · Page 1 of 1 (latest)

split rapids
#

I'm wondering how I can use whacky types from C++; specifically void*. I don't think can actually handle this specific data structure I have, though; it causes a recursion loop on next and prev.

type r_audio_processor :: %Rayex.Structs.RAudioProcessor{
       process: payload,
       next: r_audio_processor,
       prev: r_audio_processor
}

So this'll buffer overflow when it initiates. I don't think I can specify that they're pointers, either. So the native type takes RAudioProcessor* pretty much, process is a callback void*.

#

The error caused by both r_audio_processor and [r_audio_processor] for next & prev:
:erlang.binary_to_atom("sound.stream.buffer[i].processor.next[i].next[i].next[i].next[i].next[i].next[i].next[i].next[i].next[i].next[i].next[i].next[i].next[i].next[i].next[i].next[i].next[i].next[i].next[i].next[i].next[i].next[i].next[i].next[i].next[i].next[i].next[i].process", :utf8)

formal anchor
#

I do not get what you are doing there. If you want to pass struct (or any other opaque/NIF-only) data to Elixir you need to use resources. On Elixir side these will be represented as references which should be treated as opaque values on Elixir side and should be used only to interact with NIF functions.

split rapids
#

It comes down to a couple of parts, this is in the spec.exs. The actual meat and potatoes of it isn't defined because yet in the C file. I think I'm just still learning and trying to fix a problem that stumped the original maintainer so much they removed the entire audio functionality

#

I'll keep tinkering and see how I go. Oh; just realized discord converted my fuckin' * to italics

#

But yeah the main issue is me not knowing if there's something I'm missing from the Unifex typelist or if it's still under construction in some fashion

safe comet
#

How are you creating the NIF? Are you using some sort of tool or are you hooking it all up yourself?

#

You may want to try using :erts_alloc and saving the pointer to the allocation, so you don't need to represent the type in Elixir at all.

split rapids
split rapids
split rapids
#

My issue is shit types on my part.

#

Thanks @formal anchor and @safe comet; I need to completely NIF-ify miniaudio.h

#

Perhaps just the essentials 💀

safe comet
#

Wew...

split rapids
#

They do a lot of weird struct definitions for standard types, which is manageable

formal anchor
#

Split into separate files?

split rapids
#

Yeah, might have to. Thing is, I have to add my own miniaudio.h because raylib doesn't actually use it in a direct fashion, so I need to simply define the functions for it. Frankly I could just avoid the raylib wrapper for raudio and roll my own; that'd be much simpler due to this rather spaghetti-ass code. For example,

typedef struct
{
    ma_format format;
    ma_uint32 channelsIn;
    ma_uint32 channelsOut;
    ma_channel_mix_mode mixingMode;
    ma_channel_conversion_path conversionPath;
    ma_channel* pChannelMapIn;
    ma_channel* pChannelMapOut;
    ma_uint8* pShuffleTable;    /* Indexed by output channel index. */
    union
    {
        float**    f32;
        ma_int32** s16;
    } weights;  /* [in][out] */

    /* Memory management. */
    void* _pHeap;
    ma_bool32 _ownsHeap;
} ma_channel_converter;

Look at all these structs. Makes Unifex wig out so I'd need to code a bunch of converters between elixir and C. rAudioBuffer takes an ma_channel_converter type though, so I might be able to just do it for this one type and use the raudio structs

#

Like I mentioned, this stumped the last dev to the point it was removed and I think they stopped working on it all together after 0.0.2

#

You can play sound, but it's really whack. So if you hardcode LoadSound(path) | PlaySound(), it plays what you want it to in pure C which is fantastic because it means "Yeah it is possible but interop is gonna be the challenge"