Expose more MiniAudio-Functions

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
NicTheQuick
Addict
Addict
Posts: 1523
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: Expose more MiniAudio-Functions

Post by NicTheQuick »

Any idea on how to get it to work in Linux? I tried different names on the `ImportC`:
- pbminiaudio
- libpbminiaudio
- libpbminiaudio.a
- -lminiaudio
- libminiaudio
- libminiaudio.a
- libminiaudio.lib
- miniaudio.lib

The linker did not like any of these. :(
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
User avatar
idle
Always Here
Always Here
Posts: 5921
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Expose more MiniAudio-Functions

Post by idle »

Try this and save is as .so
viewtopic.php?p=628837#p628837

Search github for miniaudio and then try to compile it as shared object.
jamirokwai
Enthusiast
Enthusiast
Posts: 798
Joined: Tue May 20, 2008 2:12 am
Location: Cologne, Germany
Contact:

Re: Expose more MiniAudio-Functions

Post by jamirokwai »

I also had to set the full path to the .dylib to let PureBasic find it.
Regards,
JamiroKwai
User avatar
NicTheQuick
Addict
Addict
Posts: 1523
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: Expose more MiniAudio-Functions

Post by NicTheQuick »

idle wrote: Thu Oct 10, 2024 10:06 am Try this and save is as .so
viewtopic.php?p=628837#p628837

Search github for miniaudio and then try to compile it as shared object.
I found an easier way. I just extracted miniaudio.o from libpbminiaudio.a with the ar tool:

Code: Select all

nicolas@Rocky:~/programme/PureBasic_6.12_LTS/purelibraries/linux/libraries$ ar  t libpbminiaudio.a 
miniaudio.o
nicolas@Rocky:~/programme/PureBasic_6.12_LTS/purelibraries/linux/libraries$ ar x libpbminiaudio.a
nicolas@Rocky:~/programme/PureBasic_6.12_LTS/purelibraries/linux/libraries$ file miniaudio.o 
miniaudio.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
I then had to change the ImportC line to the full path to the file:

Code: Select all

ImportC  "/home/nicolas/programme/PureBasic_6.12_LTS/purelibraries/linux/libraries/miniaudio.o"
It compiles now but I get a segmentation fault at line 672, the Delay(1000) and some weird characters in the debug output:
PWÖ
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
User avatar
idle
Always Here
Always Here
Posts: 5921
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Expose more MiniAudio-Functions

Post by idle »

The problem is the device enum functions aren't in the pb lib version.
it's the same with ma_sound_init_from_file_w in the ma_sound lib I made
User avatar
NicTheQuick
Addict
Addict
Posts: 1523
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: Expose more MiniAudio-Functions

Post by NicTheQuick »

Oh, I see. I didn't catch that in case you already said that before. :oops:
Maybe I will try it later again by compiling it myself. I found the headers in my linux packages but not the library itself. Weird. :?
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
User avatar
idle
Always Here
Always Here
Posts: 5921
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Expose more MiniAudio-Functions

Post by idle »

Miniaudio is a header only its rebellious c
AndyMK
Enthusiast
Enthusiast
Posts: 582
Joined: Wed Jul 12, 2006 4:38 pm
Location: UK

Re: Expose more MiniAudio-Functions

Post by AndyMK »

I added the ring buffer stuff but nothing works inside the callback. I even tried the lock free ring buffer i use with Portaudio and that also locks up inside the callback. Outside the callback, the ring buffer functions work fine although useless as there is not audio to process. Hoping you geniuses can figure this out.

Code: Select all

ma_pcm_rb_init(format.ma_format, channels.ma_uint32, bufferSizeInFrames.ma_uint32, *pOptionalPreallocatedBuffer, *pAllocationCallbacks, *pRB.ma_pcm_rb)
ma_pcm_rb_acquire_read(*pRB.ma_pcm_rb, *pSizeInFrames, *ppBufferOut)
ma_pcm_rb_commit_read(*pRB.ma_pcm_rb, sizeInFrames.ma_uint32, *pBufferOut)
ma_pcm_rb_acquire_write(*pRB.ma_pcm_rb, *pSizeInFrames, *ppBufferOut)
ma_pcm_rb_commit_write(*pRB.ma_pcm_rb, sizeInFrames.ma_uint32, *pBufferOut)
ma_pcm_rb_available_read(*pRB.ma_pcm_rb)
ma_pcm_rb_available_write(*pRB.ma_pcm_rb)

Global rb.ma_pcm_rb

If ma_pcm_rb_init(#ma_format_f32, 2, 256, #Null, #Null, @rb) <> #MA_SUCCESS
  Debug "Failed to initialize ring buffer"
  End
EndIf

Debug ma_pcm_rb_available_write(@rb) ; Works fine here but not in the callback.
User_Russian
Addict
Addict
Posts: 1554
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

Re: Expose more MiniAudio-Functions

Post by User_Russian »

idle wrote: Tue Feb 27, 2024 2:09 am

Code: Select all

  ;-test device enumeration 
  Global  context.ma_context;
  Global  *pPlaybackDeviceInfos.ma_device_info_Array;
  Global  playbackDeviceCount.ma_uint32;
  Global  *pCaptureDeviceInfos.ma_device_info_Array;
  Global  captureDeviceCount.ma_uint32;
  Global  iDevice.ma_uint32;
  
  If ma_context_init(#Null, 0, #Null, @context) <> #MA_SUCCESS
    PrintN("Failed to initialize context");
    End -2                                ;
  EndIf 
  
  result = ma_context_get_devices(@context, @*pPlaybackDeviceInfos, @playbackDeviceCount, @*pCaptureDeviceInfos, @captureDeviceCount);
  If result <> #MA_SUCCESS
    PrintN("Failed to retrieve device information");
    End -3                                         ;
  EndIf 
  
  PrintN("Playback Devices");
  For iDevice = 0 To  playbackDeviceCount-1
    PrintN("device " + Str(iDevice) + " " + PeekS(@*pPlaybackDeviceInfos\e[iDevice]\name,-1,#PB_Ascii))
  Next   
  
  PrintN("")
  
  PrintN("Capture Devices");
  For iDevice = 0 To captureDeviceCount-1 
    PrintN("device " + Str(iDevice) + " " + PeekS(@*pCaptureDeviceInfos\e[iDevice]\name,-1,#PB_Ascii))
  Next 
  
  ma_context_uninit(@context)
  
  Input();
  
CompilerEndIf 

Need replace #PB_Ascii to #PB_UTF8 because the device name is not displayed correctly.
User avatar
idle
Always Here
Always Here
Posts: 5921
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Expose more MiniAudio-Functions

Post by idle »

User_Russian wrote: Sun Sep 07, 2025 5:00 pm
idle wrote: Tue Feb 27, 2024 2:09 am

Code: Select all

  ;-test device enumeration 
  Global  context.ma_context;
  Global  *pPlaybackDeviceInfos.ma_device_info_Array;
  Global  playbackDeviceCount.ma_uint32;
  Global  *pCaptureDeviceInfos.ma_device_info_Array;
  Global  captureDeviceCount.ma_uint32;
  Global  iDevice.ma_uint32;
  
  If ma_context_init(#Null, 0, #Null, @context) <> #MA_SUCCESS
    PrintN("Failed to initialize context");
    End -2                                ;
  EndIf 
  
  result = ma_context_get_devices(@context, @*pPlaybackDeviceInfos, @playbackDeviceCount, @*pCaptureDeviceInfos, @captureDeviceCount);
  If result <> #MA_SUCCESS
    PrintN("Failed to retrieve device information");
    End -3                                         ;
  EndIf 
  
  PrintN("Playback Devices");
  For iDevice = 0 To  playbackDeviceCount-1
    PrintN("device " + Str(iDevice) + " " + PeekS(@*pPlaybackDeviceInfos\e[iDevice]\name,-1,#PB_Ascii))
  Next   
  
  PrintN("")
  
  PrintN("Capture Devices");
  For iDevice = 0 To captureDeviceCount-1 
    PrintN("device " + Str(iDevice) + " " + PeekS(@*pCaptureDeviceInfos\e[iDevice]\name,-1,#PB_Ascii))
  Next 
  
  ma_context_uninit(@context)
  
  Input();
  
CompilerEndIf 

Need replace #PB_Ascii to #PB_UTF8 because the device name is not displayed correctly.
Makes sense.
I will redo it in the next beta
User_Russian
Addict
Addict
Posts: 1554
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

Re: Expose more MiniAudio-Functions

Post by User_Russian »

Tested the code on Linux and MacOS.
To do this, I changed the import code.

Code: Select all

;-Imports 
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  ImportC  "miniaudio.lib" 
CompilerElseIf #PB_Compiler_OS = #PB_OS_Linux
  ImportC  #PB_Compiler_Home+"/purelibraries/linux/libraries/libpbminiaudio.a"
CompilerElseIf #PB_Compiler_OS = #PB_OS_MacOS
  ImportC  #PB_Compiler_Home+"/purelibraries/macos/libraries/libpbminiaudio.a"
CompilerElse
  CompilerError  ""
CompilerEndIf
  ;ma_device_config_init(deviceType)
  ma_device_init(*pContext,*config,*Device)
  ma_device_start(*Device);
  ma_device_uninit(*Device);
  ma_get_bytes_per_sample(format.ma_format)
  ma_context_init(*ma_backend,backendCount.ma_uint32,*config,*context.ma_context)
  ma_context_get_devices(*context, *pPlaybackDeviceInfos, *playbackDeviceCount, *pCaptureDeviceInfos, *captureDeviceCount)
  ma_context_uninit(*context);
EndImport 
On Linux, the program exits with the message "invalid memory access" at this line in procedure data_callback().

Code: Select all

amount = framecount * (ma_get_bytes_per_sample(*Device\capture\format) * *Device\capture\channels)
In MacOS x64 the application fails to build due to a linker error.

Image

In MacOS miniaudio library does not contain all functions or what is the reason for the error?
User avatar
idle
Always Here
Always Here
Posts: 5921
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Expose more MiniAudio-Functions

Post by idle »

User_Russian wrote: Sun Sep 07, 2025 10:38 pm Tested the code on Linux and MacOS.
To do this, I changed the import code.

Code: Select all

;-Imports 
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  ImportC  "miniaudio.lib" 
CompilerElseIf #PB_Compiler_OS = #PB_OS_Linux
  ImportC  #PB_Compiler_Home+"/purelibraries/linux/libraries/libpbminiaudio.a"
CompilerElseIf #PB_Compiler_OS = #PB_OS_MacOS
  ImportC  #PB_Compiler_Home+"/purelibraries/macos/libraries/libpbminiaudio.a"
CompilerElse
  CompilerError  ""
CompilerEndIf
  ;ma_device_config_init(deviceType)
  ma_device_init(*pContext,*config,*Device)
  ma_device_start(*Device);
  ma_device_uninit(*Device);
  ma_get_bytes_per_sample(format.ma_format)
  ma_context_init(*ma_backend,backendCount.ma_uint32,*config,*context.ma_context)
  ma_context_get_devices(*context, *pPlaybackDeviceInfos, *playbackDeviceCount, *pCaptureDeviceInfos, *captureDeviceCount)
  ma_context_uninit(*context);
EndImport 
On Linux, the program exits with the message "invalid memory access" at this line in procedure data_callback().

Code: Select all

amount = framecount * (ma_get_bytes_per_sample(*Device\capture\format) * *Device\capture\channels)
In MacOS x64 the application fails to build due to a linker error.

Image

In MacOS miniaudio library does not contain all functions or what is the reason for the error?
The native PB lib is cutdown for whatever reason, if you wait for 6.30 b2 you wiill be able to call it directly with inline c
though you will need a compatible c install for the system headers to resolve types.

The main issue with Miniaudio is that it returns structures and some functions use structures as parameters, which means you either need to wrap those functions in c so you can import then into PB or use miniaudio directly with inline c in the header section. you will still need a compatible c install though for system headers and there will likely be a couple of type conflicts between PB's c typedefs though they can perhaps be fixed with pragmas.
User avatar
kenmo
Addict
Addict
Posts: 2047
Joined: Tue Dec 23, 2003 3:54 am

Re: Expose more MiniAudio-Functions

Post by kenmo »

idle wrote: Mon Sep 08, 2025 12:01 amThe main issue with Miniaudio is that it returns structures and some functions use structures as parameters, which means you either need to wrap those functions in c so you can import then into PB or use miniaudio directly with inline c in the header section. you will still need a compatible c install though for system headers and there will likely be a couple of type conflicts between PB's c typedefs though they can perhaps be fixed with pragmas.
I have nothing to contribute about MiniAudio, but I'm having this exact same issue interfacing with SDL3... For GUID functions, they pass and return the entire GUID (16-byte struct) and I haven't figured out how to handle it in PB! It's frustrating because everything else in the SDL API seems to use byref pointer-to-a-structure instead. I assumed I needed some fancy push-pop stack Assembly code, but perhaps now I can write C wrapper functions inside a HeaderSection...? To be explored...
User avatar
Piero
Addict
Addict
Posts: 961
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Re: Expose more MiniAudio-Functions

Post by Piero »

kenmo wrote: Tue Sep 09, 2025 4:19 amissue interfacing with SDL3
I hope SDL2 works better :? (seems very good for some HID stuff)
User avatar
idle
Always Here
Always Here
Posts: 5921
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Expose more MiniAudio-Functions

Post by idle »

kenmo wrote: Tue Sep 09, 2025 4:19 am
idle wrote: Mon Sep 08, 2025 12:01 amThe main issue with Miniaudio is that it returns structures and some functions use structures as parameters, which means you either need to wrap those functions in c so you can import then into PB or use miniaudio directly with inline c in the header section. you will still need a compatible c install though for system headers and there will likely be a couple of type conflicts between PB's c typedefs though they can perhaps be fixed with pragmas.
I have nothing to contribute about MiniAudio, but I'm having this exact same issue interfacing with SDL3... For GUID functions, they pass and return the entire GUID (16-byte struct) and I haven't figured out how to handle it in PB! It's frustrating because everything else in the SDL API seems to use byref pointer-to-a-structure instead. I assumed I needed some fancy push-pop stack Assembly code, but perhaps now I can write C wrapper functions inside a HeaderSection...? To be explored...
you could do it like this perhaps

Code: Select all

HeaderSection 

!integer sdl_getguid(){ 
!
!  SDL_GUID guid = SDL_FunctionThatReturnsGUID(); 
!  char *pzguid = PB_AllocateMemory(33);
!  SDL_GUIDToString(guid,*pzguid,33);
!  return *pzguid; 
!};  

EndHeaderSection  

PrototypeC SDL_GetGUID() 
Global SDL_GetGUID.SDL_GetGUID 
!g_sdl_getguid = &sdl_getguid; 

Debug PeekS(SDL_GetGUID(),16,#PB_Ascii) 
Post Reply