Thirdparty Renoise Api

I was thinking about how a thirdparty API for Renoise would be really useful. Every time one of us is doing a thirdparty tool, the methods for accessing instruments, patterns, notes, etc., are likely to have been written from scratch, and might even break if/when a new version of xrns is released!

I think a unified concept for accessing Renoise data, is something everybody could benefit from. And the more languages supported by the API, the better! So, when I discovered this haXe language, it got me thinking.
haXe supports PHP, actionsscript, javascript, and it’s author’s own language, Neko. Even though it still seems to be mostly a flash developer tool to squeeze some extra performance from one’s bytecode, I think it has real potential.

Here’s a list of haXe’s main features:
http://www.haxe.org/doc/features

I’ve started to do a list of all commands available within Renoise, which could act as the fundamental part of an API. Basically, it’s listing every context menu that’s available within the program.

Sounds familiar? (…vaporware)

Had totally forgotten about that, perhaps since I’m neither proficient in Python or C?
My needs are Flash/PHP, but I see other solutions that are javascript-based, so haXe is covering a lot of actual, used platforms.

If haXe could compile to the Java VM as well…that would be killa (jrenoisetools)!!

Edit: No source was contributed to the CVS at all? Just had a look, and found nothing…

too bad the lead developer only posed promises without actually publishing anything. I hate those “in a couple of week” statements… Above all, I hate disappearings…

If I had a voice in the choice of how to make a renoise API accessible to other programming languages I would choose SWIG. It is fairly well known and supports integration of many languages.

Holy crap! Renoise core developers liberate some of the C code and look into this? Please?

http://www.swig.org/tutorial.html

SWIG seems like the choice, when Renoise get a “proper” API.

But until then…

it sure would be sweet,with something like this :dribble:

Swig only solves the problem to “port” the interface to other languages. These ports usually work, but are far from optimal IMHO. Every language has its own “unique” good way to express stuff. Swig can not take care of that. You then end up in wrapping the interface twice to make it pretty which usually makes the original C interface even more ugly.
Also we first need something to port and an environment where this interface can be used. Via MIDI, via OSC, a “terminal” in Renoise, via Advanced Edit scripts , … ?

I have used swig for several years together with python. There was some other soft intended specially for C++ and Python, but I don’t know what happened to it. Atleast when I tried it, I still chose Swig cause it seemed to be more solid.

Nowadays, I use Javascript/ECMAscript much more than I do use Python for desktop apps. It has really eaten it’s way into the desktop domain. It really does have it’s benefits though. It’s not hard to implement in any app either. You just need to make right DOM available.

So, you’re rooting for haXe?

I see a “real” API somewhere on the horizon, but that’s not what I aiming for right now. ECMA/java/actionscript and PHP are pretty much the most documented languages on the internet, and seems like the logical choice if we’re talking about the thirdparty tools done so far. And inspired by the mod-player, I was thinking that a xrns port should be possible :dribble:

Edit: I’ll come up with something based on actionscript…will need some help porting it to haXe though…

OK, I think I’ve settled on haXe, it’s way cool. But there’s still a couple of drawbacks. For example, I was hoping that it had support for E4X (an alternative way of parsing XML). And obviously, some will miss the lack of Java support.

Now, the million $ question is, how to design an external API? What features should be implemented, how should it be structured…Well, I think the obvious starting point is to make a “Song” class, since songs contain Instruments, Samples, Patterns etc. An obvious extension to the Song class could then be an “Editor” class, which could bring extra features that deal with realtime user input (I’m thinking about functional prototypes here). So, if you don’t need realtime interaction, just instantiate a Song class.

We also need to settle on a way to access data. Dom XML is complex, and possibly slow. E4X has obvious benefits, but isn’t supported by haXe. Still, it could be simulated in the API. Imagine working with something like

Song.patterns[10].track[2].column[0].getNote(index)  

I’d prefer that over others method I know of. But someone else might disagree?

I am not sure if this is so bad, but maybe I am missing something. Is there any other
way that does not require one to explicitly write several interfaces, one for each language?

I like the idea of these Advanced Edit scripts. I imagine they could
be something similar to what is done with plugins for the gimp.

