Playing non-file audio
Playing non-file audio
Hi,
I have not linked to a library in c over 5 years, and haven't linked to a freebasic library in over ten years, so I'm really rusty. So if anyone can suggest any useful libraries to download, that would be interesting.
I haven't tried FMOD, BASS, SDL_MIXER, although I think back in the day I did use one for playing .mp3s. I am really new to linux and I read that the kernal uses something called ALSA to play audio (I assume it's like a driver). However, that seems like it may be too much effort to use directly.
What I am specifically interested in is making mathematical functions audio output on the operating system. For instance imagine a programme which outputted a sine wave at various frequencies. Which library would be the best, and any advise as to how I would tell it the amplitude over time? (Like a varying sine wave).
Thanks in advance,
Rob
I have not linked to a library in c over 5 years, and haven't linked to a freebasic library in over ten years, so I'm really rusty. So if anyone can suggest any useful libraries to download, that would be interesting.
I haven't tried FMOD, BASS, SDL_MIXER, although I think back in the day I did use one for playing .mp3s. I am really new to linux and I read that the kernal uses something called ALSA to play audio (I assume it's like a driver). However, that seems like it may be too much effort to use directly.
What I am specifically interested in is making mathematical functions audio output on the operating system. For instance imagine a programme which outputted a sine wave at various frequencies. Which library would be the best, and any advise as to how I would tell it the amplitude over time? (Like a varying sine wave).
Thanks in advance,
Rob
Re: Playing non-file audio
Some suggestions:
* Audio library for FreeBasic - Features
* fbsound 1.1 (dynamic) Windows/Linux 32 and 64-bit (wav mp3 ogg mod it xm s3m)
* Help testing ALSA streaming
fbsound is more focused on playing different file formats, but you can also create your own wave forms in memory (with some additional functions of your own).
* Audio library for FreeBasic - Features
* fbsound 1.1 (dynamic) Windows/Linux 32 and 64-bit (wav mp3 ogg mod it xm s3m)
* Help testing ALSA streaming
fbsound is more focused on playing different file formats, but you can also create your own wave forms in memory (with some additional functions of your own).
Re: Playing non-file audio
Thanks for the reply.
It's really late where I am and I have to go to bed ASAP, however I just searched 'fbsound' in the manual and Adobe reader didn't find it, do you happen to know roughly which page or section it's in?
I had a super quick look at the 'help testing ALSA' link you gave, so do I have it correct that I can stream data to it directly? I.e. not from a file, but just generate it 'live' from the code?
Thanks again!
It's really late where I am and I have to go to bed ASAP, however I just searched 'fbsound' in the manual and Adobe reader didn't find it, do you happen to know roughly which page or section it's in?
I had a super quick look at the 'help testing ALSA' link you gave, so do I have it correct that I can stream data to it directly? I.e. not from a file, but just generate it 'live' from the code?
Thanks again!
Re: Playing non-file audio
FBSound is here:
http://shiny3d.de/public/fbsound/fbsound-1.1.zip
See the sample program fbs_create_wave.bas in the `tests` subdirectory.
http://shiny3d.de/public/fbsound/fbsound-1.1.zip
See the sample program fbs_create_wave.bas in the `tests` subdirectory.
Re: Playing non-file audio
I tried the fbs_create_wave.bas code (I'm on a windows machine unfortunately ATM), thank you.
Being so out-of-practice I'm struggling on a bit of the detail for how it works (wish where was a few more comments). One thing I'm wondering is that: Is the code actually dependent on time, or does it just execute at the speed of the CPU? I.e. will it sound the same on a really old PC as it would on a very high end modern CPU?
I presume that 44100 is the sampling frequency (Hz), in the fbs_Create_Wave function, what is the @hWave used for? I remember that the @ means it's specifying an address in the memory, but I need to revise how pointers work.
Similarly, why is the 'i' multiplied by 2 here in the pSamples memory: pSamples[i*2 ] ?
I assume this is used similarly to an array? Again, I'm rusty.
Is sin in degrees or radians? I assume radians because "wstep=PI2/44100.0 * 400.0", so what is the '400' for? Because to sample 44100 times I wouldn't expect the 400 to be there. However, by modifying it I see that it IS necessary.
Note: I do get the error: FBS_INIT() message, I think it's caused by my AVG antivirus, but the code then does execute.
Thank you in advance
Being so out-of-practice I'm struggling on a bit of the detail for how it works (wish where was a few more comments). One thing I'm wondering is that: Is the code actually dependent on time, or does it just execute at the speed of the CPU? I.e. will it sound the same on a really old PC as it would on a very high end modern CPU?
I presume that 44100 is the sampling frequency (Hz), in the fbs_Create_Wave function, what is the @hWave used for? I remember that the @ means it's specifying an address in the memory, but I need to revise how pointers work.
Similarly, why is the 'i' multiplied by 2 here in the pSamples memory: pSamples[i*2 ] ?
I assume this is used similarly to an array? Again, I'm rusty.
Is sin in degrees or radians? I assume radians because "wstep=PI2/44100.0 * 400.0", so what is the '400' for? Because to sample 44100 times I wouldn't expect the 400 to be there. However, by modifying it I see that it IS necessary.
Note: I do get the error: FBS_INIT() message, I think it's caused by my AVG antivirus, but the code then does execute.
Thank you in advance
Re: Playing non-file audio
Hi,
All my questions from my last post still apply (I.e. what some of the constants were for), however I've been playing with the code to try and make it be a bit flexible with the amplitude and frequency of the sine wave and I'm having an issue. The issue is that when you loop fbs_play_sound, the initial instance still plays forever and I can't kill it, so when it loops again with a slightly different sine wave it is a superposition. Similarly, I tried CLSing to wipe off the old waveform, but it just clears so fast you can't see the next loopings waveform, and the screen just looks blank. Can anyone please offer some tips on how to remedy this?
Here is the code (use the keyboard arrow keys to do volume and frequency changes):
All my questions from my last post still apply (I.e. what some of the constants were for), however I've been playing with the code to try and make it be a bit flexible with the amplitude and frequency of the sine wave and I'm having an issue. The issue is that when you loop fbs_play_sound, the initial instance still plays forever and I can't kill it, so when it loops again with a slightly different sine wave it is a superposition. Similarly, I tried CLSing to wipe off the old waveform, but it just clears so fast you can't see the next loopings waveform, and the screen just looks blank. Can anyone please offer some tips on how to remedy this?
Here is the code (use the keyboard arrow keys to do volume and frequency changes):
Code: Select all
' #######################
' # fbs_create_wave.bas #
'#######################
'#include "../inc/fbsound.bi"
#include "../inc/fbsound_dynamic.bi"
' example of:
' fbs_Create_Wave(nSamples,@hWAve,@lpSamples)
function GetKeyNB() as integer
dim as string key
key = inkey
select case len(key)
case 0
return 0
case 1
return key[0]
case 2
return key[0] + (key[1] shl 8)
end select
end function
const data_path = "../data/"
chdir(exepath())
' only if not same as exe path
' fbs_Set_PlugPath("./")
if fbs_Init()=false then
print "error: FBS_INIT() " & FBS_Get_PlugError()
beep : sleep : end 1
end if
dim as integer nSamples = 44100
dim as integer hWave,hSound
dim as double w,wstep=PI2/44100.0 * 400.0
dim as FBS_SAMPLE ptr pSamples
dim as FBS_SAMPLE ptr pS,pP,pE
' !!! create window before init fbsound !!!
dim as integer sw=640,sh=480
screenres sw,sh
dim as double j = 1
dim as integer key
dim as integer A = 4000
do
key = GetKeyNB
select case(hex(key))
case "48FF"
A = A + 1000
case "50FF"
A = A - 1000
case "4DFF"
j = j + 0.1
case "4BFF"
j = j - 0.1
end select
fbs_Create_Wave(nSamples,@hWave,@pSamples)
for i as integer=0 to nSamples-1
' right channel
pSamples[i*2 ]=sin(w*j )*A:w+=wstep
' left channel
pSamples[i*2+1]=sin(w*j+PI)*A:w+=wstep
next
fbs_Create_Sound(hWave,@hSound)
fbs_Get_SoundPointers(hSound,@pS,@pP,@pE)
sw = 640 /2
sh = 480 /2
for x as integer=0 to sw-1
' right channel
pset (x ,sh+pE[-sw*2+x*2 ]*0.01),3 ' end of samples
pset (sw+x,sh+pS[ x*2 ]*0.01),4 ' start of samples
' left channel
pset (x ,sh+pE[-sw*2+x*2+1]*0.01),5 ' end of samples
pset (sw+x,sh+pS[ x*2+1]*0.01),6 ' start of samples
next
fbs_Play_Sound(hSound,-1) ' loop endless
loop until key = 27
print "playing clean sin wave endless"
sleep
end
Re: Playing non-file audio
If I understand correctly :
The samples are stored in an array of signed 16-bit integers. The values are -32768 to 32767. There are 65536 possible values. The dynamic is 20*log(65536) ~ 96 dB
For stereo the channels L = left and R = right are alterned :
where n is the number of samples.
This explains the multiplication by 2
Also, in the sample program 400 is the sound frequency in Hz
The samples are stored in an array of signed 16-bit integers. The values are -32768 to 32767. There are 65536 possible values. The dynamic is 20*log(65536) ~ 96 dB
For stereo the channels L = left and R = right are alterned :
Code: Select all
channel: L R L R ... L R
index: 0 1 2 3 ... n-2 n-1
where n is the number of samples.
This explains the multiplication by 2
Also, in the sample program 400 is the sound frequency in Hz
Re: Playing non-file audio
Yes, if you look at 'fbs_init.bas' you see some details:
' FBS_Init( [playbackrate in Hz.] optional default 44100
' ,[number of channels] optional default 2
' ,[number of buffers] optional default 3
' ,[frames per buffer] optional default 2048
' ,[nPlugIndex] optional default 0 = first
' ,[nDeviceIndex] optional default 0 = first) as boolean
So 2 channels: left & right. What you also see is buffers. These data buffer are transmitted [note1] to the soundcard/chip. As long as the CPU keeps sending these buffers in time, the sounds keeps going at a fixed rate (44100 Hz in this case).
[note1] Not sure if the data buffer is actually copied or if the soundchip directly plays the data at the location pointed to. But not so important for the functionality.
And yes, sin() uses radians 0..2*π for 1 full cycle.
' FBS_Init( [playbackrate in Hz.] optional default 44100
' ,[number of channels] optional default 2
' ,[number of buffers] optional default 3
' ,[frames per buffer] optional default 2048
' ,[nPlugIndex] optional default 0 = first
' ,[nDeviceIndex] optional default 0 = first) as boolean
So 2 channels: left & right. What you also see is buffers. These data buffer are transmitted [note1] to the soundcard/chip. As long as the CPU keeps sending these buffers in time, the sounds keeps going at a fixed rate (44100 Hz in this case).
[note1] Not sure if the data buffer is actually copied or if the soundchip directly plays the data at the location pointed to. But not so important for the functionality.
And yes, sin() uses radians 0..2*π for 1 full cycle.
Re: Playing non-file audio
Ah, okay you're getting things to make more sense to me. I haven't thought about db in a long time, so that is informative. Also, I was making a conceptual mistake in the size of the pSamples array, but I get it now, thanks.
Thanks for explaining that the 400 is the frequency in hz. So do you know if this is actually based on time, like some sort of operating system clock. Or is just like 400 hz, but might vary running the code on various CPUs of different computing power?
In the code, why do they get the sine waves to change colour half way across the screen? Because all you need is:
Any tips on how to kill the fbs_play_sound function, so I can re-call it at a different frequency?
P.S. I thought of a dodgy way to delete the old sine waves when the amplitude of frequency change, but I don't really think it's the best way, I modified the case statement code, it just puts black sine waves over the old ones, but it doesn't work very well because some dots remain:
I would be grateful for any tips on how to improve this too. EDIT: (P.P.S I suppose I could just CLS instead of using black sine waves in the case select statement)
Much appreciate you help
Thanks for explaining that the 400 is the frequency in hz. So do you know if this is actually based on time, like some sort of operating system clock. Or is just like 400 hz, but might vary running the code on various CPUs of different computing power?
In the code, why do they get the sine waves to change colour half way across the screen? Because all you need is:
Code: Select all
'sw = 640 /2
sh = 480 /2
for x as integer=0 to sw-1
' right channel
pset (x ,sh+pE[-sw*2+x*2 ]*0.01),3 ' end of samples
'pset (sw+x,sh+pS[ x*2 ]*0.01),4 ' start of samples
' left channel
pset (x ,sh+pE[-sw*2+x*2+1]*0.01),5 ' end of samples
'pset (sw+x,sh+pS[ x*2+1]*0.01),6 ' start of samples
next
P.S. I thought of a dodgy way to delete the old sine waves when the amplitude of frequency change, but I don't really think it's the best way, I modified the case statement code, it just puts black sine waves over the old ones, but it doesn't work very well because some dots remain:
Code: Select all
select case(hex(key))
case "48FF"
A = A + 1000
for x as integer=0 to sw-1
' right channel
pset (x ,sh+pE[-sw*2+x*2 ]*0.01),0 ' end of samples
' left channel
pset (x ,sh+pE[-sw*2+x*2+1]*0.01),0 ' end of samples
next
case "50FF"
A = A - 1000
for x as integer=0 to sw-1
' right channel
pset (x ,sh+pE[-sw*2+x*2 ]*0.01),0 ' end of samples
' left channel
pset (x ,sh+pE[-sw*2+x*2+1]*0.01),0 ' end of samples
next
case "4DFF"
j = j + 0.1
for x as integer=0 to sw-1
' right channel
pset (x ,sh+pE[-sw*2+x*2 ]*0.01),0 ' end of samples
' left channel
pset (x ,sh+pE[-sw*2+x*2+1]*0.01),0 ' end of samples
next
case "4BFF"
j = j - 0.1
for x as integer=0 to sw-1
' right channel
pset (x ,sh+pE[-sw*2+x*2 ]*0.01),0 ' end of samples
' left channel
pset (x ,sh+pE[-sw*2+x*2+1]*0.01),0 ' end of samples
next
end select
Much appreciate you help
Re: Playing non-file audio
The soundchip plays it samples exactly at 44100 Hz. So if your sample content is high - low - high - low, etc. you get a 22050 Hz sound (in theory, it is likely that some ~20 kHz low pass is used and most humans don't year this frequency).tone wrote:Thanks for explaining that the 400 is the frequency in hz. So do you know if this is actually based on time, like some sort of operating system clock. Or is just like 400 hz, but might vary running the code on various CPUs of different computing power?
A better test: 10 x high sample value, 10 x low sample value, etc. That should give a 2205 kHz square wave. And should be (crystal-oscillator) accurate. But be sure that sequential data buffers align, else you get weird 'blibs'.
Re: Playing non-file audio
Try my library at: https://sourceforge.net/projects/freeba ... ary/files/
It has specific commands to emit sine waves, or also other waveforms, and to shape and filter them
It has specific commands to emit sine waves, or also other waveforms, and to shape and filter them
Re: Playing non-file audio
I'll be honest badidea, I had to read that three times to understand what you were saying, but that's a reflection on me, not you (haha). Thanks for the explanation. I am happy to hear the soundchip should use a crystal oscillator, but does the 'backend' like the library of FBSound interface with the soundchip directly? Or were you just speaking in general terms?
Back to my code, I found this sort of list of FBSound functions here:
http://shiny3d.de/public/fbsound/english.html
In it there is 'fbs_Destroy_Sound(@hSound)', I'm not sure if I'm using it correctly, but it seems to work well but please run the code and tell me your thoughts:
Thanks all!
Back to my code, I found this sort of list of FBSound functions here:
http://shiny3d.de/public/fbsound/english.html
In it there is 'fbs_Destroy_Sound(@hSound)', I'm not sure if I'm using it correctly, but it seems to work well but please run the code and tell me your thoughts:
Code: Select all
' #######################
' # fbs_create_wave.bas #
'#######################
'#include "../inc/fbsound.bi"
#include "../inc/fbsound_dynamic.bi"
' example of:
' fbs_Create_Wave(nSamples,@hWAve,@lpSamples)
function GetKeyNB() as integer
dim as string key
key = inkey
select case len(key)
case 0
return 0
case 1
return key[0]
case 2
return key[0] + (key[1] shl 8)
end select
end function
function mathsFunctRight(w as double,A as integer) as double
return sin(w)*A + sin(w*3)*A/3
end function
function mathsFunctLeft(w as double,A as integer) as double
return sin(w+PI)*A + sin(w*3+PI)*A/3
end function
const data_path = "../data/"
chdir(exepath())
' only if not same as exe path
' fbs_Set_PlugPath("./")
if fbs_Init()=false then
print "error: FBS_INIT() " & FBS_Get_PlugError()
beep : sleep : end 1
end if
dim as integer nSamples = 44100
dim as integer hWave,hSound
dim as double w,wstep
dim as FBS_SAMPLE ptr pSamples
dim as FBS_SAMPLE ptr pS,pP,pE
' !!! create window before init fbsound !!!
dim as integer sw=640,sh=480
screenres sw,sh
dim as double j = 400
dim as integer key
dim as integer A = 4000
do
key = GetKeyNB
select case(hex(key))
case "48FF"
A = A + 1000
fbs_Destroy_Sound(@hSound):cls
wstep = PI2/44100.0 * j
fbs_Create_Wave(nSamples,@hWave,@pSamples)
for i as integer=0 to nSamples-1
' right channel
pSamples[i*2 ]=mathsFunctRight(w,A)
w+=wstep
' left channel
pSamples[i*2+1]=mathsFunctLeft(w,A)
w+=wstep
next
fbs_Create_Sound(hWave,@hSound)
fbs_Get_SoundPointers(hSound,@pS,@pP,@pE)
fbs_Play_Sound(hSound,-1) ' loop endless
'sw = 640 /2
sh = 480 /2
for x as integer=0 to sw-1
' right channel
pset (x ,sh+pE[-sw*2+x*2 ]*0.01),3 ' end of samples
'pset (sw+x,sh+pS[ x*2 ]*0.01),4 ' start of samples
' left channel
pset (x ,sh+pE[-sw*2+x*2+1]*0.01),5 ' end of samples
'pset (sw+x,sh+pS[ x*2+1]*0.01),6 ' start of samples
next
case "50FF"
A = A - 1000
fbs_Destroy_Sound(@hSound):cls
wstep = PI2/44100.0 * j
fbs_Create_Wave(nSamples,@hWave,@pSamples)
for i as integer=0 to nSamples-1
' right channel
pSamples[i*2 ]=mathsFunctRight(w,A)
w+=wstep
' left channel
pSamples[i*2+1]=mathsFunctLeft(w,A)
w+=wstep
next
fbs_Create_Sound(hWave,@hSound)
fbs_Get_SoundPointers(hSound,@pS,@pP,@pE)
fbs_Play_Sound(hSound,-1) ' loop endless
'sw = 640 /2
sh = 480 /2
for x as integer=0 to sw-1
' right channel
pset (x ,sh+pE[-sw*2+x*2 ]*0.01),3 ' end of samples
'pset (sw+x,sh+pS[ x*2 ]*0.01),4 ' start of samples
' left channel
pset (x ,sh+pE[-sw*2+x*2+1]*0.01),5 ' end of samples
'pset (sw+x,sh+pS[ x*2+1]*0.01),6 ' start of samples
next
case "4DFF"
j = j + 10
fbs_Destroy_Sound(@hSound):cls
wstep = PI2/44100.0 * j
fbs_Create_Wave(nSamples,@hWave,@pSamples)
for i as integer=0 to nSamples-1
' right channel
pSamples[i*2 ]=mathsFunctRight(w,A)
w+=wstep
' left channel
pSamples[i*2+1]=mathsFunctLeft(w,A)
w+=wstep
next
fbs_Create_Sound(hWave,@hSound)
fbs_Get_SoundPointers(hSound,@pS,@pP,@pE)
fbs_Play_Sound(hSound,-1) ' loop endless
'sw = 640 /2
sh = 480 /2
for x as integer=0 to sw-1
' right channel
pset (x ,sh+pE[-sw*2+x*2 ]*0.01),3 ' end of samples
'pset (sw+x,sh+pS[ x*2 ]*0.01),4 ' start of samples
' left channel
pset (x ,sh+pE[-sw*2+x*2+1]*0.01),5 ' end of samples
'pset (sw+x,sh+pS[ x*2+1]*0.01),6 ' start of samples
next
case "4BFF"
j = j - 10
fbs_Destroy_Sound(@hSound):cls
wstep = PI2/44100.0 * j
fbs_Create_Wave(nSamples,@hWave,@pSamples)
for i as integer=0 to nSamples-1
' right channel
pSamples[i*2 ]=mathsFunctRight(w,A)
w+=wstep
' left channel
pSamples[i*2+1]=mathsFunctLeft(w,A)
w+=wstep
next
fbs_Create_Sound(hWave,@hSound)
fbs_Get_SoundPointers(hSound,@pS,@pP,@pE)
fbs_Play_Sound(hSound,-1) ' loop endless
'sw = 640 /2
sh = 480 /2
for x as integer=0 to sw-1
' right channel
pset (x ,sh+pE[-sw*2+x*2 ]*0.01),3 ' end of samples
'pset (sw+x,sh+pS[ x*2 ]*0.01),4 ' start of samples
' left channel
pset (x ,sh+pE[-sw*2+x*2+1]*0.01),5 ' end of samples
'pset (sw+x,sh+pS[ x*2+1]*0.01),6 ' start of samples
next
end select
loop until key = 27
print "playing clean sin wave endless"
sleep
end
Re: Playing non-file audio
tone wrote:I'll be honest badidea, I had to read that three times to understand what you were saying, but that's a reflection on me, not you (haha). Thanks for the explanation. I am happy to hear the soundchip should use a crystal oscillator, but does the 'backend' like the library of FBSound interface with the soundchip directly? Or were you just speaking in general terms?
Back to my code, I found this sort of list of FBSound functions here:
http://shiny3d.de/public/fbsound/english.html
In it there is 'fbs_Destroy_Sound(@hSound)', I'm not sure if I'm using it correctly, but it seems to work well but please run the code and tell me your thoughts (go easy on me, I'm not a programmer, heehee):
Also, you can see I commented out the "Start of samples" on the PSET drawings, because I don't understand what they're for, if anyone can explain that too, that would satisfy my curiosity.Code: Select all
' ####################### ' # fbs_create_wave.bas # '####################### '#include "../inc/fbsound.bi" #include "../inc/fbsound_dynamic.bi" ' example of: ' fbs_Create_Wave(nSamples,@hWAve,@lpSamples) function GetKeyNB() as integer dim as string key key = inkey select case len(key) case 0 return 0 case 1 return key[0] case 2 return key[0] + (key[1] shl 8) end select end function function mathsFunctRight(w as double,A as integer) as double return sin(w)*A + sin(w*3)*A/3 end function function mathsFunctLeft(w as double,A as integer) as double return sin(w+PI)*A + sin(w*3+PI)*A/3 end function const data_path = "../data/" chdir(exepath()) ' only if not same as exe path ' fbs_Set_PlugPath("./") if fbs_Init()=false then print "error: FBS_INIT() " & FBS_Get_PlugError() beep : sleep : end 1 end if dim as integer nSamples = 44100 dim as integer hWave,hSound dim as double w,wstep dim as FBS_SAMPLE ptr pSamples dim as FBS_SAMPLE ptr pS,pP,pE ' !!! create window before init fbsound !!! dim as integer sw=640,sh=480 screenres sw,sh dim as double j = 400 dim as integer key dim as integer A = 4000 do key = GetKeyNB select case(hex(key)) case "48FF" A = A + 1000 fbs_Destroy_Sound(@hSound):cls wstep = PI2/44100.0 * j fbs_Create_Wave(nSamples,@hWave,@pSamples) for i as integer=0 to nSamples-1 ' right channel pSamples[i*2 ]=mathsFunctRight(w,A) w+=wstep ' left channel pSamples[i*2+1]=mathsFunctLeft(w,A) w+=wstep next fbs_Create_Sound(hWave,@hSound) fbs_Get_SoundPointers(hSound,@pS,@pP,@pE) fbs_Play_Sound(hSound,-1) ' loop endless 'sw = 640 /2 sh = 480 /2 for x as integer=0 to sw-1 ' right channel pset (x ,sh+pE[-sw*2+x*2 ]*0.01),3 ' end of samples 'pset (sw+x,sh+pS[ x*2 ]*0.01),4 ' start of samples ' left channel pset (x ,sh+pE[-sw*2+x*2+1]*0.01),5 ' end of samples 'pset (sw+x,sh+pS[ x*2+1]*0.01),6 ' start of samples next case "50FF" A = A - 1000 fbs_Destroy_Sound(@hSound):cls wstep = PI2/44100.0 * j fbs_Create_Wave(nSamples,@hWave,@pSamples) for i as integer=0 to nSamples-1 ' right channel pSamples[i*2 ]=mathsFunctRight(w,A) w+=wstep ' left channel pSamples[i*2+1]=mathsFunctLeft(w,A) w+=wstep next fbs_Create_Sound(hWave,@hSound) fbs_Get_SoundPointers(hSound,@pS,@pP,@pE) fbs_Play_Sound(hSound,-1) ' loop endless 'sw = 640 /2 sh = 480 /2 for x as integer=0 to sw-1 ' right channel pset (x ,sh+pE[-sw*2+x*2 ]*0.01),3 ' end of samples 'pset (sw+x,sh+pS[ x*2 ]*0.01),4 ' start of samples ' left channel pset (x ,sh+pE[-sw*2+x*2+1]*0.01),5 ' end of samples 'pset (sw+x,sh+pS[ x*2+1]*0.01),6 ' start of samples next case "4DFF" j = j + 10 fbs_Destroy_Sound(@hSound):cls wstep = PI2/44100.0 * j fbs_Create_Wave(nSamples,@hWave,@pSamples) for i as integer=0 to nSamples-1 ' right channel pSamples[i*2 ]=mathsFunctRight(w,A) w+=wstep ' left channel pSamples[i*2+1]=mathsFunctLeft(w,A) w+=wstep next fbs_Create_Sound(hWave,@hSound) fbs_Get_SoundPointers(hSound,@pS,@pP,@pE) fbs_Play_Sound(hSound,-1) ' loop endless 'sw = 640 /2 sh = 480 /2 for x as integer=0 to sw-1 ' right channel pset (x ,sh+pE[-sw*2+x*2 ]*0.01),3 ' end of samples 'pset (sw+x,sh+pS[ x*2 ]*0.01),4 ' start of samples ' left channel pset (x ,sh+pE[-sw*2+x*2+1]*0.01),5 ' end of samples 'pset (sw+x,sh+pS[ x*2+1]*0.01),6 ' start of samples next case "4BFF" j = j - 10 fbs_Destroy_Sound(@hSound):cls wstep = PI2/44100.0 * j fbs_Create_Wave(nSamples,@hWave,@pSamples) for i as integer=0 to nSamples-1 ' right channel pSamples[i*2 ]=mathsFunctRight(w,A) w+=wstep ' left channel pSamples[i*2+1]=mathsFunctLeft(w,A) w+=wstep next fbs_Create_Sound(hWave,@hSound) fbs_Get_SoundPointers(hSound,@pS,@pP,@pE) fbs_Play_Sound(hSound,-1) ' loop endless 'sw = 640 /2 sh = 480 /2 for x as integer=0 to sw-1 ' right channel pset (x ,sh+pE[-sw*2+x*2 ]*0.01),3 ' end of samples 'pset (sw+x,sh+pS[ x*2 ]*0.01),4 ' start of samples ' left channel pset (x ,sh+pE[-sw*2+x*2+1]*0.01),5 ' end of samples 'pset (sw+x,sh+pS[ x*2+1]*0.01),6 ' start of samples next end select loop until key = 27 print "playing clean sin wave endless" sleep end
Thanks all!
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: Playing non-file audio
@tone if you need support for FBSound use the right forum section please.
viewtopic.php?f=14&t=27272
If you will create playback samples on the fly
you don't need any hWave or hSound object
a callback method is the key :-)
Joshy
viewtopic.php?f=14&t=27272
If you will create playback samples on the fly
you don't need any hWave or hSound object
a callback method is the key :-)
Joshy
Code: Select all
#include "../inc/fbsound_dynamic.bi"
dim shared as integer gSampleRate
dim shared as integer gMIDINote = 57
sub MasterCB(byval pSamples as FBS_SAMPLE ptr, _
byval nChannels as integer, _
byval nSamples as integer)
static as double w=0.0
' no active MIDI note do nothing
if gMIDINote<1 then exit sub
' midi note to frequency
dim as double frequency = fbs_pow(2.0,(gMIDINote-69)/12.0)*440.0
dim as double wStep = PI2/gSampleRate*frequency
' render one or two channels with your own code !
select case as const nChannels
case 1 ' MONO
dim as FBS_SAMPLE ptr p = pSamples
for i as integer=0 to nSamples-1
*p=sin(w)*8000.0 : w+=wStep : p+=1
next
case 2 ' STEREO
dim as FBS_SAMPLE ptr pL = pSamples,pR=pL+1
for i as integer=0 to nSamples-1
*pL=sin(w)*8000.0 : *pR=*pL * -1 : w+=wStep
pL+=2 : pR+=2
next
end select
print "MIDI note: " & gMIDINote & " frequency: " & frequency
end sub
' init fbSound
ChDir(ExePath())
if fbs_Init()=false then
print "error: FBS_INIT() " & FBS_Get_PlugError()
beep : sleep : end 1
end if
' get playback sample rate
gSampleRate=FBS_Get_PlugRate()
' set and enable master callback
FBS_Set_MasterCallback(@MasterCB)
FBS_Enable_MasterCallback()
dim as double tRuntime,tNow,tStart=Timer()
dim as integer oldSeconds=-1,Seconds,noteStep=2
while inkey()=""
tNow=Timer():tRuntime=tNow-tStart:Seconds=int(tRuntime)
if Seconds<>oldSeconds then
gMIDINote += noteStep
if gMIDINote<57 or gMIDINote>82 then noteStep*=-1
oldSeconds = Seconds
end if
sleep 10
wend
' disable master callback
FBS_Disable_MasterCallback()
Re: Playing non-file audio
Thanks for the tip about callback, I'll go through your code again and try to get my head around it. Oh, okay, I didn't realise there was a FBSOUND section, I'll migrate over there because I have a question about getting my code to work on Linux now.
Cheers,
Rob
Cheers,
Rob