Audio library for FreeBasic - Features

General discussion for topics related to the FreeBASIC project or its community.
Post Reply
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Audio library for FreeBasic - Features

Post by badidea »

angros47 wrote:Has anyone tested it? I'd like some feedbacks and opinions
I missed / forgot this topic. I just sent myself a reminder to test tomorrow.

Maybe a stupid question, but there is no example code to be tested right?
So far, I can only say that "buildlinux.sh" did create a "libfbsfx.a" file (had to change the compiler path however).

I created a "libfbsfx32.a" and a "libfbsfx64.a" so I can test with fbc 32 & 64 bit. My first test program:

Code: Select all

#include "sfx.bi"
#inclib "fbsfx64"

? "1"
SoundSet (22000, 2, 16)
? "2"
Sound SineWave(2000), 0.5
? "3"
sleep 1000
? "4"
Play "cde", "def"
? "5"
sleep 1000
? "6"

Result:
Sound SineWave(2000), 0.5 works.
Play "cde", "def" does not do anything. Not sure that I have the syntax right.

System: Dell laptop with mostly Intel stuff, OS: Ubuntu Mate 18.04, Compiler: fbc 1.06.0
readme.txt wrote:SoundSet (Frequency, channels, bits)
It initializes the PCM sound (it must be used before using other sound commands), just as ScreenSet must be used before graphic commands. Channels can be set to 1 (mono) or 2 (stereo), "bits" can be 8 or 16, Frequency is the number of samples per second (the "resolution" of the sound)
I think you mean ScreenRes. Also ScreenRes is a function which returns ok / not ok. SoundSet does not allow this.

I did a quick conversion of the readme file to html (easier to read): readme_sfx.html
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

Re: Audio library for FreeBasic - Features

Post by angros47 »

Before using PLAY you should use SoundMidiSet to enable midi mode.

And yes, I meant ScreenRes, my mistake
VANYA
Posts: 1834
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Re: Audio library for FreeBasic - Features

Post by VANYA »

Hi angros47!

I did not use never team PLAY , but tried to ready the listing notes (example took from here):

Code: Select all

#include "sfx.bi"
#inclib "fbsfx"

SoundmidiSet ()

PLAY "T120<<e8e8f8g8g8f8e8d8c8c8d8e8e8d12d4"
PLAY "e8e8f8g8g8f8e8d8c8c8d8e8d8c12c4"
PLAY "d8d8e8c8d8e12f12e8c8d8e12f12e8d8c8d8p8"
PLAY "e8e8f8g8g8f8e8d8c8c8d8e8d8c12c4"
This example works. Linux Mint 18.3 (64-bit)

If you show other examples for testing , I'm sure , I will be able to test under Linux (64-bit) . Good luck!
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

Re: Audio library for FreeBasic - Features

Post by angros47 »

Try something like:

Code: Select all

SoundmidiSet ()

var Midi=CreateMidi()

PLAY Midi,"T120<<e8e8f8g8g8f8e8d8c8c8d8e8e8d12d4"
PLAY Midi,"e8e8f8g8g8f8e8d8c8c8d8e8d8c12c4"
PLAY Midi,"d8d8e8c8d8e12f12e8c8d8e12f12e8d8c8d8p8"
PLAY Midi,"e8e8f8g8g8f8e8d8c8c8d8e8d8c12c4"

SaveMidi "music.mid", Midi
You won't hear anything any more, but it should create a playable midi file
VANYA
Posts: 1834
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Re: Audio library for FreeBasic - Features

Post by VANYA »

angros47 wrote:Try something like:

Code: Select all

SoundmidiSet ()

var Midi=CreateMidi()

PLAY Midi,"T120<<e8e8f8g8g8f8e8d8c8c8d8e8e8d12d4"
PLAY Midi,"e8e8f8g8g8f8e8d8c8c8d8e8d8c12c4"
PLAY Midi,"d8d8e8c8d8e12f12e8c8d8e12f12e8d8c8d8p8"
PLAY Midi,"e8e8f8g8g8f8e8d8c8c8d8e8d8c12c4"

