Ooops
October 28, 2021, 12:53:13

Author Topic: MiniAudio-Wrapper for BlitzMax enables WASAPI Playback and Recording + MP3  (Read 1816 times)

Offline Midimaster

  • Sr. Member
  • ****
  • Posts: 364
    • Midimaster Music Education Software
New Version 1.25 and moved to GitHub
« Reply #15 on: June 08, 2021, 14:56:08 »
There is a new update 1.25 of the miniaudio wrapper avaiable. You will find it here:

https://github.com/MidimasterSoft/BlitzMax-Miniaudio-Wrapper

Here are some of the new functions/features:
  • Capturing Audio from Hardware USB-Devices upto 32 channels simultanously
  • New extended ExTaudioSample object for handling 32bit and multichannel Samples
  • Converting TAudioSamples into ExTAudioSamples
  • List and Select all avaiable Devices
  • Redesign of the wrapper for simplified use of the Library
  • Detailed Help-File in BlitzMax with a lot of examples

Here are three code examples related to capture:

Simply Capture into old BlitzMax TAudioSample
Code: BlitzMax
  1. SuperStrict
  2. Import mima.miniaudio
  3.  
  4. Graphics 400,300
  5.  
  6. ' Setup of the device:
  7. Const  HERTZ:Int = 48000
  8.  
  9. Global MiniAudio:TMiniAudio=New TMiniAudio
  10.  
  11. MiniAudio.OpenDevice( MiniAudio.DUPLEX, Miniaudio.FORMAT_S16, 1, HERTZ, MyCallBack)
  12.  
  13. ' we need a TaudioSample for storing the incoming samples and a SHORT PTR to handle them
  14. Global Recording:TAudioSample=CreateAudioSample( HERTZ*61,  HERTZ, SF_MONO16LE)  '60 seconds
  15. Global RecordingRam:Short Ptr = Recording.Samples
  16.  
  17. Global WritePointer:Int, RecordMode%, Audio:TChannel
  18. Local Music:TSound =LoadSound(Recording)
  19. Audio=PlaySound(Music)
  20.  
  21. SetClsColor 255,255,255
  22. Repeat
  23.     Cls
  24.                 DrawScreen
  25.                 If MouseHit(1)
  26.                         RecordMode=1-RecordMode
  27.                         If RecordMode=0
  28.                                 Print "PLAY"
  29.                                 MiniAudio.StopDevice()
  30.                                 Local Music:TSound =LoadSound(Recording)
  31.                                 Audio=PlaySound(music)
  32.                         Else
  33.                                 Print "RECORD"
  34.                                 ClearSample()
  35.                                 StopChannel Audio
  36.                                 WritePointer=0
  37.                                 MiniAudio.StartDevice()
  38.                         EndIf
  39.                 EndIf  
  40.     Flip 0
  41. Until AppTerminate()
  42. Miniaudio.CloseDevice()
  43.  
  44.  
  45. Function MyCallBack(a%, PlayBackBuffer:Short Ptr, RecordingBuffer:Short Ptr, Frames:Int)
  46.         ' cares about not to overrun the TAudioSample-size:
  47.         If WritePointer>HERTZ*60 Then WritePointer=0
  48.  
  49.         For Local i:Int=0 To frames-1
  50.                 ' fetch the sample:
  51.                 Local value:Short   = RecordingBuffer[i]
  52.                
  53.                 ' duplx it immediately:
  54.                 PlayBackBuffer[i] = value
  55.                
  56.                 'and transfer it to the TAudioSample:
  57.                 RecordingRAM[WritePointer+i] = value
  58.         Next
  59.     WritePointer = WritePointer + Frames
  60. End Function
  61.  
  62.  
  63. Function ClearSample()
  64.         For Local i:Int=0 To HERTZ*60
  65.                 RecordingRAM[i]=0
  66.         Next                           
  67. End Function
  68.  
  69. Function DrawScreen()
  70.         ...
  71. End Function


