SyntaxBomb - Indie Coders

General Category => Tutorials => Topic started by: GW on June 20, 2019, 07:14:10

Title: Easy Blitzmax Streaming realtime audio with Raylib
Post by: GW on June 20, 2019, 07:14:10
When it comes to Blitzmax and audio, There are lot of audio drivers/and libraries such as Directsound, FreeAudio, OpenAL, SoLoud, SDL, MaxMod etc.

But of those, only OpenAL has a method of streaming raw audio in realtime without the programmer  pulling thier hair out.  One downside of OpenAL is that it requires shipping a 32bit or 64bit dll (both named OpenAL32.dll   :( )  Raylib has no external dependencies and is backed by the WASAPI api for very low latency.

Enter Raylib (https://www.raylib.com/).  It's a games library with simple C interface and blitz-like command set.  That simple api carries forward into the audio portion as well and the author has done a great job putting a simple api on top of MiniAudio (https://github.com/dr-soft/miniaudio), a cross-platform low-level audio library.

How to do it:
Download the Raylib source at www.raylib.com (https://www.syntaxbomb.com/www.raylib.com)
Open the file 'raudio.c' and add the line #define RAUDIO_STANDALONE This sets the audio library to standalone and not have any dependencies with the rest of raylib.
Optional: Change 'MAX_STREAM_BUFFERS' to 3 and 'AUDIO_BUFFER_SIZE' to 2048.  If you have a slow computer, you may want to leave the defaults.

Next add the library and function definitions to blitzmax.
Import "Raylib\src\raudio.c"

Extern
    Function IsAudioDeviceReady%()
    Function InitAudioDevice()
    Function CloseAudioDevice()
    Function IsAudioBufferProcessed:Int(stream:AudioStream)                '// Check If any audio stream buffers requires refill
    Function PlayAudioStream(stream:AudioStream)                        '// Play audio stream
    Function InitAudioStream:AudioStream(sampleRate:UInt, sampleSize:UInt, channels:UInt)            '// Init audio stream (To stream raw audio pcm data)
    Function UpdateAudioStream(stream:AudioStream, Data:Byte Ptr, samplesCount:Int) '// Update audio stream buffers with data
    Function SetMasterVolume(volume:Float)
EndExtern



Steps: 
Start the audio device.
Create the audio stream that will be played.
Create a buffer that you will write your data too.
Start playing the stream.
During the program loop check if the sound card needs more data. When it does, write your audio data to the buffer you created and tell the library to integrate the new data.
That's it!


Example:
Rem
    Audio streaming with 'Raylib Audio' Example
    2019 A.Woodard "GW"
Endrem

SuperStrict
Framework brl.basic
Import brl.glmax2d

Import "C:\Dev\temp\Raylib\src\raudio.c"

Extern
    Function IsAudioDeviceReady%()
    Function InitAudioDevice()
    Function CloseAudioDevice()
    Function IsAudioBufferProcessed:Int(stream:AudioStream)                '// Check If any audio stream buffers requires refill
    Function PlayAudioStream(stream:AudioStream)                        '// Play audio stream
    Function InitAudioStream:AudioStream(sampleRate:UInt, sampleSize:UInt, channels:UInt)            '// Init audio stream (To stream raw audio pcm data)
    Function UpdateAudioStream(stream:AudioStream, Data:Byte Ptr, samplesCount:Int) '// Update audio stream buffers with data
    Function SetMasterVolume(volume:Float)
EndExtern

Struct AudioStream
    Field sampleRate:UInt      '// Frequency (samples per second)
    Field sampleSize:UInt      '// Bit depth (bits per sample): 8, 16, 32 (24 Not supported)
    Field channels:UInt        '// Number of channels (1-mono, 2-stereo)
    Field audioBuffer:Byte Ptr '// Pointer To internal data used by the audio system.
    Field format%              '// Audio format specifier
    Field source%         '// Audio source id
    Field buffers%[2]     '// Audio buffers (Double buffering)
End Struct

'--------------------------------START-----------------------------------------------
AppTitle = "RayLib realtime audio streaming"
Graphics 1024, 500
SetLineWidth(1.5)

InitAudioDevice()

If Not IsAudioDeviceReady()
    RuntimeError("No Audio")
EndIf

OnEnd(CloseAudioDevice)

Const BUFFERSIZE:Int = 2048
Global mystream:AudioStream = InitAudioStream(44100, 32, 1) ;    '// Create the audio stream
Global a_writebuff:Float[BUFFERSIZE]                        '// create a buffer and a pointer to the buffer
Global writeBuf:Float Ptr = VarPtr a_writebuff[0]
Global Time:Float = 0

Const TWOPI:Double = Pi * 2


PlayAudioStream(mystream)    '// Start playing

SetMasterVolume(0.25)    '// easy on the ears

Print "Starting!"

Const FRQ:Float = 107.66
Global phase:Float

While True
    If KeyHit(KEY_ESCAPE) Then End
    Local buffproc:Int = IsAudioBufferProcessed(mystream)    '// if the sound card wants more data this is true
    If buffproc Then
        For Local i:Int = 0 Until BUFFERSIZE
            '// Get waveform
            phase:+FRQ * (TWOPI / mystream.samplerate)
            If phase > Pi Then phase:-TWOPI
            Local x:Float = sw(FRQ, phase)    'calc audio data
            '//Mod w/mouse
            x:*Float(MouseY()) / GraphicsHeight()    '// change volume by MouseY
            Local yy:Float = Float(MouseX()) / GraphicsWidth()    '// change gain by MouseX
            If Abs(x * (yy)) > 0.5 Then x = Sine(-x)    '//fold distortion
           
            '//write to buffer
            a_writebuff[i] = x * 0.25
        Next
        UpdateAudioStream(mystream, writeBuf, BUFFERSIZE)    '// tell raylib to use the new buffer
        Draw
    EndIf
Wend

'---------------------------------------------------------------------------------------------------------------------------     
Function Draw()
    Local y:Float
    Local y2:Float
    Local t:Int = 0
    For Local i:Int = 0 Until BUFFERSIZE Step 2
        y = y2
        y2 = 250 + (a_writebuff[i] * 500)
        DrawLine(i / 2, y, i / 2, y2)
    Next
    Flip
    Cls
    Time:+1
End Function
'---------------------------------------------------------------------------------------------------------------------------
Function Sine:Double(x:Double)
    Return Sin(x / (Pi / 180.0))
End Function
'---------------------------------------------------------------------------------------------------------------------------
Function sw:Float(f:Float, ph:Float)
    Local i:Float = 1, x:Float
    While (f * i) < (4000 * (1.1 + Sin(Time * 4)))
        x:+(Sine(ph * i) * (1.0 / i))
        i:+1 + Abs(Sine(Time / 10))
    Wend
    Return x
End Function
'---------------------------------------------------------------------------------------------------------------------------



Download Sourcecode with compiled windows example (http://www.kerneltrick.com/download/BmaxAudioStreamRaylib.zip)

(https://www.syntaxbomb.com/proxy.php?request=http%3A%2F%2Fwww.kerneltrick.com%2Fdownload%2Fraylibstreaming.png&hash=8fb788dbe6eb082800176ab323a49711a6fe6619)
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: MikeHart on June 20, 2019, 08:46:23
Is that vanilla BMAX or NG?
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: GW on June 20, 2019, 09:14:49
Quote from: MikeHart on June 20, 2019, 08:46:23
Is that vanilla BMAX or NG?

It's Bmax NG.
It should work on vanilla after changing all references of 'AudioStream' to 'byte ptr',  but I tried it and received an exception on the call to InitAudioStream. So it might need little more work under the hood.  Maybe it's related to needing an unsigned int and bmax only passing a signed int.
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: Henri on June 20, 2019, 09:24:36
Hi GW,

nice example and presentation. Good job 8)

Upon further examination, Raylib seems like a minimalist all-in-one solution for simple game development, where the audio portion is a wrapper for underline miniaudio library.
Miniaudio itself seems like a useful library with support for playback, decode, streaming and capture. I think Bmax is missing a comprehensive audio package at the moment, that is up-to-date, fully supported with the ability to playback and record.

Also, I like to standalone approach, with no dependencies, and a supportive license. Very Blitzlike :-)

-Henri
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: GW on June 20, 2019, 10:04:08
Quote from: Henri on June 20, 2019, 09:24:36
Hi GW,

nice example and presentation. Good job 8)

Upon further examination, Raylib seems like a minimalist all-in-one solution for simple game development, where the audio portion is a wrapper for underline miniaudio library.
Miniaudio itself seems like a useful library with support for playback, decode, streaming and capture. I think Bmax is missing a comprehensive audio package at the moment, that is up-to-date, fully supported with the ability to playback and record.

Also, I like to standalone approach, with no dependencies, and a supportive license. Very Blitzlike :-)

-Henri
Yeah, I tried to get streaming to work with all of the other bmax libraries, but either they don't support it. no documentation or my c++ skills are too weak.  Raylib was perfect fit.

It took a very short time to refactor my chiptune tracker away from openAL to raylib and it even feels like latency reduced too.
It raylib ever implemented shadowmapping I would seriously consider doing a BMax port of the whole thing.
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: Derron on June 20, 2019, 11:37:26
https://github.com/bmx-ng/maxmod2.mod
-> audio streaming (if you talk about ogg/mp3 ... not "input") depending on the rtAudio library


https://github.com/GWRon/Dig
-> "SoundManager" with Audiostreams either using "FreeAudio" (shipped with BlitzMax) or above's maxmod2.mod


I am currently overhauling the "SoundManager" and already cut away a lot of stuff but still having issues - eg "legacy blitzmax" + "debug build" leads to crashes. Somehow the buffer I need to pass to "FreeAudio" (done by skidracer at that time) is not sized properly.

Benefit is: the original BlitzMax-Audio-commands would still work ("PlaySound()", "CueChannel()"). So best would be to have "TAudio" take care of updating its content on its own. So if you created an audiostream then the audio file should register itself to some generic stream manager. The stream manager I created uses:
- BlitzMax threading if built "threaded" (default on NG, legacy needs "-h" param)
- C threading for non-threaded builds (so legacy with out threading enabled). The C-thread just calls a function of the stream manager so that it can get regularily updated.

This threading is required as you else will have distorted audio if you eg load a big file in one "chunk" or if you process a big amount of data in one loop (buffers will run empty - or buffers will not get fresh data and play the old audio again and again).



I am with all of you: the current audio situation in BlitzMax is ... "outdated" (compared to other programming-toolkits).
Somewhere I wrote about "miniaudio" and blitzmax already but I just cannot find it.

Using a 3rd party library means to be able to rely on their bugfixes - once the audio wrapper was done.


bye
Ron
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: Brucey on June 20, 2019, 17:04:05
I've been looking at a direct miniAudio implementation, but haven't had the time recently to work on it.
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: GW on June 20, 2019, 17:49:47
Quote from: Brucey on June 20, 2019, 17:04:05
I've been looking at a direct miniAudio implementation, but haven't had the time recently to work on it.

I'd be willing to help, up to the limit of my lame c skills.  If you could take the time to write a tutorial about how you go about making modules, that would very helpful to other who would help pick up the slack. It's often hard from the source to see the logic behind how things are done.
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: Derron on June 20, 2019, 18:36:07
I thought of having found first clues on how Brucey tackles modules creation but then - some weeks ago, he started to refine the way of doing (file structure of the steam.mod thing!).

Once the module is "there" I sometimes am able to extend it a tiny bit here and there but thats it... reached GetSkillLevelMax(2019) :-)


