fbsound 1.0 Win/Lin 32/64-bit (wav mp3 ogg mod it xm s3m)

Headers, Bindings, Libraries for use with FreeBASIC, Please include example of use to help ensure they are tested and usable.
Post Reply
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: fbsound 1.0 Linux Windows 32/64-bit (wav mp3 ogg mod it xm s3m)

Post by D.J.Peters »

It's more safe to do an error check also.
To make it in fbsound style I changed the name and added byval for -w pedantic.

Code: Select all

function fbs_Get_SoundPlaying(byval hSound as integer) as boolean
   dim as integer nLoops
   if fbs_Get_SoundLoops(hSound, @nLoops) = false then return false
   return iif(nLoops, true, false)
end function
Only for info a sound can be in more states as playing or stopped.

Joshy

Something like this:

Code: Select all

enum eSoundState
  eUnknow = 0 ' may be not loaded aTM.
  eStopped ' fbs_Get_SoundLoops() nLoops = 0
  ePlaying ' fbs_Get_SoundLoops() nLoops = 1
  eLooping ' fbs_Get_SoundLoops() nLoops > 1
  ePaused ' fbs_Get_SoundPaused()
  eMuted ' fbs_Get_SoundMuted()
end enum

function fbs_Get_SoundState(byval hSound as integer) as eSoundState
...
end function
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: fbsound 1.0 Linux Windows 32/64-bit (wav mp3 ogg mod it xm s3m)

Post by badidea »

Another question or comment. I am struggling to get fbs_Set_SoundPointers() working in a way that I understand.
I have modified the example a bit:

Code: Select all

#include "../inc/fbsound.bi"

const data_path = "../data/"
chdir(exepath())

dim as integer   hWave,hSound,nSamples,nChannels
dim as short ptr lpWaveStart,lpWaveEnd
dim as short ptr lpSoundStart,lpSoundPlay,lpSoundEnd

fbs_Init()
fbs_Load_WAVFile(data_path & "fbsloop44.wav",@.hWave)
fbs_Create_Sound(hWave,@hSound)
' Get start,end and number of channels from wave object
fbs_Get_WavePointers(hWave, @lpWaveStart, @lpWaveEnd, @nChannels)
nSamples = (lpWaveEnd - lpWaveStart) / (2 * nChannels)
print nSamples, lpWaveEnd, lpWaveStart, nChannels

' begin = start of the wave
lpSoundPlay = lpWaveStart + (nSamples \ 32) * 10 ' * nChannels ???
' any begin of playback region
lpSoundStart = lpWaveStart + (nSamples \ 32) * 20 ' * nChannels ???
' any end of playback region
lpSoundEnd = lpWaveEnd - (nSamples \ 32) * 16 * (nChannels * 2) '???
fbs_Set_SoundPointers(hSound, lpSoundStart, lpSoundPlay, lpSoundEnd)

fbs_Play_Sound(hSound, 1) ' 1 times

' wait on first sample
while fbs_Get_PlayingSounds()=0:sleep 10:wend

dim as double t = timer
while fbs_Get_PlayingSounds() and inkey()=""
  sleep 1
wend
print " Time:"; timer - t
'end
This plays (on my system) sound for ~1.94 seconds. I cannot find the logic behind it.
Imortis
Moderator
Posts: 1923
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Re: fbsound 1.0 Linux Windows 32/64-bit (wav mp3 ogg mod it xm s3m)

Post by Imortis »

By the way: All tests were successful on Win7 64bit. Good work!
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: fbsound 1.0 Linux Windows 32/64-bit (wav mp3 ogg mod it xm s3m)

Post by D.J.Peters »

@Imortis thank you for testing :-)

@badidea » this would be right if you calculate with byte pointers
nSamples = (pWaveEnd - pWaveStart) / (2 * nChannels)

But if you use short pointers it's:
nSamples = (pWaveEnd - pWaveStart) / nChannels

But wait there is another mistake samples versus frames
nSamples = (pWaveEnd - pWaveStart)