Stereo Capture with high quality 32bit-Float and save to WAV-file
Code: BlitzMax
  1. SuperStrict
  2. Import mima.miniaudio
  3.  
  4. Graphics 400,300
  5.  
  6. ' Setup of the device:
  7. Const    HERTZ:Int = 48000
  8. Const CHANNELS:Int = 2
  9.  
  10. Global MiniAudio:TMiniAudio=New TMiniAudio
  11.  
  12. Global Recording:ExTAudioSample = ExTAudioSample.Create(HERTZ*61,  HERTZ, MiniAudio.FORMAT_F32, CHANNELS)
  13. Print Recording.format
  14. Print Recording.Hertz
  15. Print Recording.channels
  16. MiniAudio.OpenDevice( MiniAudio.DUPLEX, Miniaudio.FORMAT_F32, CHANNELS, HERTZ, MyCallBack)
  17.  
  18.  
  19. Global WritePointer:Int, RecordMode%
  20. SetClsColor 255,255,255
  21. Repeat
  22.     Cls
  23.                 DrawScreen
  24.                 If MouseHit(1)
  25.                         RecordMode=1-RecordMode
  26.                         If RecordMode=0
  27.                                 Print "PLAY"
  28.                                 MiniAudio.StopDevice()
  29.                                 MiniAudio.SaveExTAudioSample "MySong.WAV", Recording
  30.                         Else
  31.                                 Print "RECORD"
  32.                                 Recording.Clear
  33.                                 WritePointer=0
  34.                                 MiniAudio.StartDevice()
  35.                         EndIf
  36.                 EndIf  
  37.     Flip 0
  38. Until AppTerminate()
  39. Miniaudio.CloseDevice()
  40. End
  41.  
  42.  
  43. Function MyCallBack(a%, PlayBackBuffer:Float Ptr, RecordingBuffer:Float Ptr, Frames%)
  44.         ' cares about not to overrun the ExTAudioSample-size:
  45.         If WritePointer>HERTZ*60 Then WritePointer=0
  46.  
  47.         For Local i:Int=0 To frames-1
  48.                 ' fetch the sample:
  49.                 Local value:Float   = RecordingBuffer[i]
  50.                
  51.                 ' duplx it immediately:
  52.                 PlayBackBuffer[i] = value
  53.                
  54.                 'and transfer it to the TAudioSample:
  55.                 Recording.SampleFloat[WritePointer+i] = value
  56.         Next
  57.     WritePointer = WritePointer + Frames
  58.  
  59. End Function
  60.  
  61.  
  62.  
  63.  
  64. Function DrawDrawScreen()
  65. ...
  66. End Function
  67.  


