Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - firiban

Pages: [1]
1
Guides and Tutorials / How to use an external music editor
« on: December 26, 2011, 01:20:24 pm »
Hi there!

Since the ingame notation editor is somewhat painful to use, i wrote a script which converts standard MusicXML to a PlaneShift compatible format (PS uses a subset of MusicXML). I'm not claiming this will work for everyone with every MusicXML file, but it works for me and i thought i'd share it.

-- Edit: There's now an easier method that does not require node.js, see below --

1) Software needed
First, you need a notation editor which can write MusicXML files. Personally, i use MuseScore. Then, you'll need node.js and the jsdom library. On Linux, you can install jsdom with
Code: [Select]
npm install jsdomafter installing node.js. Node's npm package manager is kind of weird and i haven't completely figured out when node considers something to be installed and when not :|

2) The script
Copy the following into a file called converter.js in your musicalsheets directory (on Linux it's ~/.PlaneShift/musicalsheets/)
Code: [Select]
#!/usr/bin/env node

var jsdom = require("jsdom");
var fs = require('fs');


console.log("MusicXML to PlaneShift converter by Firiban - version 0.2");
console.log("parsing file "+process.argv[2]+"...");
// read file, parse it, create outfile with header
var infile = jsdom.jsdom(fs.readFileSync(process.argv[2], "utf8"));
var outfile = '<score-partwise version="2.0"><part-list><score-part id="P1"><part-name>'+process.argv[2].substr(0,process.argv[2].length-4)+'</part-name></score-part></part-list><part id="P1">';
var measures = infile.getElementsByTagName("measure");
console.log("Sorting the stuff...");

// This loop does the work: Iterates through the measures and copies the important stuff (read: "PlaneShift compatible tags") to outfile
var i=1;
var j=0;
var k=0;
var l=0;
var alter=0;
var duration=1;
var multiplier=1;
for (var i=0;i<measures.length;i++) {
outfile += '<measure number="'+(i+1)+'">';
if (i==0) {
multiplier = (4 / infile.getElementsByTagName("divisions")[0].childNodes[0].__nodeValue);
outfile += '<attributes><divisions>4</divisions><key><fifths>'+((infile.getElementsByTagName("fifths").length>0)?infile.getElementsByTagName("fifths")[0].childNodes[0].__nodeValue:"0")+'</fifths></key><time><beats>'+infile.getElementsByTagName("beats")[0].childNodes[0].__nodeValue+'</beats><beat-type>'+infile.getElementsByTagName("beat-type")[0].childNodes[0].__nodeValue+'</beat-type></time></attributes><direction>';
if (infile.getElementsByTagName("sound").length>0) {
outfile += '<sound tempo="'+infile.getElementsByTagName("sound")[0].attributes[0].value+'"/>';
} else {
outfile += '<sound tempo="90"/>';
}
outfile += "</direction>";
}
//console.log(measures[i]);
for (j=0;j<measures[i].children.length;j++) {
// we only need the notes, no stupid <print> stuff or text nodes (whitespaces/tabs/newlines etc.)
if (measures[i].children[j].tagName=="NOTE") {
outfile +="<note>";
duration=1;
// iterate through note's parameters and copy the neccessary ones (sort out <stem> etc., since they are not used by PS)
for (k=0;k<measures[i].children[j].children.length;k++) {
if (measures[i].children[j].children[k].tagName=="REST") {
outfile += "<rest/>";
} else if (measures[i].children[j].children[k].tagName=="CHORD") {
outfile += "<chord/>";
} else if (measures[i].children[j].children[k].tagName=="DURATION") {
duration = measures[i].children[j].children[k].textContent;
} else if (measures[i].children[j].children[k].tagName=="PITCH") {
outfile += "<pitch>";
alter = 0;
for (l=0;l<measures[i].children[j].children[k].children.length;l++) {
if ((measures[i].children[j].children[k].children[l].tagName=='STEP') || (measures[i].children[j].children[k].children[l].tagName=='OCTAVE')) {
outfile += "<"+measures[i].children[j].children[k].children[l].tagName.toLowerCase()+">"+measures[i].children[j].children[k].children[l].textContent+"</"+measures[i].children[j].children[k].children[l].tagName.toLowerCase()+">";
} else if (measures[i].children[j].children[k].children[l].tagName=='ALTER') {
alter = measures[i].children[j].children[k].children[l].textContent;
}
}
outfile += "<alter>"+alter+"</alter></pitch>";
}
}
outfile += "<duration>"+duration*multiplier+"</duration>";
outfile +="</note>";
}
}
outfile += '</measure>';
}

// close outfile and write it
outfile += '</part></score-partwise>';
fs.writeFileSync("PS-"+process.argv[2],outfile);
console.log("Done. Your PlaneShift-compatible music is now in PS-"+process.argv[2]+" . Enjoy! :)");
Save the file and make it executable. (chmod +x ./converter.js in a terminal)

3) Write some music
Well, open MuseScore and create a new sheet with one voice. Use flute or guitar or some other non-transposing one-staff instrument. There are some things which are not supported by PlaneShift, so you shouldn't use them in your composition:
  • Polyrhythm (e.g. whole note chord with quarter note melody above it)
  • I haven't tested key signatures different from C major/A minor (but single #s and bs should work)
  • tied notes