nFrames = (pWaveEnd - pWaveStart) / nChannels

The number of Frames are independent from mono vs stereo samples

Setting the buffer pointers are an advanced feature and only for special cases.

Don't worry if your first results are not what you would accept.

I can help if you are tell me what you are trying to do with the pointers ?

May be it would be better to calculate new pointer positions by a time base.

Seconds or in milliseconds or BPM or ...

Joshy
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: fbsound 1.0 Linux Windows 32/64-bit (wav mp3 ogg mod it xm s3m)

Post by badidea »

It is actually a modified version of 'fbs_set_get_pointers.bas' in the 'tests' directory.
What I am trying to do, is from e.g. a 10 seconds long sound, play second 3 to 5.
But I will do some more testing and tweaking, also under Windows. There seems to be a bug here.
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: fbsound 1.0 Linux Windows 32/64-bit (wav mp3 ogg mod it xm s3m)

Post by paul doe »

D.J.Peters wrote:May be it would be better to calculate new pointer positions by a time base.

Seconds or in milliseconds or BPM or ...

Joshy
Hi Joshy,

Very nice lib, works ok so far here (Win10). About the question by badidea (who usually has good ideas =D), may I suggest a feature? Exposing some functions to easily manipulate the timing could prove useful. Something along the lines of...

Code: Select all

setPlaybackTime( byval milliseconds as double ) '' Sets the playback time in milliseconds
playSound( byval startTime as double, byval endTime as double ) '' Plays endTime - startTime milliseconds of a sound
...or something, to have a portable way to do these manipulations, so if you later change/fix/debug the library, compatibility isn't broken with the current codebase that uses the lib. That way the user end doesn't need, if he doesn't want/don't know how to, fiddle with pointers. Just a suggestion...
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: fbsound 1.0 Linux Windows 32/64-bit (wav mp3 ogg mod it xm s3m)

Post by badidea »

Improved code. Setting the 'end time' seems to work, but not the 'start time'. (Linux and Windows).

Code: Select all

#include "../inc/fbsound.bi"

function main() as string
	dim as boolean ok
	dim as integer hWave

	ok = fbs_Init()
	if ok = false then return "Error: fbs_Init()" + FBS_Get_PlugError()
	print "Success: fbs_Init()"

	dim as string waveFileName = "../data/fbsloop44.wav"
	ok = fbs_Load_WAVFile(waveFileName, @hWave)
	if ok = false then return "Error: fbs_Load_WAVFile(" + waveFileName + ")"
	print "Success: fbs_Load_WAVFile(" + waveFileName + ")"

	'fbsloop44.wav details:
	'16-bit stereo: 2-byte left, 2-byte right, ... ?
	'1 frame = 4 bytes (left + right) ?
	'44100 Hz, 16-bit, stereo, ~3.85 seconds = ~679,140 bytes
	'filesize = 683,684 bytes 

	dim as short ptr pWaveStart, pWaveEnd
	dim as integer nSamples, nBytes, nChannels, nFrames
	dim as single waveLength 
	  
	fbs_Get_WavePointers(hWave, @pWaveStart, @pWaveEnd, @nChannels)
	nSamples = pWaveEnd - pWaveStart
	nBytes = nSamples * 2 'sizeof(short) 
	nFrames = nSamples \ nChannels
	waveLength = nFrames / 44100 'default value for now

	print "nBytes: " + str(nBytes)
	print "nSamples: " + str(nSamples)
	print "nFrames: " + str(nFrames)
	print "waveLength [s]: " + str(waveLength)

	dim as integer hSound

	fbs_Create_Sound(hWave, @hSound)

	dim as short ptr pSoundStart, pSoundPlay, pSoundEnd
	dim as single startTime, endTime 'seconds

	startTime = 1.0 'This does not work !?
	endTime = 2.0
	pSoundPlay = pWaveStart' + cint((startTime * 44100) * nChannels)
	pSoundStart = pWaveStart + cint((startTime * 44100) * nChannels)
	pSoundEnd = pWaveStart + cint((endTime * 44100) * nChannels)

	ok = fbs_Set_SoundPointers(hSound, pSoundStart, pSoundPlay, pSoundEnd)
	if ok = false then return "Error: fbs_Set_SoundPointers()"
	print "Success: fbs_Set_SoundPointers()"

	fbs_Play_Sound(hSound, 1) ' 1 times

	'wait for playing
	while fbs_Get_PlayingSounds() = 0
		sleep 1
	wend

	dim as double t = timer

	'wait for end of play
	while fbs_Get_PlayingSounds() <> 0
	  sleep 1
	wend

	print "playTime [s]: " + str(timer - t)

	return "The end."
