From: Michael H. <kor...@ya...> - 2009-08-24 01:59:29
|
When I click on the "Paste" button from within the "Get" patch dialog I get the following: Exception occurred during event dispatching: java.lang.NullPointerException at core.Driver.createPatches(Driver.java:298) at core.SysexGetDialog.pasteIntoSelectedFrame(SysexGetDialog.java:156) at core.SysexGetDialog$PasteActionListener.actionPerformed(SysexGetDialo g.java:246) at javax.swing.AbstractButton.fireActionPerformed(Unknown Source) at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source) at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source) at javax.swing.DefaultButtonModel.setPressed(Unknown Source) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Sour ce) at java.awt.Component.processMouseEvent(Unknown Source) at javax.swing.JComponent.processMouseEvent(Unknown Source) at java.awt.Component.processEvent(Unknown Source) at java.awt.Container.processEvent(Unknown Source) at java.awt.Component.dispatchEventImpl(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Window.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.Dialog$1.run(Unknown Source) at java.awt.Dialog$3.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.awt.Dialog.show(Unknown Source) at java.awt.Component.show(Unknown Source) at java.awt.Component.setVisible(Unknown Source) at java.awt.Window.setVisible(Unknown Source) at java.awt.Dialog.setVisible(Unknown Source) at core.Actions$GetAction.actionPerformed(Actions.java:1055) at javax.swing.AbstractButton.fireActionPerformed(Unknown Source) at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source) at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source) at javax.swing.DefaultButtonModel.setPressed(Unknown Source) at javax.swing.AbstractButton.doClick(Unknown Source) at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source) at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source) at java.awt.Component.processMouseEvent(Unknown Source) at javax.swing.JComponent.processMouseEvent(Unknown Source) at java.awt.Component.processEvent(Unknown Source) at java.awt.Container.processEvent(Unknown Source) at java.awt.Component.dispatchEventImpl(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Window.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source) |
From: Michael H. <kor...@ya...> - 2009-08-25 02:00:57
|
Hi JSynthLib fans, Well, after hours (3 to be exact) of careful troubleshooting and tinkering, I was able to pull in a patch from my Korg Poly-800. But as with most things in life, I now have more questions than I started with. I am hoping that someone who has more experience with JSynthLib than me can help me out. To get the patch "get" and "paste" to work required that a) I set sysexID = "F0422106*"; this is the header for a patch dump coming from the Poly-800. and b) that I comment out sending a bank change in requestPatchDump. The Poly-800 sends an acknowledgement sysex message after it receives a bank change. So the "Get" code seems to have choked on the 7 bytes that it receives just prior to receiving the patch sysex message itself. So, I could just rewrite the sysex implementation on the Poly-800 so that it doesn't send an acknowledgment sysex message but that seems to be a bit of a cop out and especially so if there is a way that I could rewrite the requestPatchDump so that it would intercept that ack. message and ignore it instead of choking on it? Now, I don't want to be too pushy here because I like JSynthLib and I like the idea of an open source patch editor but hopefully someone on this list can answer a question or two because it has taken me hours to get this far and I have many more questions that need answering. Here is another question, the Poly-800 does not support patch names in its sysex implementation nor programming but does that stop me from using patch names in JSynthLib itself? Is it possible to save patch names outside of the sysex message but inside the patch when stored in JSynthLib? Anyway, in advance, I would like to thank anyone that might provide me with some assistance. If I don't hear anything from anybody, I may have to consider an alternative to JSynthLib because the learning curve might be just too steep while going at this completely alone. Here's my singledriver below: /* * @version $Id: KorgHAWK800SingleDriver.java 111 2009-08-20 04:05:40Z hawkins $ */ package synthdrivers.KorgHAWK800; import core.Driver; import core.ErrorMsg; import core.JSLFrame; import core.Patch; import core.SysexHandler; public class KorgHAWK800SingleDriver extends Driver { private int curBank = 0, curPatch = 0; public KorgHAWK800SingleDriver() { super("Single", "Michael Hawkins"); sysexID = "F0422106*"; sysexRequestDump=new SysexHandler("F0 42 21 07 *patchNum* F7"); patchSize=262; deviceIDoffset=-1; bankNumbers = new String[] { "0-Bank1", "1-Bank2","2-Bank3", "3-Bank4" }; // patch numbers use octal representation with no zeroes (11-88) patchNumbers=new String[] {"11","12","13","14","15","16","17","18", "21","22","23","24","25","26","27","28", "31","32","33","34","35","36","37","38", "41","42","43","44","45","46","47","48", "51","52","53","54","55","56","57","58", "61","62","63","64","65","66","67","68", "71","72","73","74","75","76","77","78", "81","82","83","84","85","86","87","88"}; } public void setBankNum(int bankNum) { try { send(new byte[] { (byte)0xF0,(byte)0x42,(byte)0x21,(byte)0x0E, (byte)bankNum,(byte)0xF7 }); } catch (Exception e) {} } public void requestPatchDump(int bankNum, int patchNum) { //setBankNum(bankNum); try {Thread.sleep(250); } catch (Exception e){} byte sysex[] = { (byte)0xF0, (byte) 0x42, (byte) 0x21, (byte) 0x07, (byte)patchNum, (byte) 0xF7 }; send(sysex); } public void storePatch (Patch p, int bankNum,int patchNum) { setBankNum(bankNum); try {Thread.sleep(250); } catch (Exception e){} //patchNum=patchNum&0x3F; ((Patch)p).sysex[4]=(byte)patchNum; sendPatchWorker(p); setPatchNum(patchNum); } public void sendPatch (Patch p) { byte [] newsysex = new byte[262]; System.arraycopy(((Patch)p).sysex,0,newsysex,0,262); newsysex[4] = (byte)(0x40); try { send(newsysex); }catch (Exception e) {ErrorMsg.reportStatus(e);} } public Patch createNewPatch() { byte [] sysex = new byte[262]; sysex[0]=(byte)0xF0; sysex[1]=(byte)0x42; sysex[2]=(byte)0x21; sysex[3]=(byte)0x06; sysex[261]=(byte)0xF7; Patch p = new Patch(sysex, this); //setPatchName(p,"NewPatch"); calculateChecksum(p); return p; } protected void calculateChecksum(Patch p,int start,int end,int ofs) { // no checksum } //public JSLFrame editPatch(Patch p) { // return new KorgHAWK800SingleEditor((Patch)p); protected JSLFrame editPatch(Patch p) { return (new synthdrivers.Generic.HexDumpEditorFrame(p)); } } |
From: Daniel R. <dr....@co...> - 2009-08-25 07:36:13
|
Hi Michael, 1) three hours of tinkering is either not mentioned or called, "a bit of tinkering" when you develop software. Plan to lose many more. 2) I did give up on JSynthLib (resulting in www.confusionists.com/handsonic), but there was a LOT of help on the list. I ditched it because what I needed to do was not really a librarian. 3) My guess: it's August, they're Europeans, and so you have to wait until September when they are actually working. 4) Sounds like your problems are outside of JSynthlib anyway, but I'm not sure. Use JSynthlib if you are going to be making that kind of functionality anyway. good luck! D On Tue, Aug 25, 2009 at 4:00 AM, Michael Hawkins <kor...@ya...>wrote: > Hi JSynthLib fans, > > Well, after hours (3 to be exact) of careful troubleshooting and tinkering, > I was able to pull in a patch from my Korg Poly-800. > > But as with most things in life, I now have more questions than I started > with. I am hoping that someone who has more experience with JSynthLib than > me can help me out. > > To get the patch "get" and "paste" to work required that a) I set sysexID = > "F0422106*"; this is the header for a patch dump coming from the Poly-800. > and b) that I comment out sending a bank change in requestPatchDump. > > The Poly-800 sends an acknowledgement sysex message after it receives a > bank change. So the "Get" code seems to have choked on the 7 bytes that it > receives just prior to receiving the patch sysex message itself. > > So, I could just rewrite the sysex implementation on the Poly-800 so that > it doesn't send an acknowledgment sysex message but that seems to be a bit > of a cop out and especially so if there is a way that I could rewrite the > requestPatchDump so that it would intercept that ack. message and ignore it > instead of choking on it? > > Now, I don't want to be too pushy here because I like JSynthLib and I like > the idea of an open source patch editor but hopefully someone on this list > can answer a question or two because it has taken me hours to get this far > and I have many more questions that need answering. > > Here is another question, the Poly-800 does not support patch names in its > sysex implementation nor programming but does that stop me from using patch > names in JSynthLib itself? Is it possible to save patch names outside of the > sysex message but inside the patch when stored in JSynthLib? > > Anyway, in advance, I would like to thank anyone that might provide me with > some assistance. > > If I don't hear anything from anybody, I may have to consider an > alternative to JSynthLib because the learning curve might be just too steep > while going at this completely alone. > > Here's my singledriver below: > > /* > * @version $Id: KorgHAWK800SingleDriver.java 111 2009-08-20 04:05:40Z > hawkins $ > */ > package synthdrivers.KorgHAWK800; > > import core.Driver; > import core.ErrorMsg; > import core.JSLFrame; > import core.Patch; > import core.SysexHandler; > > public class KorgHAWK800SingleDriver extends Driver > { > private int curBank = 0, curPatch = 0; > > public KorgHAWK800SingleDriver() { > super("Single", "Michael Hawkins"); > sysexID = "F0422106*"; > sysexRequestDump=new SysexHandler("F0 42 21 07 *patchNum* F7"); > > patchSize=262; > deviceIDoffset=-1; > > bankNumbers = new String[] { > "0-Bank1", "1-Bank2","2-Bank3", "3-Bank4" > }; > // patch numbers use octal representation with no zeroes (11-88) > patchNumbers=new String[] {"11","12","13","14","15","16","17","18", > "21","22","23","24","25","26","27","28", > "31","32","33","34","35","36","37","38", > "41","42","43","44","45","46","47","48", > "51","52","53","54","55","56","57","58", > "61","62","63","64","65","66","67","68", > "71","72","73","74","75","76","77","78", > "81","82","83","84","85","86","87","88"}; > } > > public void setBankNum(int bankNum) > { > try { > send(new byte[] { > (byte)0xF0,(byte)0x42,(byte)0x21,(byte)0x0E, > (byte)bankNum,(byte)0xF7 > }); > } catch (Exception e) {} > } > > public void requestPatchDump(int bankNum, int patchNum) { > //setBankNum(bankNum); > try {Thread.sleep(250); } catch (Exception e){} > byte sysex[] = { > (byte)0xF0, (byte) 0x42, (byte) 0x21, (byte) 0x07, > (byte)patchNum, (byte) 0xF7 > }; > send(sysex); > } > > public void storePatch (Patch p, int bankNum,int patchNum) > { > setBankNum(bankNum); > try {Thread.sleep(250); } catch (Exception e){} > //patchNum=patchNum&0x3F; > ((Patch)p).sysex[4]=(byte)patchNum; > sendPatchWorker(p); > setPatchNum(patchNum); > } > > public void sendPatch (Patch p) > { > byte [] newsysex = new byte[262]; > System.arraycopy(((Patch)p).sysex,0,newsysex,0,262); > newsysex[4] = (byte)(0x40); > try { > send(newsysex); > }catch (Exception e) {ErrorMsg.reportStatus(e);} > } > > public Patch createNewPatch() > { > byte [] sysex = new byte[262]; > sysex[0]=(byte)0xF0; sysex[1]=(byte)0x42; sysex[2]=(byte)0x21; > sysex[3]=(byte)0x06; sysex[261]=(byte)0xF7; > Patch p = new Patch(sysex, this); > //setPatchName(p,"NewPatch"); > calculateChecksum(p); > return p; > } > > protected void calculateChecksum(Patch p,int start,int end,int ofs) > { > // no checksum > } > > //public JSLFrame editPatch(Patch p) { > // return new KorgHAWK800SingleEditor((Patch)p); > protected JSLFrame editPatch(Patch p) { > return (new synthdrivers.Generic.HexDumpEditorFrame(p)); > } > > } > > > |
From: Peter G. <pet...@gm...> - 2009-08-25 08:53:50
|
Hi, On Tue, Aug 25, 2009 at 7:11 AM, Daniel Rosenstark wrote: > Hi Michael, > > 1) three hours of tinkering is either not mentioned or called, "a bit of > tinkering" when you develop software. Plan to lose many more. IMHO That's where the introduction in the programmer's guide is pretty misleading: III.a.1. How hard is it to add support for a new synthesizer to JSynthLib? The hardest part is simply becoming familiar with how JSynthLib works and how it's laid out internally. Spend some time looking through the driver code for other synthesizers and you'll basically pick it up by osmosis. Once your familiar with what you have to do, actually doing it shouldn't take too long. I've gotten librarian (not editing) support for synthesizers hacked up in under two hours. It depends of course, on the complexity of the synthesizer and the quality of the sysex specification. Adding editing support can be a little more time consuming, but is probably even more fun than writing librarian support. I've spent anywhere between 3 or 4 hours (working on the DR660 Editor) up to 5 days (working on the Matrix 1000 editor). If you run into any trouble, you can email JSynthLib mailing list<jsy...@li...>for help. If we're writing this to an audience of musicians, better add that knowing how to program in general and in Java is required. Then it's possible to 'pick it up by osmosis'. Else, we should provide a much more detailed guide. > 2) I did give up on JSynthLib (resulting in > www.confusionists.com/handsonic), > but there was a LOT of help on the list. I ditched it because what I needed > to do was not really a librarian. There WAS a lot of help, but the information is hard to find now. > > 3) My guess: it's August, they're Europeans, and so you have to wait until > September when they are actually working. That's true, in September, the rainy days come again. (At least in Belgium and most countries up north, yes, Belgium is a country, Brussels is a city, where it's raining today ;-) > 4) Sounds like your problems are outside of JSynthlib anyway, but I'm not > sure. Use JSynthlib if you are going to be making that kind of > functionality > anyway. I guess 'your problems' refers to Mikes previous mails, and troubles with the Java installation ? I'm having similar problems ... see my previous mail<http://www.mail-archive.com/jsy...@li.../msg00140.html> Would it be better if we go to a java-forum to ask for help with these problems ? Cheers, Peter |
From: Peter G. <pet...@gm...> - 2009-08-25 09:30:17
|
Hmm, I forgot to "reply all", so Mike, sorry if you get this twice ;-) Anyway, I added some more thoughts .. On Tue, Aug 25, 2009 at 2:00 AM, Michael Hawkins <kor...@ya...>wrote: > Hi JSynthLib fans, > > Well, after hours (3 to be exact) of careful troubleshooting and tinkering, > I was able to pull in a patch from my Korg Poly-800. > > But as with most things in life, I now have more questions than I started > with. I am hoping that someone who has more experience with JSynthLib than > me can help me out. > > To get the patch "get" and "paste" to work required that a) I set sysexID = > "F0422106*"; this is the header for a patch dump coming from the Poly-800. > and b) that I comment out sending a bank change in requestPatchDump. > > The Poly-800 sends an acknowledgement sysex message after it receives a > bank change. So the "Get" code seems to have choked on the 7 bytes that it > receives just prior to receiving the patch sysex message itself. > > So, I could just rewrite the sysex implementation on the Poly-800 so that > it doesn't send an acknowledgment sysex message but that seems to be a bit > of a cop out and especially so if there is a way that I could rewrite the > requestPatchDump so that it would intercept that ack. message and ignore it > instead of choking on it? Maybe you should to make the KorgHAWK800SingleDriver extends *BankDriver*, like I did with my SPD11PatchDriver<http://spd-11.wikispaces.com/SPD11PatchDriver>, and use a 'bankChangeDriver' and 'K800SingleDriver', like I used a SPD11PadDriver and SPD11SettingsDriver. I'm not really understanding the difference between a singleDriver, bankDriver, converter I'm reading the programmer's guide again, and I'm wondering if a Single Patch really is a *set of* sysex messages like described there<http://jsynthlib.svn.sourceforge.net/viewvc/jsynthlib/trunk/JSynthLib/doc/programming.html#areas>. I first thought a Single Patch would hold just one Single SysEx Message. Because a single patch of my drumsynth is composed of 32 sysexmessages describing each drumpad + 1 sysexmessage describing the effects and pedal settings. In your case a patch is 1 bank ack sysexmessage + a 262 bytes patch sysexmessage > > > Now, I don't want to be too pushy here because I like JSynthLib and I like > the idea of an open source patch editor but hopefully someone on this list > can answer a question or two because it has taken me hours to get this far > and I have many more questions that need answering. Four hands do three times more work than two hands, I guess it's good to ask questions to many heads too, instead of keeping the questions for yourself. > > > Here is another question, the Poly-800 does not support patch names in its > sysex implementation nor programming but does that stop me from using patch > names in JSynthLib itself? Is it possible to save patch names outside of the > sysex message but inside the patch when stored in JSynthLib? My drum kits are named numbers 1~64, and I'd like to give 'em names too, so I actually have the same question. I think maybe we should take a look at how e.g. the TD-6 driver stores settings for padInfo<http://jsynthlib.svn.sourceforge.net/viewvc/jsynthlib/trunk/JSynthLib/synthdrivers/RolandTD6/PadInfo.java?view=markup>in the prefs file, it keeps info about if a pad is active or not, look at how it's done in RolandTD6Device<http://jsynthlib.svn.sourceforge.net/viewvc/jsynthlib/trunk/JSynthLib/synthdrivers/RolandTD6/RolandTD6Device.java?revision=646&view=markup>(line 56 & 75). The same trick may work to keep patch names in a preferences.node("Name(s)") > > > Anyway, in advance, I would like to thank anyone that might provide me with > some assistance. > > If I don't hear anything from anybody, I may have to consider an > alternative to JSynthLib because the learning curve might be just too steep > while going at this completely alone. > > Here's my singledriver below: > > /* > * @version $Id: KorgHAWK800SingleDriver.java 111 2009-08-20 04:05:40Z > hawkins $ > */ > package synthdrivers.KorgHAWK800; > > import core.Driver; > import core.ErrorMsg; > import core.JSLFrame; > import core.Patch; > import core.SysexHandler; > > public class KorgHAWK800SingleDriver extends Driver > { > private int curBank = 0, curPatch = 0; You don't use these variables anywhere ? > > public KorgHAWK800SingleDriver() { > super("Single", "Michael Hawkins"); > sysexID = "F0422106*"; > sysexRequestDump=new SysexHandler("F0 42 21 07 *patchNum* F7"); > > patchSize=262; This is why it chokes on the first returned ack message > > deviceIDoffset=-1; > > bankNumbers = new String[] { > "0-Bank1", "1-Bank2","2-Bank3", "3-Bank4" > }; > // patch numbers use octal representation with no zeroes (11-88) > patchNumbers=new String[] {"11","12","13","14","15","16","17","18", > "21","22","23","24","25","26","27","28", > "31","32","33","34","35","36","37","38", > "41","42","43","44","45","46","47","48", > "51","52","53","54","55","56","57","58", > "61","62","63","64","65","66","67","68", > "71","72","73","74","75","76","77","78", > "81","82","83","84","85","86","87","88"}; > } > > public void setBankNum(int bankNum) > { > try { > send(new byte[] { > (byte)0xF0,(byte)0x42,(byte)0x21,(byte)0x0E, > (byte)bankNum,(byte)0xF7 > }); > } catch (Exception e) {} > } > > public void requestPatchDump(int bankNum, int patchNum) { Maybe here add patchSize = SIZE_OF_ACK; //the number of bytes that comprise the returned ack message patchNameSize = 0; > > //setBankNum(bankNum); uncomment > > try {Thread.sleep(250); } catch (Exception e){} and now set patchSize = SIZE_OF_PATCH; //the number of bytes that comprise the returned patch message > > byte sysex[] = { > (byte)0xF0, (byte) 0x42, (byte) 0x21, (byte) 0x07, > (byte)patchNum, (byte) 0xF7 > }; > send(sysex); > } > > public void storePatch (Patch p, int bankNum,int patchNum) > { > setBankNum(bankNum); > try {Thread.sleep(250); } catch (Exception e){} > //patchNum=patchNum&0x3F; > ((Patch)p).sysex[4]=(byte)patchNum; > sendPatchWorker(p); > setPatchNum(patchNum); > } > > public void sendPatch (Patch p) > { > byte [] newsysex = new byte[262]; > System.arraycopy(((Patch)p).sysex,0,newsysex,0,262); > newsysex[4] = (byte)(0x40); > try { > send(newsysex); > }catch (Exception e) {ErrorMsg.reportStatus(e);} > } > > public Patch createNewPatch() > { > byte [] sysex = new byte[262]; > sysex[0]=(byte)0xF0; sysex[1]=(byte)0x42; sysex[2]=(byte)0x21; > sysex[3]=(byte)0x06; sysex[261]=(byte)0xF7; > Patch p = new Patch(sysex, this); > //setPatchName(p,"NewPatch"); > calculateChecksum(p); > return p; > } > > protected void calculateChecksum(Patch p,int start,int end,int ofs) > { > // no checksum > } > > //public JSLFrame editPatch(Patch p) { > // return new KorgHAWK800SingleEditor((Patch)p); > protected JSLFrame editPatch(Patch p) { > return (new synthdrivers.Generic.HexDumpEditorFrame(p)); > } > > } > It would be easier to help if you added more //comments to explain what's happening and why. |
From: Michael H. <kor...@ya...> - 2009-08-25 15:56:43
|
Pete, I had a look at the Roland TD6 driver and I have been able to get basic patch names working in JSynthLib. THANKS FOR THE TIP! So to explain, JSynthLib assumes that somewhere inside of a single patch sysex message there will be the text for the patch name. So the convention of JSynthLib was that you would set up an offset pointer and patch name size that would point at the start of the string in the sysex data array. Well, we all know that there are many synth's that never supported patch names at all so what I did was extended the size of the sysex array to be 262 bytes (for the actual sysex patch dump data) + 20 bytes for the patch name (character string). But then, the patch send routines have to send just the first 262 bytes. The 20 bytes for the patch name are just text stored for JSynthLib patch names. And also, the create new patch routine needed to include defining the patch sysex as being the larger size (282 bytes) and define some text in the last 20 bytes as shown below. public Patch createNewPatch() { // define sysex byte array with 262 bytes for sysex patch dump data message and 20 bytes for JSynthLib stored patch name text byte [] sysex = new byte[262+20]; // set up sysex patch dump data with SOX,manufacturer,device, patch and EOX values sysex[0]=(byte)0xF0; sysex[1]=(byte)0x42; sysex[2]=(byte)0x21; sysex[3]=(byte)0x06; sysex[261]=(byte)0xF7; // create the patch object Patch p = new Patch(sysex, this); // set the patch name for a new patch setPatchName(p,"**** New Patch ****"); calculateChecksum(p); return p; } Also, I noticed that you were absolutely correct about a "single" patch being able to hold more than one sysex message at a time. But of course, you have to define the sysex array size in the patch object as being large enough to hold all of the messages. So, I could extend the size of the sysex data array to allow storing the bank change acknowledgment message along with the actual single patch dump message. But that is an awfully bad way to write a single driver because the acknowledgment message is of no use to a patch whatsoever and would just be wasting memory. So, I am still looking for a way to rewrite the patch receiver code so that it can ignore such unwanted received data. It would be nice if a developer on JSynthLib could provide a hint. In the meantime, I'll go back to trudging through other drivers to see if someone else has already done something similar. The snippet below is my tweaked version of the generic single editor that shows the captured sysex message. In my version, the the sysex message is displayed and the additional 20 bytes are printed out as text underneath showing that they are being used by JSynthLib to provide a local patch name. public KorgHAWK800SingleEditor(Patch p) { this(); SysexMessage[] messages = p.getMessages(); for(int i=0; i<messages.length; i++) { append("Message " + i + ":\n"); appendBytes(messages[i].getMessage()); } // now display the patch name below the sysex message by printing bytes from 262 to 282 as a string append("Patch name: " + new String(((Patch)p).sysex, 262, 20) ); } Message 0: 0000 - f0 42 21 06 00 00 00 00 00 00 00 00 00 00 00 00 - .B!............. 0010 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ................ 0020 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ................ 0030 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ................ 0040 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ................ 0050 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ................ 0060 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ................ 0070 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ................ 0080 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ................ 0090 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ................ 00a0 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ................ 00b0 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ................ 00c0 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ................ 00d0 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ................ 00e0 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ................ 00f0 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ................ 0100 - 00 00 00 00 00 f7 - ...... Patch name: **** New Patch **** ________________________________ From: Peter Geirnaert <pet...@gm...> To: Michael Hawkins <kor...@ya...> Cc: JSynthLib Developers <Jsy...@li...> Sent: Tuesday, August 25, 2009 5:29:41 AM Subject: Re: [Jsynthlib-devel] Got something going but... Hmm, I forgot to "reply all", so Mike, sorry if you get this twice ;-) Anyway, I added some more thoughts .. On Tue, Aug 25, 2009 at 2:00 AM, Michael Hawkins <kor...@ya...> wrote: Hi JSynthLib fans, > >>Well, after hours (3 to be exact) of careful troubleshooting and tinkering, I was able to pull in a patch from my Korg Poly-800. > >>But as with most things in life, I now have more questions than I started with. I am hoping that someone who has more experience with JSynthLib than me can help me out. > >>To get the patch "get" and "paste" to work required that a) I set sysexID = "F0422106*"; this is the header for a patch dump coming from the Poly-800. and b) that I comment out sending a bank change in requestPatchDump. > >>The Poly-800 sends an acknowledgement sysex message after it receives a bank change. So the "Get" code seems to have choked on the 7 bytes that it receives just prior to receiving the patch sysex message itself. > >>So, I could just rewrite the sysex implementation on the Poly-800 so that it doesn't send an acknowledgment sysex message but that seems to be a bit of a cop out and especially so if there is a way that I could rewrite the requestPatchDump so that it would intercept that ack. message and ignore it instead of choking on it? Maybe you should to make the KorgHAWK800SingleDriver extends BankDriver, like I did with my SPD11PatchDriver , and use a 'bankChangeDriver' and 'K800SingleDriver', like I used a SPD11PadDriver and SPD11SettingsDriver. I'm not really understanding the difference between a singleDriver, bankDriver, converter I'm reading the programmer's guide again, and I'm wondering if a Single Patch really is a set of sysex messages like described there. I first thought a Single Patch would hold just one Single SysEx Message. Because a single patch of my drumsynth is composed of 32 sysexmessages describing each drumpad + 1 sysexmessage describing the effects and pedal settings. In your case a patch is 1 bank ack sysexmessage + a 262 bytes patch sysexmessage > >>Now, I don't want to be too pushy here because I like JSynthLib and I like the idea of an open source patch editor but hopefully someone on this list can answer a question or two because it has taken me hours to get this far and I have many more questions that need answering. Four hands do three times more work than two hands, I guess it's good to ask questions to many heads too, instead of keeping the questions for yourself. > >>Here is another question, the Poly-800 does not support patch names in its sysex implementation nor programming but does that stop me from using patch names in JSynthLib itself? Is it possible to save patch names outside of the sysex message but inside the patch when stored in JSynthLib? My drum kits are named numbers 1~64, and I'd like to give 'em names too, so I actually have the same question. I think maybe we should take a look at how e.g. the TD-6 driver stores settings for padInfo in the prefs file, it keeps info about if a pad is active or not, look at how it's done in RolandTD6Device (line 56 & 75). The same trick may work to keep patch names in a preferences.node("Name(s)") > >>Anyway, in advance, I would like to thank anyone that might provide me with some assistance. > >>If I don't hear anything from anybody, I may have to consider an alternative to JSynthLib because the learning curve might be just too steep while going at this completely alone. > >>Here's my singledriver below: > >>/* >> * @version $Id: KorgHAWK800SingleDriver.java 111 2009-08-20 04:05:40Z hawkins $ >> */ >>package synthdrivers.KorgHAWK800; > >>import core.Driver; >>import core.ErrorMsg; >>import core.JSLFrame; >>import core.Patch; >>import core.SysexHandler; > >>public class KorgHAWK800SingleDriver extends Driver >>{ >> private int curBank = 0, curPatch = 0; You don't use these variables anywhere ? > >> public KorgHAWK800SingleDriver() { >> super("Single", "Michael Hawkins"); >> sysexID = "F0422106*"; >> sysexRequestDump=new SysexHandler("F0 42 21 07 *patchNum* F7"); > >> patchSize=262; This is why it chokes on the first returned ack message >> deviceIDoffset=-1; > >> bankNumbers = new String[] { >> "0-Bank1", "1-Bank2","2-Bank3", "3-Bank4" >> }; >> // patch numbers use octal representation with no zeroes (11-88) >> patchNumbers=new String[] {"11","12","13","14","15","16","17","18", >> "21","22","23","24","25","26","27","28", >> "31","32","33","34","35","36","37","38", >> "41","42","43","44","45","46","47","48", >> "51","52","53","54","55","56","57","58", >> "61","62","63","64","65","66","67","68", >> "71","72","73","74","75","76","77","78", >> "81","82","83","84","85","86","87","88"}; >> } > >> public void setBankNum(int bankNum) >> { >> try { >> send(new byte[] { >> (byte)0xF0,(byte)0x42,(byte)0x21,(byte)0x0E, >> (byte)bankNum,(byte)0xF7 >> }); >> } catch (Exception e) {} >> } > >> public void requestPatchDump(int bankNum, int patchNum) { Maybe here add patchSize = SIZE_OF_ACK; //the number of bytes that comprise the returned ack message patchNameSize = 0; >> //setBankNum(bankNum); uncomment >> try {Thread.sleep(250); } catch (Exception e){} and now set patchSize = SIZE_OF_PATCH; //the number of bytes that comprise the returned patch message >> byte sysex[] = { >> (byte)0xF0, (byte) 0x42, (byte) 0x21, (byte) 0x07, (byte)patchNum, (byte) 0xF7 >> }; >> send(sysex); >> } > >> public void storePatch (Patch p, int bankNum,int patchNum) >> { >> setBankNum(bankNum); >> try {Thread.sleep(250); } catch (Exception e){} >> //patchNum=patchNum&0x3F; >> ((Patch)p).sysex[4]=(byte)patchNum; >> sendPatchWorker(p); >> setPatchNum(patchNum); >> } > >> public void sendPatch (Patch p) >> { >> byte [] newsysex = new byte[262]; >> System.arraycopy(((Patch)p).sysex,0,newsysex,0,262); >> newsysex[4] = (byte)(0x40); >> try { >> send(newsysex); >> }catch (Exception e) {ErrorMsg.reportStatus(e);} >> } > >> public Patch createNewPatch() >> { >> byte [] sysex = new byte[262]; >> sysex[0]=(byte)0xF0; sysex[1]=(byte)0x42; sysex[2]=(byte)0x21; >> sysex[3]=(byte)0x06; sysex[261]=(byte)0xF7; >> Patch p = new Patch(sysex, this); >> //setPatchName(p,"NewPatch"); >> calculateChecksum(p); >> return p; >> } > >>protected void calculateChecksum(Patch p,int start,int end,int ofs) >> { >> // no checksum >> } > >>//public JSLFrame editPatch(Patch p) { >>// return new KorgHAWK800SingleEditor((Patch)p); >>protected JSLFrame editPatch(Patch p) { >> return (new synthdrivers.Generic.HexDumpEditorFrame(p)); >> } > >>} > It would be easier to help if you added more //comments to explain what's happening and why. |
From: Michael H. <kor...@ya...> - 2009-08-25 11:54:56
|
Hi Daniel, 1) actually the three hours of tinkering was after the first 4 hours learning Eclipse another 4 hours fixing a broken Java installation and then another 12 hours or more getting JSynthLib working, reading the documentation and putting a basic device driver together. But I know what you mean and understand how much work is involved in programming. Nevertheless, I am sure you can understand my frustration when sending emails to a list that seems to be on a permanent European vacation! 2) I like the idea of JSynthLib for the purpose of a patch editor and librarian for my upgrade kit for the Poly-800 (www.hawk800.com). And since last night I was actually able to get, copy, paste and send to patches, I am still leaning toward using JSynthLib. 3) Those Europeans have a great life don't they. 4) No, the problem now is right inside JSynthLib. I worked out the issues with my classpath, JDK/SDK, launching Eclipse, etc. Now the problem lies directly with JSynthLib code itself. But I appreciate hearing your voice, even though it appears that you can't help me because you dumped JSynthLib in favor of going it alone! Nice product by the way. Cheers, Mike. |
From: Daniel R. <dr....@co...> - 2009-08-25 17:52:57
|
While it is true that millions of hours lost are sort of the way of things around here (my girlfriend's wireless connection just stopped working, unrelated but will waste a lot of time I'm sure), 4 hours to learn Eclipse are well spent in any case! I meant that your problems sounded like they were with the hawk800 communications, and not with the actual JSynthlib stuff. In any case, the beauty of open source is not that the code is there in case you need it. The beauty of open source is that, if the code is in a language you need, the shit support forces you to get into the code yourself. You will be a better person for it. Use Eclipse to debug in real time and watch the call stack do its thing. You will track down your problem, gain self esteem, and rule the world (after, that is). Sorry that I can't be more specific.... Best! Daniel > |