8-Channel Capture from USB-hardware device and save as 8track-file
Code: BlitzMax
  1. ' example to demonstrate MULTI-CHANNEL capturing audio with miniaudio
  2. ' and transfering datas to the NEW extended ExTAudioSample type
  3. ' Quality is FORMAT_S32 only for demonstration
  4. ' the DUPLEX will reduce the 8 channels to 2 "manually"
  5. ' when recording is stopped the ExTAudioSample is saved as a 8track-16bit WAV-file
  6. ' this make it necessary to convert from S32 to S16
  7. SuperStrict
  8. Import mima.miniaudio
  9.  
  10. Graphics 400,300
  11.  
  12. ' Setup of the device:
  13. Const    HERTZ:Int = 44100
  14. Const CHANNELS:Int = 8
  15.  
  16. Global MiniAudio:TMiniAudio=New TMiniAudio
  17.  
  18. 'only hardware devices can capture 8 channels. So connect your USB-device and select it with its ID:
  19. Print   "Capture-Devices:"
  20. Local i:Int
  21. For Local DeviceName:String= EachIn MiniAudio.CaptureDevices()
  22.         Print  "ID=" + i + ": " + DeviceName
  23.         i=i+1
  24. Next
  25. Local MyUsbDevice:Int=1
  26. Miniaudio.SelectDevices(-1,MyUsbDevice)
  27.  
  28.  
  29. Global Recording:ExTAudioSample = ExTAudioSample.Create(HERTZ*61,  HERTZ, MiniAudio.FORMAT_S32, CHANNELS)
  30. Print Recording.format
  31. Print Recording.Hertz
  32. Print Recording.channels
  33. ' use OpenDevice_II when Playback and Capture needs different parameters:
  34. MiniAudio.OpenDevice_II( MiniAudio.DUPLEX, Miniaudio.FORMAT_S32, 2, Miniaudio.FORMAT_S32, CHANNELS, HERTZ, MyCallBack)
  35.  
  36.  
  37. Global WritePointer:Int
  38. Global RecordMode%
  39.  
  40. SetClsColor 255,255,255
  41. Repeat
  42.     Cls
  43.                 DrawScreen
  44.                 If MouseHit(1)
  45.                         RecordMode=1-RecordMode
  46.                         If RecordMode=0
  47.                                 Print "PLAY"
  48.                                 MiniAudio.StopDevice()
  49.                                 'this would easily save the wav with 32bit-INT:
  50.                                 MiniAudio.SaveExTAudioSample "MySong.WAV", Recording
  51.                                
  52.                                 ' but we can also change the format during saving:
  53.                                 Local StreamID:MMStreamID = MiniAudio.OpenWavFile("My16bitsong.Wav" , Miniaudio.FORMAT_S16, CHANNELS, HERTZ)
  54.                                 MiniAudio.WriteWavFile StreamID, Recording.SampleInt, Recording.Frames, Recording.Format, CHANNELS, HERTZ
  55.                                 MiniAudio.CloseWavfile StreamID
  56.                         Else
  57.                                 Print "RECORD"
  58.                                 Recording.Clear
  59.                                 WritePointer=0
  60.                                 MiniAudio.StartDevice()
  61.                         EndIf
  62.                 EndIf  
  63.     Flip 0
  64. Until AppTerminate()
  65. Miniaudio.CloseDevice()
  66. End
  67.  
  68.  
  69. Function MyCallBack(a%, PlayBackBuffer:Int Ptr, RecordingBuffer:Int Ptr, Frames:Int)
  70.         If WritePointer > (HERTZ*60*CHANNELS) Then WritePointer=0
  71.  
  72.         For Local i:Int=0 To Frames-1
  73.                 For Local j:Int=0 To CHANNELS-1
  74.                         ' fetch the samples:
  75.                         Local value:Int = RecordingBuffer[i*CHANNELS + j]
  76.                        
  77.                         'and transfer it to the TAudioSample:
  78.                         Recording.SampleInt[WritePointer+i*CHANNELS + j] = value               
  79.                 Next
  80.                 ' now route the 8 capture channels to only 2 playbak channels as you like:
  81.                 ' to prevent Distortion we divide each sample volume by 2
  82.                 Local valueL:Int = RecordingBuffer[8*i+0]/2 + RecordingBuffer[8*i+1]/2 + RecordingBuffer[8*i+2]/2 + RecordingBuffer[8*i+3]/2
  83.                 Local valueR:Int = RecordingBuffer[8*i+4]/2 + RecordingBuffer[8*i+5]/2 + RecordingBuffer[8*i+6]/2 + RecordingBuffer[8*i+7]/2
  84.                 PlayBackBuffer[2*i+0] = valueL
  85.                 PlayBackBuffer[2*i+1] = valueR
  86.         Next
  87.     WritePointer = WritePointer + Frames*CHANNELS
  88. End Function
  89.  
  90.  
  91. Function DrawScreen()
  92.         ...
  93. End Function
  94.  

Full example code can be downloaded form the GitHub repository!
See my current project on PlayStore: 20Tracks-Audio-Player https://play.google.com/store/apps/details?id=midimaster.twentytrackd

Offline Baggey

  • Full Member
  • ***
  • Posts: 198
Absolutly awsome!