end function

print main()
end
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: fbsound 1.0 Linux Windows 32/64-bit (wav mp3 ogg mod it xm s3m)

Post by D.J.Peters »

Normally for game coders a sound library is low level.
The primary functionality are loading and playing sounds.

It comes with some tools to make more complex tasks by the user of the library.

Tools are:
Left and right channel paning
Volume control
different playback speed
10 user defined EQ's
Sound callbacks.
...

With this tools you an create:
Realistic 3D sounds with doppler effect
Indore vs outdoor switchable setups.
Sound sources with cone or sphere characteristic.
Inside the callback's you can calculate any DSP effect
and many more ...

I would encapsulate my sound objects from the low level stuff
like this pseudo code:

Code: Select all

type hWave as integer
type hSound as integer

type tWavePool
  declare function Load(Path as string) as hWave
  as hWave Poll()
  ' ...
end type

type tSound
  declare constructor(WaveID as hWave)
  declare constructor(Path as string)
  declare constructor(nSamples as integer, nChannesl as integer=2)
  declare function Play(nLoops as integer=1) as boolean
  declare function PlayFrom(timeStart as double, nLoops as integer=1) as boolean
  declare function PlayTo(timeEnd as double, nLoops as integer=1) as boolean
  declare function PlayRange(timeStart as double, timeEnd as double, nLoops as integer=1) as boolean
  declare property Pan as single
  declare property Pan(value as single)
  declare property Speed as single
  declare property Speed(value as single)
  ...
  as hSound ID
end type

type tSound3D extends tSound2D
  declare sub setPosition(x as single, x as single, z as single)
  declare sub getPosition(byref x as single, byref x as single, byref z as single)
  declare sub setVelocity(x as single, x as single, z as single)
  declare sub getVelocity(byref x as single, byref x as single, byref z as single)
  declare sub setCone(angle as single=60, umbra as single, penumbra as single)
  declare sub getCone(byref angle as single,byref umbra as single,byref penumbra as single)
  declare sub setSphere(radius as single)
  declare sub getSphere(byref radius as single)
  enum eMode
    bothoff
    cone
    sphere
  end enum   
  declare sub setMode(mode as eMode)
  ...
end type  
  
type tEffect extends tSound
  declare sub setEQ(index as integer, centerFrequency as single, db as single)
  declare sub getEQ(index as integer, byref centerFrequency as single, byref db as single)
  declare sub enableEQ(index as integer, onoff as boolean)  
  
  declare sub setEcho(roomSize as single, delaytime as single, intensity as single)
  declare sub getEcho(byref roomSize as single, byref delayTime as single, byref intensity as single)
  declare sub enableEcho(onoff as boolean)  
  ...
end type

type tEffect3D extends tEffect
  declare sub setDoppler(factor as single, minFrequency as single, db as single)
  declare sub getDoppler(byref factor as single, byref minFrequency as single, byref db as single)
  declare sub enableDoppler(onoff as boolean)  
  
  declare sub setEcho3D(roomWidth as single, roomHeight as single, roomDepth as single, intensity as single)
  declare sub getEcho3D(byref roomWidth as single, byref roomHeight as single, byref roomDepth as single, byref intensity as single)
  declare sub enableEcho3D(onoff as boolean)  
  ...
