Regarding Sunvox Playback library

Multi-platform modular music creation studio
Post Reply
Darkhog
Posts: 250
Joined: Wed Apr 06, 2011 11:03 pm

Regarding Sunvox Playback library

Post by Darkhog » Mon May 02, 2016 4:51 am

Could you please compile Windows x64 version of the lib? There isn't one in the archive (only x86 provided) which prevents me from linking against it in x64 applications such as games.

I'm planning to work on Unity Engine SunVox playback plugin because Sunvox files are both really small, if used without samples and sound awesome and can't proceed since Unity's IDE is x64 only at the moment plus I know of people who would use it (because they use SunVox for music anyway, with converting exported wav to OGG) but have to make x64 builds of their games for one reason or another.

I see Linux has x64 version of the library so you obviously have access to computer with x64 CPU, possibly even dualbooting.

User avatar
NightRadio
Site Admin
Posts: 3150
Joined: Fri Jan 23, 2004 12:28 am
Location: Ekaterinburg. Russia
Contact:

Re: Regarding Sunvox Playback library

Post by NightRadio » Tue May 03, 2016 1:16 am

I will try to make it soon. Building for Win64 is not tested by me yet...

TheoXD
Posts: 5
Joined: Wed May 04, 2016 5:06 am

Re: Regarding Sunvox Playback library

Post by TheoXD » Wed May 04, 2016 8:59 pm

Hello, I have a question of my own, how to play the entire song just by using sv_send_event()? Here's the main loop:

Code: Select all

	while (true) {
		int patterns = sv_get_number_of_patterns(0);
		for (int pattern = 0; pattern < patterns; pattern++) {
			int x = sv_get_pattern_x(0, pattern);
			int size = sv_get_pattern_lines(0, pattern);

			if (tick >= x && tick < (x + size)) {
				sunvox_note* data = sv_get_pattern_data(0, pattern);
				int line = tick - x;

				int tracks = sv_get_pattern_tracks(0, pattern);
				for (int track = 0; track < tracks; track++) {
					sunvox_note* note = &data[line * tracks + track];
					sv_send_event(0, track, note->note, note->vel, note->module, note->ctl, note->ctl_val);
				}
			}
		}

		Sleep(sv_get_ticks_per_second() / 100 / 5);
		tick++;
	}
The rest is pretty much the code provided with the library. Not sure if events should be send simultaneously or not, but the order in which I send them has impact on the song. Please guide me :Search:

User avatar
NightRadio
Site Admin
Posts: 3150
Joined: Fri Jan 23, 2004 12:28 am
Location: Ekaterinburg. Russia
Contact:

Re: Regarding Sunvox Playback library

Post by NightRadio » Thu May 05, 2016 9:32 am

sv_send_event() is a realtime command. So the event will be played right after the sv_send_event() call (plus some audio system delay).
You should use the call order like this:

Code: Select all

for( pattern lines )
{
  sv_send_event( track 0 ); sv_send_event( track 1 ); ... sv_send_event( track X );
  pause( number of ms per line );
}

TheoXD
Posts: 5
Joined: Wed May 04, 2016 5:06 am

Re: Regarding Sunvox Playback library

Post by TheoXD » Thu May 05, 2016 6:55 pm

Thanks, but isn't it exactly what my code is doing? I don't have problems playing one pattern at a time, the issue occurs when several patterns have to be played simultaneously, that's when it sounds like it's skipping a few patterns. The song does not sound like if it was played with play() instead.
Edit: I've passed a sequential value as second parameter, and it's crashing, but sounds about right.

Code: Select all

	int tick = 0;
	while (true) {
		int slot = 0;
		int patterns = sv_get_number_of_patterns(0);
		printf("%i \n", sv_get_song_bpm(0));
		for (int pattern = 0; pattern < patterns; pattern++) {
			int x = sv_get_pattern_x(0, pattern);
			int size = sv_get_pattern_lines(0, pattern);

			if (tick >= x && tick < (x + size)) {
				sunvox_note* data = sv_get_pattern_data(0, pattern);
				int line = tick - x;

				int tracks = sv_get_pattern_tracks(0, pattern);
				for (int track = 0; track < tracks; track++) {
					sunvox_note* note = &data[line * tracks + track];
					sv_send_event(0, slot, note->note, note->vel, note->module, note->ctl, note->ctl_val);
					slot += 1;
				}
			}
		}

		Sleep(sv_get_ticks_per_second() / 100 / 5);
		tick++;
	}