Got some more time to play with the sound side of my spectrum emulator

Ive down loaded mima.mod and extracted to  C:/Blitzmax/mod

when i try C:\BlitzMax\mod\mima.mod\miniaudio.mod\examples\PlayNoise.bmx

I am using Windows 10 and Blitzmax 1.5 I think it's called Vanilla

Code: BlitzMax
  1. SuperStrict
  2. Import mima.miniaudio
  3.  
  4. Graphics 800,600
  5.  
  6. ' Setup of the device:
  7. Global MiniAudio:TMiniAudio=New TMiniAudio
  8. MiniAudio.OpenDevice( MiniAudio.PLAYBACK, Miniaudio.FORMAT_S16, 1, 48000, MyCallBack)
  9.  
  10.  
  11.  
  12. ' now start it:
  13. MiniAudio.StartDevice()
  14. Global NOISE%=0, Zeit%=MilliSecs()
  15. Repeat
  16.         Cls
  17.         DrawText "Kick LEFT MOUSE for NOISE",100,100
  18.         If MouseDown(1)
  19.                         NOISE=1
  20.         Else
  21.                 NOISE=0
  22.         EndIf
  23.         Flip 0
  24. Until AppTerminate()
  25. Miniaudio.CloseDevice()
  26. End
  27.  
  28.  
  29. Function MyCallBack(a%, PlayBuffer:Short Ptr, RecordingBuffer:Short Ptr, Frames%)
  30.         ' here you manipulate the sound:
  31.         If NOISE=1
  32.                 For Local i%=0 To frames-1
  33.                         PlayBuffer[i]=Rand(-32000,+32000)
  34.                 Next
  35.         EndIf
  36. End Function