Be sure there's a time signature at the beginning of your piece, otherwise the script will fail.
You may add a tempo definition, otherwise, it will use 90BPM.

4) Make your song PlaneShift compatible
Save your composition as MusicXML (not compressed MusicXML) in your musicalsheets directory. Then let the script convert it. On Linux, open in a terminal and do
Code: [Select]
./converter.js yoursong.xml(converter.js and yoursong.xml should both be in musicalsheets, and yoursong.xml should be the filename you used for your song :P)
You'll now get a file called PS-song.xml which you can put in your musicalsheets directory and open with the ingame editor. Have fun! :)


Known Bugs: In the ingame editor, only the first measure of the converted piece is shown, but everything is played. If anyone can tell me how to fix this, please do so.


If you have any questions, please post them here (though i might not be able to help you, depending on your problem :P).

Happy composing :)
Firiban


Easier method

1) Create a file called converter.html with the following content
Code: [Select]
<html>
<head>
</head>
<body>
<h1>MusicXML to PlaneShift converter by Firiban - version 0.2</h1>
<form name="convert" action="#" method="get">
<textarea name="code" cols="100" rows="30"></textarea>
<br />
<input type="button" value="Convert!" name="startme" />
</form>
<script type="application/x-javascript">
// NOTE: This is just the web browser compatible port of the original converter.js
document.forms.convert.startme.onclick = function () {
console.log("MusicXML to PlaneShift converter by Firiban - version 0.2");
console.log("parsing file input...");
// read file, parse it, create outfile with header
if (window.DOMParser) {
var infile = (new DOMParser()).parseFromString(document.forms.convert.code.value,"text/xml");
}
else {
alert ("Incompatible Browser. Try Firefox.");

var outfile = '<score-partwise version="2.0"><part-list><score-part id="P1"><part-name>converted stuff</part-name></score-part></part-list><part id="P1">';
var measures = infile.getElementsByTagName("measure");
console.log("Sorting the stuff...");

// This loop does the work: Iterates through the measures and copies the important stuff (read: "PlaneShift compatible tags") to outfile
var i=1;
var j=0;
var k=0;
var l=0;
var alter=0;
var duration=1;
var multiplier=1;
for (var i=0;i<measures.length;i++) {
outfile += '<measure number="'+(i+1)+'">';
if (i==0) {
multiplier = (4 / infile.getElementsByTagName("divisions")[0].childNodes[0].textContent);
outfile += '<attributes><divisions>4</divisions><key><fifths>'+((infile.getElementsByTagName("fifths").length>0)?infile.getElementsByTagName("fifths")[0].childNodes[0].__nodeValue:"0")+'</fifths></key><time><beats>'+infile.getElementsByTagName("beats")[0].childNodes[0].__nodeValue+'</beats><beat-type>'+infile.getElementsByTagName("beat-type")[0].childNodes[0].__nodeValue+'</beat-type></time></attributes><direction>';
if (infile.getElementsByTagName("sound").length>0) {
outfile += '<sound tempo="'+infile.getElementsByTagName("sound")[0].attributes[0].value+'"/>';
} else {
outfile += '<sound tempo="90"/>';
}
outfile += "</direction>";
}
//console.log(measures[i]);
for (j=0;j<measures[i].children.length;j++) {
// we only need the notes, no stupid <print> stuff or text nodes (whitespaces/tabs/newlines etc.)
if (measures[i].children[j].tagName=="note") {
outfile +="<note>";
duration=1;
// iterate through note's parameters and copy the neccessary ones (sort out <stem> etc., since they are not used by PS)
for (k=0;k<measures[i].children[j].children.length;k++) {
if (measures[i].children[j].children[k].tagName=="rest") {
outfile += "<rest/>";
} else if (measures[i].children[j].children[k].tagName=="chord") {
outfile += "<chord/>";
} else if (measures[i].children[j].children[k].tagName=="duration") {
duration = measures[i].children[j].children[k].textContent;
} else if (measures[i].children[j].children[k].tagName=="pitch") {
outfile += "<pitch>";
alter = 0;
for (l=0;l<measures[i].children[j].children[k].children.length;l++) {
if ((measures[i].children[j].children[k].children[l].tagName=='step') || (measures[i].children[j].children[k].children[l].tagName=='octave')) {
outfile += "<"+measures[i].children[j].children[k].children[l].tagName+">"+measures[i].children[j].children[k].children[l].textContent+"</"+measures[i].children[j].children[k].children[l].tagName+">";
} else if (measures[i].children[j].children[k].children[l].tagName=='alter') {
alter = measures[i].children[j].children[k].children[l].textContent;
}
}
outfile += "<alter>"+alter+"</alter></pitch>";
}
}
outfile += "<duration>"+duration*multiplier+"</duration>";
outfile +="</note>";
}
}
outfile += '</measure>';
}

// close outfile and write it
outfile += '</part></score-partwise>';
document.forms.convert.code.value = outfile;
console.log("Done. Enjoy! :)");
}
</script>
</body>
</html>

2) open that file with your web browser. paste the content of your musicxml file there, click convert.

3) save the resulting code to an xml file in your musicalsheets folder and load it with planeshift.


Edit #1: added html method
Edit #2: Fixed bug with accidentals
Edit #3: Added support for adding missing <fifths> tag; now supports Rosegarden

2
Fan Art / More music!
« on: June 27, 2009, 12:59:24 pm »
Hi,
as there was a litte party at the Explorers' camp today and we lacked some music, i felt like making some - here it is  :) .
There's no MIDI, except for the drum part. The rest was recorded and mixed using Audacity. I tried to have it fit into the medieval setting.

Download
--->http://filebin.ca/wobzb/Firiban-Under_the_Cliffs.zip
Password is: ojagughydlaa
Sorry for the filebin, it will soon be avalible on the psde.de mirror.

The archive includes three songs.
Released under
cc-by-nc-nd

Firiban - Under the Cliffs
Welcoming Warmup1:10
Ambigous Aim2:44
Silent Samba6:39


Have fun listening and please comment :)
Firiban

3
Linux Specific Issues / Avoid the Crashes using WINE
« on: December 22, 2008, 04:15:24 pm »
Scroll down to the post starting with "Update!" please!



Hi,
as i had a lot of these random client crashes since 0.4.03, i tried to run the windows version of planeshift using wine on top of linux. and it worked! Here are the step by step instructions on how to install it:

If you already have wine installed, you can skip the steps 1-3.

1. Install the latest stable version of WINE using your distro's package manager
2. Install the package cabextract
3. Run WINE's configuration utility 'winecfg', it will create the directory ~/.wine/
4. Go into this directory and execute 'wget http://www.kegel.com/wine/winetricks'
5. Run the command 'sh winetricks vcrun6 vcrun2005 corefonts'. I'm not sure if you need a license of Windows to do this legally! I'm neither sure what exactly the winetricks script does; i didn't write it :P
6. Download and install the Windows version of PlaneShift into wine. To run the installer type 'wine name_of_the_installer.exe' in the directory where you downloaded it.
7. Run your new PlaneShift client: Go to '~./wine/drive_c/Programs/PlaneShift' (or however these directories are called on your PC) and execute 'wine psclient.exe'

You can even symlink your ~/.PlaneShift directory to the Windows version's PlaneShift directory to use the same settings and logs with both clients.

The WINE client runs stable for me, Thob from my guild uses it too. However, we both have a completely transparent GUI under wine. That means, you can't see any window backgrounds and buttons without text. But it doesn't crash ;)

I don't know if that works for everyone, try it ON YOUR OWN RISK!



Firiban

4
Linux Specific Issues / Invisible map Parts
« on: September 20, 2008, 12:14:49 pm »
Hi,
i currently have some really annoying graphics bugs.
When entering a new map, i first see everything correctly, but after a less than a second, everything (houses, trees, statues, players, npcs, my char) begins to vanish. ~2 secs after entering the map i can see the ground and a few houses. i can still walk around and i can see my char’s shadow on the floor. I can also see chars and npcs which are directly in front of my camera. when looking out of the map into the next map, i can only see gfx-corruption coloured like the edge of the map i’m walking on. after relogging everything is ok again. but in the winch area and the death realm even that doesnt work and i have to navigate without seeing my environment.

I experience the bug on linux with ps version 0.4.02 (all updates from the updater) ati-fglrx 8.08.

A similar problem is described in this post:
[[http://www.happypenguin.org/show?PlaneShift&showall=1#44641|External Link]]

The bugs appear with VBO set to off on or default, 15, 16 or 32 bit color depth.

am i doing anything wrong? is there a workaround? i already posted it on the bugtracker, but the task was closed as caarrie said it isn't a bug.

thanks in advance
firiban

Pages: [1]