end type
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: fbsound 1.0 Linux Windows 32/64-bit (wav mp3 ogg mod it xm s3m)

Post by paul doe »

D.J.Peters wrote:Normally for game coders a sound library is low level.
The primary functionality are loading and playing sounds.

It comes with some tools to make more complex tasks by the user of the library.
I know. It was just a suggestion.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: fbsound 1.0 Linux Windows 32/64-bit (wav mp3 ogg mod it xm s3m)

Post by D.J.Peters »

paul doe wrote:... It was just a suggestion.
Same here ;-)

Joshy
mrToad
Posts: 430
Joined: Jun 07, 2005 23:03
Location: USA
Contact:

Re: fbSound for Linux x86 Win32 (wav mp3 ogg mod it xm s3m)

Post by mrToad »

D.J.Peters wrote:I edit 2,500 lines of assembler codes and it works now :- )
Just want to say thank you for all your hard work and many hours, Joshy! This was a really pleasant surprise.
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: fbsound 1.0 Win/Lin 32/64-bit (wav mp3 ogg mod it xm s3m)

Post by coderJeff »

This library works well. Thank-you joshy. We recently had some name mangling changes to fbc and I was worried it might break the library. Initial tests look OK to me. I only tested on win7. Compiling from fbsound from sources is not great. Inspection of the libraries used (like libdumb) show that some libraries are compiled with exeception handling, and some with setjmp/longjmp. I had to disable libdumb to get fbsound to compile on win7. With all the ASM used, choice of gcc seems to be important. I think it has something to do with stack alignment, though I am not 100% sure at the moment. Thanks again for this excellent library.
St_W
Posts: 1619
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: fbsound 1.0 Win/Lin 32/64-bit (wav mp3 ogg mod it xm s3m)

Post by St_W »

@coderJeff: I ran into a structure alignment issue when trying to compile fbsound using gcc a while ago; fbc patch:
https://github.com/swurzinger/fbc/commi ... 7d60a95b71

You mentioned that it were a problem that libaries are compiled with different exception handling mechanisms (sjlj/dwarf/seh). As FB for itself does not support any exception handling at all, what are the issues caused by mixing different EH types?
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: fbsound 1.0 Win/Lin 32/64-bit (wav mp3 ogg mod it xm s3m)

Post by D.J.Peters »

You can recompile the static lib's with the same gcc that your FreeBASIC used.

libdumb: viewtopic.php?f=14&t=23247
libmad: viewtopic.php?f=14&t=26625
libogg: viewtopic.php?f=14&t=26626

Put the fresh build of static lib's in the right fbsound (source) folder and recompile fbsound.

Or in next release of fbsound (if any) I can compile fbsound as a dynamic lib *.dll/*.so without any gcc dependencies also.

Joshy
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: fbsound 1.0 Win/Lin 32/64-bit (wav mp3 ogg mod it xm s3m)

Post by coderJeff »

Thanks Joshy, I will give that a try. libdumb was one issue.

I remember now my earlier post was about: the 64-bit version fbsound builds from sources OK for me using "win-builds" version of gcc (4.8.3), but not when using mingw-w64 version of gcc (gcc (x86_64-win32-sjlj-rev1, Built by MinGW-W64 project) 7.1.0):
fbc & c:\mingw-w64\mingw64\bin\gcc.exe wrote: E:\fbsound-1.0-src>d:\fb.git\fbc-64.exe -w pendantic -mt -asm intel -lib src/fbscpu.bas -x lib/win64/libfbscpu.a -target win64
src/fbscpu.c: In function 'FBSCPU_INIT':
src/fbscpu.c:476:1: internal compiler error: in print_reg, at config/i386/i386.c:17656
}
^
Causing gcc itself to crash with fbc's emitted '.c' code, and because FBSCPU_INIT includes some inline asm, I was thinking it might be stack alignment related.

Anyway, it's leading me towards thinking there is a bug in fbc that only shows up with inline asm and depending on version of gcc used. Sorry, I haven't looked at it further.
Post Reply