Dark Bit Factory & Gravity

GENERAL => General chat => Topic started by: n00bstar on May 31, 2012

Title: klystrack!
Post by: n00bstar on May 31, 2012
For some reason, a few week backs, I decided to check what was happening in the world of trackers. I've graduated from trackers to actual 'real' studio stuff years ago, but tracking will still always have a big warm fluffy place in my heart. So I've found the usual assortment of softwares, from clones of FT2 and IT to trackers that support all the VSTs in the world and dice your veggies and takes your kids to school and all that. All in all, it was a fairly disappointing experience. No scene spirit anywhere.. just VSTs and commercial products. That is, until I added the magic word to my Googling: Chiptune!

On top of a long list of only 1 item came: klystrack!

So heading over there and downloading this gizmo, I fell in love. The scene-cred is very high with this one, it looks like it was made in the 90s, it's fully open source, great developer support and a very comprehensive manual/wiki.

Those of you who remember AHX on the Amiga will be riiight at home with Klystrack, it takes most of its cues from it down to the sequence editor using floating patterns of variable lengths etc.

There's a library for it should you want to use the synth engine for your own products or to playback .KT tracks.

If you've read this far and haven't yet googled it and downloaded it, then lemme at least do the first step to help you out: http://code.google.com/p/klystrack/

Title: Re: klystrack!
Post by: energy on May 31, 2012
Very good work. :clap:
Is there a replay routine available?
Title: Re: klystrack!
Post by: Pot Noodle on May 31, 2012
Good info n00bstar, Thanks for that I am glad you found the Amiga scene spirit you were looking for.  :goodpost:
Title: Re: klystrack!
Post by: n00bstar on May 31, 2012
@Energy, yes there is! Well... kind of, the code is there and the dev gives you all the info needed to compile your own. From what little I've toyed with the code, it is extremely efficient and has almost no CPU hit to speak of. Seeing as it takes me 8 hours of hard work and case of red bull to put a single sinescroller on screen, I don't think I'll be the one compiling it into a nifty little lib, but if anyone wants to give it a go (make me a blitz wrapper purdy pleez?) I will make music for all your projects out of sheer gratitude :D
Title: Re: klystrack!
Post by: benny! on June 01, 2012
Looks awesome. Thanks for sharing!
Title: Re: klystrack!
Post by: zawran on June 01, 2012
I took a look at getting it to work with Bmax, and here is some code for you:

Code: [Select]
'
' load the KSND DLL into memory
'
Const KSND_DLL:String = "ksnd.dll"
Global g_hndDLL:Int
g_hndDLL = loadlibrarya(KSND_DLL)
If g_hndDLL = Null Or g_hndDLL = 0 Then
RuntimeError "Unable to find the file: "+KSND_DLL
End If

Private
' player calls
Global KSND_CreatePlayer:Byte Ptr(samplerate:Int)"Win32" = GetProcAddress(g_hndDLL,"KSND_CreatePlayer")
Global KSND_FreePlayer(kplayer:Byte Ptr)"Win32" = GetProcAddress(g_hndDLL,"KSND_FreePlayer")
Global KSND_PlaySong(kplayer:Byte Ptr,ksong:Byte Ptr,position:Int)"Win32" = GetProcAddress(g_hndDLL,"KSND_PlaySong")
Global KSND_Stop(kplayer:Byte Ptr)"Win32" = GetProcAddress(g_hndDLL,"KSND_Stop")
Global KSND_Pause(kplayer:Byte Ptr,state:Int)"Win32" = GetProcAddress(g_hndDLL,"KSND_Pause")
Global KSND_GetPlayPosition:Int(kplayer:Byte Ptr)"Win32" = GetProcAddress(g_hndDLL,"KSND_GetPlayPosition")
Global KSND_SetVolume(kplayer:Byte Ptr,volume:Int)"Win32" = GetProcAddress(g_hndDLL,"KSND_SetVolume")
' song calls
Global KSND_LoadSong:Byte Ptr(kplayer:Byte Ptr,path:Byte Ptr)"Win32" = GetProcAddress(g_hndDLL,"KSND_LoadSong")
Global KSND_LoadSongFromMemory:Byte Ptr(kplayer:Byte Ptr,mem:Byte Ptr,length:Int)"Win32" = GetProcAddress(g_hndDLL,"KSND_LoadSongFromMemory")
Global KSND_FreeSong(ksong:Byte Ptr)"Win32" = GetProcAddress(g_hndDLL,"KSND_FreeSong")
Global KSND_GetSongLength:Int(ksong:Byte Ptr)"Win32" = GetProcAddress(g_hndDLL,"KSND_GetSongLength")
Public

Type TKSND
Field player:Byte Ptr ' handle to active player
Field song:Byte Ptr ' handle to currently playing song

Function init:TKSND(samplerate:Int)
Local tmp:TKSND = New TKSND
tmp.player = KSND_CreatePlayer(samplerate)
Return tmp
End Function

' Player methods

Method play(position:Int=0)
KSND_PlaySong(Self.player,Self.song,position)
End Method

Method pause(state:Int=0)
' 1 = pause, 0 = continue
KSND_Pause(Self.player,state)
End Method

Method stop()
KSND_Stop(Self.player)
End Method

Method free()
KSND_FreePlayer(Self.player)
End Method

Method setVolume(volume:Int)
KSND_SetVolume(Self.player,volume)
End Method

Method getPlayPosition:Int()
Return KSND_GetPlayPosition(Self.player)
End Method

' Song methods

Method loadSong(path:String)
' check if a song is already loaded
If Self.song <> Null Then Self.freeSong()
Self.song = KSND_LoadSong(Self.player,path.ToCString())
If Self.song = Null Then
RuntimeError "Unable to load song: "+path
Else
Print "song loaded"
End If
End Method

Method loadSongFromMemory(mem:Byte Ptr,length:Int)
' check if a song is already loaded
If Self.song <> Null Then Self.freeSong()
Self.song = KSND_LoadSongFromMemory(Self.player,mem,length)
If Self.song = Null Then
RuntimeError "Unable to load song!"
Else
Print "song loaded"
End If
End Method

Method freeSong()
KSND_FreeSong(Self.song)
End Method

Method getSongLength:Int()
Return KSND_GetSongLength(Self.song)
End Method
End Type

And here is an example of using the above code:

Code: [Select]
SuperStrict
Incbin "obspatial.kt" ' this is for including the song in the exe

Include "TKSND.BMX"

Graphics 800,600


' prepare a player
Global music:TKSND = TKSND.init(44100)

' use this when loading song from bank
Global bk:TBank = LoadBank("incbin::obspatial.kt") ' this loads the song into a bank
music.loadSongFromMemory(LockBank(bk),BankSize(bk))
bk = Null

' use this when loading song from disc
'music.loadSong("obspatial.kt")

' play the music
music.play()

Global mute:Int = 0

While Not KeyHit(KEY_ESCAPE)
Cls
Local sl:Int = music.getSongLength()
Local pp:Int = music.getPlayPosition()
DrawText("Song Length: "+sl,8,8)
DrawText("Play Position: "+pp,8,24)
If mute = 1 Then DrawText("MUTED",8,48)
' check for pause/continue
If KeyHit(KEY_P) Then music.pause(1)
If KeyHit(KEY_C) Then music.pause(0)
' check for mute/unmute
If KeyHit(KEY_M) Then
mute = 1-mute
If mute = 0 Then
music.setVolume(100)
Else
music.setVolume(0)
End If
End If
Flip
Wend
music.freeSong()
music.free()
End

The known bugs are that the method for getting the length of the song returns a wrong number in release mode, but works correct in debug mode. I am not really sure where the problem lies, but since it is not something that will prevent people from using the klystrack tunes in their productions I figured that I might as well release the code already. I hope someone finds it useful. Remember to copy the ksnd.dll file to your project folder.
Title: Re: klystrack!
Post by: n00bstar on June 01, 2012
!!!!!!!!!!!

You rock sir. Tonight when you come home, your wife will be gold plated and your car will have spoilers on ALL FOUR SIDES. Damn right.

Now I have no choice, I have to switch to BMax! I was kinda of planning on it anyways (seeing as its s'posed to share a lot of syntax with Monkey) and this is a very good reason for it :)

But I'm at work and I only got b3d installed here. This is gonna be a long ass day before I get to play with this!
Title: Re: klystrack!
Post by: zawran on June 01, 2012
No problem, it was fun trying to get it to work.
Title: Re: klystrack!
Post by: Shockwave on June 01, 2012
Cool deed Zawran :) K+
Title: Re: klystrack!
Post by: Rbz on June 02, 2012
Very nice little tracker!

I've made a Freebasic wrapper using klystrack static library, examples included.
Purebasic version can be also easily made ;)

Title: Re: klystrack!
Post by: jace_stknights on June 02, 2012
As fast as the light!  :clap: Rbz :clap:
Title: Re: klystrack!
Post by: zawran on June 02, 2012
Seeing that RBZ has made a wrapper for freebasic using the static library so that you do not have to have the dll file in the folder, I thought that I would give it a go at making the wrapper do the same for Bmax. And after some thinkering I managed to get it to work.

Here is the new type for the wrapper:

Code: [Select]
Private
Extern "Os"
Function KSND_CreatePlayer:Byte Ptr(samplerate:Int)"C"
Function KSND_FreePlayer(kplayer:Byte Ptr)"C"
Function KSND_PlaySong(kplayer:Byte Ptr,ksong:Byte Ptr,position:Int)"C"
Function KSND_Stop(kplayer:Byte Ptr)"C"
Function KSND_Pause(kplayer:Byte Ptr,state:Int)"C"
Function KSND_GetPlayPosition:Int(kplayer:Byte Ptr)"C"
Function KSND_SetVolume(kplayer:Byte Ptr,volume:Int)"C"
' song calls
Function KSND_LoadSong:Byte Ptr(kplayer:Byte Ptr,path:Byte Ptr)"C"
Function KSND_LoadSongFromMemory:Byte Ptr(kplayer:Byte Ptr,mem:Byte Ptr,length:Int)"C"
Function KSND_FreeSong(ksong:Byte Ptr)"C"
Function KSND_GetSongLength:Int(ksong:Byte Ptr)"C"
End Extern
Public

Type TKSND
Field player:Byte Ptr ' handle to active player
Field song:Byte Ptr ' handle to currently playing song

Function init:TKSND(samplerate:Int)
Local tmp:TKSND = New TKSND
tmp.player = KSND_CreatePlayer(samplerate)
Return tmp
End Function

' Player methods

Method play(position:Int=0)
KSND_PlaySong(Self.player,Self.song,position)
End Method

Method pause(state:Int=0)
' 1 = pause, 0 = continue
KSND_Pause(Self.player,state)
End Method

Method stop()
KSND_Stop(Self.player)
End Method

Method free()
KSND_FreePlayer(Self.player)
End Method

Method setVolume(volume:Int)
KSND_SetVolume(Self.player,volume)
End Method

Method getPlayPosition:Int()
Return KSND_GetPlayPosition(Self.player)
End Method

' Song methods

Method loadSong(path:String)
' check if a song is already loaded
If Self.song <> Null Then Self.freeSong()
Self.song = KSND_LoadSong(Self.player,path.ToCString())
If Self.song = Null Then
RuntimeError "Unable to load song: "+path
Else
Print "song loaded"
End If
End Method

Method loadSongFromMemory(mem:Byte Ptr,length:Int)
' check if a song is already loaded
If Self.song <> Null Then Self.freeSong()
Self.song = KSND_LoadSongFromMemory(Self.player,mem,length)
If Self.song = Null Then
RuntimeError "Unable to load song!"
Else
Print "song loaded"
End If
End Method

Method freeSong()
KSND_FreeSong(Self.song)
End Method

Method getSongLength:Int()
Return KSND_GetSongLength(Self.song)
End Method
End Type

And here is a new example to show how it is called:

Code: [Select]
SuperStrict
Import "-lksndstatic"

Incbin "Paranoimia (Suntronic).kt" ' this is for including the song in the exe

Include "TKSNDstatic.BMX"

Graphics 800,600


' prepare a player
Global music:TKSND = TKSND.init(44100)

' use this when loading song from bank
Global bk:TBank = LoadBank("incbin::Paranoimia (Suntronic).kt") ' this loads the song into a bank
music.loadSongFromMemory(LockBank(bk),BankSize(bk))
bk = Null

' use this when loading song from disc
'music.loadSong("obspatial.kt")

' play the music
music.play()

Global mute:Int = 0

While Not KeyHit(KEY_ESCAPE)
Cls
Local sl:Int = music.getSongLength()
Local pp:Int = music.getPlayPosition()
DrawText("Song Length: "+sl,8,8)
DrawText("Play Position: "+pp,8,24)
If mute = 1 Then DrawText("MUTED",8,48)
' check for pause/continue
If KeyHit(KEY_P) Then music.pause(1)
If KeyHit(KEY_C) Then music.pause(0)
' check for mute/unmute
If KeyHit(KEY_M) Then
mute = 1-mute
If mute = 0 Then
music.setVolume(100)
Else
music.setVolume(0)
End If
End If
Flip
Wend
music.freeSong()
music.free()
End

So instead of copying the dll file to your project folder, you copy the following file "libksndstatic.a" to the "lib" folder in your Bmax installation folder.

