How to write a wrapper?

Started by Midimaster, April 01, 2021, 14:59:29

Previous topic - Next topic

Midimaster

#195
News related to the MAC-DEBUG-Problem with MiniAudio

The MiniAudio-module runs prefect on Windows RELEASE and DEBUG, also on MAC RELEASE, but crashes during main loop on MAC DEBUG.

We are now again searching for the reason for this problem. Thanks a lot to @Derron and @col for their expert knowledge and the time they both give!

We are sure, that they problems are caused the the fact, that the debugger cannot handle the third party thread established by the MiniAudio library. 

Now we found out, that as a workaround a nodebug flag prevents the debugger from observing the Callback() and so prevents from crashing.

You simply add the keyword nodebug to the function headline:
Function MyCallBack(a:Byte Ptr, PlayBuffer:Short Ptr, RecordingBuffer:Short Ptr, Frames%) nodebug
    PlayBuffer[0] = 0
End Function

here is a complete runable example

SuperStrict
Import mima.miniaudio

Graphics 800,600
' Setup of the device:
Global MiniAudio:TMiniAudio=New TMiniAudio
MiniAudio.OpenDevice( MiniAudio.PLAYBACK, Miniaudio.FORMAT_S16, 2, 48000, MyCallBack)

MiniAudio.StartDevice()
Repeat
    Cls
    Flip
Until AppTerminate()
Miniaudio.CloseDevice()
End


Global Audio:Int[10000]
For Local i:Int=0 Until 10000
    Audio[i]=Rand(-10000,+10000)
Next

Function MyCallBack(a:Byte Ptr, PlayBuffer:Short Ptr, RecordingBuffer:Short Ptr, Frames%) nodebug
    For local i:Int=0 Until Frames
        PlayBuffer[i] = Audio[i]
    Next
End Function


Not a final solution

But this is not working in every situation. As long as we only access to RAM or do simple calculations it works.
If we call inside the MyCallBack() a function, that is observed by the debugger it crashes again:

Function MyCallBack(a:Byte Ptr, PlayBuffer:Short Ptr, RecordingBuffer:Short Ptr, Frames%) nodebug
    PlayBuffer[0] = Rand(-10000,+10000)
End Function


Here Rand() is per default observed by the debugger and now the debugger stumples again over the MidiAudio-thread.

So we keep on fighting....

Feel free to join us on Discord, if you have ideas
...back from Egypt

Midimaster

#196
I have to update my MiniAudio-Wrapper to new version MiniAudio 0.11.18. Some things have changed. I think I managed them nearly all without skills in C.

Here is the update repository:
https://github.com/MidimasterSoft/BlitzMax-Miniaudio-Wrapper/tree/future


But here I need your confirmation:

One of the function does not longer return framesWritten as a result of the function, but now expects a 4th parameter which is handled ByVAR.

This is my try to handle the difference:

OLD APPROACH:
// my call:
 int framesWritten = ma_encoder_write_pcm_frames(encoder, pPCMFramesToWrite, frames);
// called this in minaudio.h:
MA_API ma_uint64 ma_encoder_write_pcm_frames(ma_encoder* pEncoder, const void* pFramesIn, ma_uint64 frameCount);


NEW APPROACH:
// my call:
int framesWritten;
ma_encoder_write_pcm_frames(encoder, pPCMFramesToWrite, frames, framesWritten);
// calls now:
MA_API ma_result ma_encoder_write_pcm_frames(ma_encoder* pEncoder, const void* pFramesIn, ma_uint64 frameCount, ma_uint64* pFramesWritten)

I think that I need an asterix at framesWritten, or?

And do I need to define a 64bit-integer?



Still open Issue

I still have the problem with DEBUG mode on MAC. As long as I stay in release mode the apps run perfect. But when I switch to DEBUG mode on MAC all apps crash at the very beginning.

Suggestions for improvement are welcome


...back from Egypt

SToS

#197
Quote from: Midimaster on November 06, 2023, 10:33:21I think that I need an asterix at framesWritten, or?


NEW APPROACH:
// my call:
int framesWritten;
ma_encoder_write_pcm_frames(encoder, pPCMFramesToWrite, frames, framesWritten);
// calls now:
MA_API
 ma_result ma_encoder_write_pcm_frames(ma_encoder* pEncoder, const void*
 pFramesIn, ma_uint64 frameCount, ma_uint64* pFramesWritten)
You need to pass framesWritten as a reference i.e. (address of) &framesWritten
Then inside the function you access/assign the framesWritten by de-referencing i.e *pFramesWritten = ? or ? = *pFramesWritten etc..
NEW APPROACH:
// my call:
int framesWritten;
ma_encoder_write_pcm_frames(encoder, pPCMFramesToWrite, frames, &framesWritten);
// calls now:
MA_API
 ma_result ma_encoder_write_pcm_frames(ma_encoder* pEncoder, const void*
 pFramesIn, ma_uint64 frameCount, ma_uint64* pFramesWritten)

Midimaster

thank you for pointing me to the correct notation. It was the "&" not the asterix.

Quote...Then inside the function you access/assign...
I only need to call the function, because the function itself is a  third party thing from a C-library.

Does this "by reference" need to be exactly the same byte-length? As you see I still use a INTEGER variable for the call, but the third party function expects ma_uint64* pFramesWritten
...back from Egypt

SToS

Quote from: Midimaster on November 06, 2023, 18:20:12Does this "by reference" need to be exactly the same byte-length? As you see I still use a INTEGER variable for the call, but the third party function expects ma_uint64* pFramesWritten
The ma_uint64 type is just a typedef for uint64_t as defined in the stdint.h c header, so yes you need to declare framesWritten (or whatever variable to receive the value) as
#include <stdint.h>

uint64_t framesWritten;
or without stdint.h
unsigned long long framesWritten;