Im getting Compile Error Can't find interface for module 'mima.miniaudio'



 :-[

Kind Regards Baggey
« Last Edit: July 03, 2021, 10:56:26 by Baggey »
Currently Running a PC that just Aint fast enough!?
ZX Spectrum 48k, NEXT, C64, ORIC Atmos 48K, Enterprise 128K, The SID chip.

Jesus was only famous because of his DAD.    Resistance Is Futile! The code will be assimulated!

Offline Baggey

  • Full Member
  • ***
  • Posts: 198
So Ive tried in,

Blitzmax 1.5 ' It Dosent Work!  :'(

Works in Blitzmax NG  Thou? :-X

Any idea Why this dosent work in Blitzmax 1.5 or do the files need to be put into different places.

Kind regards Baggey
Currently Running a PC that just Aint fast enough!?
ZX Spectrum 48k, NEXT, C64, ORIC Atmos 48K, Enterprise 128K, The SID chip.

Jesus was only famous because of his DAD.    Resistance Is Futile! The code will be assimulated!

Offline Midimaster

  • Sr. Member
  • ****
  • Posts: 364
    • Midimaster Music Education Software
Did you already build the modules?
What were the complate error mesages you received?


Also Hardcoal had problems using it with BlitzMax 1.50. Did you find his post already?
https://www.syntaxbomb.com/index.php/topic,8467.msg347050348.html#msg347050348

We could change some code lines to make it more compatible to BlitzMAX 1.50 too. But afterwards Hardcoal reported more issues and canceled futher testings.

We think the problems now are related to the reduced multi-thread-capabilities of old BlitzMax.
See this answer from Col:
https://www.syntaxbomb.com/index.php/topic,8467.msg347050389.html#msg347050389

Maybe he can write something here?
See my current project on PlayStore: 20Tracks-Audio-Player https://play.google.com/store/apps/details?id=midimaster.twentytrackd

Offline Baggey

  • Full Member
  • ***
  • Posts: 198
My error messages are from the Output window! I don't know how to get a more detailed Log?



Kind Regards Baggey
« Last Edit: July 03, 2021, 12:10:01 by Baggey »
Currently Running a PC that just Aint fast enough!?
ZX Spectrum 48k, NEXT, C64, ORIC Atmos 48K, Enterprise 128K, The SID chip.

Jesus was only famous because of his DAD.    Resistance Is Futile! The code will be assimulated!

Offline Hardcoal

  • Hero Member
  • *****
  • Posts: 749
  • Nothing is personal
i tried to compile the  mima.miniaudio and it didnt work..

im using blitzmax vanilla

it gives me this error

Code: [Select]
►mima.miniaudio was scheduled to next iteration
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s: Assembler messages:
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:2: Error: junk at end of line, first unrecognized character is `,'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:3683: Error: junk at end of line, first unrecognized character is `,'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:93856: Error: junk at end of line, first unrecognized character is `,'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:93857: Error: junk at end of line, first unrecognized character is `,'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:93858: Error: junk at end of line, first unrecognized character is `,'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:96818: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:97458: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:97672: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:98312: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:98408: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:99048: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:99144: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:99784: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:99880: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:100520: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:108021: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:108661: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:108757: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:109397: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:109493: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:110133: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:110229: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:110869: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:112495: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:113135: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:115440: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:116049: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:122339: Error: no such instruction: `lzcntl %eax,%eax'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:148911: Error: junk at end of line, first unrecognized character is `,'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:166658: Error: junk at end of line, first unrecognized character is `,'
C:\Users\Hardc\AppData\Local\Temp\ccpKnT8e.s:166805: Error: junk at end of line, first unrecognized character is `,'
Build Error: failed to compile D:/PORTABLE/BlitzMax/mod/mima.mod/miniaudio.mod/miniaudiowrapper.c
►►►►mima.miniaudio was not built. See error information on latest attempt.
Some things can break me down.
Some cant

Offline Midimaster

  • Sr. Member
  • ****
  • Posts: 364
    • Midimaster Music Education Software
i tried to compile the  mima.miniaudio and it didnt work..

im using blitzmax vanilla



Sorry MiniAudio is for BlitzMax NG only. We tried to convert, but there a re too many problems. Maybe in the far future...

Problems are:
  • BlitzMax Vanilla has not full Threaded support
  • BlitzMax Vanilla does not compile with GCC-, but with FASM-Compiler
  • BlitzMax casting problems
See my current project on PlayStore: 20Tracks-Audio-Player https://play.google.com/store/apps/details?id=midimaster.twentytrackd

Offline Derron

  • Hero Member
  • *****
  • Posts: 3675
Blitzmax vanilla compiles C stuff with GCC - hence the required MinGW installation (or a copy - if you use NGs BMK, which finds MinGW inside MinGW32 or MinGWx86 ...)

BlitzMax vanilla has threaded support - but requires you do do a threaded build while NG defaults to threaded builds.
Nonetheless the "buffer refill threads" could be kicked off from threads written in C.

For an example check these codes:
https://github.com/TVTower/TVTower/blob/master/source/Dig/base.sfx.soundmanager.freeaudio.bmx
https://github.com/TVTower/TVTower/blob/master/source/Dig/base.sfx.soundmanager.freeaudio.c

In essence you have the C code run your thread and on "tick" it calls back into the (non threaded built) blitzmax vanilla part.


bye
Ron

Offline Midimaster

  • Sr. Member
  • ****
  • Posts: 364
    • Midimaster Music Education Software
@derron

I can send you a list of problem I had when comping it with BlitzMax 1.50.

some of the problems I could already solve with compiler branches. But the list is still long, and always new message appear if old problems are solved.



Maybe we succedd in getting it run on BlitzMax 1.50 too...
See my current project on PlayStore: 20Tracks-Audio-Player https://play.google.com/store/apps/details?id=midimaster.twentytrackd

Offline Hardcoal

  • Hero Member
  • *****
  • Posts: 749
  • Nothing is personal
Its ok..

I dont expect people to convert things just for me lol..

ill manage somehow..

in the case of turning MP3 into wave ill just make something on NG and call it from BM 1.50
Some things can break me down.
Some cant

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal