An here it is... a first release of my Retronitus Music Composer.
The main window allows to edit music by entering the notes and instruments in a spreadsheet-like table, with column groups representing the available channels. If you have a Propeller chip connected to a serial port with the player (included) loaded you can preview the music and sound effects using the play button on the main window and the keyboard on the instruments editor.
You can use different instruments on the same channel, the editor should take care of generating the appropriate patterns. It doesn't have many optimizations and the resulting music data may not be compact like one written by hand and you can't repeat the same pattern or play a song in a loop (these things will be added in the future).
I have included as examples some musics from the Frogger arcade game and a sound effect from the Lode Runner game. Speaking of which, if you want to see a practical application for Retronitus, I have recently ported Lode Runner using it as the sound engine to my P8X Game System. It uses only the sound effects, no music.
Remember that this is a preview release, it should be usable enough to experiment but there aren't many safety checks and it may crash at any time.
I have found a couple of bugs in the latest version of Retronitus that I will resolve. Music looping for instance will cause some channels to get out of sync in some situations.
@macca cool! If I could get the emulator to work, it would go along perfectly with this!
Edit: Oh, and BTW:
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: java.lang.UnsatisfiedLinkError: Cannot load 32-bit SWT libraries on 64-bit JVM
at org.eclipse.swt.internal.Library.loadLibrary(Library.java:259)
at org.eclipse.swt.internal.Library.loadLibrary(Library.java:236)
at org.eclipse.swt.internal.C.<clinit>(C.java:16)
at org.eclipse.swt.widgets.Display.<clinit>(Display.java:138)
at com.maccasoft.composer.Main.main(Main.java:541)
... 5 more
@macca cool! If I could get the emulator to work, it would go along perfectly with this!
Yes, that would be perfect. I see you wrote a Propeller emulator in Java, I tried to port the Gear emulator to Java once but ended up being too slow for any practical application, hope you can optimize it. I also tried to port Gear to C, still too slow, it helped me to better understand how Retronitus works but still too far from realtime. Honestly I haven't put much efforts on optimizing it.
Edit: Oh, and BTW:
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: java.lang.UnsatisfiedLinkError: Cannot load 32-bit SWT libraries on 64-bit JVM
at org.eclipse.swt.internal.Library.loadLibrary(Library.java:259)
at org.eclipse.swt.internal.Library.loadLibrary(Library.java:236)
at org.eclipse.swt.internal.C.<clinit>(C.java:16)
at org.eclipse.swt.widgets.Display.<clinit>(Display.java:138)
at com.maccasoft.composer.Main.main(Main.java:541)
... 5 more
Are you using a 64 bit JVM on Windows ? The current windows release is 32-bit, can you install the 32-bit version of the JVM ?
No problem, IIRC you actually have to put in effort to get a 64 bit JRE, they always give you 32-bit (again, IIRC).
But you DO get the choice upfront when downloading a JDK. And I usually set my JDK as my default JVM for some reason.
EDIT: Checked, they give you the 64/32 bit build depending on your browser. Even tough java in browser is dead because...
, for one, Oracle or whoever believes people are stupid enough to lower the security level(in the contol panel!) THEN run a malicious java applet AFTER confirming to run it(!!), so they now only offer high and very high as options. Also someone at Google decided to throw out the perfectly good java support in Chrome! RIP Java 1995-201X.
No problem, IIRC you actually have to put in effort to get a 64 bit JRE, they always give you 32-bit (again, IIRC).
But you DO get the choice upfront when downloading a JDK. And I usually set my JDK as my default JVM for some reason.
The next release will have a 64 bit Windows build. I'm not sure to understand what you mean with the browser choice, this isn't meant to be run in a browser, it is a standalone application, if it runs in a browser is just luck.
Good. I still think something is wrong with my audio out code, still. for exmample, when i add
//convert to signed samples
l -= Integer.MIN_VALUE;
r -= Integer.MIN_VALUE;
and change the audio output to signed, it's very quiet?!?!
I don't know if it is your case (haven't looked much at your code) but in my early attempt to port Gear to Java and now with the retronitus build code, I had to use long instead of int because in Java all numbers are signed and if you use int with a variable/register meant to roll over at 32-bit you end with the wrong results. With longs you have to just mask the lower 32-bits when needed, it may be slower but the results are more accurate. Also beware that when you assign a variable the sign is expanded, so if the int variable is negative also the long will be negative, you have to mask the lower 32-bits to get the correct value.
@macca I meant to say: They give you a 64-bit JRE by default when you use a 64-bit browser to download the JRE.
Also, don't int's roll over as usual, e.g. from Integer.MAX_Value to Integer.MIN_VALUE? I use bytes as if they were unsigned in another project of mine and hadn't had any problems (except when using them as array indexes...). For the record: I do use longs in some Instructions, in particular the ones where you get a carry or whatever.
But i might look into it...
EDIT: And BTW, i now at least get a sequence of tones, i think im getting there!
Ok, I messed around some more and came to the conclusion that unsigned 16-bit audio is broken in some kind of driver, because unsigned 8-bit is sortof quiet too. Still sounds like ... junk. Mr
@Ahle2
What range of values is usually written to FRQA/FRQB?
@Heater
Good stuff! Pity they scrapped the computer tho..
Now, somewhat back on-topic: Could someone please look at my code and tell me that im not going insane? I have no idea where the problem could be! All instructions i'm not 100% sure on aren't used in both Retronitus and the Spin interpreter! It's somewhere in https://github.com/Wuerfel21/EmuRetronitus ... I feel like i'm almost hijacking the thread at this point, might make a separate one if the topic of Retronitus emulation isn't solved soon.
Some general fixes (including the out of range note delta), implemented a simple error checking and polished the user interface a bit.
The build system was updated to include native launchers (executable for Windows and script for Linux), it isn't packaged as a single jar anymore. To start the program unpack the downloaded package and run composer from the retronitus-composer folder.
This release has a Windows64 download, I don't have a 64-bit windows right now so it isn't tested, hope it works.
Some general fixes (including the out of range note delta), implemented a simple error checking and polished the user interface a bit.
The build system was updated to include native launchers (executable for Windows and script for Linux), it isn't packaged as a single jar anymore. To start the program unpack the downloaded package and run composer from the retronitus-composer folder.
This release has a Windows64 download, I don't have a 64-bit windows right now so it isn't tested, hope it works.
Tried it on Windows64, but I had an exception.
I will see if I can install said development kit later today.
I will see if I can install said development kit later today.
The windows64 version requires a 64-bit java runtime, the windows version requires a 32-bit java runtime (it is a bit complicated but I haven't yet found a way to include both in a single package, seems that launch4j doesn't allow a classpath dependendent on the runtime architecture).
This assuming you don't have an older runtime (older than 1.7.0), if so you better update as soon as possible.
It should work well with the latest 1.8.0 release, I have lowered the minimum version to 1.7.0 because I'm not using any special construct that requires a later release.
Also, i encountered the looping bug Ahle mentioned at some point. I'm betting imaginary money on it being caused by the fact that c*_stepWait are initialized to 1, but are not reset by reStart. Thus, the channels get desynced. Now to test my hypothesis...
Well, that was easy. Fixed with 4 extra instructions. However, I found some odd behavior: If i turned c1_stepWait into a res (uninitialized variable), everything breaks for some reason. However, no problems when initializing it to value other than 1 (i tried 0,-1 and 555). So I just left that one initialized and changed the other 7. Seems to work fine now.
Wait, no, they all need to be initialized! I don't understand why. They are all written by the reStart routine now and really, the value they are initialized to doesn't seem to matter...
EDIT: Scratch that, i found it! The offsets between some of the variables were hardcoded. And tempoAccumulator needs to be zero, for some reason.
EDIT 2: The attached file should now actually be the correct one!
Yes, the octaves goes backwards.... The reason is because note frequency precision is highest in the highest octave and the octave parameter just divides the frequency table by two (right shift) for each octave.
I will eventually fix all issues with Retronitus. Thanks for showing interested in my work.
Comments
The main window allows to edit music by entering the notes and instruments in a spreadsheet-like table, with column groups representing the available channels. If you have a Propeller chip connected to a serial port with the player (included) loaded you can preview the music and sound effects using the play button on the main window and the keyboard on the instruments editor.
You can use different instruments on the same channel, the editor should take care of generating the appropriate patterns. It doesn't have many optimizations and the resulting music data may not be compact like one written by hand and you can't repeat the same pattern or play a song in a loop (these things will be added in the future).
I have created a GitHub repository for this project, you can download the binaries and source code from there:
https://github.com/maccasoft/retronitus-composer
https://github.com/maccasoft/retronitus-composer/releases
I have included as examples some musics from the Frogger arcade game and a sound effect from the Lode Runner game. Speaking of which, if you want to see a practical application for Retronitus, I have recently ported Lode Runner using it as the sound engine to my P8X Game System. It uses only the sound effects, no music.
Remember that this is a preview release, it should be usable enough to experiment but there aren't many safety checks and it may crash at any time.
Hope you enjoy!
I have found a couple of bugs in the latest version of Retronitus that I will resolve. Music looping for instance will cause some channels to get out of sync in some situations.
/Johannes
/Johannes
Edit: Oh, and BTW:
Thanks.
It isn't handled right now and generates a wrong delta. I'll fix that in the next release, by generating a new pattern sequence automatically.
Yes, that would be perfect. I see you wrote a Propeller emulator in Java, I tried to port the Gear emulator to Java once but ended up being too slow for any practical application, hope you can optimize it. I also tried to port Gear to C, still too slow, it helped me to better understand how Retronitus works but still too far from realtime. Honestly I haven't put much efforts on optimizing it.
Are you using a 64 bit JVM on Windows ? The current windows release is 32-bit, can you install the 32-bit version of the JVM ?
But you DO get the choice upfront when downloading a JDK. And I usually set my JDK as my default JVM for some reason.
EDIT: Checked, they give you the 64/32 bit build depending on your browser. Even tough java in browser is dead because...
Ah, in Spin longs are treated as signed integers.
The next release will have a 64 bit Windows build. I'm not sure to understand what you mean with the browser choice, this isn't meant to be run in a browser, it is a standalone application, if it runs in a browser is just luck.
I don't know if it is your case (haven't looked much at your code) but in my early attempt to port Gear to Java and now with the retronitus build code, I had to use long instead of int because in Java all numbers are signed and if you use int with a variable/register meant to roll over at 32-bit you end with the wrong results. With longs you have to just mask the lower 32-bits when needed, it may be slower but the results are more accurate. Also beware that when you assign a variable the sign is expanded, so if the int variable is negative also the long will be negative, you have to mask the lower 32-bits to get the correct value.
Also, don't int's roll over as usual, e.g. from Integer.MAX_Value to Integer.MIN_VALUE? I use bytes as if they were unsigned in another project of mine and hadn't had any problems (except when using them as array indexes...). For the record: I do use longs in some Instructions, in particular the ones where you get a carry or whatever.
But i might look into it...
EDIT: And BTW, i now at least get a sequence of tones, i think im getting there!
@Ahle2
What range of values is usually written to FRQA/FRQB?
http://blogs.bl.uk/sound-and-vision/2016/09/restoring-the-first-recording-of-computer-music.html
By Alan Turing none the less.
Good stuff! Pity they scrapped the computer tho..
Now, somewhat back on-topic: Could someone please look at my code and tell me that im not going insane? I have no idea where the problem could be! All instructions i'm not 100% sure on aren't used in both Retronitus and the Spin interpreter! It's somewhere in https://github.com/Wuerfel21/EmuRetronitus ... I feel like i'm almost hijacking the thread at this point, might make a separate one if the topic of Retronitus emulation isn't solved soon.
The range should be "full" 32 bit swing! (Or at least near full swing)
https://github.com/maccasoft/retronitus-composer/releases/latest
Some general fixes (including the out of range note delta), implemented a simple error checking and polished the user interface a bit.
The build system was updated to include native launchers (executable for Windows and script for Linux), it isn't packaged as a single jar anymore. To start the program unpack the downloaded package and run composer from the retronitus-composer folder.
This release has a Windows64 download, I don't have a 64-bit windows right now so it isn't tested, hope it works.
Tried it on Windows64, but I had an exception.
I will see if I can install said development kit later today.
The windows64 version requires a 64-bit java runtime, the windows version requires a 32-bit java runtime (it is a bit complicated but I haven't yet found a way to include both in a single package, seems that launch4j doesn't allow a classpath dependendent on the runtime architecture).
This assuming you don't have an older runtime (older than 1.7.0), if so you better update as soon as possible.
It should work well with the latest 1.8.0 release, I have lowered the minimum version to 1.7.0 because I'm not using any special construct that requires a later release.
EDIT: Scratch that, i found it! The offsets between some of the variables were hardcoded. And tempoAccumulator needs to be zero, for some reason.
EDIT 2: The attached file should now actually be the correct one!
I will eventually fix all issues with Retronitus. Thanks for showing interested in my work.