Java Synthesizer, Part 20 – File Handling

Finally, I can save and load patch settings.

Actually, it took a bit of code to get to this point, too. Things really were speeded up with the introduction of the command line parser, since all I really needed to do was add code to call the parser from the top menu bar. And that’s where things got more messy (and/or fun, depending on your definition of “fun”).

I started out by simply adding a new menu item for listing command line instructions, modules, pin wiring, etc. – all the “list” commands already in the parser.

From here, it was a relatively simple step to add a second new menu item for creating new modules. I decided that it’d be easier all around to just hard code the constructor and range settings, then let the user tweak everything using the sliders within the GUI.

The third new menu item was “connections”, which allows for making and breaking the wiring between modules. So, in fact, the menu bar now has the same functionality for creating new synth circuits as the command line does, the only difference being that the menus use pre-coded range values, and the command line allows the user to specify everything themselves.

One bug that I ran into, that I’m not going to try to fix, is that the “pin” command needs to specify the pin ranges in the same order, and for each and every pin, as given in the inpins[] arrays for each module. It’s not really a *bug* per se, but more of my being lazy. Plus, you need to specify the range for each of the pins you want to vary from the GUI screens. I did put in a check for whether a control that you’re trying to wire has been specified with the “pin” command, but it’s easy to overlook if you’re hand entering commands through the command line.

Loading a circuit from an existing file is trivial. I just read the file one text line at a time and send it to the command line parser. This does create a long pause from when I click “ok” to when Java starts printing out parsing results in the jTextArea1 window, especially if it’s a big circuit. I think this is a limitation in Java itself, wanting to finish printing everything to the text area before displaying it to the user.  (Copying the patch from a textfile into jTextArea1 and using the grab command is several times faster than loading the same patch directly from a file.)

Saving the patch file is equally simple. First, I just write the contents of the instructions[] array, which contains the wiring commands entered by the user. Then I go through the ranges ArrayLists for each module and write a new “setting” line. I added “setting” to the command parser at the last minute. This takes the slider settings, and text field values for each module and pin, as previously changed by the user, and puts them in the ranges ArrayLists for each module. When the user saves the patch to file, the save method appends the “settings” statements to the end of the wiring commands. Then, when the file is loaded again later, the parser sees the “settings” statements and restores the user’s last synth patch settings.  This is really the key to making my program usable, because now I not only have user-configurable circuit wiring, but I can save and load the last slider settings (i.e. – what everyone calls the actual “patch”) as well. To avoid having multiple copies of the settings commands show up in the patch file with each “file save”, I strip them out of the instructions ArrayList during file save, and then save only the current range values each time.

While creating and saving various simple circuits for testing the command line parser, I made one that I called “simple osc and gated ADSR with echo and noise”. I decided to use it at random for testing the file load and save function, and suddenly the playback sound seemed strange to me. It was very hissy and had a bell-like component in the echo loop. Thinking that I’d screwed up the echo class when I tweaked it to make it compatible with the range setting function, I started digging into the in() and out() methods, then realized that I had indeed written the echo loop portion wrong. I was varying the loop buffer length, but not the time between the bufferReadPtr and bufferWritePtr for allowing the time from write to read to change.  So I ripped out the old code and put in what I’d originally planned for that class (varying loopLength, then having a variable going from 0.0 to 1.0 to set bufferReadPtr as a ratio of loopLength, lagging behind bufferWritePtr). Unfortunately, this didn’t fix the noise-bell issue, and I lost several hours until realizing that it was a natural side-effect of that particular circuit. Switching to “simple osc. with gated ADSR and echo” (and no noise) produced the kind of echo I wanted. But, the new echo loop code produces hiss when I change settings with the sliders. So, I figured “what the heck” and added a mode setting for selecting between the old version of the echo loop and the new one.

Not too much more to say about the synth from the Java side.  I still need to re-implement the pitch wheel, and I’m getting occasional “timer concurrent operations” errors when I load the patch via the parser (seems to be something with the timer class, but it doesn’t hurt anything so I’ll live with it until I figure out what the cause is). I also need to do more testing to verify that everything else works right. Plus, there is one extra feature I need to add at some point – allowing two or more keys to be pressed at the same time (I’ll retain the monophony restriction, I just don’t like having the keyboard turn off when the first key is released and the second is still pressed).  After that, I’ll make a youtube video for a quick demonstration of the app. It is still hissy, which bugs me, but that may be caused by either Java itself, the sound card hardware or the card drivers. At the moment, I have no idea how to remove the last of the hiss when changing slider settings, but at least the clicking isn’t as bad as when I first started out a month ago.

Raw formatted script file here (same as last blog entry).


Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: