Jump to content


Photo
- - - - -

Orgs in Java


Old topic!
Guest, the last post in this thread is over 60 days old. Posting in this thread will be considered a bump, so please make an attempt to be courteous if you go ahead with it.

If the last post is over 6 months old, it may instead be a better idea to start a new topic. If you aren't sure about what to do, feel free to ask a staff member for help, or try to locate a 'general questions'-type thread if it exists in this (sub-)forum.


  • Please log in to reply
37 replies to this topic

#1 13 October 2010 - 10:54 PM

If you snoose, you loose
"Heavy swords for sale. Suitable for most RPG Protagonists. Apply now!"
Join Date: 02 Jul 2008
Location: Locationtrapped in mspaint
Posts: 1,884
Age: 22
 

So I made a thingy in case there are any Java programmers out there interested in giving their Java programs the ability to play *.org files.

Java organya player
Source code

This version is hopefully final.

Also, I figure I might as well post this here for convenience:
Notes on Organya playback details by Bavi_H



The format of the "orgsamp.dat" file:

All integer values are unsigned big-endian,
except sample frames, which are signed (2s complement).

1 byte: number of melody samples (100)
3 bytes: number of sample frames per melody sample (256)
for each melody sample:
   for each sample frame:
      1 byte: sample frame
1 byte: number of drum samples (28)
2 bytes: sampling rate of drum samples in Hertz at lowest non-zero frequency (2205)
for each drum sample:
   3 bytes: number of sample frames
   for each sample frame:
      1 byte: sample frame



The *.org format specs:

All integer values are unsigned little-endian.
A "click" is the smallest unit of time in an org file.

6 bytes: ascii string "Org-02" (or "Org-03" if the file uses percussion instruments only available in orgmaker 2.05)
2 bytes: "wait" value (the length of a click in milliseconds)
1 byte: beats per measure
1 byte: clicks per beat
4 bytes: position of the loop start, in clicks (the first click being position 0)
4 bytes: position of the loop end, in clicks
for each track:
   2 bytes: "freq" value*
   1 byte: instrument
   1 byte: 1 if "pi" checkbox is checked, 0 otherwise*
   2 bytes: number of resources
for each track:
   for each resource:
      4 bytes: position of the resource, in clicks
   for each resource:
      1 byte: note (0=lowest note, 45=A440, 95=highest note, 255=no change)
   for each resource:
      1 byte: duration (in clicks, I believe this is ignored if note value is "no change")
   for each resource:
      1 byte: volume (0=silent, 200=default, 254=max, 255=no change)
   for each resource:
      1 byte: pan (0=full left, 6=center, 12=full right, 255=no change)

*Even though orgmaker only allows you to edit these for melody tracks, percussion tracks also have this data, 
with the default values of freq=1000, pi=0.
I haven't tested to see if modifying these has any effect on playback.

Posted Image

#2 13 October 2010 - 11:17 PM

Carrotlord Offline
Not anymore
"Run, rabbit run. Dig that hole, forget the sun."
Join Date: 28 Jan 2010
Location: LocationInternet
Posts: 1,367
Age: 24
 

Some cool stuff here.

It's nice that Pixel's music formats are more available in other mediums.

#3 13 November 2010 - 08:25 PM

CapFuture Offline
Novice Member
"Fresh from the Bakery"
Join Date: 13 Nov 2010
Location:
Posts: 4
 

First of all thanks for the Java version :D

Unfortunately there is some kind of bug when loading Wanpak2.org aka Scorching Back: An ArrayIndexOutOfBoundsException happens in the constructor of Organya...

Spoiler


time can be >= than this.data[i].length, why so ever...

Unfortunately I don't know a lot about the org format and neither hacking the org file to set the "correct" song length nor only allowing times which are smaller than this.data[i].length solved the problem...

Any hint where the problem lies?

#4 13 November 2010 - 10:21 PM

If you snoose, you loose
"Heavy swords for sale. Suitable for most RPG Protagonists. Apply now!"
Join Date: 02 Jul 2008
Location: Locationtrapped in mspaint
Posts: 1,884
Age: 22
 

Ah, good catch there.

replace this:
data[i][unsign(stuff[0])+256*stuff[1]]=1;

with this:
int time=unsign(stuff[0])+256*stuff[1];
if(time<songLen) data[i][time]=1;

and it will work.


Notice that, in Scorching Back, the percussion tracks keep going even after the end of the song, so there are notes that never actually get played, but are just superfluous. That extra if statement will make it automatically ignore such notes.


Also, I may make an update eventually which will allow the use of other percussion instruments (including 2.05 ones) and support the "freq" and "pi" track settings, and of course this new bug fix. If anyone could hook me up with the samples used in the non-cavestory percussion instruments, that would be great (If not, I could probably just use Audacity).
Posted Image

#5 14 November 2010 - 12:04 AM

CapFuture Offline
Novice Member
"Fresh from the Bakery"
Join Date: 13 Nov 2010
Location:
Posts: 4
 

Ok, that's the same fix that I've applied ^^

But it causes another bug in getSample():
Just as the bug before the samp2 might try to access the melody array where it's not defined... I fixed it with another check which solved the problem.

Here's the code:
Spoiler


Finally the Scorching Back playback works like a charm :)

#6 14 November 2010 - 01:52 AM

If you snoose, you loose
"Heavy swords for sale. Suitable for most RPG Protagonists. Apply now!"
Join Date: 02 Jul 2008
Location: Locationtrapped in mspaint
Posts: 1,884
Age: 22
 

Actually, looking back at that code, it looks like I messed up the parenthesis in that line, and the line after that (which does interpolation) was wrong too. I fail at life apparently...

double samp2=j<8? melody[256*instruments[j]+((int)(256*tpos[j])+1)%256]:tpos[j]+1<drums[j-8].length?(unsign(drums[j-8][(int)tpos[j]+1])-128):0.0;
double samp=samp1+(samp2-samp1)*(tpos[j]*256-(int)(tpos[j]*256));

^ that's what it should be, and it fixes the error.

Incidentally, after experimenting, I find it actually sounds closer to the original if you remove the interpolation entirely (which amounts to changing the second line to "double samp=samp1;" and makes the first line useless, since the variable samp2 is never used).
Posted Image

#7 14 November 2010 - 12:59 PM

CapFuture Offline
Novice Member
"Fresh from the Bakery"
Join Date: 13 Nov 2010
Location:
Posts: 4
 

Ahh... ok

But I also think that it sounds better without the interpolation than with it :p

When I find some time I'll programm a little gui for a more convenient player ^^

Thanks alot for your quick fixes. :)
After the java xm player went offline I had no org player which runs natively under OSX. But this is even better *likes source code*

#8 18 November 2010 - 12:15 AM

CapFuture Offline
Novice Member
"Fresh from the Bakery"
Join Date: 13 Nov 2010
Location:
Posts: 4
 

Hi again

I created a little gui using Wedge's playback-engine.
If the tune list is empty just press play and you can select any number of tracks from a single directory to the list. To empty the list later on press eject. Everything else is self-explanatory.

Currently you cannot remove single tunes or mix them from different directories or save playlists, etc...

http://www.mediafire...779x6o6wx2x7l1x

The zip file contains a runnable jar as well as the "wave100" file which contains the samples for the melody and drum instruments (see first post). Both have to be in the same directory or otherwise you won't here anything.

The app ist Java 1.5 complient and don't expect miracles from the app ^^

#9 18 November 2010 - 01:55 AM

If you snoose, you loose
"Heavy swords for sale. Suitable for most RPG Protagonists. Apply now!"
Join Date: 02 Jul 2008
Location: Locationtrapped in mspaint
Posts: 1,884
Age: 22
 

Ah I think I figured out the best way to handle the interpolation. Use it for drum tracks, but not for melody tracks. So say like double samp=samp1; if(j>=8) samp+=all that other interpolation stuff; If you play a song that has low percussion, it sounds really bad without interpolation.
Posted Image

#10 18 November 2010 - 01:58 AM

Lace Offline
Lesbian Seagull
"Life begins and ends with Nu."
Join Date: 04 Jan 2008
Location: LocationHunky Dory
Posts: 3,049
 

This is sorta random, but could you port this to the far lesser language of C?
Or make a dll?


Haven't looked at the code yet, but I'm sure it'll be interesting.
Good work bud.
Posted Image



Old topic!
Guest, the last post in this thread is over 60 days old. Posting in this thread will be considered a bump, so please make an attempt to be courteous if you go ahead with it.

If the last post is over 6 months old, it may instead be a better idea to start a new topic. If you aren't sure about what to do, feel free to ask a staff member for help, or try to locate a 'general questions'-type thread if it exists in this (sub-)forum.



0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users