One step closer - here’s the xrns data structure, divided into classes. This is a great step towards exposing most song properties to a script, but some of them require an extra bit of functionality. For instance, song comments are actually an array of strings (one for each line). For such a case, I imagine a convenience method, Song.setComment(), that accept a string and automatically creates the required XML.

  
EffectColumn.number:String  
EffectColumn.value:String  
EnumInputMode:Enum("L","R","L-R","L+R")  
EnumLoopMode:Enum("Off","Forward","Backward","PingPong")  
EnumNewNoteAction:Enum("Cut","NoteOff","None")  
EnumParameterChunkType:Enum("Chunk","ParameterBag")  
EnumPluginType:Enum("VST","AU","LADSAP")  
EnumShape:Enum("Linear","Points","Curve")  
EnumState:Enum("Active","Off","Mute")  
EnumVelocityScaling:Enum("Log Fast","Log Slow","Linear","Exp Slow","Exp Fast")  
EnumVisualization:Enum("Dont Show","Device only","Mixer and Device")  
Envelope.DeviceIndex:int(-1)  
Envelope.Envelope.Length:int(1)  
Envelope.Envelope.PlayMode:EnumShape("Linear")  
Envelope.Envelope.Points:Array(String("-1,-1"))  
Envelope.Envelope.ValueQuantum:float(0.0)  
Envelope.ParameterIndex:int(-1)  
Instrument.samples:Array(Sample)  
Instrument.splitMap:Array(int)  
NoteColumn.instrument:String  
NoteColumn.note:String  
NoteColumn.panning:String  
NoteColumn.volume:String  
Pattern.name:string("")  
Pattern.NumberOfLines:int(64)  
Pattern.tracks:Array(PatternTrack)  
PatternMasterTrack extends PatternTrack  
PatternSendTrack extends PatternTrack  
PatternTrack.Automations:Array(envelopes:Array(Envelope))  
PatternTrack.Lines:Array(Line:Array(NoteColumn/EffectColumn))  
Sample.BaseNote:Byte(48)  
Sample.BeatSyncIsActive:Bool(false)  
Sample.BeatSyncLines:Short(16)  
Sample.FileModificationDate:Date  
Sample.FileModificationDayTime:Time  
Sample.FileName:String  
Sample.Finetune:Byte(0)  
Sample.InterpolationMode:EnumInterpolationMode("Cubic")  
Sample.LoopEnd:uInt(0)  
Sample.LoopMode:EnumLoopMode("Off")  
Sample.LoopStart:uInt(0)  
Sample.Name:String  
Sample.NewNoteAction:EnumNewNoteAction("Cut")  
Sample.Panning:Float(0.5)  
Sample.Volume:Float(1.0)  
SequencerMasterTrack extends SequencerTrack  
SequencerMasterTrack.name:String("Mst")  
SequencerMasterTrack.numberOfVisibleNoteColumns:int(0)  
SequencerMasterTrack.volumeColumnIsVisible:Bool(false)  
SequencerSendTrack extends SequencerTrack  
SequencerSendTrack.name:String("Sxx") **  
SequencerSendTrack.numberOfVisibleNoteColumns:int(0)  
SequencerSendTrack.volumeColumnIsVisible:Bool(false)  
SequencerTrack.filterDevices:Array()  
SequencerTrack.name:String("Track xx") **  
SequencerTrack.noteColumnStates:EnumState("Active")  
SequencerTrack.numberOfVisibleEffectColumns:int(1)  
SequencerTrack.numberOfVisibleNoteColumns:int(1)  
SequencerTrack.panningColumnIsVisible:Bool(false)  
SequencerTrack.state:EnumState("Active")  
SequencerTrack.trackRouting:int(0)  
SequencerTrack.volumeColumnIsVisible:Bool(true)  
Song.GlobalSongData.adjustVstTempoWithTPL:Bool(true)  
Song.GlobalSongData.artist:String("By Somebody")  
Song.GlobalSongData.beatsPerMin:int(135)  
Song.GlobalSongData.correctSamplePitch:Bool(true)  
Song.GlobalSongData.editStep(1)  
Song.GlobalSongData.loopCoeff:int(4)  
Song.GlobalSongData.loopPlay:Bool(false)  
Song.GlobalSongData.loopStart:int(0)  
Song.GlobalSongData.octave(4)  
Song.GlobalSongData.pitchEffectsCompatibilityMode:Bool(false)  
Song.GlobalSongData.sampleOffsetCompatibilityMode:Bool(false)  
Song.GlobalSongData.showSongCommentsAfterLoading:Bool(false)  
Song.GlobalSongData.shuffleAmounts:Array(int)  
Song.GlobalSongData.shuffleIsActive:Bool(false)  
Song.GlobalSongData.songComments:Array(String)  
Song.GlobalSongData.songName:String("untitled")  
Song.GlobalSongData.ticksPerLine:int(6)  
Song.instruments:Array(Instrument)  
Song.PatternPool.defaultPatternLength:int(64)  
Song.PatternPool.highliteStep:int(4)  
Song.PatternPool.patterns:Array(Pattern)  
Song.PatternSequence.currentPosition:int(0)  
Song.PatternSequence.highliteOffset:int(0)  
Song.PatternSequence.highliteStep:int(0)  
Song.PatternSequence.loopSelection:PatternSequenceSelection  
Song.PatternSequence.patternNameWidth:int(0)  
Song.PatternSequence.patternSequence:Array(int)  
Song.PatternSequence.sequenceSelection:PatternSequenceSelection  
Song.PatternSequenceSelection.cursorPos:int(-1)  
Song.PatternSequenceSelection.rangePos:int(-1)  
Song.RecordManager.linkedTrackIndex:int(-1)  
Song.selectedInstrumentIndex:int(0)  
Song.selectedSampleIndex:int(0)  
Song.selectedTrackIndex:int(0)  
Song.tracks:Array(SequencerTrack)  
  