You can put this instead of play() inside test.cpp to test it out. I'm still confused of what second parameter is for, I'm pretty sure I'm doing something wrong.

TheoXD
Posts: 5
Joined: Wed May 04, 2016 5:06 am

Re: Regarding Sunvox Playback library

Post by TheoXD » Sat May 07, 2016 6:04 pm

After digging around I've figured out it crashes during playback of "silence_artifacts.sunvox" when it sends events to module with ID 12. I just did additional check if(note->module != 12) { sv_send_event() }Without it the song sounds 95% accurate. In case of "sfields3.sunvox" it's module with ID 6 I believe.

User avatar
NightRadio
Site Admin
Posts: 3150
Joined: Fri Jan 23, 2004 12:28 am
Location: Ekaterinburg. Russia
Contact:

Re: Regarding Sunvox Playback library

Post by NightRadio » Sun May 08, 2016 11:05 pm

Thanks, but isn't it exactly what my code is doing?
Yes, for sure :) But here is the main problem which i forgot to mention: sv_send_event() works within the single virtual pattern. So the max value for the track_num parameter is 15.
So for example you can't call sv_send_event( 0, 16 ... sorry.

TheoXD
Posts: 5
Joined: Wed May 04, 2016 5:06 am

Re: Regarding Sunvox Playback library

Post by TheoXD » Mon May 09, 2016 4:48 am

Well in my case this isn't an issue since I don't exceed 16 simultaneous events. As I stated earlier, some events from example songs makes the dynamically linked code to crash. Maybe version mismatch, I don't know. The reason I'm not using play() function is that I need to alter the song on the fly. Currently I'm happy that it's working to some extent, but it's not very reliable for a product that would use sunvox.dll as a dependency.

User avatar
NightRadio
Site Admin
Posts: 3150
Joined: Fri Jan 23, 2004 12:28 am
Location: Ekaterinburg. Russia
Contact:

Re: Regarding Sunvox Playback library

Post by NightRadio » Mon May 09, 2016 10:34 am

Ok! I will test this code on my PC and tell you what is wrong :)

User avatar
NightRadio
Site Admin
Posts: 3150
Joined: Fri Jan 23, 2004 12:28 am
Location: Ekaterinburg. Russia
Contact:

Re: Regarding Sunvox Playback library

Post by NightRadio » Mon May 09, 2016 11:49 am

I found a bug :)
Please try this version: http://warmplace.ru/temp/sunvox_dll.zip
But remember that sv_send_event() has the following disadvantages in the context of your task:
  • 16 tracks only (but it may be increased to 32 in future updates);
  • timer-based effects (19, 1C, 1D) can't be handled;
  • time accuracy of sv_send_event() may be different on different audio systems; the worst results will be on Android.
So if it is possible - try to avoid the use of this function for the complex song playing. There is an alternative way: create the song with one or several looped patterns, and then change the content of these patterns from the code.

TheoXD
Posts: 5
Joined: Wed May 04, 2016 5:06 am

Re: Regarding Sunvox Playback library

Post by TheoXD » Mon May 09, 2016 5:33 pm

This totally works now, thank you! I plan to use it with PCs only anyway so performance shouldn't be an issue.

Darkhog
Posts: 250
Joined: Wed Apr 06, 2011 11:03 pm

Re: Regarding Sunvox Playback library

Post by Darkhog » Wed May 18, 2016 2:22 pm

NightRadio wrote:I will try to make it soon. Building for Win64 is not tested by me yet...
Thank you. Shouldn't be much different than building for Win32 tho, main difference being you having to have 64bit Windows and setting win64 as a target in compiler.

Post Reply