From: Brian <br...@ov...> - 2005-03-07 19:23:14
|
Hello, Thanks for your feedback. This is the kind of stuff we need to discuss to move JSynthLib forward. I've taken some time to digest what you've said too see if I can figure how these ideas would fit into the existing code base. My understanding of your complaints is that they fall into two problems: ( 1 ) There is a certain amount of functionality you expect from a Librarian that JSynthLib lacks ( 2 ) Some functionality that JSynthLib does indeed have, you can not use because the design of JSynthLib is different than you would expect. I think ( 2 ) at least in the short term is a documentation issue. I've been thinking of writing a step by step tutorial w/ screen shots showing new users how to perform various tasks for a while. The only reason it hasn't materialized already is that I thought most of it was self explanatory :-). Actually, I think once you figure the most basic abstraction behind JSynthLib, it should all fall into place anyway. I believe your issue is you are expecting a different abstraction As for ( 1 ) and a more long term view of ( 2)-- let me first explain the fundamental abstraction behind JSynthLib, and then explain my understanding of the fundamental abstraction you see in your mind for what you expect. Then we can talk about how to merge the two into a more useful program. JSynthLib as it stands now (somewhat rambling....) ----------------------------------- JSynthLib is a disk based Editor/Librarian for Synthesizer patches. It provides a rich set of operations for loading patches from your hard disk, storing patches from your hard disk, and cataloging your collection of patches. This is done by taking all the patches which would otherwise sit in various .syx files on your disk and placing them in .patchlib libraries. Once your patches are in .patchlib libraries you can copy them between libraries, and generally move the data around in your computer. For example, I have two files on my computer. One is a sysex for a single patch for my Kawai K4 called "CoolPiano". The other is a sysex of an entire bank dump (16 patches) That does not contain CoolPiano. I want to add CoolPiano into that bank. First I create a library and import both the bank and the single. Next I open the bank and I can see a grid of all the singles that make up that bank. I choose one to overwrite, and I drag-and-drop CoolPiano over it. Done! Now I can either export the modified bank back to disk, or preferably, simply save the Library containing the bank, as this lets me maintain comments, etc. for the bank. All "Banks" and "Libraries" in JSynthLib exist on your computer. Therefore they are all "Virtual Banks" though they have the same format and size as real banks on the synths. The Patches and Banks in JSynthLib do not represent any data currently on the synth, but represent data on your computer. In the same manner it is possible to take the CoolPiano sound in that bank, open it in an editor and change the LFO settings. Then I can resave the library and that patch in that bank will be modified. All operations are performed directly on your "Library of patches" stored on your computer's hard drive. In fact none of the above operations even require you to have a Kawai K4 connected to your computer. Of course a Librarian also needs to be able to communicate with the actual device to be useful, and JSynthLib can do this as well. The design behind JSynthLib is to give a simple mechanism for retrieving patches from the device, a simlple mechansism for storing patches back to the device, and a rich set of editing primitives that modify the patch while it is stored on your computer. I think this is what is different than you are used to. JSynthLib makes no attempt to modify patches that are already loaded on your synth, nor does it allow you to view the current environment on your synth. JSynthLib lets you view/modify the patches on your computer, and then load/store patches back to your synth when you are done. JSynthLib has a very loose integration with the actual synth. There is a "Get" Command to retrieve a given patch (say Single B-14) from the K4 and place it in the current library, and a "Store" command to place a patch from the current library to a given location on the K4 (Say Single A-2). Other than that, JSynthLib doesn't know/care about your synths layout. All it cares about is that the synth has something called an "Edit Buffer" in which JSynthLib can place a patch in its library in temporarily in order to play it to here what it sounds like. Sounds in the Edit buffer are not permentantly stored on the synth, they are stored in the JSynthLIb library and only temporarily placed in the edit buffer because otherwise JSynthLib is unable to play the sound. The Idea behind JSynthLib is this: Your synth has the ability to load, save, and play a patch via midi. It also has its own very limited "internal librarian" system built in. It is limited though, because it only allows a few patches loaded at a time (maybe 64), if it allows editing at all it uses a tiny LCD., it only plays patches for one model of synth, it doesn't allow you to add comments to your patches, etc. To compensate for this maybe it allows you to save patches to a floppy disk to be lost behind your desk and never seen again. JSynthLib sees itself as a *replacement* for your synth's internal librarian. You still have to use the synth to generate the actual sound ,but everything else is done within JSynthLib. The JSynthLib model basically says "A Synthesizer is a machine capable of playing a patch that is sent to it" That is all that is expected of a synth. Of course, at some point you want to stop selecting sounds and tweaking paramters and actually make your synth "standalone" either to take it to a gig or do some sequencing where you want multiple sounds loaded on it. At this point you don't want your synth to be treated as only a glorified "Edit Buffer", but want to transfer your current ideas/setup from JSynthLib back to the "Internal Librarian" of your synth. There are three ways to do this in JSynthLib" First, if you only want to place a few patches from your JSynthLib library into various locations in your synth's internal librarian, you can use the "Store" menu option for each. For example you can highlight CoolPiano in your current library, and store it to spot A-5 in your internal librarian. Then you can place "FunkyBass" into A-7 for example. This is pretty simplistic. A better way is to first create a virtual bank in jsynthlib, copy the patches you want into it, and then store the entire bank into your synth (Say into bank B). This is the way I work with JSynthLib. The third way is to use a scene, you can copy the patches you want to send into your internal librarian into a scene, along with the desired desitinations, and then chose "Transfer Scene" This has the advantage that one scene can contain patches and desired locations for many synths and JSynthLib can deal automatically with all the different 'internal librarians' to get the patches where you want them. In Summary, JSynthLib is designed as a replacement for your synths internal librarian. While you are using JSynthLib, you use it instead of an internal librarian. Then, you can use it to seed your more limited "internal librarian" in the case that you need to perform a task like multitimberal sequencing or playing live, where you must use the "internal librarian" in order to get at the full functionality of your synth. JSynthLib is designed to have a rich editing framework for patches stored on your computer's hardisk, and simple mechanisms to load and save patches to and from an actual hardware device. (And a mechanism to force the synth to play a patch on the harddrive, since, it JSynth can't play it without some help from the hardware). ---------------------------------------- My Understanding of what you are expecting different Your ideal program would be, not a librarian to manage patches on your disk to replace the internal librarian in your synth, but an extention to your synth which provided an easier to use than the front panel display into the on board librarian functionality of your synth. Instead of manipulating patches on your computer and storing them to your synth when done, your ideal design would give the impression you were editing patches directly on the synth in place. With this program, the primary purpose would not be to edit and catalog patches on your hard disk, but to peek and poke at the internal ram on your synth, occasionaly copying things from that ram to your disk or vise versa. In JSynthLib, there is minimal store/retrieve from synth and most of the time is spend manipulating data on the computer. With your ideal program, most of the time is spent manipulating the contents of your synth directly. Is this correct? -------------------------- Synthesis The question then becomes, how can we make this model of working with JSynthLib possible without creating a mixed-metaphore monstrosity. That is, can we make a Editor/Librarian that I can work with in the Disk Librarian mode I prefer, and that you can work with in the Device Manager mode you prefer, without basically having two applications in one. Before I give my proposal, let me mention the constraints we are working with: 1) Backwards Compatability-- People who work with JSynthLib the way it currently do should be able to basically continue to do so. File formats (.patchlib, .scene) should still exist and work the same way they do now. I don't want to lose the current functionality to add the new functionality, nor do I want to dichotomize it so that a user must choose one or the other. They should get all the advantages of current JSynthLib and the "Device Manager" abstraction 2) No Driver Changes- We can't add any new synth specific functionality, many of the drivers that work with the current JSynthLib are not currently active. In some cases the developers who wrote them are no longer active, and in other cases, though the developers are active, the synths are no longer available (For example, I wrote the Ensoniq ESQ1 driver, but no longer own t he synth. )While it is possible to make cosmetic changes to the driver API (as we have done in the past) We can't add any functionality that wouuld need to be programmed per synth. We need to add whatever abstractions we add above the driver layer 3) Gracefully handle partial support- One nice thing about the current JSynthLib is that it is very modular. If there exists no Multi Driver for your synth, you can't use Multi's but everything else works. If there doesn't exist a Single Bank Editor, you can't view banks, but you can still work with/ modify/ and store all the patches in banks on your synth. This is very importand since JSynthLIb is OSS. Not everyone who is willing to contribute some driver support would do so if it was an all or nothing deal. The fact that they can spend a small amount of time to get basic driver support working and contribute it is very important. I wouldn't want to lose this by making everything more integrated such that, it wouldn't work (for example) without Bank Editor Support if all you had was a Single Driver for a synth. Proposal ----------------------- (1) We leave everything that already exists there: Libraries, Banks, Scenes, etc. but make evident from the interface that these are "Virtual" objects that exist on your computer and that JSynthLib is manipulating on your hard disk. Changes made to these objects are not effecting your Synthesizer but are only effecting the state on your JSynthLib "Desktop". (2) The interface to the actual synths become a much larger part of the JSynthLib interface. The functionality remains the same (Receive Patch / Store Patch), but the interface to those functions become much more expressive. Rather than just being a menu option, I envision the following: We have a new Window type in addition to the ones we have now, it could be called Device Manager.It is either a box of Icons, or maybe a tree view. For the purpose of this discussion, lets assume its a tree: At the top level you have each synth you own, perhaps with a nice picture next to the text. When you delve deeper into the tree, you see each datatype supported by a driver for this synth. Under that you would have all the available banks. For example, you might have: Kawai K4 Single Internal External Multi Internal External Effect Drum Oberheim Matrix 1000 Single Bank 000 Bank 100 When you click one of the Banks JSynthLib issues a Receive Patch request for that bank behind the scenes and populates the subsiquent "Non Virtual Bank" window (or perhaps place the patches right in the tree) With the actual patches on that synth currently. You could then right click the resulting patches and edit them just like normal, but knowing the results will automatically be stored back to the synth when you are done with them. In addition, you could request / send patches between the "Device Manager" actual banks and the "Disk Librarian" virtual banks / libraries, by using drag and drop or cut and paste rather than having to use the explicit "Get / Store" menu options. Plus, we could even make an option in the Preferences to associate a "Default" Library with each device that could pop open when you open the device in the "Device Manager", this way when you clock on Kawai K4, you could automatically pop open your default 'virtual; library of Kawai K4 patches. Of course there are lots of technical details to work out and I'm not even sure if this is feasable, but if we could do this, would it allow you to work the way you wish to? Technical Issues I see include 1) How to handle devices for which no Bank Driver exists, I guess we could create a Stand in which just iterates through all the patches and sends and receives them from the synth serially. This would not allow for a true 'Virtual Bank' as these are often compressed .syx representations, but it would be enough to view and work with your patches. 2) Keeping up the metaphore that you are really working "On the synth". For example, if I edit a patch that is from the device manager and make a change, that change goes into the synths edit buffer, but we wouldn't actually re-store it in its location until the patch editor was closed. (Otherwise we would be sending a lot of sysex info for each fader movement). This might violate the abstraction? We need to deal with this sensibly. In addition we couldn't allow two simultaneious "real" patches to be edited on the same synth at the same time as there is only one edit buffer, unless we did a send/restore everytime an editor window gained/lost focus. 3) Automatically changing to the right patch type. For example,If I'm editing K4 Singles and then Click on a K4 Multis, the synth needs to automatically change and select the correct multi. On some synths this is a patch change with an offset, others its a bank change, others its a sysex message. This would require new functionality for the drivers, but perhaps we could implement a base case that pops up a dialog box saying "Hit the Multi Button on your Synth" That would get called if that functionality didn't exist for a particular device. This would be annoying but it would have the added benefit of forcing people to add the functionality to do this automatically :) 4) Dealing with the user's setup vs. the standard setup for a given device. For example, the KawaiK4 has internal and external banks, but if the user doesn't have a data card installed, the external banks don't work, how could JSynthLib deal with this situation? What do you think? In addition, I am going to answer some of your more specific questions below, though hopefully the discussion above clarify's the way JSynthLib works in all these situations and why it does. > > Okay. I choose to work with a desktop metaphor, with all of my midi > device arranged on a panel. I want to double-click on one of them and > get a window showing me all of the categories of settings (patches, > performances, controller configs) that I can mess with, along with a > list of all of the patches that I have stored locally on the hard disk > for that synth. > > Oddly, I'm not finding the checkbox to turn that "choice" on. :P Thats because you haven't programmed that checkbox yet :-) The nice thing about Open Source is that you can add missing features yourself. The bad thing about Open Source is that you can add missing features yourself :) > One problem I had was trying to figure out just what a "Library" is. > It's the only thing I'm able to create at the outset (until I figure > out how to go add synths), yet there were no cues as to what it was a > library *of*. Patches, I figured... but I didn't know for what synth. Perhaps we should make this more clear somehow? Libraries can hold *any* kind of patch for *any* synth. They're flexible like that > > Granted, I could experiment and yell and curse and eventually train my > brain to do things the JSL way. But remember... if this is the kind of > trouble that a quick-study like myself has, normal users will be > completely lost. For example, I work with Jon Anderson (the lead > singer from Yes. You know... "Owner of a Lonely Heart", and > "Roundabout", etc?) and I wouldn't *dare* tell him to use this with > it's current UI. One of my bandmates is a Yes fan. I think we need to fix these issues so you can get Jon Anderson to use JSynthLib so I can brag to my bandmate about it. :-) > > I'll explain. Say that you find a neat sound? You went down the list > of patches and heard something that you liked. *Now* what? I think > it's reasonable to expect that you'd want to store that patch in your > synth's internal memory somewhere. So, you need to bring up a window > showing the layout of all of the patches within that synth, right? > Does JSL already let you right-click and see that synth's current > patches? If it does, it's not at all intuitive that this is how JSL is > supposed to be used. Besides, this brings a host of other problems. > What if I have two of the same synth? What if I want to put it into a > virtual bank on the local hard disk? The functionality does exist, Its the "Store" option from the Patch Menu, you select it from the menu and choose the patch number you want to send it to. I think after my discussion of the JSynthLib design metaphore, this should make more sense to you? JSynthLib doesn't have anything currently telling you the current "State" of your Synth. To JSynthLib a synth is just something it sends data to and gets data back from. There is no facility currently to view the current 'state' of your synth. > Has the notion of a software design ever surfaced? By "software > design", I mean the type with just verbal/graphical descriptions > detailing the user experience. It's a lot like writing the > documentation before the app. One nice thing about it is that it > allows any developer to work on any part at any time, since everybody > knows what the finished product is supposed to operate like. The even > NICER thing about it is that it forces the developers to work out the > details of the entire user experience before they code too much. I did exactly that. Fully and completely and in painstaking detail actually before I even wrote a single line of Java. I worked out menu layouts, window types, how the user would interact, etc. The thing is the spec was fully implemented by around version 0.10 and since then its basically been "whatever someone wants badly enough to write gets added". Brian |