SunVox for ZGE

Use of external libraries (DLLs) from ZGE.

Moderator: Moderators

User avatar
Rado1
Posts: 771
Joined: Wed May 05, 2010 12:16 pm

Re: SunVox for ZGE

Post by Rado1 » Tue Nov 21, 2017 7:37 pm

Today, I tested ZGE with the latest SunVox DLL 1.9.3. It works fine.

User avatar
Ats
Posts: 233
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: SunVox for ZGE

Post by Ats » Thu Feb 14, 2019 7:56 pm

So I started toying with SunVox, which is quite amazing. Everything works on PC and Android ( latest lib 1.9.4c).

I'm still learning the basics, therefore I try to load some examples. The problem is that musics plays on ZGE, such as "Boomlinde - Caravan.sunvox", while others don't play at all, or even make ZGE crash. Do you happen to know what is causing that? Is it coming from a custom and rather complicated module, or from the number of tracks, or something else?
Because everything works fine in SunVox, so I'm not sure if the problem comes from ZGE or the sunvox.dll
Thanks for your knowledge on the subject :)

Edit:
Thanks to Kjell, now I know that everything is fine with SunVox. I spent one hour this morning to try all the example songs and classify them into subfolders such as OK, BAD (all instruments are messed up), NO (not playing), CRASH (crashes ZGE). Turns out that the problem was coming from the computer :shock:
I'll try that computer again tomorrow morning and try to discover what's going on with it.

User avatar
Ats
Posts: 233
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: SunVox for ZGE

Post by Ats » Fri Feb 15, 2019 7:40 pm

