GLBasic forum

Codesnippets => Inline / 3rd party => Topic started by: Ruidesco on 2011-Sep-19

Title: SunVox Engine DLL
Post by: Ruidesco on 2011-Sep-19
Hello GLBasic forums!

I'm a new user of GLBasic and have been fiddling with it about a couple of weeks, so it was about time I started participating in the community.
Since this is something I am going to use in my current project, and was a good exercise for learning to make a (simple) wrapper, I'm going to share it here.

SunVox (http://www.warmplace.ru/soft/sunvox/) is a recent synth-tracker in continual development, and its creator was generous enough to give a Win32/MacOSX/Linux player library (http://www.warmplace.ru/soft/sunvox/sunvox_dll.zip) to be used in other apps. You will need to download the library package and extract the one that matches your OS into the .app directory of the project for it to work (so far I could only test it in Windows).

So without further ado, I attach the SunVox Engine wrapper for GLBasic coupled with a very simple usage example.

Regards.

[attachment deleted by admin]
Title: Re: SunVox Engine DLL
Post by: Marmor on 2011-Sep-19
wow ! thanks a lot
Title: Re: SunVox Engine DLL
Post by: trucidare on 2011-Sep-19
i like the combination of type and methods used with inline - nice to see
Title: Re: SunVox Engine DLL
Post by: bigsofty on 2011-Sep-19
Excellent stuff, thank you for sharing!  :good:
Title: Re: SunVox Engine DLL
Post by: Wampus on 2011-Sep-22
Excellent. I love it.

I notice its possible to jump to any position of a playing song by using the Rewind command. The trouble is on my PC it will take anything from 90 to 180 milliseconds to execute. It would be great if it was possible to manipulate the pattern sequence while a song is playing. It could be as simple as telling the tracker routine to jump to a certain position after it reaches line n, either repeatedly or one time only. That way music could be created that seamlessly blended into different moods depending on what was happening in the app. For example, I imagine it being used to change music from calm to menacing if an enemy was encountered during a game.

Title: Re: SunVox Engine DLL
Post by: Ruidesco on 2011-Sep-22
Yes, I have something akin planned for my own project. Sadly, I have no access to the source code (probably no one besides the author does) so your best bet would be registering on their forum and reporting the laggy behavior.

Something that you could try is, so to speak, having "calm.sunvox" and "fight.sunvox" loaded from the start of a stage, the first in slot 0 and the second in slot 1. If an enemy appears then you could just tell the engine to Stop(0) and Play(1). Or, if the change might be less abrupt, having them crossfade during a little while using the Volume method, since it works by slots as well.
Title: Re: SunVox Engine DLL
Post by: Wampus on 2011-Sep-22
Quote from: Ruidesco on 2011-Sep-22
Yes, I have something akin planned for my own project. Sadly, I have no access to the source code (probably no one besides the author does) so your best bet would be registering on their forum and reporting the laggy behavior.

I suspect the lag is due to some kind of re-initialisation of the player. A simple "position jump on x" kind of thing included in the sunvox.dll would probably allow seamless transitions without much trouble. I'll certain register and bring the subject up.

Ketil on the forum here has talked about this before (http://www.glbasic.com/forum/index.php?topic=3955). I realise Send Event could be used for various purposes too. Could solve issues such as  needing to change pitch of a sound (http://www.glbasic.com/forum/index.php?topic=6025).

Quote from: Ruidesco on 2011-Sep-22
Something that you could try is, so to speak, having "calm.sunvox" and "fight.sunvox" loaded from the start of a stage, the first in slot 0 and the second in slot 1. If an enemy appears then you could just tell the engine to Stop(0) and Play(1). Or, if the change might be less abrupt, having them crossfade during a little while using the Volume method, since it works by slots as well.

I may be doing something wrong because I can't seem to get that to work. Trying to make two tracks play simultaneously then fade between them doesn't seem possible. The app crashes. Alternatively, trying to set things up so that one track can be stopped and another quickly started still creates a noticeable lag. Nice idea though.
Title: Re: SunVox Engine DLL
Post by: Ruidesco on 2011-Sep-22
Quote from: Wampus on 2011-Sep-22I may be doing something wrong because I can't seem to get that to work. Trying to make two tracks play simultaneously then fade between them doesn't seem possible. The app crashes. Alternatively, trying to set things up so that one track can be stopped and another quickly started still creates a noticeable lag. Nice idea though.
A quick test adapting the usage example to crossfade two tracks seems to be working on this end. Here is the code for it:
Code (glbasic) Select
SETCURRENTDIR("Media")

PRINT "CLICK / PRESS ESC TO EXIT THE TEST", 5, 5
SHOWSCREEN

GLOBAL sv AS SUNVOX

sv.Init(0, 44100, 2, 0)
sv.OpenSlot(0)
sv.OpenSlot(1)
sv.Load(0, "slot_0_music.sunvox")
sv.Load(1, "slot_1_music.sunvox")
sv.Volume(1, 0)
sv.Play(0)
sv.Play(1)
MOUSEWAIT

default_max_volume = 64
FOR i = 1 TO default_max_volume
sv.Volume(0, default_max_volume - i)
sv.Volume(1, i)
SLEEP 50
NEXT
MOUSEWAIT

END

SUB GLB_ON_QUIT:
sv.Stop(0)
sv.Stop(1)
sv.CloseSlot(0)
sv.CloseSlot(1)
sv.DeInit()
ENDSUB
Title: Re: SunVox Engine DLL
Post by: Wampus on 2011-Sep-22
Thanks  :)

I thought I needed to call sv.Init(0, 44100, 2, 0) twice.
Title: Re: SunVox Engine DLL
Post by: Ruidesco on 2011-Sep-22
You're welcome. We're here to try and help each other.
Quote from: Wampus on 2011-Sep-22I realise Send Event could be used for various purposes too. Could solve issues such as  needing to change pitch of a sound (http://www.glbasic.com/forum/index.php?topic=6025).
Yes, preparing a separate sunvox project to handle SFX in that fashion can prove very useful. You would just have to set up the modules that create the different sounds and then send the events from your code. Things like wind, seashores, car engines and such would sound much more dynamic.
By the way, NightRadio (SunVox's author) has "Ability to load sunvox project as module" in his to-do list, which can prove interesting in terms of dynamic music when it is finally implemented.
Title: Re: SunVox Engine DLL
Post by: bigsofty on 2011-Sep-30
BTW I posted a request for a static Lib for iOS and the author said he would stick it in the next release.
Title: Re: SunVox Engine DLL
Post by: Ruidesco on 2011-Sep-30
Yup, saw that. :) NightRadio does really seem to want people to use SunVox for something else than rendering WAVs.
Ideally it should just mean adding another ?IFDEF inside the TYPE to specify the library name, but things are seldom that easy.
Title: Re: SunVox Engine DLL
Post by: ketil on 2011-Oct-01
Quote from: Ruidesco on 2011-Sep-22
Yes, I have something akin planned for my own project. Sadly, I have no access to the source code (probably no one besides the author does) so your best bet would be registering on their forum and reporting the laggy behavior.

Something that you could try is, so to speak, having "calm.sunvox" and "fight.sunvox" loaded from the start of a stage, the first in slot 0 and the second in slot 1. If an enemy appears then you could just tell the engine to Stop(0) and Play(1). Or, if the change might be less abrupt, having them crossfade during a little while using the Volume method, since it works by slots as well.

If you can track down an earlier version of sunvox tracker, i think the sourcecode are included under an BSD like license.
I might have it on one of my older computers.
Title: Re: SunVox Engine DLL
Post by: spicypixel on 2012-Nov-18
I downloaded this before and could not get it to play the test.sunvox file. I simply have no audio whatsoever. I ignored it at the time but would now like to use this wrapper and I'm curious as to everyone saying "wow" and "thank you" when I get a black screen with click to exit and no sound.

Any idea what I'm doing wrong? Is test.sunvox a blank tracked file?

I'm using this to test...
Code (glbasic) Select

// Project: SunVoxWrapper
// Start: Saturday, September 10, 2011
// IDE Version: 10.106

SETCURRENTDIR("Media")

GLOBAL sv AS SUNVOX

sv.Init(0, 44100, 2, 0)
sv.OpenSlot(0)
sv.Load(0, "8bit_tales.sunvox")
sv.Volume(0, 64)
sv.Play(0)

REPEAT
PRINT "ESC TO EXIT THE TEST", 8, RND(2)+5
SHOWSCREEN
UNTIL FALSE

SUB GLB_ON_QUIT:
sv.Stop(0)
sv.CloseSlot(0)
sv.DeInit()
ENDSUB


My structure is 8bit_tales.sunvox within my Media directory and sunvox.dll next to my exe file in the .app directory.
Title: Re: SunVox Engine DLL
Post by: Ruidesco on 2012-Nov-18
It would seem that the current SunVox library has changed, so its previously existing functions have different names besides there being more in number. If you use the SunVox library from last year (http://www.mediafire.com/?qkp271a8lao5c7r) this example works.
Title: Re: SunVox Engine DLL
Post by: spicypixel on 2012-Nov-18
Thank you very much for the old DLL. I did think it might be to do with a newer DLL but I downloaded it a long time ago and it didn't work then so I wasn't sure. Will try this new(old) DLL now and report back :)

Any thoughts on updating the wrapper, or some links, guides for others to follow should they wish to walk in your footsteps :D
Title: Re: SunVox Engine DLL
Post by: Ruidesco on 2012-Nov-18
IIRC the proper sunvox_dll.zip from the SunVox website includes a sunvox.h, which is where I got the function names/parameters to wrap back then.

As you can see the wrapper is nothing fancy at all. It should suffice swapping the quoted old function names/parameters in the DECLARE_C_ALIAS calls for the current ones, and adding the new ones if need be.
Title: Re: SunVox Engine DLL
Post by: spicypixel on 2012-Nov-18
Quote from: Ruidesco on 2012-Nov-18
It would seem that the current SunVox library has changed, so its previously existing functions have different names besides there being more in number. If you use the SunVox library from last year (http://www.mediafire.com/?qkp271a8lao5c7r) this example works.

This works perfectly, think I may look at the new dll thanks for the heads up :)
Title: Re: SunVox Engine DLL
Post by: spicypixel on 2012-Nov-18
I changed these and it works with the latest DLL. I'll investigate the other names/params as and when but this is cool :)

Code (glbasic) Select

DECLARE_C_ALIAS(exSV_OPEN_SLOT,    libSunVox, "sv_open_slot", (int slot),   int);
DECLARE_C_ALIAS(exSV_CLOSE_SLOT,    libSunVox, "sv_close_slot", (int slot),   int);
DECLARE_C_ALIAS(exSV_INIT,    libSunVox, "sv_init", (const char* dev, int freq, int channels, int flags),   int);
DECLARE_C_ALIAS(exSV_DEINIT,    libSunVox, "sv_deinit", (void),   int);
DECLARE_C_ALIAS(exSV_LOAD,    libSunVox, "sv_load", (int slot, const char* name),   int);
DECLARE_C_ALIAS(exSV_PLAY,    libSunVox, "sv_play", (int slot),   int);
DECLARE_C_ALIAS(exSV_PLAY_FROM_BEGINNING,    libSunVox, "sv_play_from_beginning", (int slot),   int);
DECLARE_C_ALIAS(exSV_STOP,    libSunVox, "sv_stop", (int slot),   int);
DECLARE_C_ALIAS(exSV_REWIND,    libSunVox, "sv_rewind", (int slot, int t),   int);
DECLARE_C_ALIAS(exSV_VOLUME,    libSunVox, "sv_volume", (int slot, int vol),   int);
DECLARE_C_ALIAS(exSV_SEND_EVENT,    libSunVox, "sv_send_event", (int slot, int channel_num, int note, int vel, int module, int ctl, int ctl_val), int);
DECLARE_C_ALIAS(exSV_GET_CURRENT_LINE,    libSunVox, "sv_get_current_line", (int slot),   int);
DECLARE_C_ALIAS(exSV_GET_CURRENT_SIGNAL_LEVEL, libSunVox, "sv_get_current_signal_level", (int slot, int channel),