By simply choosing one “major/common” language like Python which is perfectly suited for this task…
Everyone who knows any scripting language can easily adopt to for example Python. Its very well documented, so why bother with 100 languages which no one uses?

Yes, that would at least be a start!

I disagree, In fact I find that this statement is preposterous.

Languages used to write programs that take advantage of Renoise, so far:

  • C
  • PHP
  • Java
  • JavaScript
  • ActionScript
  • AutoHotKey
  • Perl

Publicly available scripts written in Python for Renoise, so far:

  • Zero

Support for Python and nothing else is cruel and unusual at this stage of the game. I know it’s every “real” programmer’s favorite choice, but Renoise scripting isn’t academia. It’s near anarchy at this point. To come in with the clue stick at this stage will certainly discourage me from writing anything else.

If an official API should be released, would it not be trivial to write an interface to other languages?

More thoughts:

I’m not saying PHP is the best choice, I’m more than willing to accept that it’s the worst, but if I am to put time into something new it will be OBJ-C and VST/AU programming.

The reasons I chose PHP is because it takes me minutes to write stuff. I’m not interested in learning another language to do stuff that won’t give me transferable skills into my own life. When I write PHP for Renoise, i learn stuff applicable to my real life. Python? Won’t be using it, ever. Regardless of it’s “superiority.”

I would imagine it’s the same for ActionScript. Why write Python when your job is Flash?

AutoHotKey, I never heard of it until RPG. Does that make AutoHotKey unworthy of support? No. RPG is one of the better applications for Renoise right now.

I strongly feel that this is one of those things that has to evolve on it’s own and be extremely simple, flexible, opensource, and dirty. I feel any time put into a closed source tightly integrated unilingual API would be time better spent doing something else.

The user’s are certainly not asking for this feature.

I think the whole point he wanted to make is we have to settle on some standard. So far we had all our own approach. I wouldn’t have any problem to settle on one project which wouild grow over time. Also a thing to consider would be it should be a language with an own well established standard library supporting most things out of the box.

Renoise is XML data and choosing one language to read and write to it very, very odd.

The whole point of XML is any language can read/write it.

If by standards we are talking about naming conventions and pseudocode for methods/functions that manipulate Renoise data, then i’d be willing to write something in PHP that clones someone else’s API, so long as it’s opensource.

That way, when we discuss stuff we can do it our own way, but we talk using very similar terms when posting about it.

I guess that is what Danoise is trying to do, and I support that.