I just made a test in order to only play the bass line at some point. But I'm not sure what would be the best method to do that.
I thought of 3 methods (you can set the method number in *Onloaded/ZExpression", just press space to mute the song and keep the bass)

Method 1:
By using two files, I play the Song and the Bass at the same time on two different tracks. Then I play with the volume on the Song track.
This is working great, but I wonder if they will still be coordinated and play at the same time...

Method 2:
I also use two files. One being the complete Song, and the other just the Bass. I play the first file, then I stop it and play the Bass starting from the timecode where the other file stoped. The problem is that I don't know how to get that timecode, since SunVox run with custom Ticks.

Method 3:
I just use the complete song File and I mute paterns (or modules?) directly in it. But I have no clue how to retrive such a thing from the file.

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" MouseVisible="255" FileVersion="2">
  <OnLoaded>
    <ZExternalLibrary ModuleName="SunVox">
      <Source>
<![CDATA[/*
  Adapter to the SunVox Library.
  http://www.warmplace.ru/soft/sunvox

  Created by Rado1(c)2012-2013

  Download the library from http://www.warmplace.ru/soft/sunvox/sunvox_dll.zip
  More info: http://www.emix8.org/forum/viewtopic.php?p=5446

*/

// Constants

const int SV_NOTECMD_NOTE_OFF = 128;
const int SV_NOTECMD_ALL_NOTES_OFF  = 129; // notes of all synths off
const int SV_NOTECMD_CLEAN_SYNTHS = 130; // stop and clean all synths
const int SV_NOTECMD_STOP = 131;
const int SV_NOTECMD_PLAY = 132;

const int SV_INIT_FLAG_NO_DEBUG_OUTPUT = 1 << 0;
const int SV_INIT_FLAG_USER_AUDIO_CALLBACK = 1 << 1;
const int SV_INIT_FLAG_AUDIO_INT16 = 1 << 2;
const int SV_INIT_FLAG_AUDIO_FLOAT32 = 1 << 3;
const int SV_INIT_FLAG_ONE_THREAD =  1 << 4;

const int SV_MODULE_FLAG_EXISTS = 1;
const int SV_MODULE_FLAG_EFFECT = 2;
const int SV_MODULE_INPUTS_OFF = 16;
const int SV_MODULE_INPUTS_MASK = ( 255 << SV_MODULE_INPUTS_OFF );
const int SV_MODULE_OUTPUTS_OFF = ( 16 + 8 );
const int SV_MODULE_OUTPUTS_MASK = ( 255 << SV_MODULE_OUTPUTS_OFF );

const int SV_STYPE_INT16 = 0;
const int SV_STYPE_INT32 = 1;
const int SV_STYPE_FLOAT32 = 2;
const int SV_STYPE_FLOAT64 = 3;

// Initialization functions

int sv_init(string dev, int freq, int channels, int flags) {}
int sv_deinit() {}
int sv_open_slot(int slot) {}
int sv_close_slot(int slot) {}
int sv_lock_slot(int slot ) {}
int sv_unlock_slot(int slot) {}
int sv_load(int slot, string name) {}
int sv_load_from_memory(int slot, xptr data, int data_size) {}

// Functions to control song playing

int sv_play(int slot) {}
int sv_play_from_beginning(int slot) {}
int sv_stop(int slot) {}
int sv_set_autostop(int slot, int autostop) {}
  // autostop values: 0 - disable autostop; 1 - enable autostop.
  // When disabled, song is playing infinitely in the loop.
int sv_rewind(int slot, int t) {}
int sv_volume(int slot, int vol) {}
int sv_send_event(int slot, int channel_num, int note, int vel, int module, int ctl, int ctl_val) {}

// Functions to get info about the engine, song and its playing

int sv_audio_callback(xptr buf, int frames, int latency, int out_time) {}
  // Get the next piece of SunVox audio.
  // buf - destination buffer of type signed short (if SV_INIT_FLAG_AUDIO_INT16 used in sv_init())
  //       or float (if SV_INIT_FLAG_AUDIO_FLOAT32 used in sv_init());
  //       stereo data will be interleaved in this buffer: LRLR... ; where the LR is the one frame;
  // frames - number of frames in destination buffer;
  // latency - audio latency (in frames);
  // out_time - output time (in ticks).
int sv_get_sample_type() {}
  // Get internal sample type of the SunVox engine.
  // Return value: one of the SV_STYPE_xxx defines.
  // Use it to get the scope buffer type from get_module_scope() function.
int sv_end_of_song(int slot) {}
  // Return values: 0 - song is playing now; 1 - stopped.
int sv_get_current_line(int slot) {}
int sv_get_current_signal_level(int slot, int channel) {}
string sv_get_song_name(int slot) {}
int sv_get_song_bpm(int slot) {}
int sv_get_song_tpl(int slot) {}
int sv_get_song_length_lines(int slot) {}
int sv_get_song_length_frames(int slot) {}
  // Frame is one discrete of the sound. Sampling frequency 44100 Hz
  // means, that you hear 44100 frames per second.
int sv_get_ticks() {}
  // Returns the current tick counter (from 0 to 0xFFFFFFFF).
  // SunVox engine uses its own time space, measured in ticks.
int sv_get_ticks_per_second() {}
  // Returns the number of SunVox ticks per second.
int sv_get_number_of_modules(int slot) {}
int sv_get_module_flags(int slot, int mod_num) {}
string sv_get_module_name(int slot, int mod_num) {}
int[] sv_get_module_inputs(int slot, int mod_num) {}
int[] sv_get_module_outputs(int slot, int mod_num) {}
int sv_get_module_xy(int slot, int mod_num) {}
int sv_get_module_color(int slot, int mod_num) {}
byte[] sv_get_module_scope(int slot, int mod_num, int channel, int[] offset, int[] buffer_size) {}
int sv_get_number_of_patterns(int slot) {}
int sv_get_pattern_x(int slot, int pat_num) {}
int sv_get_pattern_y(int slot, int pat_num) {}
int sv_get_pattern_tracks(int slot, int pat_num) {}
int sv_get_pattern_lines(int slot, int pat_num) {}
byte[] sv_get_pattern_data(int slot, int pat_num) {}
  // Returns array of structures:
  // typedef struct {
  //   unsigned char  note;    // 0 - nothing; 1..127 - note num; 128 - note off; 129, 130... - see NOTECMD_xxx
  //   unsigned char  vel;     // Velocity 1..129; 0 - default
  //   unsigned char  module;  // 0 - nothing; 1..255 - module number
  //   unsigned char  nothing;
  //   unsigned short ctl;     // CCXX. CC - number of controller. XX - std effect
  //   unsigned short ctl_val; // Value of controller
  // } sunvox_note;
int sv_pattern_mute(int slot, int pat_num, int mute) {}
  // Use it with sv_lock_slot() and sv_unlock_slot()]]>
      </Source>
    </ZExternalLibrary>
    <ZExpression>
      <Expression>
<![CDATA[//

sv_init("", 44100, 2, 0);
sv_open_slot(0); // All
sv_open_slot(1); // Melody
sv_open_slot(2); // Bass


Method = 1;

switch(Method)
{
  case 1:
    sv_load_from_memory(1, MusicSongFile.FileEmbedded, MusicSongFile.Size);
    sv_load_from_memory(2, MusicBassFile.FileEmbedded, MusicBassFile.Size);
    sv_play_from_beginning(1);
    sv_play_from_beginning(2);
    break;

  default:
    sv_load_from_memory(0, MusicAllFile.FileEmbedded, MusicAllFile.Size);
    sv_play_from_beginning(0);
    break;


}]]>
      </Expression>
    </ZExpression>
  </OnLoaded>
  <OnUpdate>
    <ZExpression Expression="PressSpace = 0;"/>
    <KeyPress CharCode="32">
      <OnPressed>
        <ZExpression Expression="PressSpace = 1;"/>
      </OnPressed>
    </KeyPress>
    <ZExpression>
      <Expression>
<![CDATA[


switch (Method)
{

  // Play Song and Bass file at the same time

  case 1:

    if (PressSpace)
    {
      if (Volume > 0) Volume -= App.DeltaTime * 400;
    }
    else
    {
       if (Volume < 100) Volume += App.DeltaTime * 400;
    }
    sv_volume(1, Volume);
    break;



  // Switch File to play All or Bass only
  // But I don't know how to retrieve where we were in the music

  case 2:

    if (sv_end_of_song(0)) Time = 0; // This is not working
    else Time += App.DeltaTime;
    trace(IntToStr(Time*100));

    if (PressSpace != OnlyBass)
    {
      OnlyBass = PressSpace;
      int ticks = sv_get_ticks();
    //trace(IntToStr(ticks));

      if (OnlyBass) sv_load_from_memory(0, MusicBassFile.FileEmbedded, MusicBassFile.Size);
      else          sv_load_from_memory(0, MusicAllFile.FileEmbedded, MusicAllFile.Size);

    //sv_rewind(0, ticks);
      //float ttime = Ticks / sv_get_ticks_per_second();
     // trace(IntToStr(ttime));
     // sv_rewind(0, ttime);
      //sv_rewind(0, Time);
      sv_play(0);
    }
    break;


  // Play just file All and mute certain tracks
  // Is it possible?

  case 3:
    trace(IntToStr(sv_get_pattern_tracks(0,3)));
    break;
}]]>
      </Expression>
    </ZExpression>
  </OnUpdate>
  <OnClose>
    <ZExpression>
      <Expression>
<![CDATA[//

sv_stop(0);
sv_close_slot(0);
sv_close_slot(1);
sv_close_slot(2);
sv_deinit();]]>
      </Expression>
    </ZExpression>
  </OnClose>
  <Content>
    <File Name="MusicAllFile" Comment="Imported from music-all.sunvox">
      <FileEmbedded>
<![CDATA[78DAED5A0D7C144715DFFBC817F90E148E260D9B122909012F4028C654F6721FB933F7C5DD254D620B494808912389F9E04BF0AE6AB55AACB1965A296D23B4D52A2215055B6C7B466A63AB524AA5524B89B5B5B482A256C5523877EE76EF86C9CEEDEEDC71D0FEBAF7BBBC3733EFCDECCCFFBD376FE6E26E743451ECD36874B9D52C55AA3314B56C01F06A559AA2D669A301BF99FDBA9D4603E053D9AFA7CE15E2D521DE309FE7EB1A1D56401BD9AF5D673316B154EFD6B90C3A37AD77D83D167B43838D6EDF409B1A9A1C260F6573EB43F2E3ECD7D6E270009E52B03CDB1AE2417D7394B7DADCF53CAF6F705979DE63B119015F0CDED3680DCD653290AF33DA015FC07E9D3A4F88CF0EF31E5E97E543FDA8006FF0E8C0F8F32865A84DCBD14A8E5671B49AA3351CBD01295723F295487F576AFF3A8E3AF5E6D05A29006FB584781AF0CDEE96086FB2D645D6D0A277803A4A033E9A29EC67AAE65ACDCC8A92D292074B46E9D1D6D14020A453A757712AB56136180C3A4DA608C2CEA6A6A608DFDCDC0CF82D8037DA0D148F90928AFB591CB2638A327334D9CF87E3C7373E6FA14A99167AC792377CAA9C40E14ABA9A7E595F5D3BA9FDC2CC02EDDAA23773B57967679C5D4266A1A5A885B28E33954ABBE88DF9F2748EE2DAE32DC7DB3F4E5F8394A723E542A44C1C43E0474DA5800F73B8D6E972BA1817710C3905641084265199C80A84CB7CBD9FABE7CB687B2A420B90723A47A720E50CA41FD2F1B3113A1D296721FD67206552848AD9991684FF2EA66607CA98394C39338FA1197A139D162045E8208A9012EC63E9098D3A65487F68FF5AA45C19E7F85584FA8B583D15BB001753154753121885D32FC9FBF38F3FCEF713B250468285DEFCF8FED38FDD77E0F88B738EAE2E2D9DD5317B4AB9A762E1BC416DD67CEBCEA75FAB23B3D0EDEF430B8DEA0BD34522ED5522ED0B44DAE5D24AA4AC45CAE87CE6C6B9FE6502FA4A8AE6A896A30C9626CA424F4E7BFBC653D793582813CB42D9D76A10C9B03EE8EDE47988DFE7D7B15FC6EFDBCEB01FDF6DCC70DFF0F211668409F84877B90E814C3117D9970BB9722E9207F065B47D12427179029A1FF0FAF9C8F8D720F5FCF87C196D4729DAAE41FACF4F501EC29E5F8BE97C6D3E7D8476D5DCC43A02C36C3A93359C7E7FAE92F54D950C845A2184C604A2BCD4A7BC2DBED354B92E4EFD0FC7BF24E3939E3659D709507D5451384405A83369415FD0E7A7C21FD218A286630862A90B44F2877291F60571668462FA62F98A56A47DAEE47C67E2A3A67273C9E88CB8A93F41FD8851D27CE4EEEE8A854D57EFC90E064F9C7B72734D0D6B86C10BBEF796346FDB61BCABAC2F47BAA50670F98853E78ADCB3727A0A488FC69D05393D8504BDD9B047088CA7C2E44D6332C66344C6C3E9C17B4C85801E25617E5B64E831847AAD227AB8F9F9213DAD080E38BD3119F63242682F2332EC05D61B271C2F2082BB42C27872ECC54F88FB08A15E80506F5C442F4DC27842F6A296B02E42714929C1FF4EC9D06308F55A09F5FC847A23847A0142BD7111BD5409387408D84BAA041CE4E8B512EAF909F54608F502847AE3227AE9127050CBD06308F55A09F5FC847A23847A0142BD718C9E9B93D503DEAEB38175770C0DF60D0DE2B35FB7299CF185789731F2FBB89B1B4BC33AA59B1BEB7550DFD2D21291E17E8B072FE76E7486F7264516E5D63BAC5CBAE7B6592C11719B450FF1B5EAB00890714678ABBD1E4C3B932F23536B86A656D7D9D3D9DF36D8DB8F9B9AA7D939E92239B1C9EEA7A2936514F2269B12A448261BFABF84465DA46B9E4F83EAFD109F0AF1A5109F07F723813F0C789BC5E08CAE57305114056DA93A0A9A71C5AADE58A731005A0A2F2786D76E4514AFF54A99C6B9D34782571E97EF81723A4785F08331F3623056A0D8B0786809F088B5DEA66EEF60677FECF54E8BCA89ADF87268C59F95E921BE63C4E100F0D998553C5E206CE12A884F97E21D509F33A17A1AE25B2861F494B1FA67515D7F09BC8CD43A2C5008ADEF5EB15A8A75707262D651A58A5A47914A9E7550F70613193F294CFCA430C852327CD49C403463A163E81F5AE3DED033B84A64838BCA89016481009A26336052CFC50DD0BBD0C23E04D5AB217E0C03044309F338195C306630863181BF82DD56D7D3E6EDEDA2BB700910308C7C213931FB78070AEF57C974E0DDF12740B7636CA213E3A8FB30F5B0D34E5546F9932A61F93D8BA2FC32B5703F0720BE03336E9EC83670CF65B42731AA37DBEB23EB6EB6DB22EF6D367880CD3D72E82D4D792575F8C068CE897DAF7497ECBD73DB0B79E65B1E3D5F32FC84EFD0C30FE8CDA69049187645F5159C7EF604038D91D65B3BDB3AC432447969FD5128AD9FA54C4A5ACF272D707A3888B15038F2A440FCF3548C6D48A43EA8B83CE9BDC9DBD6D31523A300E0A5437262D0954001E92999D06DF7054933FC34CE995108719B8A1FB381293139E84E091052D40703420B7483B02B7910A686FE9D215C3759425EF07E87100EA1A6A18D1BE9DAB681818485D06108C42C55D26F46A4844E583E5BC2D9EF8A089D7414347DEF9ABEFECE8101DC7D16002DF3623931D48A21D4CEC93CAD07B544A8693897C90086C26D68B1A26806C4AFC06C844111F75A1C0752131081DCC8B834F6FF7E004454613931245E8290E89319047DE789EF4DD4C80DD56905E6B4AC98B8AAB484558DB57A063D5DEBEDC5DF2FF0F60CC989AD6206940DF4C8B5E7677CA4ABA840EFF9B81582FE6F24663876AFEBF47A139AD1EE8532DAEB5449CB6873918568C038E63A88D76232DA2B392C5BF29411F06C43DEC1EE18B730BC19437262E8B541E89965A2F76AFC9B296ED35C25E12A2DE6E5298B0E930074629D44FDD07672B91EF4741B7DBF70BD92AB5700018552A54E494D4BCF989499959D939B975F3079CA5553A769A65F5D58744DF10CBAE4DA99A51F9975DDECB2F2391573E77D545B397FC1C2AA45D72FFE58F5C76B6EF8C4124657AB37184D7566CB27EBAD36BBC3B9D4E5F63434DED8D4DCF2A99B6E5EB6BCB5AD7D4547E7CAAE55DD9F5EED5DD3D3DBF799FE81C1A1B5EBD66FD8F8D94D9B3FE7F3DFF2F92F7CF1D62F7DF9B6AF7CF5F62D5FBBE3EBC3DFB8F39B776DBDFB5BF77C7BDBBDDBEFBBFF8191EFECD8F9E0430F7FF77B8F7CFF07BB7EB8FB477B1EFDF1DE9FFC74DFFE9F3DF6F8819F3FF1E453815F8CFEF2E0D3BF7A66ECD7CF3EF79BDFFEEED0F3875F38F2E2EF8FBEF487632FFFF195E3AF9E18FFD36B7F7EFD8DBFBC79F2ADB7FF7AEAF4DFFE7EE61FFFFCD73BFFFECF7FCFFEEFDD73EF9DBF108C79D268EC6E07E14EF4A4C1CB89F9D549C8AF3432FDCA173C481A157342FFA02CEC3B2AA9694C92D21BC1DF4FE7276A5BBA1502608732E9DB92DBDA23B85FE32E587081B04A21F397A3CBB44DC1607ABA7BBABC1B129963144229EBD6E41FF99661CEE05B310B5F469183A65326F1C80781E6EA5CDBD9DF2EFEF31B272786D84A08B1F532110B1E214E8F0B10770B627E6D3986733D09B9069C156626F986E5FF87E50951]]>
      </FileEmbedded>
    </File>
    <File Name="MusicBassFile" Comment="Imported from music-bass.sunvox">
      <FileEmbedded>
<![CDATA[78DADD5A09781345149E4DD2BBA50758538B752BC8256241AB88A89BE6686273914D6B5B115A20966A686B0FA188B61E78815A0FBC40A85C8A221E28A888D48A8A2756BC5081AAA8A878DF07C69DCD6E324E33D9EC360674F3A5F3CFEC7BB33BEF7FF3E6CDA46C99A31C705799D1C56AB852A549A28AB80AC41A750255E4B4D1105FCC7D59A7D100713CF77517BB78ACE1B1619C888BCB1C565896715FBBCE661CCC957A56E732E8585AEFB0BB2DF6D2521B3DAD953695963B4C6E6063F5BC7C2FF7B5553A1C10038AC3DC5D1EC3F68A20B6DAD81211EB4B5D5611BB2D3623C4D9F03D8D567E2C03A17CB1D10E7116F775EADC3CA6FCD82DEA7298EF270762835B0705C600157FAF4028C70A65A1504E10CA8942791A569F80C98FC5FA3B54FBD709A5536F0EDACA6AE1310D71055B19C0266B71C08616BD03B6012DFC6807719F6CEDD1DA21A3F387E6AFCCEFA6BBABBABBBA789D62BD5A5029F2439FCFE73499020C3BCBCBCB03B8A2A202E285101BED068030940D12007A89F51CA124DDEF6FBDBFFD93F4B5583D07ABE76275C50CA19706C4C10FD353E474395D8C4B3143FBA10CC6503248C12CE0AF8BEDED42BB58C7EFC7636516564F14CA41583D09EB47E9F3D3B03207ABA762FD276175A50CE57123CDF2FF1D0F46748D648E65463163189AA1E7D1095D4A19DA1A82A174EC8D73857A3A6621B18EDF4FC64A920571CB89FA99D8F38FC4DAC5E78B75FC3E5EE2F7B558FF995162888B9B7974664126BD83764D9C0C18C030F3BE4DED485C9AAEE2E2A75A0643550843DB50869C3A7E0D56F16FE0D7A3103D9AC4AC841E437A1EA60F2278EE42197A8C42BD2A093DD238DB15DAB553A15D7B497A118EB35DA17D3A15EA7529D4EB95D05347F0BC507C5011F8DB7E197A8C42BD2A857AED0AF53A15EA7529D4EB25E8B182AC1E622E71877677B43437B43403E2C59AFC1193C72E63201767856769B9C9C20ACFDA0BDB2B2B2B033242DE0F5F8E2D73FADF994A05ACDE6115C2256BB35802E2368B1EC1451ABF08947106B0D55E92C8E114B18E0DAD02195AB1A7CED358DD5CDF481A9ABBC299FC0F39A9C16E04C1C13294BCC1C6F98092C1F27BA0325DA06B112720EDED088E47F0500467A0FD44807B20B6590CCEA0BD7CD12A71D2266982A419A7CFAC07612E485A9C2827C5D73A2AC8D71C954CE75CD1A684AF0C213EC27AA25086E20FE5CC4BE098C2B9E1F82850C047387B9B6ABDCD9EC6F0F64E08CA49597C2A62F19764CE90B69D8AC301C469042BEECA0AEDE16A042746323B903E8720ED34822B4168F654E1FAE7589DF32FCC32A5DE6141426849EDF4F323F10E414ECA3B0AD541EF18AC96E71D60B12F9AF11310E22720300B64CC517314D90CC78EA1B16516DB5AD73C5362810BCA49116441083A5C66C0042FF79BA0DF11C3AE42DA3508DE46208201A1314986148C198263F4C187F0B4D5D5557BEB6BE81A5202041D2333949C947FFC8884F7C3644EE075FD4F8016107CC24398A81B08EDE8A4CD5605F13E7568F9874E0AE2299AD0FD6C42F00CC27333249681DB0FA23F49957AB3BD246077B3DD16786FB3C10D7D6ECDF6CFB5A3C6829E4DDD03F66CF8A0367FFD4D77BE9161BEF4E103F91D9BDBB6AF5EA6379B789730AC0DEA53827E5A1F070D93D65B3DD533A432447969FDDB485A3F4C1593B45E4C5AD0F4B099E0A168E48943F0EB20CC3224D1EEA30E4E7A6FF256D7D584C928207989889C1475F94840DA2293BA256D3EA5197E823099710A498B4A3B6101531172D015115008C0FF83420B7282B0367614C6F347D8FEB68111E405FF750AD1106A6A993B972EAA6E6A8A5A08ED40484C55C7FC642492D089CAA745B0F73B2442271D244D5F3FABA1D1D3D4443ACF82A4A5FC534E8AB53C84B53F64EED67D058A58D30A532689FF6DCDBFA0858BA249089E4E58087D12D36B7C3F98EAC308328D8C930090CA44D47E392926DE419868901904DB0E283E37D16027545F5184DD32D5D7AA7404560D673D839E2EF2D693CF17447F46E4A4AC988464037572FDF98536A556A4F0733EC142898885C2856376B6C7EB8D6A46BB1EC96887AB6396D1A6638628254CCCD9082E2064B4877258B664A802E4D95ABCCDB5614E61443746E4A4D8AB46D833CB646F77FF1753D2A2393382A3B4B087A71C3B4C14D809B7136D4796938375E1BBDBE0FBF9DB55423B050528955A13179F9098949C929A36203D23336BE0A0C3B20FD7E61C913BF8C8BCA3E8FCA3870C3D66D8F01123471D3BFAB831C7178C1D77C28985279D3CFE9409A74E3CEDF433185D91DE6034159B2D6796586D768773928B7597969D555E5179F6E473A64CADAA9E367D86E7DC9A99B5E79DEF9D5557DF7041635373CB85B3E7B4CEBD68DEC597B4B55F7AD9E557CCBFF2AAABAFB976C1C2EBAEBFA1E3C69B6EBE65D1ADB7DD7EC79D8B97DCB57459E7DDCB57AC5CB5FA9E7BD7DC77FFDA07D63DF8D0C38FAC7FF4B10D1B1F7FE2C94D4F6D7E7A4BD733DDCF6E7DEEF917B6BDF8D2CBAFBCFADAF6D77BDED8F1E65B6FBFF3EECEF7DEFF60D7EE3DBD1F7EF4F1DE4F3EFD6CDFE75F7CB9FFABAFBFF9F6BBEF7FF8F1A79F7FF9F5B7DFFFF8F3C05FBEB03B8DB2DA6930DC49EE344439A979B50F99575A99F3AACDB75569541CC0FF534AE8B9A38E348D89517A13F2F7D371D15A96E623042C57C57C5962AD7521D76BD2010B29101652327F393A48CB144AA6BBB6AEC6DB1ACD1C2317495917C57ECB3785B0075F4430FC48A09C349D2A865B3E843497E7424FE334E99FDF043929C6CE45189B239331DF0EC5E9711636DD7C845F5B7692A65E04B9069A15A6C4F884E56FCE358B47]]>
      </FileEmbedded>
    </File>
    <File Name="MusicSongFile" Comment="Imported from music-song.sunvox">
      <FileEmbedded>
<![CDATA[78DAED590974134518DECDA6B4057A50502A5408529196C37014115192E6686273D14D4B531568692895D0D636E5524CF056142B8207A256501145045150F18807E28D28822047BD11C1FB40AE7527DD24439AD9D9DD84703C366FDF7C99FDFFDDD9F9FE6B66E9126B29C11E25BA225ACEB632793299CFFE01584E2592F936B302E059EC49DB745A80DBB1A7BDA0C88FE57EAC1D1CC005255613684BD8D3A236EBB2D85643AB8BB46A5AA1B15AEC464B71B159513143A12F2EB5EAED8499D6F8E55BD8D35C66B5024C902C66AFFA31E87784B0C94C1706B0A6B8C814C076A35907F052304E9DC9FF2E9D817C81CE0270067BDAD4764B609C2CB6077459ECBF0F05B0D6AE266444D4C770FF2C1184816BE37D9C797E74CFB7690C7E5B01A6603319FD5801B0832E0B62BDA9206843468D15F4CD1DF5BD874AF5759FA818A1D8AE1991DFBEE268EF0CE5D4AC1FD394E9077A1E1865D31768284E25BF15320C63D3EB83166E2B2D2D0D6287C3017036C03A8B96802C74209114D319CB09BB5FF8FD9561FF0745F9FC3C89FAC3583D8A9D80635B8A6B1362684149C765FC81C31BE5F802164A4216AA1260A157BDB276FFCB0FAFDBB9B9DF96C9D9D97D2AFB76C9B5F71F3AD0ADEC38D8B464FD3705D22C74119039C52C34A41FB91D86B99E87B93E04735D6C3B28ECBF32EC7FF8FB0C8872FE7322E8CBFC76055A25D7AA906DAC2C744FD7BD63F65D24C542557C16CA0EAB18931D4EF7EB91181292E5D8E8E5F1AAD953E5F52C52B13FCF6DAAA6BAA671CDAA6695CF0374A4C490CA08594EE8915B1E5D9D91AB8E52FFCCF38FCBF3A5D6616C7AF511754456AB03F888DF12190FE3F112AD3FA9162A8F60A14330592917737D489475064E1F97059598EB030467D1B6879C484B93D6F68CBAF5C6E83EB8566A96BBAFBAFFD0D26E2B531866F7A1D7678D1CC99A1F73D473789463E162DDFC9CBA54E116EA4365399BBA2828CBE991909E02D2EB0B5B36464F25516F3CA4D75F849E17D2538AD06B96384E9FC471B660F44801EF17893F4A007F95119E4709E04F8CDE78897A5E897ACD12F57C12F55A307A72013CC845E8A924EA8D97A8E795A8D72C51CF2751AF05A14773B21A802D6A3398776BA3BBAED18DCE4EB4BE3522FB71912EB85F4873CFCA643338CD3DEB3BD05F56561694E1F626C1E0E8125BAB0F931D095A633571E198361B8D4171B35103E17C79AB0890B105B1C95208D26587C0FFB0577340AF56E0AC71D697BB6BEB51AF6677D8DA1F23877BD9B544E86555A4B8974D6008292FEBDFA72D51076F1DC08950BF17C2ED209C0DE174F83E02F02680CD46AD2D345F4CACDA70D246CB43A4E9264CAAE5AB9600690901391C5F2BC8105FD365228D7389470A5FE95C7C04FF93B836127F30672E04C76438372C1F4A097CF0CDB7BEDAE576D6F3CF7762480E37E3E3A019FF40A48778B6490E0700A72066716746640BA7209C24C43BA07BF686FA15102E2322B327E3BB3FCBEAF4E3E06552ADC30885D0C2EA09938558072787B38E3C2A641D599438EB201E6262193F0944FC2410CC12227CD4104336F9D8D1D6374EA167D4B82761125C480E47901122A8ABC880497C18354107A1897D02EA9743F83D04112A223246C9A082B10A61186DF049ECB6EA9A72576D95A20A550001C3E814490E671F7F41E1FD2C910EBC22FA02680EC2269C08475D83E8879DF66C5908EFA122CBAF1C16C263E591EFB30EC29588E7A663D2C00327D09E70ADC660290CCEBBC1620E8EDBA0B5039B5BB6F1A7CCDC41C4A6756FA5EE5EB3A3BAD7EA790B3F4B37CC5E75A457D36B9E8D4F3EAA31E8FD26A15D1ED22739FD943606CA53D69B9CE595B80A515C59BF052AEBFBC8E252D6078A16B83C74232C148E3C0910FE94E04943987E863C31E5BDDE555E53C5535100F29220391C75BDA080F48648EA167918A9157E22E7CCE114A2928A1791C064881A7489000A09E2F4A0D008ED202C8F1F8560A1DC9EEBEB2CA02E38D5298443A8BE71E64C457E794343CC4268134462472AEE3B234242272C9F2260ED7752844E4588344DED94BA7A6743036A3F0B90D6E158391C6B3D20D60E895CAD334A49AC65722E930C0C854B687C513419C213108990C1B8D7F028986AC308E446BAD1FCDF64012354AB1C8E89AD1013752283A0E788E47D1379D80ED57E12B15A26DBCEAA42C0ACF2CD9E56A3C877D5A2F71702F60CC9E1663119AA066AC4DAF3068FD45924C3F7F9B81982BEEBF286637A9AD3E58A6945BB1AAA682FA0E256D1A6854D4431C231A7415889A8684FE6B06C4C9705C93337BADCD53CBB30013386E470EC9543EC1944B2B72BFA648A4A9A93046CA5F16E9EB2ECA862C00EDF4AD40BA593137584AF6E43E36BED9771FD24102065943CA15D625272FB0E1D5352D3D23B6574EE72D6D95D33CFE9D63DEBDC1E3D15BDCEEB9D7D7E9F0BFAE6E4F6EB3F60E085CA4183870CCD1B76D1F08B475C32F2D2CB46A9D4F91AAD4E5F60305E5E68325BACB6D145B4BDB8644CA9A3EC8A2BAF1A3B6E7C79C5844AE7C4AA49D5574F764DA9A9ADBBA6BEC1DD3875DAF41933AFBD6ED6F51EEFEC1B6EBCE9E65B6EBDEDF63BE6DC79D7DCBB9BEE9977EFFC05F7DDFFC0830B1F5AF4F0238F363FB678C9E34F3CB9F4A9654F3FB3FCD915CFAD5CF5FCEA175E5CB3F6A5975F59F7EA6BAFBFE17BF3ADB7DF59FFEE86F7DEFFE0C38F3EFE64E3A79B3EFB7CF3175BB67EB96DFB573B76EEDADDF2F537DF7EF7FD0F3FEEF969EFCFFBF6FFF2EB6FBFFFF1E75F7FFFF3EF81FF0E1E3A7CE428C3BBD228A9AE00E10EBBD208C8E1FC6A0FE4579922FDCAC3BC23352AA6B2672784EF5042CB9838953711BF9F0E8E555ABA192260B12CEE698936D544CCD7A80D165420CC23457E393A41690A26D35E5D53E59A11CB1AA33B54B22E88FF926F2C620DBE0031F1398474D2D4B2382EF920D28A9C539DF515F8CF6F9C1C8EB1891063D34532C67C2EB93CCE08733706F1B5651BCAF504D41A7055D821CE3B2CFF030377D10E]]>
      </FileEmbedded>
    </File>
    <Variable Name="OnlyBass" Type="1"/>
    <Variable Name="PressSpace"/>
    <Variable Name="Time"/>
    <Variable Name="Method"/>
    <Variable Name="Volume"/>
  </Content>
</ZApplication>

User avatar
Kjell
Posts: 1706
Joined: Sat Feb 23, 2008 11:15 pm

Re: SunVox for ZGE

Post by Kjell » Fri Feb 15, 2019 9:54 pm

Hi Ats,
Ats wrote:
Fri Feb 15, 2019 7:40 pm
I just made a test in order to only play the bass line at some point. But I'm not sure what would be the best method to do that.
You can use the sv_send_event function. Attached is a simple example ( use the left-mouse-button to toggle the "melody" on and off ).

K
Attachments
Foo.zip
(1.37 KiB) Downloaded 27 times

User avatar
Ats
Posts: 233
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: SunVox for ZGE

Post by Ats » Fri Feb 15, 2019 11:35 pm

Thanks Kjell :D
I think I get it. It will be a bit more complicated to handle that method with several music files but it's very efficient!
Where did you find that 0x0100 is the for the volume? In SunVox source code?

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" FileVersion="2">
  <OnLoaded>
    <ZExternalLibrary ModuleName="SunVox">
      <Source>
<![CDATA[//

int sv_init(string dev, int freq, int channels, int flags) {}
int sv_deinit() {}
int sv_open_slot(int slot) {}
int sv_close_slot(int slot) {}
int sv_load(int slot, string name) {}
int sv_load_from_memory(int slot, xptr data, int data_size) {}

int sv_play(int slot) {}
int sv_play_from_beginning(int slot) {}
int sv_stop(int slot) {}
int sv_send_event(int slot, int channel_num, int note, int vel, int module, int ctl, int ctl_val) {}]]>
      </Source>
    </ZExternalLibrary>
    <ZExpression>
      <Expression>
<![CDATA[//

sv_init("", 44100, 2, 0);
sv_open_slot(0);
//sv_load(0, "Foo.sunvox");
sv_load_from_memory(0, MusicAllFile.FileEmbedded, MusicAllFile.Size);
sv_play_from_beginning(0);

Volume = 0x4000;]]>
      </Expression>
    </ZExpression>
  </OnLoaded>
  <OnUpdate>
    <KeyPress Keys="{" RepeatDelay="0.25">
      <OnPressed>
        <ZExpression Expression="Toggle = !Toggle;"/>
      </OnPressed>
    </KeyPress>
    <ZExpression>
      <Expression>
<![CDATA[// sv_send_event(int slot,
//               int channel_num,
//               int note,
//               int vel,
//               int module,  // SunVox Module n° + 1
//               int ctl,     // Volume
//               int ctl_val) // Volume value

if (Toggle) // OFF
{
 if (Volume > 0)
 {
  Volume -= 0x0200;
  sv_send_event(0, 1, 0, 0, 2, 0x0100, Volume);//Generator
  sv_send_event(0, 1, 0, 0, 6, 0x0100, Volume);//Kicker
  sv_send_event(0, 1, 0, 0, 7, 0x0100, Volume);// Analog generator
  sv_send_event(0, 1, 0, 0, 8, 0x0100, Volume);//Lead
 // sv_send_event(0, 1, 0, 0, 11, 0x0100, Volume);//FuzzBass 0B
 }
}
else
{
 if (Volume < 0x4000)
 {
  Volume += 0x0200;
  sv_send_event(0, 1, 0, 0, 2, 0x0100, Volume);
  sv_send_event(0, 1, 0, 0, 6, 0x0100, Volume*2);//Should I retrieve module's original volume at the start?
  sv_send_event(0, 1, 0, 0, 7, 0x0100, Volume);
  sv_send_event(0, 1, 0, 0, 8, 0x0100, Volume);
 // sv_send_event(0, 1, 0, 0, 11, 0x0100, Volume);
 }
}]]>
      </Expression>
    </ZExpression>
  </OnUpdate>
  <OnClose>
    <ZExpression>
      <Expression>
<![CDATA[//

sv_stop(0);
sv_close_slot(0);
sv_deinit();]]>
      </Expression>
    </ZExpression>
  </OnClose>
  <Content>
    <Variable Name="Toggle" Type="4"/>
    <Variable Name="Volume" Type="1"/>
    <File Name="MusicAllFile" Comment="Imported from music-all.sunvox">
      <FileEmbedded>
<![CDATA[78DAED5A0D7C144715DFFBC817F90E148E260D9B122909012F4028C654F6721FB933F7C5DD254D620B494808912389F9E04BF0AE6AB55AACB1965A296D23B4D52A2215055B6C7B466A63AB524AA5524B89B5B5B482A256C5523877EE76EF86C9CEEDEEDC71D0FEBAF7BBBC3733EFCDECCCFFBD376FE6E26E743451ECD36874B9D52C55AA3314B56C01F06A559AA2D669A301BF99FDBA9D4603E053D9AFA7CE15E2D521DE309FE7EB1A1D56401BD9AF5D673316B154EFD6B90C3A37AD77D83D167B43838D6EDF409B1A9A1C260F6573EB43F2E3ECD7D6E270009E52B03CDB1AE2417D7394B7DADCF53CAF6F705979DE63B119015F0CDED3680DCD653290AF33DA015FC07E9D3A4F88CF0EF31E5E97E543FDA8006FF0E8C0F8F32865A84DCBD14A8E5671B49AA3351CBD01295723F295487F576AFF3A8E3AF5E6D05A29006FB584781AF0CDEE96086FB2D645D6D0A277803A4A033E9A29EC67AAE65ACDCC8A92D292074B46E9D1D6D14020A453A757712AB56136180C3A4DA608C2CEA6A6A608DFDCDC0CF82D8037DA0D148F90928AFB591CB2638A327334D9CF87E3C7373E6FA14A99167AC792377CAA9C40E14ABA9A7E595F5D3BA9FDC2CC02EDDAA23773B57967679C5D4266A1A5A885B28E33954ABBE88DF9F2748EE2DAE32DC7DB3F4E5F8394A723E542A44C1C43E0474DA5800F73B8D6E972BA1817710C3905641084265199C80A84CB7CBD9FABE7CB687B2A420B90723A47A720E50CA41FD2F1B3113A1D296721FD67206552848AD9991684FF2EA66607CA98394C39338FA1197A139D162045E8208A9012EC63E9098D3A65487F68FF5AA45C19E7F85584FA8B583D15BB001753154753121885D32FC9FBF38F3FCEF713B250468285DEFCF8FED38FDD77E0F88B738EAE2E2D9DD5317B4AB9A762E1BC416DD67CEBCEA75FAB23B3D0EDEF430B8DEA0BD34522ED5522ED0B44DAE5D24AA4AC45CAE87CE6C6B9FE6502FA4A8AE6A896A30C9626CA424F4E7BFBC653D793582813CB42D9D76A10C9B03EE8EDE47988DFE7D7B15FC6EFDBCEB01FDF6DCC70DFF0F211668409F84877B90E814C3117D9970BB9722E9207F065B47D12427179029A1FF0FAF9C8F8D720F5FCF87C196D4729DAAE41FACF4F501EC29E5F8BE97C6D3E7D8476D5DCC43A02C36C3A93359C7E7FAE92F54D950C845A2184C604A2BCD4A7BC2DBED354B92E4EFD0FC7BF24E3939E3659D709507D5451384405A83369415FD0E7A7C21FD218A286630862A90B44F2877291F60571668462FA62F98A56A47DAEE47C67E2A3A67273C9E88CB8A93F41FD8851D27CE4EEEE8A854D57EFC90E064F9C7B72734D0D6B86C10BBEF796346FDB61BCABAC2F47BAA50670F98853E78ADCB3727A0A488FC69D05393D8504BDD9B047088CA7C2E44D6332C66344C6C3E9C17B4C85801E25617E5B64E831847AAD227AB8F9F9213DAD080E38BD3119F63242682F2332EC05D61B271C2F2082BB42C27872ECC54F88FB08A15E80506F5C442F4DC27842F6A296B02E42714929C1FF4EC9D06308F55A09F5FC847A23847A0142BD7111BD5409387408D84BAA041CE4E8B512EAF909F54608F502847AE3227AE9127050CBD06308F55A09F5FC847A23847A0142BD718C9E9B93D503DEAEB38175770C0DF60D0DE2B35FB7299CF185789731F2FBB89B1B4BC33AA59B1BEB7550DFD2D21291E17E8B072FE76E7486F7264516E5D63BAC5CBAE7B6592C11719B450FF1B5EAB00890714678ABBD1E4C3B932F23536B86A656D7D9D3D9DF36D8DB8F9B9AA7D939E92239B1C9EEA7A2936514F2269B12A448261BFABF84465DA46B9E4F83EAFD109F0AF1A5109F07F723813F0C789BC5E08CAE57305114056DA93A0A9A71C5AADE58A731005A0A2F2786D76E4514AFF54A99C6B9D34782571E97EF81723A4785F08331F3623056A0D8B0786809F088B5DEA66EEF60677FECF54E8BCA89ADF87268C59F95E921BE63C4E100F0D998553C5E206CE12A884F97E21D509F33A17A1AE25B2861F494B1FA67515D7F09BC8CD43A2C5008ADEF5EB15A8A75707262D651A58A5A47914A9E7550F70613193F294CFCA430C852327CD49C403463A163E81F5AE3DED033B84A64838BCA89016481009A26336052CFC50DD0BBD0C23E04D5AB217E0C03044309F338195C306630863181BF82DD56D7D3E6EDEDA2BB700910308C7C213931FB78070AEF57C974E0DDF12740B7636CA213E3A8FB30F5B0D34E5546F9932A61F93D8BA2FC32B5703F0720BE03336E9EC83670CF65B42731AA37DBEB23EB6EB6DB22EF6D367880CD3D72E82D4D792575F8C068CE897DAF7497ECBD73DB0B79E65B1E3D5F32FC84EFD0C30FE8CDA69049187645F5159C7EF604038D91D65B3BDB3AC432447969FD5128AD9FA54C4A5ACF272D707A3888B15038F2A440FCF3548C6D48A43EA8B83CE9BDC9DBD6D31523A300E0A5437262D0954001E92999D06DF7054933FC34CE995108719B8A1FB381293139E84E091052D40703420B7483B02B7910A686FE9D215C3759425EF07E87100EA1A6A18D1BE9DAB681818485D06108C42C55D26F46A4844E583E5BC2D9EF8A089D7414347DEF9ABEFECE8101DC7D16002DF3623931D48A21D4CEC93CAD07B544A8693897C90086C26D68B1A26806C4AFC06C844111F75A1C0752131081DCC8B834F6FF7E004454613931245E8290E89319047DE789EF4DD4C80DD56905E6B4AC98B8AAB484558DB57A063D5DEBEDC5DF2FF0F60CC989AD6206940DF4C8B5E7677CA4ABA840EFF9B81582FE6F24663876AFEBF47A139AD1EE8532DAEB5449CB6873918568C038E63A88D76232DA2B392C5BF29411F06C43DEC1EE18B730BC19437262E8B541E89965A2F76AFC9B296ED35C25E12A2DE6E5298B0E930074629D44FDD07672B91EF4741B7DBF70BD92AB5700018552A54E494D4BCF989499959D939B975F3079CA5553A769A65F5D58744DF10CBAE4DA99A51F9975DDECB2F2391573E77D545B397FC1C2AA45D72FFE58F5C76B6EF8C4124657AB37184D7566CB27EBAD36BBC3B9D4E5F63434DED8D4DCF2A99B6E5EB6BCB5AD7D4547E7CAAE55DD9F5EED5DD3D3DBF799FE81C1A1B5EBD66FD8F8D94D9B3FE7F3DFF2F92F7CF1D62F7DF9B6AF7CF5F62D5FBBE3EBC3DFB8F39B776DBDFB5BF77C7BDBBDDBEFBBFF8191EFECD8F9E0430F7FF77B8F7CFF07BB7EB8FB477B1EFDF1DE9FFC74DFFE9F3DF6F8819F3FF1E453815F8CFEF2E0D3BF7A66ECD7CF3EF79BDFFEEED0F3875F38F2E2EF8FBEF487632FFFF195E3AF9E18FFD36B7F7EFD8DBFBC79F2ADB7FF7AEAF4DFFE7EE61FFFFCD73BFFFECF7FCFFEEFDD73EF9DBF108C79D268EC6E07E14EF4A4C1CB89F9D549C8AF3432FDCA173C481A157342FFA02CEC3B2AA9694C92D21BC1DF4FE7276A5BBA1502608732E9DB92DBDA23B85FE32E587081B04A21F397A3CBB44DC1607ABA7BBABC1B129963144229EBD6E41FF99661CEE05B310B5F469183A65326F1C80781E6EA5CDBD9DF2EFEF31B272786D84A08B1F532110B1E214E8F0B10770B627E6D3986733D09B9069C156626F986E5FF87E50951]]>
      </FileEmbedded>
    </File>
  </Content>
</ZApplication>

User avatar
Kjell
Posts: 1706
Joined: Sat Feb 23, 2008 11:15 pm

Re: SunVox for ZGE

Post by Kjell » Sat Feb 16, 2019 1:19 am

Hi Ats,
Ats wrote:
Fri Feb 15, 2019 11:35 pm
Where did you find that 0x0100 is the for the volume? In SunVox source code?
From the original header ( sunvox.h ) included with the SunVox library.

Code: Select all

/*
   sv_send_event() - send some event (note ON, note OFF, controller change, etc.)
   Parameters:
     slot;
     track_num - track number within the pattern;
     note: 0 - nothing; 1..127 - note num; 128 - note off; 129, 130... - see NOTECMD_xxx defines;
     vel: velocity 1..129; 0 - default;
     module: 0 - nothing; 1..255 - module number + 1;
     ctl: 0xCCEE. CC - number of a controller (1..255). EE - effect;
     ctl_val: value of controller or effect.
*/
int sv_send_event( int slot, int track_num, int note, int vel, int module, int ctl, int ctl_val ) SUNVOX_FN_ATTR;
Volume is the first "controller" of the SpectraVoice module, hence a value of 0x0100 for the "ctl" argument.

K

Post Reply