bye
Ron
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: Baggey on December 24, 2021, 18:10:13
Just Found this thread.

Are you or would you be interested in having a crack at creating a C64 SID player in BlitzmaxNG! could be FUN!  8)

Kind Regards Baggey
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: mainsworthy on May 07, 2022, 07:15:58
GW , I have been following this tutorial, and adapted the code, I have it playing RAW data and can speed it up and slow it down. But I cant stop the channel or sound , How do I do I?

here is a pic of what Im doing and I have put you in all the credits and help button

(https://img.itch.zone/aW1hZ2UvMTUxNjE3NS84ODU5NDU3LnBuZw==/original/ZQtWZp.png)

(https://img.itch.zone/aW1hZ2UvMTUxNjE3NS84ODU5NDU2LnBuZw==/original/SOw9EN.png)

https://agamecreator.itch.io/the-search-for-extra-terrestrials-program

this is the version i was following. both really but went for pure blitz, Im new to audio so I really am trying very hard, stopchannel and pausechannel dont work, I dont think they will because there not part of the type structure.

what im trying to do, is close it on a button, then start it again on a button, i want to switch it on off , I can turn the display off but the sound continues.

https://www.syntaxbomb.com/audio/frequency-modulation-sound/msg347054650/#msg347054650


Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: GW on May 07, 2022, 11:21:20
The simplest way to stop the sound output is to just write zeros into the audio buffer when you want silence. 
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: mainsworthy on May 07, 2022, 12:52:58
Quote from: GW on May 07, 2022, 11:21:20
The simplest way to stop the sound output is to just write zeros into the audio buffer when you want silence.

Thankyou! I will do it now.
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: mainsworthy on May 07, 2022, 22:52:58
Quote from: GW on May 07, 2022, 11:21:20
The simplest way to stop the sound output is to just write zeros into the audio buffer when you want silence.

I am really not good at this sound stuff, can you answer just a couple of things GW?   first I am taking the2 channel  16bit sample 4 bytes

ay2 = 0 + (modstore[44+aut]  +  modstore[44+aut+1] * 256)
ay = 0 + (modstore[44+aut+2]  +  modstore[44+aut+3] * 256)    ' the 44 is the header for audio files and aut is the counter that gets steped by 4, im not using ay at the moment i am asuming ay2 is mono

and I am also taking a 1 channel 16 bit sample 2 bytes and feeding them to your sliders

CFslider.val = tw
MAslider.val = ay2
MAslider.Name$ = ""

it shows the wav and seems to work but it does not sound like music

but It does not sound like audio, is this right, I am a total noob to audio, but its very interesting, but I need to have a startpoint where I can hear a Wav file?

any help would be great?
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: mainsworthy on May 08, 2022, 03:40:23
OK I can now here is Wav, but its quite distorted, I have set the 3 sliders with values, and I got some output, Im learning :)

No its not my wav, it seems to be software relating to the driver, but it is a tune of sorts, how do i use the buffer? I am putting data shorts direct into buffer prior to


buffer[Pos+f-] = data
buffer[Pos+f] = getaudio()

i just cant get a byte to sound

ok I filled the whole buffer, but I just cant tell whats playing
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: GW on May 08, 2022, 09:32:16
It's hard to understand what you're doing and what problems you're having. 
You said that your audio stream is setup to process 16bit, 2 channel audio. In that case you'll need to write short (2-byte) values to the buffer.
It would probably be best to create a short pointer to the buffer array to make writing easier.  the audio values are written in a left-channel, right-channel, left-channel... of short values. 
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: mainsworthy on May 08, 2022, 19:40:22
sorry I missed your reply before I posted  how do i set the channel position, this seems to be whats going wrong there is there  some sort of command like  fa_ChannelPosition(channel) to set the read  position of the audio player , or can i only read it?

.
OK, The sliders are position and value on each slider, got that

Im filling the buffer every time I have played a bufffer full, got that

the tune Im hearing seems to happen when I run out of data to fill buffer, kinda default driver tune.

but I still dont hear the buffer, to I need to do some math on the buffer data prior to putting it in bufffer like  Value%=Abs(Test.samples-127)

any help would be great!, but Im learning, I learn slow but once i know i know forever, never done audio its unbelievable, but fun
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: GW on May 08, 2022, 21:18:44
Are you generating audio to play or are you playing audio from a file?
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: mainsworthy on May 08, 2022, 21:31:05
Quote from: GW on May 08, 2022, 21:18:44
Are you generating audio to play or are you playing audio from a file?

im trying to fill the buffer with a 2 channel 16bit audio stream and then play it, I am so new to this audio stuff. i know its 44 byte header aswell but after 10 cycles it would be ok anyway.   I know this is wrong buffer[Pos + fq] = GetAudio() * 30000  i need to set to begining or something, just realised its streaming so you cant set the position , its continouse

If fill = 1
   Local readpos:Int = fa_ChannelPosition(channel)
   Local Write:Int = readpos + FRAG * 1 - writepos
   Local frags:Int = Write / FRAG
   
      While frags > 0
       Pos = writepos Mod (FRAG * 8)

      For fq = 0 Until FRAG * 8
      If aut+(Pos) < end of wav -4
      buffer[Pos+fq] = modstore[aut+fq]
      aut = aut + 1
      buffer[Pos+fq+1] = modstore[aut+fq]
      aut = aut + 1
buffer[Pos+fq+2] = modstore[aut+fq]
      aut = aut + 1
   buffer[Pos+fq+3] = modstore[aut+fq]
      aut = aut + 1
      
    buffer[Pos + fq] = GetAudio() * 30000

         EndIf
      Next
   
      writepos:+FRAG
      frags:-1
   Wend
'score = 0

fill = 0

Return
EndIf
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: GW on May 08, 2022, 22:12:44
Here is an basic example that uses the Raylib mod with the audio to stream for a 16bit stereo file.
The raylib drawing stuff is not needed to use the audio library. 
I would recommend that you make the most basic program you can to confirm that the streaming works correctly, then work on the other stuff.
Sample audio file can be downloaded here: http://www.gutterbox.com/download/sample.wav


SuperStrict
Framework brl.basic
Import brl.retro
Import ray.lib
Import ray.audio

Const BUFFERSIZE:Int = 2048 * 2

'// The Raylib drawing routines are optional.

InitWindow(500, 500, "stream")
InitAudioDevice()

Global my_stream:RAudioStream = InitAudioStream(44100, 16, 2)

Global a_writebuff:Short[BUFFERSIZE * 2]         
Global writeBuf:Short Ptr = Varptr a_writebuff[0]
Global BufPtr%
Global song:RWave = LoadWave("sample.wav")
Global songPtr:Short Ptr = song.Data

PlayAudioStream(my_stream)

SetMasterVolume(0.33)

While Not WindowShouldClose()
BeginDrawing()
ClearBackground(Black)

'// Audio stuff here //
'/////////
Local buffproc:Int = IsAudioStreamProcessed(my_stream) '// audio stream wants more data
If buffproc Then
For Local i:Int = 0 Until BUFFERSIZE * 2 Step 2
writeBuf[i] = songPtr[BufPtr]
writeBuf[i + 1] = songPtr[BufPtr + 1]
BufPtr:+2

BufPtr:Mod song.sampleCount*2
Next
UpdateAudioStream(my_stream, writeBuf, BUFFERSIZE * 2)
End If
'/////////

DrawText("song ptr: "+String(Int(BufPtr)), 10,10,20,Gray)
EndDrawing()
Wend


Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: mainsworthy on May 08, 2022, 22:50:39
Quote from: GW on May 08, 2022, 22:12:44
Here is an basic example that uses the Raylib mod with the audio to stream for a 16bit stereo file.
The raylib drawing stuff is not needed to use the audio library. 
I would recommend that you make the most basic program you can to confirm that the streaming works correctly, then work on the other stuff.
Sample audio file can be downloaded here: http://www.gutterbox.com/download/sample.wav


SuperStrict
Framework brl.basic
Import brl.retro
Import ray.lib
Import ray.audio

Const BUFFERSIZE:Int = 2048 * 2

'// The Raylib drawing routines are optional.

InitWindow(500, 500, "stream")
InitAudioDevice()

Global my_stream:RAudioStream = InitAudioStream(44100, 16, 2)

Global a_writebuff:Short[BUFFERSIZE * 2]         
Global writeBuf:Short Ptr = Varptr a_writebuff[0]
Global BufPtr%
Global song:RWave = LoadWave("sample.wav")
Global songPtr:Short Ptr = song.Data

PlayAudioStream(my_stream)

SetMasterVolume(0.33)

While Not WindowShouldClose()
BeginDrawing()
ClearBackground(Black)

'// Audio stuff here //
'/////////
Local buffproc:Int = IsAudioStreamProcessed(my_stream) '// audio stream wants more data
If buffproc Then
For Local i:Int = 0 Until BUFFERSIZE * 2 Step 2
writeBuf[i] = songPtr[BufPtr]
writeBuf[i + 1] = songPtr[BufPtr + 1]
BufPtr:+2

BufPtr:Mod song.sampleCount*2
Next
UpdateAudioStream(my_stream, writeBuf, BUFFERSIZE * 2)
End If
'/////////

DrawText("song ptr: "+String(Int(BufPtr)), 10,10,20,Gray)
EndDrawing()
Wend



Thanks GW im on it now.
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: mainsworthy on May 09, 2022, 01:10:26
GW , its quite and a little slow, but I can now hear a Wav file, Thankyou so much. its all downhill from here
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: Midimaster on May 09, 2022, 07:09:37
did you have a look on the MiniAudio-Module and its tutorials? I might be helpful to you.

https://www.syntaxbomb.com/worklogs/miniaudio-wrapper-for-blitzmax-enables-wasapi-playback-and-recording-mp3/msg347049742/#msg347049742
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: mainsworthy on May 09, 2022, 12:21:18
(https://img.itch.zone/aW1hZ2UvMTUxNjE3NS84ODg0MDUzLnBuZw==/original/jnqy35.png)

https://agamecreator.itch.io/the-search-for-extra-terrestrials-program   here is the link if you want to try it

Thanks MidiMaster, I cant believe it , I have been watching the Carrier signal play a tune, and I thought it was my Wav files, cant believe it, I learned so much. I would love to know how you stop a channel and restart it with the same name. I can stopchannel but it wont restart. any help will be grately recieved

I have discovered a new geek hobby, "The Search For Extra Terrestrial Inteligence" its great fun

Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: Baggey on April 20, 2023, 17:29:36
Hi Guys, This is all cool! It's a good geek Hobby :-X

mainsworthy (https://www.syntaxbomb.com/profile/?u=2854) I cant get the link to work?

GW (https://www.syntaxbomb.com/profile/?u=26) Ive followed what you've said. And as usual im missing something :-[ . 

When i run or compile i get these errors?

Building BmaxAudioStreamRaylib
[100%] Linking:BmaxAudioStreamRaylib.exe
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/.bmx/BmaxAudioStreamRaylib.bmx.gui.release.win32.x86.o:BmaxAudioStreamRaylib.bmx.gui.release.win32.x86.c:(.text+0x411): undefined reference to `InitAudioStream'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/.bmx/BmaxAudioStreamRaylib.bmx.gui.release.win32.x86.o:BmaxAudioStreamRaylib.bmx.gui.release.win32.x86.c:(.text+0x517): undefined reference to `IsAudioBufferProcessed'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x92fd0): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x93010): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x93075): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x930a3): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x930ec): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x93112): more undefined references to `TraceLog' follow
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x93e95): undefined reference to `LoadFileData'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x93ea7): undefined reference to `GetFileExtension'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x941a0): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x941d0): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x941f4): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x9425d): undefined reference to `LoadFileData'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x9426f): undefined reference to `GetFileExtension'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x945b8): undefined reference to `IsFileExtension'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x947e7): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x94813): undefined reference to `IsFileExtension'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x948d9): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x9490b): undefined reference to `SaveFileData'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x94950): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x94973): undefined reference to `IsFileExtension'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x949a3): undefined reference to `SaveFileData'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x94d1b): undefined reference to `SaveFileText'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x94d43): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x94d68): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x956c6): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x95f79): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x95fb0): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x95fe6): undefined reference to `IsFileExtension'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x9606e): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x9618b): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x961b6): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x961d2): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x961ee): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x96224): more undefined references to `TraceLog' follow
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x96260): undefined reference to `IsFileExtension'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x963a4): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x963e0): undefined reference to `IsFileExtension'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x96480): undefined reference to `IsFileExtension'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x96537): undefined reference to `IsFileExtension'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x9660b): undefined reference to `IsFileExtension'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x96754): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x9676d): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x9678e): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x96d2f): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x96eaf): undefined reference to `TraceLog'
C:/BlitzMaxNG/MinGW32x86/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/BlitzMaxNG/tmp/Raylib/src/.bmx/tRs_raudio.c.release.win32.x86.o:raudio.c:(.text+0x96ed2): more undefined references to `TraceLog' follow
collect2.exe: error: ld returned 1 exit status
Build Error: Failed to link C:/BlitzMaxNG/tmp/BmaxAudioStreamRaylib.exe
Process complete

Kind Regards Baggey
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: GW on April 23, 2023, 17:39:30
You should have an example in your "mod\ray.mod\examples\audio\" directory.  (audio_raw_stream.bmx)
See if that works for you. The api may have changed.
Title: Re: Easy Blitzmax Streaming realtime audio with Raylib
Post by: Baggey on April 24, 2023, 01:16:45
Quote from: GW on April 23, 2023, 17:39:30You should have an example in your "mod\ray.mod\examples\audio\" directory.  (audio_raw_stream.bmx)
See if that works for you. The api may have changed.

Hi, yes it works fine! LOL the Sine wave is upside down? ???

Baggey