From: Joe E. <jo...@em...> - 2011-09-03 13:54:03
|
I think it would be a help if people could minimize changes to Actions.java for a little bit. It's one of the files that getting modified quite a bit in the re-factor, so I'm worried about how the merge is going to go with that... - Joe -------- Original Message -------- Subject: [Jsynthlib-cvs] SF.net SVN: jsynthlib:[1104] trunk/JSynthLib/core/Actions.java Date: Sat, 03 Sep 2011 12:46:24 +0000 From: fra...@us... To: jsy...@li... Revision: 1104 http://jsynthlib.svn.sourceforge.net/jsynthlib/?rev=1104&view=rev Author: frankster Date: 2011-09-03 12:46:23 +0000 (Sat, 03 Sep 2011) Log Message: ----------- add an accelerator for new patch: ctrl-shift-p (probably cmd-shift-p on a mac but not sure). so you can now do ctrl-l, ctrl-shift-p to create a new library then create a patch within the library Modified Paths: -------------- trunk/JSynthLib/core/Actions.java This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Special Offer -- Download ArcSight Logger for FREE! Finally, a world-class log management solution at an even better price-free! And you'll get a free "Love Thy Logs" t-shirt when you download Logger. Secure your free ArcSight Logger TODAY! http://p.sf.net/sfu/arcsisghtdev2dev _______________________________________________ Jsynthlib-cvs mailing list Jsy...@li... https://lists.sourceforge.net/lists/listinfo/jsynthlib-cvs |
From: frankster <jsy...@te...> - 2011-09-03 14:00:15
|
* which files are you planning to include in the refactor so I can avoid changing those files? * is it possible to submit the refactoring in several stages to that only a few files are off limits at a time? this depends how far you are through it I guess frankie On 09/03/11 14:53, Joe Emenaker wrote: > I think it would be a help if people could minimize changes to > Actions.java for a little bit. It's one of the files that getting > modified quite a bit in the re-factor, so I'm worried about how the > merge is going to go with that... > > - Joe > > -------- Original Message -------- > Subject: [Jsynthlib-cvs] SF.net SVN: jsynthlib:[1104] > trunk/JSynthLib/core/Actions.java > Date: Sat, 03 Sep 2011 12:46:24 +0000 > From: fra...@us... > To: jsy...@li... > > > > Revision: 1104 > http://jsynthlib.svn.sourceforge.net/jsynthlib/?rev=1104&view=rev > Author: frankster > Date: 2011-09-03 12:46:23 +0000 (Sat, 03 Sep 2011) > Log Message: > ----------- > add an accelerator for new patch: ctrl-shift-p (probably cmd-shift-p on a mac but not sure). > so you can now do ctrl-l, ctrl-shift-p to create a new library then create a patch within the library > > Modified Paths: > -------------- > trunk/JSynthLib/core/Actions.java > > This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. > > > ------------------------------------------------------------------------------ > Special Offer -- Download ArcSight Logger for FREE! > Finally, a world-class log management solution at an even better > price-free! And you'll get a free "Love Thy Logs" t-shirt when you > download Logger. Secure your free ArcSight Logger TODAY! > http://p.sf.net/sfu/arcsisghtdev2dev > _______________________________________________ > Jsynthlib-cvs mailing list > Jsy...@li... > https://lists.sourceforge.net/lists/listinfo/jsynthlib-cvs > > > ------------------------------------------------------------------------------ > Special Offer -- Download ArcSight Logger for FREE! > Finally, a world-class log management solution at an even better > price-free! And you'll get a free "Love Thy Logs" t-shirt when you > download Logger. Secure your free ArcSight Logger TODAY! > http://p.sf.net/sfu/arcsisghtdev2dev > _______________________________________________ > Jsynthlib-devel mailing list > Jsy...@li... > https://lists.sourceforge.net/lists/listinfo/jsynthlib-devel |
From: Joe E. <jo...@em...> - 2011-09-03 14:57:45
|
On 9/3/2011 6:59 AM, frankster wrote: > * which files are you planning to include in the refactor so I can avoid > changing those files? I've tracked down which revision I started the refactor on (it's from back in 2006... yeah, really), so now I'm doing a diff on all of the files to see what I've changed. So far, it's the big-picture window/desktop stuff. I don't think I've touched any of the widget stuff. I think I've also left the "action" parts of Action.java alone. By that, I mean... the stuff where each action has a unique ID and they register their place in the menus and their hot-keys and such. But those inner classes in Actions like Actions.MenuDesktop and Actions.MenuFrame, I'm pretty sure that's all been yanked to a dedicated set of UI classes... so that a class named "Actions" doesn't need to be importing BorderLayout and Dimension. I should have a concrete list for you in a day. - Joe |
From: frankster <jsy...@te...> - 2011-09-07 13:28:31
|
On 09/06/11 19:15, Joe Emenaker wrote: >> The TX81z seems to have a hardware limitation whereby an error message >> can appear on its screen talking about its midi message buffer being >> full. I am assuming this is because there needs to be some kind of rate >> limit on messages sent to it. > Oooh. A rate-limited "sendSysex()" or something could be a good addition. It might need to be a little more complicated than just sendSysex(), because I think the UI controls could send quite a lot of messages out if you changed them quite frequently. |
From: William Z. <wrz...@po...> - 2011-09-08 05:55:40
|
On Wed, Sep 7, 2011 at 6:28 AM, frankster <jsy...@te...>wrote: > On 09/06/11 19:15, Joe Emenaker wrote: > > Oooh. A rate-limited "sendSysex()" or something could be a good addition. > It might need to be a little more complicated than just sendSysex(), > because I think the UI controls could send quite a lot of messages out > if you changed them quite frequently. > I worry that for some synths, the rate limiting is synth-specific. Is there (or are you thinking of) a framework to plug rate limiting into? Or would we need to implement a layer on top of sendSysex()? As for UI controls, we definitely need a smart system for that. If the user drags a slider from 0 to 100, we don't want to send 100 updates, just the few we actually have time for. -Bill Zwicky |
From: William Z. <wrz...@po...> - 2011-09-08 10:02:23
|
On Thu, Sep 8, 2011 at 2:31 AM, frankster <jsy...@te...>wrote: > (just have each driver register a max amount per time frame it can handle). > What if the delay depends on the nature of the change? Maybe parameter changes are no problem, but those huge patch sets take a few seconds to digest. It might be possible to send a request that is only answered when the synth is done, or you might have to just set a 3 second timer and hope. The sender could then store the latest value received from the widget > for a parameter, then check with > this central rate tracker whether its allowed to send or not, and if its > not allowed to send then it stores > the widget value and requests notification from the central rate tracker > when it would be ok to send. > In the meantime if any additional widget events come in before the > notification, they can store their values > too. Finally the notification comes through from the central rate > tracker and it sends it. > > Its getting a bit complicated because maybe if two widgets were modified > in close succession we might > need a queue of notifications so that we don't miss out on one widget > update because it was drowned > out by another. > Yeah, that's pretty much it. When a parameter changes but we cannot send, we save the new value, and set a flag. When an opportunity to send arrives, we scan for those flags and send the first one we find. But even this may be synth-dependent -- if multiple params change, I may want to build a single message that updates them all at once. Can anyone think of anything simpler that would do the job? Although one > advantage of this is that it would > keep the driver simple, and all the complexity would be in core base > classes. > The only alternative I can think of is to defer the high-level layer, and instead try these tricks with individual synths. After that, we can hunt for commonalities, and implement a higher-level layer. -Bill Zwicky |
From: frankster <jsy...@te...> - 2011-09-08 11:22:37
|
On 09/08/11 11:01, William Zwicky wrote: > On Thu, Sep 8, 2011 at 2:31 AM, frankster<jsy...@te...>wrote: > >> (just have each driver register a max amount per time frame it can handle). >> > What if the delay depends on the nature of the change? Maybe parameter > changes are no problem, but those huge patch sets take a few seconds to > digest. It might be possible to send a request that is only answered when > the synth is done, or you might have to just set a 3 second timer and hope. Perhaps there are two classes of sysex/controller data to consider - bulk dump and real-time patch change - and they can't be handled the same. > > The sender could then store the latest value received from the widget >> for a parameter, then check with >> this central rate tracker whether its allowed to send or not, and if its >> not allowed to send then it stores >> the widget value and requests notification from the central rate tracker >> when it would be ok to send. >> In the meantime if any additional widget events come in before the >> notification, they can store their values >> too. Finally the notification comes through from the central rate >> tracker and it sends it. >> >> Its getting a bit complicated because maybe if two widgets were modified >> in close succession we might >> need a queue of notifications so that we don't miss out on one widget >> update because it was drowned >> out by another. >> > Yeah, that's pretty much it. When a parameter changes but we cannot send, > we save the new value, and set a flag. When an opportunity to send arrives, > we scan for those flags and send the first one we find. But even this may > be synth-dependent -- if multiple params change, I may want to build a > single message that updates them all at once. Maybe the synths Sender subclass could handle this if it gets a notification - check with the other sender instances and decide whether it wants to send 2 controller changes or re-dump the patch or whatever. > The only alternative I can think of is to defer the high-level layer, and > instead try these tricks with individual synths. After that, we can hunt > for commonalities, and implement a higher-level layer. > Yeah no point implementing a high level layer until the low level details are well understood by all involved - I probably haven't written enough drivers yet to be an expert on flow control issues. But its definitely worth having flow control in the back of our minds as we do other things. My current plan of action is: * M350 driver (nearly done) * U220 driver (if I can work out what the manual is on about) * Keystation Pro 88 driver * Proteus 2000 family driver - this is a big one Assuming I make it this far, then this might be the time when I would be ready to think about rate limiting. frankie |
From: Joe E. <jo...@em...> - 2011-09-08 15:16:32
|
On 9/8/2011 3:01 AM, William Zwicky wrote: > What if the delay depends on the nature of the change? Maybe parameter > changes are no problem, but those huge patch sets take a few seconds > to digest. It might be possible to send a request that is only > answered when the synth is done, or you might have to just set a 3 > second timer and hope. The sender could then store the latest value > received from the widget Now it's getting trickier. My initial thought is that something like this should be handled in the synthdriver, because it's not an issue in *transferring* the data over the MIDI wires. See what I'm saying? There's the limit that the synth has in how many bytes per second it can gobble from the wires (which would be managed by the MIDI layer) and then there's any extra time that the synth needs to digest the data once it has been received. That second category might be best managed in the synthdriver. > Yeah, that's pretty much it. When a parameter changes but we cannot send, > we save the new value, and set a flag. When an opportunity to send arrives, > we scan for those flags and send the first one we find. But even this may > be synth-dependent -- if multiple params change, I may want to build a > single message that updates them all at once. Well, in the idea that I posed in my previous post, the MIDI layer would just accept changes until it decided that the queue was full and, when it was full, it would just throw exceptions to the widgets. The widgets would have the option to tell the MIDI layer to purge all other queued messages from the widget, etc. However, if it's the case that some synths support sysex message which update multiple parameters at once, then I can see the rationale for letting the widgets inspect all of their queued messages and then trading them out of a consolidated one. I can't think of a slick way of preserving their place in the queue, though. They'd either go right to the front of the queue or to the end. - Joe |
From: Joe E. <jo...@em...> - 2011-09-08 14:22:32
|
On 9/7/2011 10:54 PM, William Zwicky wrote: > I worry that for some synths, the rate limiting is synth-specific. Is there > (or are you thinking of) a framework to plug rate limiting into? Or would > we need to implement a layer on top of sendSysex()? It has been a while since I worked on the raw MIDI subsystem. But this is what I was thinking: - It should be possible for individual synths to tell the MIDI layer their maximum speed. The MIDI layer probably knows what interface they're on (and could also know what synth they're sending a message on behalf of), so... if we're lucky, the speed would only be throttled for message to that specific synth. If we're not lucky, speed would be limited for that whole interface. - Even if we *are* lucky and can limit the speed based upon the synth, there should *also* be a way for a synth to ask that the entire interface be speed-limited. This would be in cases where, even though the sysex (or other MIDI) traffic is not *targeted* to the slow synth, the slow synth still locks up when it sees the traffic going by. - This would not be something we'd add to sendSysex(). We'd just add some new method in the MIDI layer for synthdrivers to ask for speed-limiting once and the MIDI layer would just honor that until it was asked for a new speed limit. > As for UI controls, we definitely need a smart system for that. If the user > drags a slider from 0 to 100, we don't want to send 100 updates, just the > few we actually have time for. Oh, wow... you're right. That's a dicey problem. We'd kinda want to either have the widget not send an update when the user is moving the widget *fast*, but then, when they got close, to start sending then... or maybe only send when they released the widget. Actually, we probably want the user to indicate how "eager" the widgets are with some setting in the control panel. - Joe |
From: frankster <jsy...@te...> - 2011-09-08 14:35:28
|
On 09/08/11 15:22, Joe Emenaker wrote: > On 9/7/2011 10:54 PM, William Zwicky wrote: >> I worry that for some synths, the rate limiting is synth-specific. Is there >> (or are you thinking of) a framework to plug rate limiting into? Or would >> we need to implement a layer on top of sendSysex()? > It has been a while since I worked on the raw MIDI subsystem. But this > is what I was thinking: > - It should be possible for individual synths to tell the MIDI layer > their maximum speed. The MIDI layer probably knows what interface > they're on (and could also know what synth they're sending a message on > behalf of), so... if we're lucky, the speed would only be throttled for > message to that specific synth. If we're not lucky, speed would be > limited for that whole interface. > - Even if we *are* lucky and can limit the speed based upon the synth, > there should *also* be a way for a synth to ask that the entire > interface be speed-limited. This would be in cases where, even though > the sysex (or other MIDI) traffic is not *targeted* to the slow synth, > the slow synth still locks up when it sees the traffic going by. Yeah it might turn out that a number of devices have to process all midi messages on the port regardless of who the message is addressed to. > - This would not be something we'd add to sendSysex(). We'd just add > some new method in the MIDI layer for synthdrivers to ask for > speed-limiting once and the MIDI layer would just honor that until it > was asked for a new speed limit. > >> As for UI controls, we definitely need a smart system for that. If the user >> drags a slider from 0 to 100, we don't want to send 100 updates, just the >> few we actually have time for. > Oh, wow... you're right. That's a dicey problem. We'd kinda want to > either have the widget not send an update when the user is moving the > widget *fast*, but then, when they got close, to start sending then... If this was a live performance system it would be a critical issue getting smooth fader slides etc, however its just a patch editor, so possibly something as basic as "no control may update more often than every 100ms" could work well enough for our purposes across many devices. > or maybe only send when they released the widget. Actually, we probably > want the user to indicate how "eager" the widgets are with some setting > in the control panel. > > - Joe > I don't know if this is something the user should have to fiddle with - ideally we should be able to work it out once for each device, register the setting with the midi layer, and then get it right in perpetuity. cheers, Frankie |
From: Joe E. <jo...@em...> - 2011-09-08 15:01:26
|
On 9/8/2011 2:31 AM, frankster wrote: > Can anyone think of anything simpler that would do the job? Although one > advantage of this is that it would > keep the driver simple, and all the complexity would be in core base > classes. I'm thinking this: - There should be a application-wide rate limit on how often widgets send updates when the user is moving them. This limit would be able to be set by the user. It would *always* send when the user releases the widget, but they could also ask for updates to be sent X times per second... or whenever the control has moved another X% of the entire range since the last send. - Widgets would be ignorant of any rate limit imposed by the individual synths. The MIDI layer would know about them, and it would queue up and throttle outbound messages. If the outgoing queue ever got too full (ie, we don't want the MIDI layer queuing up 30 seconds of widget updates), then it would throw some exception. The widgets would decide how to deal with the exception. They could just discard the latest update they wanted to send, or they could possibly tell the MIDI layer something like "Discard all of the pending updates from me that you've got queued, and just send this one". - Joe |
From: frankster <jsy...@te...> - 2011-09-08 15:13:43
|
On 09/08/11 16:01, Joe Emenaker wrote: > On 9/8/2011 2:31 AM, frankster wrote: >> Can anyone think of anything simpler that would do the job? Although one >> advantage of this is that it would >> keep the driver simple, and all the complexity would be in core base >> classes. > I'm thinking this: > - There should be a application-wide rate limit on how often widgets > send updates when the user is moving them. This limit would be able to > be set by the user. It would *always* send when the user releases the > widget, but they could also ask for updates to be sent X times per > second... or whenever the control has moved another X% of the entire > range since the last send. This sounds reasonable. > - Widgets would be ignorant of any rate limit imposed by the individual > synths. The MIDI layer would know about them, and it would queue up and This is a sensible division of responsibility I think. > throttle outbound messages. If the outgoing queue ever got too full (ie, > we don't want the MIDI layer queuing up 30 seconds of widget updates), > then it would throw some exception. The widgets would decide how to deal > with the exception. They could just discard the latest update they > wanted to send, or they could possibly tell the MIDI layer something > like "Discard all of the pending updates from me that you've got queued, > and just send this one". What about if the midi layer will never queue more than 1 message from a particular widget (so the midi layer would have to track the source of each message) and if multiple messages appeared from the same widget's Sender class, it would discard all but the most recent. This would mean that widget messages have to be stateless and interchangeable. Is this a reasonable condition? It is on the synths/drivers i've played with but I can't speak for most of them. frankie |
From: Joe E. <jo...@em...> - 2011-09-08 15:55:04
|
On 9/8/2011 8:13 AM, frankster wrote: > What about if the midi layer will never queue more than 1 message from > a particular widget (so the midi layer would have to track the source > of each message) and if multiple messages appeared from the same > widget's Sender class, it would discard all but the most recent. This strikes me as a great way to do it. We could even do it without the widget losing its place in the queue. We could just replace the old message with the new one. I'm not troubled by the fact that the midi layer would need to track the source. That seems like we could do some handy things with that kind of info down the road. > This would mean that widget messages have to be stateless and > interchangeable. Is this a reasonable condition? It is on the > synths/drivers i've played with but I can't speak for most of them. We could let each synthdriver decide their own queue policy (ie, only hold one message per widget, or hold all of them). A more-complicated solution would be for widgets to indicate which messages belong as a set... but I don't see a need for that. - Joe |
From: William Z. <wrz...@po...> - 2011-09-09 08:57:44
|
On Thu, Sep 8, 2011 at 8:54 AM, Joe Emenaker <jo...@em...> wrote: > On 9/8/2011 8:13 AM, frankster wrote: > > What about if the midi layer will never queue more than 1 message from > > a particular widget (so the midi layer would have to track the source > > of each message) and if multiple messages appeared from the same > > widget's Sender class, it would discard all but the most recent. > > This strikes me as a great way to do it. We could even do it without the > widget losing its place in the queue. We could just replace the old > message with the new one. > That actually sounds pretty decent. But what if my synth won't tolerate a queue? i.e. Maybe I need to strictly control the ordering of messages, or maybe the synth won't accept the second message until the first message has properly completed all handshaking. We could let each synthdriver decide their own queue policy (ie, only > hold one message per widget, or hold all of them). A more-complicated > solution would be for widgets to indicate which messages belong as a > set... but I don't see a need for that. > I think my example above matches that last case. Once the message for widget A has started sending, other messages can be queued, but they can't be sent until widget A says 'handshake complete'! Maybe we need lockSynth() and unlockSynth() to block the queue until some code is complete. And if the synth is really flaky, lockBus() and unlockBus() to prevent other messages from confusing the synth. Speaking of lockBus(), I believe this only needs to block transmission to synths downstream (i.e. farther from the computer) from the flaky synth, as upstream synths will not pass thru messages targeted at themselves. Are there any synths that pass thru all their own messages? Do we need an API to flag synths that behave in non-standard ways? Finally, I'd like to vote against the user rate-limit option that was proposed earlier. Rate limiting is not a real feature, it's a workaround to cope with flaky synths. And these workarounds should be properly researched and coded in the driver so that the user doesn't need to worry about it at all. It *might* be useful as an emergency feature to cope with situations the developer didn't discover, but it should *not* be part of the normal operation of JSynthLib. -Bill Zwicky |
From: Joe E. <jo...@em...> - 2011-09-09 14:03:32
|
On 9/9/2011 1:56 AM, William Zwicky wrote: > We could let each synthdriver decide their own queue policy (ie, only >> hold one message per widget, or hold all of them). A more-complicated >> solution would be for widgets to indicate which messages belong as a >> set... but I don't see a need for that. >> > I think my example above matches that last case. Once the message for > widget A has started sending, other messages can be queued, but they can't > be sent until widget A says 'handshake complete'! My initial reaction to this is that this isn't an issue with the rate of data sent by the MIDI layer, so the MIDI layer shouldn't be involved. I'm thinking that the synthdriver should be able to manage all of this itself. The only reason we'd need to trouble the MIDI layer with this is if your synthdriver either needed special transfer-rate limits *or* if your synthdriver needed to block all traffic for *other* synths on that interface while the communication were happening. Otherwise, this should be able to be managed by the synthdriver. > Finally, I'd like to vote against the user rate-limit option that was > proposed earlier. Rate limiting is not a real feature, it's a workaround to > cope with flaky synths. And these workarounds should be properly researched > and coded in the driver so that the user doesn't need to worry about it at > all. It *might* be useful as an emergency feature to cope with situations > the developer didn't discover, but it should *not* be part of the normal > operation of JSynthLib. Okay... just so we're clear, you're referring to *user* rate-limit. The idea of the end user being able to determine how often widgets send updates to the synth, right? But raw data throughput limiting in the MIDI layer is still a useful feature? - Joe |
From: frankster <jsy...@te...> - 2011-09-09 14:18:10
|
On 09/09/11 15:03, Joe Emenaker wrote: > On 9/9/2011 1:56 AM, William Zwicky wrote: >> We could let each synthdriver decide their own queue policy (ie, only >>> hold one message per widget, or hold all of them). A more-complicated >>> solution would be for widgets to indicate which messages belong as a >>> set... but I don't see a need for that. >>> >> I think my example above matches that last case. Once the message for >> widget A has started sending, other messages can be queued, but they can't >> be sent until widget A says 'handshake complete'! > My initial reaction to this is that this isn't an issue with the rate of > data sent by the MIDI layer, so the MIDI layer shouldn't be involved. > I'm thinking that the synthdriver should be able to manage all of this > itself. The only reason we'd need to trouble the MIDI layer with this is > if your synthdriver either needed special transfer-rate limits *or* if > your synthdriver needed to block all traffic for *other* synths on that > interface while the communication were happening. Otherwise, this should > be able to be managed by the synthdriver. I think it does concern the midi layer because transmitting data to one synth could overload a different synth on the same port. Although we can expect a synth driver to know how much traffic its device can handle, we can't expect a synth driver to care or know about other synths. So it could make sense for the midi layer to have the ability to enforce the lowest common denominator throughput if required. I would think drivers would need to be able to specify a maximum number of bytes to occur in a specified timeframe. But maybe for a driver the problems occur only while processing large sysex messages, in which case maybe it would need to lock its port for e.g. 30ms after sending a message. frankie |
From: Joe E. <jo...@em...> - 2011-09-09 14:40:39
|
On 9/9/2011 7:17 AM, frankster wrote: > On 09/09/11 15:03, Joe Emenaker wrote: >> On 9/9/2011 1:56 AM, William Zwicky wrote: >>> I think my example above matches that last case. Once the message >>> for widget A has started sending, other messages can be queued, but >>> they can't be sent until widget A says 'handshake complete'! >> My initial reaction to this is that this isn't an issue with the rate of >> data sent by the MIDI layer, so the MIDI layer shouldn't be involved. >> I'm thinking that the synthdriver should be able to manage all of this >> itself. The only reason we'd need to trouble the MIDI layer with this is >> if your synthdriver either needed special transfer-rate limits *or* if >> your synthdriver needed to block all traffic for *other* synths on that >> interface while the communication were happening. Otherwise, this should >> be able to be managed by the synthdriver. > I think it does concern the midi layer because transmitting data to one > synth could overload a different synth on the same port. Although we can > expect a synth driver to know how much traffic its device can handle, we > can't expect a synth driver to care or know about other synths. Well, that's a different case (but it's one that we've still discussed, and I think there does need to be a way for a synthdriver to tell the MIDI layer "I can't handle more than X bytes per second... no matter *what* synth it's for, so don't let any data onto the wires faster than that"). What *Bill* seems to be referring to is that there seems to be a synth which requires an orchestrated series of messages for updating synth settings. For example: Where I imagine most synths use self-contained messages, like: Msg: Update parameter 27 to value 10 Msg: Update parameter 27 to value 12 Msg: Update parameter 27 to value 14 Bill seems to have a synth which requires something like: Msg: Begin messing with parameter 27 Msg: Set parameter to value 10 Msg: Set parameter to value 12 Msg: Set parameter to value 14 Msg: Done messing with parameter 27 You can see how things would get messed up if there was a second "begin" message before the "end" message for the first. So, my point was that this kind of awareness of the *context* (not the data-rate) of the messages is probably best kept in the synthdrivers. - Joe |
From: frankster <jsy...@te...> - 2011-09-10 14:15:49
|
On 09/09/11 15:40, Joe Emenaker wrote: > On 9/9/2011 7:17 AM, frankster wrote: >> On 09/09/11 15:03, Joe Emenaker wrote: >>> On 9/9/2011 1:56 AM, William Zwicky wrote: >>>> I think my example above matches that last case. Once the message >>>> for widget A has started sending, other messages can be queued, but >>>> they can't be sent until widget A says 'handshake complete'! >>> My initial reaction to this is that this isn't an issue with the rate of >>> data sent by the MIDI layer, so the MIDI layer shouldn't be involved. >>> I'm thinking that the synthdriver should be able to manage all of this >>> itself. The only reason we'd need to trouble the MIDI layer with this is >>> if your synthdriver either needed special transfer-rate limits *or* if >>> your synthdriver needed to block all traffic for *other* synths on that >>> interface while the communication were happening. Otherwise, this should >>> be able to be managed by the synthdriver. >> I think it does concern the midi layer because transmitting data to one >> synth could overload a different synth on the same port. Although we can >> expect a synth driver to know how much traffic its device can handle, we >> can't expect a synth driver to care or know about other synths. > Well, that's a different case (but it's one that we've still discussed, > and I think there does need to be a way for a synthdriver to tell the > MIDI layer "I can't handle more than X bytes per second... no matter > *what* synth it's for, so don't let any data onto the wires faster than > that"). What *Bill* seems to be referring to is that there seems to be a > synth which requires an orchestrated series of messages for updating > synth settings. For example: > > Where I imagine most synths use self-contained messages, like: > Msg: Update parameter 27 to value 10 > Msg: Update parameter 27 to value 12 > Msg: Update parameter 27 to value 14 > > Bill seems to have a synth which requires something like: > > Msg: Begin messing with parameter 27 > Msg: Set parameter to value 10 > Msg: Set parameter to value 12 > Msg: Set parameter to value 14 > Msg: Done messing with parameter 27 > > You can see how things would get messed up if there was a second "begin" > message before the "end" message for the first. > > So, my point was that this kind of awareness of the *context* (not the > data-rate) of the messages is probably best kept in the synthdrivers. > ah ok i was getting confused with the other situation frankie |
From: frankster <jsy...@te...> - 2011-09-04 21:08:51
|
On 03/09/2011 15:57, Joe Emenaker wrote: > On 9/3/2011 6:59 AM, frankster wrote: >> * which files are you planning to include in the refactor so I can avoid >> changing those files? > I've tracked down which revision I started the refactor on (it's from > back in 2006... yeah, really), so now I'm doing a diff on all of the > files to see what I've changed. Must be some kind of world record! > So far, it's the big-picture window/desktop stuff. I don't think I've > touched any of the widget stuff. I think I've also left the "action" > parts of Action.java alone. By that, I mean... the stuff where each > action has a unique ID and they register their place in the menus and > their hot-keys and such. But those inner classes in Actions like > Actions.MenuDesktop and Actions.MenuFrame, I'm pretty sure that's all > been yanked to a dedicated set of UI classes... so that a class named > "Actions" doesn't need to be importing BorderLayout and Dimension. > > I should have a concrete list for you in a day. I'm also planning on making it so that when you right click on an empty part of the background of a library or scene, it will pop up a "new patch" menu. It sounds from what you said like I will be able to do this without interfering with your refactoring. But I will hold off until I hear back from you. regards, Frankie |
From: Joe E. <jo...@em...> - 2011-09-04 22:33:31
|
On 09/04/2011 02:08 PM, frankster wrote: > On 03/09/2011 15:57, Joe Emenaker wrote: >> On 9/3/2011 6:59 AM, frankster wrote: >>> * which files are you planning to include in the refactor so I can avoid >>> changing those files? >> I've tracked down which revision I started the refactor on (it's from >> back in 2006... yeah, really), so now I'm doing a diff on all of the >> files to see what I've changed. > Must be some kind of world record! For procrastination? :-O Okay, here's a sort-of list. What I did was run diff on every file from revision 1051 to compare it to my refactoring code and then I ran each diff into a line-counter so that I could see what files have changed the most... 308 JSynthLib.1051/JSynthLib/core/MidiUtil.java 224 JSynthLib.1051/JSynthLib/core/Actions.java 74 JSynthLib.1051/JSynthLib/core/SysexGetDialog.java 74 JSynthLib.1051/JSynthLib/core/DriverUtil.java 60 JSynthLib.1051/JSynthLib/core/AbstractLibraryFrame.java 53 JSynthLib.1051/JSynthLib/midiprovider/OSX/CAProvider/CAMIDISource.java 38 JSynthLib.1051/JSynthLib/core/Scene.java 36 JSynthLib.1051/JSynthLib/core/DevDrvPatchSelector.java 32 JSynthLib.1051/JSynthLib/core/BankEditorFrame.java 28 JSynthLib.1051/JSynthLib/core/PatchEdit.java 23 JSynthLib.1051/JSynthLib/core/PatchEditorFrame.java 12 JSynthLib.1051/JSynthLib/org/jsynthlib/editorbuilder/EditorBuilder.java 8 JSynthLib.1051/JSynthLib/JSynthLib.java 8 JSynthLib.1051/JSynthLib/core/ErrorMsg.java I'm a little surprised that so few lines have been altered. I'm also surprised that MidiUtil is the top of the list, but I just looked at my copy and I now remember that I've made the whole thing its own process thread which dispatches MIDI messages to the appropriate driver, etc. After that, Actions is the class that has been modified pretty heavily. - Joe |
From: frankster <jsy...@te...> - 2011-09-04 23:18:01
|
On 04/09/2011 23:33, Joe Emenaker wrote: > On 09/04/2011 02:08 PM, frankster wrote: >> On 03/09/2011 15:57, Joe Emenaker wrote: >>> On 9/3/2011 6:59 AM, frankster wrote: >>>> * which files are you planning to include in the refactor so I can avoid >>>> changing those files? >>> I've tracked down which revision I started the refactor on (it's from >>> back in 2006... yeah, really), so now I'm doing a diff on all of the >>> files to see what I've changed. >> Must be some kind of world record! > For procrastination? :-O Getting in the record books is an achievement regardless of the method, right? ;) > > Okay, here's a sort-of list. What I did was run diff on every file from > revision 1051 to compare it to my refactoring code and then I ran each > diff into a line-counter so that I could see what files have changed the > most... > > 308 JSynthLib.1051/JSynthLib/core/MidiUtil.java > 224 JSynthLib.1051/JSynthLib/core/Actions.java > 74 JSynthLib.1051/JSynthLib/core/SysexGetDialog.java > 74 JSynthLib.1051/JSynthLib/core/DriverUtil.java > 60 JSynthLib.1051/JSynthLib/core/AbstractLibraryFrame.java > 53 JSynthLib.1051/JSynthLib/midiprovider/OSX/CAProvider/CAMIDISource.java > 38 JSynthLib.1051/JSynthLib/core/Scene.java > 36 JSynthLib.1051/JSynthLib/core/DevDrvPatchSelector.java > 32 JSynthLib.1051/JSynthLib/core/BankEditorFrame.java > 28 JSynthLib.1051/JSynthLib/core/PatchEdit.java > 23 JSynthLib.1051/JSynthLib/core/PatchEditorFrame.java > 12 JSynthLib.1051/JSynthLib/org/jsynthlib/editorbuilder/EditorBuilder.java > 8 JSynthLib.1051/JSynthLib/JSynthLib.java > 8 JSynthLib.1051/JSynthLib/core/ErrorMsg.java > > Thanks for the list. Probably best if I stay away from Actions.java after all as its such a big one. cheers, frankie |
From: frankster <jsy...@te...> - 2011-09-06 17:44:19
|
On 04/09/2011 23:33, Joe Emenaker wrote: > 308 JSynthLib.1051/JSynthLib/core/MidiUtil.java > > > I'm a little surprised that so few lines have been altered. I'm also > surprised that MidiUtil is the top of the list, but I just looked at my > copy and I now remember that I've made the whole thing its own process > thread which dispatches MIDI messages to the appropriate driver, etc. > Is this thread separation only for receiving messages, or is it also for sending messages? Both the current TX81Z driver and my planned Proteus 2000 series driver look like they may need some kind of asynchronous sending mechanism so I've been thinking of how best to achieve this. The TX81z seems to have a hardware limitation whereby an error message can appear on its screen talking about its midi message buffer being full. I am assuming this is because there needs to be some kind of rate limit on messages sent to it. The Proteus 2000 seems to have very long single patch dumps - 2k+! The Proteus 2000 provides 2 transfer mechanisms - one where you just send it blind, and another where there is some handshaking. So the Proteus driver could just send the patches in the blind method, which might be ok for 1 patch, but I shudder to think about sending an entire bank of patches that way without flow control! So to do a good job on the driver I think it will need to support handshaking. While I could imagine implementing the TX81z flow control as a generic mechanism that could apply to various drivers (a simple setting each could set), the P2k handshaking protocol maybe doesn't lend itself to a generic implementation. I wonder if there are any other drivers that use some kind of flow control or rate limitation mechanism (beyond freezing the UI for a few ms! ). frankie |
From: Joe E. <jo...@em...> - 2011-09-06 18:15:59
|
On 9/6/2011 10:44 AM, frankster wrote: > On 04/09/2011 23:33, Joe Emenaker wrote: >> I'm a little surprised that so few lines have been altered. I'm also >> surprised that MidiUtil is the top of the list, but I just looked at my >> copy and I now remember that I've made the whole thing its own process >> thread which dispatches MIDI messages to the appropriate driver, etc. > Is this thread separation only for receiving messages, or is it also for > sending messages? Well, sending doesn't really need to be threaded, but I guess it *can* be to guard against UI pauses during sending of long SYSEX stuff. Looking at my copy of MidiUtil, it looks like what I did was make a thread which listens on all of the incoming MIDI interfaces for incoming stuff and it handles the problem of re-assembling multi-part SYSEX by itself. Only when it has a complete SYSEX message does it give it to any of the "observers". I think I set it up kind of like how Java Swing does UI notifications with "listeners" being able to sign up for notification when things happen. > The TX81z seems to have a hardware limitation whereby an error message > can appear on its screen talking about its midi message buffer being > full. I am assuming this is because there needs to be some kind of rate > limit on messages sent to it. Oooh. A rate-limited "sendSysex()" or something could be a good addition. > The Proteus 2000 seems to have very long single patch dumps - 2k+! The > Proteus 2000 provides 2 transfer mechanisms - one where you just send > it blind, and another where there is some handshaking. So the Proteus > driver could just send the patches in the blind method, which might be > ok for 1 patch, but I shudder to think about sending an entire bank of > patches that way without flow control! So to do a good job on the driver > I think it will need to support handshaking. Well, you could send one patch (or piece), and then wait for notification from MidiUtil about it transferring okay, and then send the next piece, etc. We may have to brainstorm on this one a bit. - Joe |
From: frankster <jsy...@te...> - 2011-09-08 09:31:54
|
On 08/09/2011 06:54, William Zwicky wrote: > On Wed, Sep 7, 2011 at 6:28 AM, frankster <jsy...@te...>wrote: > >> On 09/06/11 19:15, Joe Emenaker wrote: >>> Oooh. A rate-limited "sendSysex()" or something could be a good addition. >> It might need to be a little more complicated than just sendSysex(), >> because I think the UI controls could send quite a lot of messages out >> if you changed them quite frequently. >> > I worry that for some synths, the rate limiting is synth-specific. Is there > (or are you thinking of) a framework to plug rate limiting into? Or would > we need to implement a layer on top of sendSysex()? Maybe the Sender base class that we already use with the widgets can do this for us without having to write plugins (just have each driver register a max amount per time frame it can handle). For example if we have something centrally tracking the rate of data that has recently been sent to a device or a midi port (and each driver can register how much data in what time frame its device can handle), The sender could then store the latest value received from the widget for a parameter, then check with this central rate tracker whether its allowed to send or not, and if its not allowed to send then it stores the widget value and requests notification from the central rate tracker when it would be ok to send. In the meantime if any additional widget events come in before the notification, they can store their values too. Finally the notification comes through from the central rate tracker and it sends it. Its getting a bit complicated because maybe if two widgets were modified in close succession we might need a queue of notifications so that we don't miss out on one widget update because it was drowned out by another. Can anyone think of anything simpler that would do the job? Although one advantage of this is that it would keep the driver simple, and all the complexity would be in core base classes. > > As for UI controls, we definitely need a smart system for that. If the user > drags a slider from 0 to 100, we don't want to send 100 updates, just the > few we actually have time for. yeah my tx81z definitely can't handle all these ui events and I don't think the TC M350 can either even though its much more modern. ;) Should have the driver ready for this later tonight actually frankie |
From: Vladimir A. <vl...@gm...> - 2011-09-08 15:27:46
|
On 09/08/2011 04:31 AM, frankster wrote: > Can anyone think of anything simpler that would do the job? Although one > advantage of this is that it would > keep the driver simple, and all the complexity would be in core base > classes. > Well, i can think of something more complicated, but maybe more universal. So the idea is that synth driver would register with core each kind of midi message it is going to send. During registration it specifies max rate or processing time for each message. Also it specifies the type - only last message of the kind shall be sent, or all queued messages of the kind shall be sent. Also maybe priority with respect to other messages. Then the drivers submit messages for sending to core in any order at any rate. The core maintain the queues for each registered kind of message. When the interface is available, the core selects among the queues next message, send it and blocks the sending for time specified at registration. -- Vladimir |