Using this version will pack the player code into your exe and you no longer need the dll file. Please note that new line <Import "-lksndstatic"> at the top of the example. You will have to have that line in the top of your project code along with what other imports you have. It is the line that loads the c library.
Title: Re: klystrack!
Post by: Pot Noodle on June 02, 2012
Well done guys, I don't think n00bstar will need all that Red Bull now!  :goodpost:
Title: Re: klystrack!
Post by: TinDragon on June 02, 2012
For the Bmax users, if you dont feel like copying the libksndstatic.a into your bmax lib folder and would rather have it in the projects folder (I know some people prefer this) then you can do so, just change the import line from
Code: [Select]
Import "-lksndstatic"to
Code: [Select]
Import "libksndstatic.a"
Nice job on wrapping this player guys, now lets seem some of you creative types make some tunes in it :D
Title: Re: klystrack!
Post by: n00bstar on June 03, 2012
music?

three tracks included, free for all to use in dbf-related prods :)

Title: Re: klystrack!
Post by: padman on June 05, 2012
Quote
Purebasic version can be also easily made ;)

Word. PB wrapper & example attached. ;D

I didn't do too much testing, but the main functions work on my WinXP machine...

Enjoy!


Title: Re: klystrack!
Post by: Shockwave on June 05, 2012
K+
Title: Re: klystrack!
Post by: Kirl on June 05, 2012
:clap: @ all
Title: Re: klystrack!
Post by: n00bstar on June 05, 2012
Very good work people!

Yknow, I think that, with's you's people's permissions'ses of course, we should be contacting klystrack's author and have him host these wrappers alongside the software, it would certainly give a bigger incentive to interested parties who might not have the know how to wrap the lib and can't afford the real estate of downmixing to wav.

Also, I'm a man of my word, I re-extend the offer for one (1) free and personalized klystrack song to anyone who develops something for my favorite little tracker :)
Title: Re: klystrack!
Post by: jace_stknights on June 06, 2012
 :clap: well done Pad!
Title: Re: klystrack!
Post by: padman on June 06, 2012
I have no problems if anyone includes the PB wrapper in their packages. But to be honest I'd rather have people google for it, find this site and then register to download it. We then got a new member, who might help to keep this place alive.  :carrot: Just enter "Klystrack Purebasic" in Google and see how well optimised this forum is regarding search engines.  ;)
Title: Re: klystrack!
Post by: Shockwave on June 06, 2012
I have no problems if anyone includes the PB wrapper in their packages. But to be honest I'd rather have people google for it, find this site and then register to download it. We then got a new member, who might help to keep this place alive.  :carrot: Just enter "Klystrack Purebasic" in Google and see how well optimised this forum is regarding search engines.  ;)

K+

All these altruistic gestures It all help to keep the site alive and well :)

See the attached screen shot for more evidence of our SEO efforts ;)
Title: Re: klystrack!
Post by: n00bstar on June 07, 2012
Well I've emailed the author about it! He obviously finds it very very cool and he'd of course be willing to host the files, or link to this forum depending on preferences. Whatever is the best for the promotion of everybody's work :) There's so much cross-pollination between websites today with all those social thingamajigs spamming The Entire Source Code Of The Universe to every living organism with an email address, news is bound to reach the right places in no time :D
Title: Re: klystrack!
Post by: zawran on June 07, 2012
Consider the blitzmax wrapper code public domain and do with it as you please.
Title: Re: klystrack!
Post by: energy on June 07, 2012
Added Klystrack_Replay as Purebasic USERLIB based on RBRAZ StaticLib and PADMANs Purebasic include.
No linking of any staticlib (include gcc.lib)  needed anymore.
Definitions of ksndstatic.pbi no needed anymore.
Just copy the Purebasic Userlib in "PureBasic\PureLibraries\UserLibraries\"

@n00bstar :  your tracks are bombastic!! Well done, hope yu continue!
 
Title: Re: klystrack!
Post by: Shockwave on June 07, 2012
nOObstar, if you can get them to link to DBF that would be cool, when I finally get around to finishing the front end of the site I'll backlink to him too :)
Title: Re: klystrack!
Post by: benny! on June 07, 2012
Could someone make a small player so that we can listen to those tracks?
Title: Re: klystrack!
Post by: Kirl on June 07, 2012
^ What benny said!

Pretty please? :)
Title: Re: klystrack!
Post by: zawran on June 07, 2012
I have attaced a player. It does not do much else but play the tunes. When run it will show a filerequester where you can pick the tune. To stop it, press the ESC key or click on the close icon. You can pause/unpause using the P key.
Title: Re: klystrack!
Post by: Kirl on June 08, 2012
Awesome, thanks a lot zawran!  :cheers:

And excellent tunes n00bstar, rox!  :updance:
Title: Re: klystrack!
Post by: n00bstar on June 08, 2012
Thanks for the comments  :)

I know I'm repeating myself here.. but these songs are yours guys, do with them as you want! Just drop my name where its appropriate (It's James Clark btw heheh) and I'll be a happy camper :D