Title: A perfectly useless plugin :) Post by: sciurius on January 04, 2019, 07:18:21 AM However, it may be handy at times...
Plugin Ignore // Normal @Ignore Whatever is here // Track Bass @Ignore Whatever is here // Block Begin @Ignore 1 the quick brown fox 2 jumps over the lazy dog End Title: Re: A perfectly useless plugin :) Post by: bvdp on January 04, 2019, 04:16:24 PM An interesting way to out-comment a section of code. :)
You do know that you can get the same with Begin Comment Cm ... .. End Title: Re: A perfectly useless plugin :) Post by: sciurius on January 04, 2019, 09:37:55 PM Sure... I told you it was useless ;D
Title: Re: A perfectly useless plugin :) Post by: sciurius on April 21, 2020, 01:15:12 PM Revamping an old thread...
I have a plugin that turns a string like "|3-3-3-3-|3-1-3-1-|" into "Sequence { 1 0 90; 2 0 90; 3 0 90; 4 0 90 } { 1 0 90; 2 0 30; 3 0 90; 4 0 30 }" I can now use it as follows: Code: SeqSize 4 Neat. But I also want to use it like this: Drum-Snare @rhythm "|3-3-3-3-|3-1-3-1-|" A quick hack to parse.py can solve this: Code: *** parse.py~ 2020-03-27 10:04:06.211477746 +0100 This dedupes a duplicate track name at the start of a command. What do you think? Are there situations were a track command can be identical to the track name? Alternatively, I can abuse beginPoints/beginData in the plugin code to detect whether I'm in a Begin/End construct... Title: Re: A perfectly useless plugin :) Post by: bvdp on April 21, 2020, 04:55:06 PM I think that track commands and names will always be different.
Currently (correct me if I'm wrong ... I'm into building things with wood mode right now) you cannot strip out the leading command from a line inside the begin/end block. I recall having some problems with this when using COPY ... my my solution was to have mung in a COPY FROM and COPY TO variant. Is this the same thing you're running into here? I'm assuming that your plugin returns something like "Sequence ...." and inside a begin/end loop this works since the plugin is evaluated first and its output is appended to the Begin stuff. But, in the 2nd example it'll barf ... unlike a macro. Matter of where the MMA code is being evaluated ... macros at the top (before looking for command), and the opposite for plugins. We look at plugins as new (user added) commands, so this makes sense. Perhaps, a better solution would be to make the stuff in the line BEFORE the @plugin request available to the plugin? In this case, in a Begin/End there would be a null. In your 2nd call there would be "drum-snare". Would this be as simple as duplicating the result of Code: l = macros.expand(curline available at a module level (perhaps as "gbl.parse.currentLine") which could then be read by the plugin? Might give plugins a lot more power this way! Would this solve the other issue we were discussing for multi line defines using a plugin? I don't think so ... Title: Re: A perfectly useless plugin :) Post by: sciurius on April 21, 2020, 08:13:44 PM I think that track commands and names will always be different. Good. Quote Currently ... you cannot strip out the leading command from a line inside the begin/end block. That seems to be my experience as well. That's why I'm trying different approaches. Quote I'm assuming that your plugin returns something like "Sequence ...." and inside a begin/end loop this works since the plugin is evaluated first and its output is appended to the Begin stuff. But, in the 2nd example it'll barf ... Let's start with the easy case: Drum-Snare @rhythm ... This calls the trackRun() method and passes track = 'Drum-Snare' and line = ... . It pushes back the command line 'Drum-Snare Sequence {...}'. Ok. Now the begin/end case: Begin Drum-Snare @rhythm ... End This is expanded to Drum-Snare @rhythm .... Again, the trackRun() method is called, it pushes back 'Drum-Snare Sequence {...}'. Then MMA processes the pushed-back line. First it adds the begin stuff, so the actual line becomes Drum-Snare Drum-Snare Sequence {...} And oops. What I do now is that in the plugin I inspect parse.beginData. If it has a value and is equal to the 'track' argument the plugin returns the command line without prepending the 'track' argument and everybody is happy again. Quote Perhaps, a better solution would be to make the stuff in the line BEFORE the @plugin request available to the plugin? In this case, in a Begin/End there would be a null. In your 2nd call there would be "drum-snare". Isn't this what parse.beginData is? Although I must admit that a formally defined parse method to access its content would be nice. Quote Might give plugins a lot more power this way! Jay! Even more power! Current state of the plugin (with un-modified MMA): @rhythm Groove, Seq, Bpm=4, Level=9, RTime=0, RVolume=0, Clear=0, SeqSize=0, Debug=0 This defines a groove according to the seq, with optional values for RTime etc. For example: @rhythm G1, Debug=1, Level=3, Clear=1, RTime=3, RVolume=2, \ Seq=SnareDrum1 |-3-2| KickDrum1 |3-3-| This is identical to: Code: SeqClear Note about Seq : Space separated pairs of instrument and sequence data. Instrument can be one of the MMA built-in percussion tones, or a decimal number between 1 and 16. In the latter case Zoom compliant names for tracks and tones are used. Note about Level: This indicates the maximum volume level in the sequence. Normally volumes are 0..9, corresponding to silent..90. Zoom tabs use volumes 0,1,2,3, so with level=3 these become volumes 0,30,60,90. As a track plugin: Track @rhythm Seq, Bpm=4, Level=9, Debug=0 or Begin Track @rhythm Seq, Bpm=4, Level=9, Debug=0 End For example: Drum-Snare @rhythm |9-9-6-9-|9-6-9--9| is identical to: Drum-Snare Sequence { 1 0 90; 2 0 90; 3 0 60; 4 0 90 } { 1 0 90; 2 0 60; 3 0 90; 4.5 0 90 } As for the sequences: a sequence consists of one or more bars separated by vertical bars. Each bar is divided into equal divisions, corresponding to the number of characters in the bar. Each division has either a decimal number indicating that the instrument must sound, or a '-' to do nothing. Special bars are: || repeat the previous bar. If this is the first, use a silent bar. |-| a silent bar |*| use the currently defined sequence Sounds interesting? Title: Re: A perfectly useless plugin :) Post by: bvdp on April 21, 2020, 09:12:28 PM You'll need to change the subject of this ... not useless at all! Exactly what plugins are designed for :)
I think you are right about using parse.beginData[] in your plugin. It'll be up-to-date no matter how many levels of begin/end there are. The current line will not ... silly me ... I'm trying to make things more complicated :) So, it's all working then with MMA code as is? Love to hear the resulting patterns ... as good in MMA as on the Zoom? Title: Re: A perfectly useless plugin :) Post by: sciurius on April 22, 2020, 06:53:36 PM Love to hear the resulting patterns ... as good in MMA as on the Zoom? The Zoom is a bit limited. It has nice sounds for 16 instruments but plays like a real computer. It produces audio only. MMA can add some liveliness with RTime/RVolume, and the generated MIDI can be played using many soundfonts. There are very good soundfonts for drumsets. Title: Re: A perfectly useless plugin :) Post by: sciurius on April 23, 2020, 02:33:57 PM BTW, did you know:
If a plugin (or some other module) does: Code: from MMA.parse import beginData This works. Once. After the first END, beginData keeps its old value and never changes again. The reason is, apparently, the above import returns the dict item 'beginData' from parse.py. When a BEGIN is processed, the begin stuff is appended to beginData. This is seen in the other modules. However, after processing END, parse.py does: Code: beginData = beginData[:beginPoints.pop(-1)] This effectively creates a new dict item, discarding the old one. No problem, except that the other modules keep looking at the old item. The following is failsafe: Code: from MMA import parse Title: Re: A perfectly useless plugin :) Post by: bvdp on April 23, 2020, 04:36:06 PM I think this is just how python works. Read up on mutable and immutable for gory details.
However, I would not be importing a specific item like this. Just import the module and then you module can treat it "normally". Methinks you are getting too fancy :) Title: Re: A perfectly useless plugin :) Post by: sciurius on April 23, 2020, 05:22:06 PM In this particular case best would be a formal access method in parse.py, e.g. something similar to:
Code: def in_block(): |