SaveMidi "music.mid", Midi
You won't hear anything any more, but it should create a playable midi file
The file is created and playing with code like this:

Code: Select all

#include "sfx.bi"
#inclib "fbsfx"

SoundmidiSet ()

var Midi=LoadMidi("music.mid")

PlayMidi(Midi, 1)

sleep
I also tried to play it in the program timidity , everything is fine.
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Audio library for FreeBasic - Features

Post by badidea »

Last character of play string is not played?

Code: Select all

play "a " 'ok

Code: Select all

play "a" 'nothing
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

Re: Audio library for FreeBasic - Features

Post by angros47 »

Yes, a little bug in the parser I haven't fixed yet
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Audio library for FreeBasic - Features

Post by badidea »

Just for fun, a command line 'egg timer'.

Code: Select all

#include "string.bi"
#include "sfx.bi"
#inclib "fbsfx"

dim as integer waitSec = val(command(1)) * 60
if waitSec = 0 then
	print "Use: timer.exe <minutes>"
	end
end if

function formatTime(sec as integer) as string
	return str(sec \ 60) + ":" + format(sec mod 60, "00")
end function

dim as double tStart = timer, tNow = tStart
dim as double tEnd = tStart + waitSec

SoundSet (44000, 2, 16)
SoundMidiSet()
sleep 100,1

print "Sound check, press <esc> to abort timer..."
play "L16 AAA L1 C "
cls

while tNow < tEnd
	locate 1,1: print "Time elapsed: " + formatTime(int(tNow - tStart))
	locate 2,1: print "Time left:    " + formatTime(int(tEnd - tNow))
	sleep 1000
	if inkey = chr(27) then exit while
	tNow = timer
wend

dim as string music(...) = {_
	"T180 <d8d8d8 T120 g2>d2", "T180 c8<b8a8 T120 >g2d4", _
	"T180 c8<b8a8 T120 >g2d4", "T180 c8<b8>c8 T120 <a2>"}

print "Playing alarm music"
while 1
	for i as integer = 0 to ubound(music)
		play("mb" + music(i) + " ")
		if inkey <> "" then exit while
	next
	sleep 1000
wend

print "End"
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

Re: Audio library for FreeBasic - Features

Post by angros47 »

In file "playtomidi.bas", change the line:

Code: Select all

	do while p < len(playstr)
to:

Code: Select all

	do while p <= len(playstr)
to fix the bug in PLAY of the last character being ignored
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

Re: Audio library for FreeBasic - Features

Post by angros47 »

I have updated the file on sourceforge, with the fix in playtomidi.bas and in the readme.txt file.

So far, I have the impression that people who tested it were more interested in the PLAY feature than in the SOUND feature.
VANYA
Posts: 1834
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Re: Audio library for FreeBasic - Features

Post by VANYA »

Hi angros47!

I tried the function "SOUND". Everything works, but strange to assign function to a signal. The usual syntax has always been: SOUND(freguency, duration), and you: SOUND(func, duration)

---------------------

For those who are interested , simple example using "SOUND":

Code: Select all

#include "sfx.bi"
#inclib "fbsfx"

SoundSet (44100,1,16)

sound SineWave(2000), 1 ' sine 2 kHz 
sound NoiseWave(), 1 ' noise 

sleep
-----------------------

I have 2 WAV file . One format is WAVE_FORMAT_PCM , and the second is in the format WAVE_FORMAT_IEEE_FLOAT. As they simultaneously load and play through your library?
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

Re: Audio library for FreeBasic - Features

Post by angros47 »

At the moment, only PCM WAV files are supported, FLOAT files are not supported.

About the SOUND command: the new syntax is needed to allow to specify the waveform: in QBASIC, the only waveform allowed was the square wave (since PC speaker was only able to emit that one), while modern audio system can produce thousands of different waves.
The equivalent of SOUND frequency, duration is SOUND PulseWave(frequency), duration (the square wave is, in fact, a pulse wave with a duty cycle of 50%, so there is no need to have a function for it, when it's already covered by the more generic function PulseWave)

Using a SineWave, low frequency sounds (50 hertz or less, that could be produced with no issues with QBASIC) would be inaudible: in fact. such low frequencies would require a large loudspeaker (a woofer, for example) to be played properly, and most PCs don't have one. A square wave can be heard, instead, because even if the fundamental wave is too low, its harmonics are in the audible portion of the spectrum.

Also, by combining many functions, it's possible to achieve more interesting effects, like:

Code: Select all

sound amplitudemodulate(noisewave(),sawtoothwave(-2)),10
VANYA
Posts: 1834
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Re: Audio library for FreeBasic - Features

Post by VANYA »

I understand. I'll wait for your library will be included in the official delivery of the compiler. Good luck!
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

Re: Audio library for FreeBasic - Features

Post by angros47 »

I re-uploaded it again, fixing a small bug in the file SoundFunction.bas: when a sound buffer was created using a sampling rate different from the default one, the default sample rate was used to render a sound inside that buffer, instead of the buffer rate. It is fixed now
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Audio library for FreeBasic - Features

Post by badidea »

I did some more testing on linux with a wave-file, seems to work fine.

Wave file: https://nr100.home.xs4all.nl/badidea/34 ... k_okay.wav [108 KB]

Visualisation of the sample:

Code: Select all

#include "..\sfx\sfx.bi"

#ifdef __FB_64BIT__
	#inclib "fbsfx64"
#else
	#inclib "fbsfx32"
#endif 

const SW = 1024, SH = 768
screenres(SW, SH, 32)

'SoundMidiSet()
SoundSet(44100, 2, 16)

dim as string fileName = "345299_scrampunk_okay.wav"
dim as WaveHeaderType ptr pWave

pWave = LoadWave(fileName)
if pWave = 0 then
	print "pWave = 0" : end
end if

PlayWave(pWave)
dim as ubyte ptr pSamples = cast(ubyte ptr, pWave) + sizeof(WaveHeaderType)

'for 16 bit, 2 channel only!
dim as integer numSamples = pWave->DataLength / (pWave->Channels * (pWave->FmtSpecific \ 8))
dim as integer startSample = 0
dim as integer y = 50
while (1)
	for i as integer = 0 to SW - 1
		dim as integer j = i + startSample 'current sample j
		if j + 1 > numSamples then
			'print "ERROR: out of bounds"
			exit while
		end if
		pset(i, y + cast(short ptr, pSamples)[j] * 100 / (2 ^ 16)), rgb(0, 255, 0)
		pset(i, y - cast(short ptr, pSamples)[j + 1] * 100 / (2 ^ 16)), rgb(255, 0, 0)
	next
	startSample += SW
	y += 25
wend

print "=== RIFF header ==="
print "RiffID         " & pWave->RiffID
print "RiffLength     " & pWave->RiffLength
print "WavID          " & pWave->WavID
print "FmtID          " & pWave->FmtID
print "FmtLength      " & pWave->FmtLength
print "=== FMT chunck ==="
print "wavformattag   " & pWave->wavformattag
print "Channels       " & pWave->Channels
print "SamplesPerSec  " & pWave->SamplesPerSec
print "avgBytesPerSec " & pWave->avgBytesPerSec
print "blockalign     " & pWave->blockalign
print "BitsPerSample  " & pWave->FmtSpecific
print "=== DATA chunck ==="
print "DataID         " & pWave->DataID
print "DataLength     " & pWave->DataLength
print "samples ptr    " & pSamples
print

sleep

'http://soundfile.sapp.org/doc/WaveFormat/
Output screenshot: https://nr100.home.xs4all.nl/badidea/34 ... k_okay.png [68KB]
Post Reply