<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Recent changes to Home</title><link>https://sourceforge.net/p/midgen/wiki/Home/</link><description>Recent changes to Home</description><atom:link href="https://sourceforge.net/p/midgen/wiki/Home/feed" rel="self"/><language>en</language><lastBuildDate>Sun, 30 May 2021 13:43:51 -0000</lastBuildDate><atom:link href="https://sourceforge.net/p/midgen/wiki/Home/feed" rel="self" type="application/rss+xml"/><item><title>Home modified by Bert Mueller</title><link>https://sourceforge.net/p/midgen/wiki/Home/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v38
+++ v39
@@ -77,9 +77,18 @@
 ### top level modules

 - MidGen.pl - top level framework entry point
-- MIDI.pm - basic smf input/output module (contains general smf read/write/event functions)
+- MIDI.pm - basic smf input/output module (contains general smf read/write and event-insert functions)
 - MidiDebug.pm - not necessarily required, but contains additional track and event list output functions
-- Edit.pm - contains general smf editor functions such as micro-sequencer, step-sequencer, copy/paste, fade-in/out, portamento, etc.
+- Edit.pm - contains general smf editor functions such as
+  - micro-sequencer
+  - step-sequencer
+  - copy/paste tracks, regions, etc.
+  - quantize tracks (note timestamps, durations)
+  - fade-in/out single tracks or entire songs
+  - portamento
+  - randomize (humanize) timestamps, durations, note on/off velocities
+
+and much more.

 ### Devices

&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Bert Mueller</dc:creator><pubDate>Sun, 30 May 2021 13:43:51 -0000</pubDate><guid>https://sourceforge.net2fe46dd51c82c08357d08f37909753add50afcea</guid></item><item><title>Home modified by Bert Mueller</title><link>https://sourceforge.net/p/midgen/wiki/Home/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v37
+++ v38
@@ -440,6 +440,20 @@
 Example: demonstrating different velocities and stretching notes.

 &lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img26.png" style=""/&gt;
+
+## portamento
+
+The Edit::Portamento() function emulates portamento functionality by collapsing monotonic melody tracks into single note pitch tracks with fixed keys while the pitches are provided by pitch bend events.
+
+`&amp;lt;pitch-bend-sensitivity&amp;gt; = Edit::Portamento(&amp;lt;smf-hash-pointer&amp;gt;, &amp;lt;track&amp;gt;, &amp;lt;portamento-time&amp;gt;);`
+
+- `&amp;lt;smf-hash-pointer&amp;gt;` - smf hash pointer handle
+- `&amp;lt;track&amp;gt;` - selected track
+- `&amp;lt;portamento-time&amp;gt;` - gliding time
+
+The function returns the required pitch bend sensitivity which must be inserted in the very beginning of the track, else the sequence will sound off.
+
+&lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img29.png" style=""/&gt;

 eof

&amp;lt;/portamento-time&amp;gt;&amp;lt;/smf-hash-pointer&amp;gt;&amp;lt;/portamento-time&amp;gt;&amp;lt;/smf-hash-pointer&amp;gt;&amp;lt;/pitch-bend-sensitivity&amp;gt;&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Bert Mueller</dc:creator><pubDate>Fri, 28 May 2021 14:00:37 -0000</pubDate><guid>https://sourceforge.net7c0344539cbad01cdec3ae94792a607d44aad753</guid></item><item><title>Home modified by Bert Mueller</title><link>https://sourceforge.net/p/midgen/wiki/Home/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v36
+++ v37
@@ -38,7 +38,7 @@

 ## usage

-Once you have perl installed, just run:
+Once you have installed perl, just run:

     perl MidGen.pl &amp;lt;project.pl&amp;gt;

@@ -51,6 +51,57 @@
 &lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img0.png" width="100%"/&gt;

 ------
+
+## examples
+
+The easiest way to explore MidGen in order to see how it works and what it can do, is to process some of the example files. Since some of them are made specifically for playsmf containing loops and arpeggios, it would be helpful to play the output smf using this tool.
+
+- MidGenPrj\BalladePourAdeline.pl - simple score showing how the micro-sequencer works
+- MidGen\Projects\ReadSty.pl \&amp;lt;filename.sty\&amp;gt; - converts Yamaha Style files into looped SMF (usable with playsmf)
+- MidGen\Projects\ReadCmf.pl \&amp;lt;filename.cmf\&amp;gt;- converts CMF (Creative Music File) to SMF
+- MidGen\Projects\DancingSliders.pl - shows how continous controller data can be generated
+- MidGen\Projects\PortamentoExample.pl - demonstrates the portamento function
+- MidGenPrj\STYLES\Laeufer_Humanized.pl - piano style arpeggio with timing and velocity randomization
+- MidGenPrj\STYLES\Current51_GuitarStrumEFX.pl - guitar strumming style example w/ Roland EFX effects attached
+- MidGenPrj\STYLES\Current30_SoloMatrix.pl - style example with drum, bass and guitar strumming
+- MidGenPrj\STYLES\Current38_GuitarLive.pl - guitar strumm style example (keys down and up will trigger guitar chords down/up)
+- MidGen\Projects\RolandHp503Test0.pl - demontrates how to use smf phrases (live played parts) and generated styles
+- MidGenPrj\STYLES\Current53_MC.pl -  demonstrates midi clock
+- MidGenPrj\STYLES\Current54_MTC.pl -  demonstrates midi time code
+- MidGenPrj\STYLES\Current55_ChordCheck.pl - simple style pattern with few guitar chords to check all implemented chord types and inversions
+
+
+
+## package/module structure
+
+### top level modules
+
+- MidGen.pl - top level framework entry point
+- MIDI.pm - basic smf input/output module (contains general smf read/write/event functions)
+- MidiDebug.pm - not necessarily required, but contains additional track and event list output functions
+- Edit.pm - contains general smf editor functions such as micro-sequencer, step-sequencer, copy/paste, fade-in/out, portamento, etc.
+
+### Devices
+
+The Devices sub-folder contains mainly device specific packages and modules.
+
+- GM.pm - GM controller definitions including RPN/NRPN and GM reset SysEx function
+- GM2.pm - contains mainly GM2 universal SysEx functions such as MasterVolume, FineTune, Reverb, Chorus and MMC functionality
+- GS.pm - Roland GS functions (mostly SysEx functionality)
+- XG(lite).pm - very few Yamaha XG(lite) definitions
+- MMC.pm - Multimedia control (mostly SysEx transport control functions - moved later into GM2 standard)
+- MG.pm - few MidGen specific definitions
+- SMF.pm - few SMF specific definitions
+- Sync.pm - midiclock and midi time code functions
+  - InsertMC() - insert midi clock event series using escape sequence events
+  - InsertMTC() - insert midi timing clock event series using escape sequence events
+- playsmf.pm - definitions and functions specifically for playsmf midi player/looper/arpeggiator
+  - OverrideCmdLineArgs() - override command line arguments using sequencer specific meta events
+  - PreProc() - event pre-processor especially for jump on jump and zero shot sequence preparation (dummy event insertion)
+
+### Sequences
+
+This sub-folder was originally meant to store a sequence library for musical pattern like bass lines, drum pattern, styles, etc., however it evolved over time to a library of tools, helper functions and other miscellaneous perl packages.

 ## internal smf data structure

&amp;lt;/filename.cmf\&amp;gt;&amp;lt;/filename.sty\&amp;gt;&amp;lt;/project.pl&amp;gt;&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Bert Mueller</dc:creator><pubDate>Fri, 28 May 2021 12:51:39 -0000</pubDate><guid>https://sourceforge.net17d2f4883405360c5f7e8d9da658e5c2b5d91042</guid></item><item><title>Home modified by Bert Mueller</title><link>https://sourceforge.net/p/midgen/wiki/Home/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v35
+++ v36
@@ -75,6 +75,37 @@
 ```

 Make sure that you provide a new filename (smf "track" -1, argument 0), else the original smf will be overwritten.
+
+**track event list view output**
+
+As mentioned, each individual track provides additional event lists within separate text (.txt) files which are written in parallel to the smf output. Those lists might be helpful for debugging or just to get an event overview by track. The following information is organized in individual columns:
+
+-  event timestamp in PPQ ticks (1st level smf hash key)
+- event timestamp in bar:beat:tick
+- ordered event ID (2nd level smf hash key)
+- event data in raw hex representation
+- event data interpretation (type, channel, value, duration, etc.)
+- graphical value representation (ascii bar)
+
+Example track lists:
+
+&lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img28.png" width="100%"/&gt;
+
+**special "track" -1**
+
+As already mentioned, there is one specific "track" (-1) holding generic smf information by 2nd level key values such as:
+
+- -3: smf position pointer - only valid after reading a smf. This field contains the file position after reading the smf. Typically it points to EOF (end of file = file size), however is some cases the file contains more than just smf data which is indicated by smf position &amp;lt; smf size. In this case the pointer can be used to continue reading data from there. For instance the Yamaha style reader makes use of this parameter since the the style CASM sections starts after the smf data block.
+- -2: smf size - only valid after reading a smf. This field can be used in combination with the smf position pointer to determine if there is more than just smf data stored with the file.
+- -1: smf timestamp - only valid after reading a smf
+- 0: smf name
+- 1: smf type (typically type 1 since type 0 gets automatically converted to type 1 if not otherwise specified)
+- 2: number of tracks - only valid after reading a smf for information, else unused
+- 3: PPQ (pulses per quarter note / smf timing resolution)
+- 4: initial tempo
+- 5/6: initial time signature nominator/denominator
+- 7: initial key signature
+- 8: copyright text

 **timestamps and durations**

@@ -325,7 +356,11 @@

 &lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img22.png" style=""/&gt;

-Example: tempo adjustment
+Example - alignment: Insert 16 x 1/16th notes, go back in time and insert controller 11 (0xb) in alignment with notes, but 1/64th ahead of note events.
+
+&lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img27.png" style=""/&gt;
+
+Example - tempo adjustment: Insert initial tempo and sweep +/- 25%

 &lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img24.png" style=""/&gt;

@@ -333,13 +368,13 @@

 In general the Micro-Sequencer contains an embedded Step-Sequencer which kicks in if a sequence text string is enclosed within | bar character symbols. In this case the enclosed step sequences get internally converted to micro-sequences before the micro sequencer compiles the smf similar to a pre-processor. Step-sequences are basically text strings were each single character or symbol refers to an individual micro-sequence. Those individual sequences can be either quite simple just containing single notes or more complex containing chords, guitar strums or other pattern types.

-A typical use case for step sequences are for instance drum patterns since they usually run on a regular fixed time base with static key-&amp;gt;voice assignments. In this case a time base (or step granulyrity resolution) and a note definition is required before the step sequence is applied. This is simply done with a dummy rest event which does not advance in time (see example below).
+A typical use case for step sequences are for instance drum patterns since they usually run on a regular fixed time base with static key-&amp;gt;voice assignments. In this case a time base (or step granularity resolution) and a note definition is required before the step sequence is applied. This is simply done with a dummy rest event which does not advance in time (see example below).

 Example: insert few micro-step-sequences with 1/16 resolution across multiple drum voices

 &lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img25.png" style=""/&gt;

-Lets take a closer look at the example above: The initial dummy event `1/16&amp;gt;:35_%` is just a rest event without advancing in time, but defines the resolution and the absolute key value based on chromatic scale with basenote=0. The remaining characters are all enclosed within bars very left and very right belonging to the step-sequence.
+Lets take a closer look at the example above: The initial dummy event `1/16&amp;lt;:35_%` is just a rest event without advancing in time, but defines the resolution and the absolute key value based on chromatic scale with basenote=0. The remaining characters are all enclosed within bars very left and very right belonging to the step-sequence.

 &amp;gt; Remark: Additional bar | characters within a step sequence are just visual separator symbols for better readability without any semantic meaning. Internally they get removed before parsing the sequence.

@@ -351,7 +386,7 @@
 - `#` - one semitone up
 - `b` - one semitone down

-Another example demonstrating different velocities and stretching notes.
+Example: demonstrating different velocities and stretching notes.

 &lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img26.png" style=""/&gt;

&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Bert Mueller</dc:creator><pubDate>Tue, 25 May 2021 17:57:16 -0000</pubDate><guid>https://sourceforge.net3575a08687bdc6bc19d570695646ad42abb84c0e</guid></item><item><title>Home modified by Bert Mueller</title><link>https://sourceforge.net/p/midgen/wiki/Home/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v34
+++ v35
@@ -333,11 +333,29 @@

 In general the Micro-Sequencer contains an embedded Step-Sequencer which kicks in if a sequence text string is enclosed within | bar character symbols. In this case the enclosed step sequences get internally converted to micro-sequences before the micro sequencer compiles the smf similar to a pre-processor. Step-sequences are basically text strings were each single character or symbol refers to an individual micro-sequence. Those individual sequences can be either quite simple just containing single notes or more complex containing chords, guitar strums or other pattern types.

-A simple use case for step sequencers are typically drum pattern running on a regular time base with one individual instrument (bass drum, snare drum, etc.) per line.
-
-In order to use user defined micro sequences, a lookup table is required.
-
-
+A typical use case for step sequences are for instance drum patterns since they usually run on a regular fixed time base with static key-&amp;gt;voice assignments. In this case a time base (or step granulyrity resolution) and a note definition is required before the step sequence is applied. This is simply done with a dummy rest event which does not advance in time (see example below).
+
+Example: insert few micro-step-sequences with 1/16 resolution across multiple drum voices
+
+&lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img25.png" style=""/&gt;
+
+Lets take a closer look at the example above: The initial dummy event `1/16&amp;gt;:35_%` is just a rest event without advancing in time, but defines the resolution and the absolute key value based on chromatic scale with basenote=0. The remaining characters are all enclosed within bars very left and very right belonging to the step-sequence.
+
+&amp;gt; Remark: Additional bar | characters within a step sequence are just visual separator symbols for better readability without any semantic meaning. Internally they get removed before parsing the sequence.
+
+By default, the step sequence characters have the following interpretation:
+
+- `.`  - rest
+- `0,1,2,3,4,5,6,7,8,9,X,x` - notes with different velocity values 0%, 10%, 20% .... 100% (X,x)
+- `&amp;gt;` - repeat or stretch the previous note
+- `#` - one semitone up
+- `b` - one semitone down
+
+Another example demonstrating different velocities and stretching notes.
+
+&lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img26.png" style=""/&gt;
+
+eof

 ------

&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Bert Mueller</dc:creator><pubDate>Mon, 24 May 2021 12:23:05 -0000</pubDate><guid>https://sourceforge.net2bb708accd27d8dd89b5f73b0f8f4b6d181aeee6</guid></item><item><title>Home modified by Bert Mueller</title><link>https://sourceforge.net/p/midgen/wiki/Home/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v33
+++ v34
@@ -115,7 +115,7 @@
 &amp;gt; ***Note: If there is no timestamp provided, the sequencer automatically applies the latest valid timestamp value.***

 #### Duration alignment
-To avoid complex arithmetic equations and to keep sequences more readable, it is possible to align event durations to given timestamp grid boundaries by using the alignment operator `|` in front of the value. This advices the sequencer to proceed in time until the next grid boundary timestamp is reached. So in the example above, the `|1/1:%` event will simply insert a rest in alignment with the next whole note timestamp value. In this case it proceeds to the next bar since the time signature is 4/4 (whole note grid boundary).
+To avoid complex arithmetic equations and to keep sequences more readable, it is possible to align event durations to given timestamp grid boundaries by using the alignment operator `|` in front of the duration value. This advices the sequencer to proceed in time until the next grid boundary timestamp is reached. So in the example above, the `|1/1:%` event will simply insert a rest in alignment with the next whole note timestamp value. In this case it proceeds to the next bar since the time signature is 4/4 (whole note grid boundary).

 #### Visual beat/bar separator
 In order to keep the sequence more structured and readable, it is possible to insert additional `|` character symbols to visualize bar, beat or other timestamp separations. Semantically they dont have any meaning and are just ignored like comments or remarks by the sequencer as long as they stay in clear separation from events.
@@ -249,7 +249,7 @@

 ### additional note attribute data

-Each note- or pause-event of the micro sequencer supports additional (optional) attributes such as on/off velocity values and/or attached controller data events or event series. This way you can easily attach additional articulation attributes to each individual note in alignment with note-on and duration timestamps. Note attributes are typically appended to existing event data by undersscore  `_` separations. For example `" 1/4:0_.75_r.25 "` inserts a quarter note with note value 0 (relative to scale and base note), NoteOn velocity 0.75 and release velocity 0.25.
+Each note- or pause-event of the micro sequencer supports additional (optional) attributes such as on/off velocity values and/or attached controller data events or event series. This way you can easily attach additional articulation attributes to each individual note in alignment with note-on and duration timestamps. Note attributes are typically appended by undersscore  `_` separations. For example `" 1/4:0_.75_r.25 "` inserts a quarter note with note value 0 (relative to scale and base note), NoteOn velocity 0.75 and release velocity 0.25.

 #### note on velocity

@@ -265,11 +265,19 @@

 #### controller-type  attribute data

-Controller-type attribute data are either additional single events inserted together with NoteOn or rest events at the current timestamp position in sequence or continous event series inserted along the given note duration. They are appended to note or rest events with additional arguments in the following format:
-
-`&amp;lt;duration&amp;gt;:&amp;lt;event&amp;gt;_C&amp;lt;controller#&amp;gt;_&amp;lt;function&amp;gt;_&amp;lt;centered&amp;gt;_&amp;lt;value&amp;gt;_&amp;lt;value1&amp;gt;`
-
-Controller type data can be one of the following event types specified by the  `Controller#` number argument:
+Controller-type attribute data are either additional single events inserted together with NoteOn or rest events at the current timestamp position in sequence or continous event series inserted along the given note duration. They are appended to note or rest events with additional arguments by one of the following syntax formats.
+
+Single event controller (e.g. foot, switch, pedals,  etc) are provided by either two or three additional arguments like:
+
+`&amp;lt;duration&amp;gt;:&amp;lt;event&amp;gt;[_C&amp;lt;controller#&amp;gt;_&amp;lt;value&amp;gt;]*`
+
+`&amp;lt;duration&amp;gt;:&amp;lt;event&amp;gt;[_C&amp;lt;controller#&amp;gt;_&amp;lt;centered&amp;gt;_&amp;lt;value&amp;gt;]*`
+
+For continous controller data series, the following format is used:
+
+`&amp;lt;duration&amp;gt;:&amp;lt;event&amp;gt;[_C&amp;lt;controller#&amp;gt;_&amp;lt;function&amp;gt;_&amp;lt;centered&amp;gt;_&amp;lt;value&amp;gt;_&amp;lt;value1&amp;gt;[_&amp;lt;align&amp;gt;]]*`
+
+Controller type data can be one of the following event types specified by the  `Controller#` argument:

 - 0x0..0x7f: regular (7bit) MIDI controller
 - 0x80..0xff: poly after touch by key
@@ -285,29 +293,51 @@
 - 0x4000..0x7fff: RPN
 - 0x8000..0xbfff: NRPN

-The Function argument specifies one of the following data sweep shapes:
+The `Function` argument specifies one of the following data sweep shapes:

 - 0: unused
 - 1: linear transition sweep from Value to Value1 or single event if Value1=Value or if Value1 is not provided
-- 2: full swing sinusoid [0 , 2pi] sweep from Value to Value with elongation = Value1 (sign determines swing direction)
-- 3: half swing sinusoid [0 , pi] sweep from Value to Value with elongation = Value1 (sign determines swing direction)
+- 2: full swing sinusoid [0 , 2pi] sweep from Value to Value with elongation = Value1 (sign determines up/down swing direction)
+- 3: half swing sinusoid [0 , pi] sweep from Value to Value with elongation = Value1 (sign determines up/down swing direction)
 - 4: half sinuoid [-pi/2 , pi/2] transition sweep from Value to Value1
 - 5: sigmoid transition sweep from Value to Value1

-&amp;gt; Remark: If the function argument is provided as a negative number, the data sweep will be inverted.
-
-The `Centered` argument determines if the `Value` arguments are provided in centered or uncentered format:
+&amp;gt; Remark: If the function argument is provided as a negative number, the data sweep will be inverted (up&amp;lt;---&amp;gt;down).
+
+The `Centered` argument determines if the `Value` arguments are provided in centered (signed) or uncentered (unsigned) format:

 - 0: uncentered - normalized values provided as [0.0 ... 1.0]
 - 1: centered - normalized values provided as [-1.0 ... 0.0 ... 1.0]

 &amp;gt; The centered format makes especially sense for centered controller types such as pan, balance, pitch-bend, etc. while other controllers such as volume, expression, etc. make more sense in uncentered format representation - although there is no restriction for one or the other format type.

-The following example inserts a MIDI controller 7 (volume) series along the given note.
+The optional `aligned` argument determines if controller data series get inserted continously (default) or in alignement with Note-On events. This feature can be used to reduce the amount of data in case controller changes are only required when notes get triggered.
+
+Example - switch controller: attach additional sustain pedal press/release events to 1st and last note in sequence
+
+&lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img23.png" style=""/&gt;
+
+Example - continous controller: sweep MIDI controller 7 (volume) using full swing sinusoid function along the given note

 &lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/Example4.png" style=""/&gt;

-The following example inserts a MIDI controller 7 (volume) series along the given note.
+Below a few more examples inserting whole note rests along with marker text and midi controller 11 (0xb hex) demonstrating different swing and transition types.
+
+&lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img22.png" style=""/&gt;
+
+Example: tempo adjustment
+
+&lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img24.png" style=""/&gt;
+
+### Step-Sequencer (pre-processor)
+
+In general the Micro-Sequencer contains an embedded Step-Sequencer which kicks in if a sequence text string is enclosed within | bar character symbols. In this case the enclosed step sequences get internally converted to micro-sequences before the micro sequencer compiles the smf similar to a pre-processor. Step-sequences are basically text strings were each single character or symbol refers to an individual micro-sequence. Those individual sequences can be either quite simple just containing single notes or more complex containing chords, guitar strums or other pattern types.
+
+A simple use case for step sequencers are typically drum pattern running on a regular time base with one individual instrument (bass drum, snare drum, etc.) per line.
+
+In order to use user defined micro sequences, a lookup table is required.
+
+

 ------

&amp;lt;/align&amp;gt;&amp;lt;/value1&amp;gt;&amp;lt;/value&amp;gt;&amp;lt;/centered&amp;gt;&amp;lt;/function&amp;gt;&amp;lt;/controller#&amp;gt;&amp;lt;/event&amp;gt;&amp;lt;/duration&amp;gt;&amp;lt;/value&amp;gt;&amp;lt;/centered&amp;gt;&amp;lt;/controller#&amp;gt;&amp;lt;/event&amp;gt;&amp;lt;/duration&amp;gt;&amp;lt;/value&amp;gt;&amp;lt;/controller#&amp;gt;&amp;lt;/event&amp;gt;&amp;lt;/duration&amp;gt;&amp;lt;/value1&amp;gt;&amp;lt;/value&amp;gt;&amp;lt;/centered&amp;gt;&amp;lt;/function&amp;gt;&amp;lt;/controller#&amp;gt;&amp;lt;/event&amp;gt;&amp;lt;/duration&amp;gt;&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Bert Mueller</dc:creator><pubDate>Sun, 23 May 2021 13:15:31 -0000</pubDate><guid>https://sourceforge.net5662d17f05a99dd1827043c2543477057a827a74</guid></item><item><title>Home modified by Bert Mueller</title><link>https://sourceforge.net/p/midgen/wiki/Home/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v32
+++ v33
@@ -265,18 +265,18 @@

 #### controller-type  attribute data

-Controller-type attribute data are either additional single events inserted together with NoteOn or rest events at the current timestamp position in sequence or a continous event series inserted along the given note duration. They are appended to note or rest events with additional arguments in the following format:
+Controller-type attribute data are either additional single events inserted together with NoteOn or rest events at the current timestamp position in sequence or continous event series inserted along the given note duration. They are appended to note or rest events with additional arguments in the following format:

 `&amp;lt;duration&amp;gt;:&amp;lt;event&amp;gt;_C&amp;lt;controller#&amp;gt;_&amp;lt;function&amp;gt;_&amp;lt;centered&amp;gt;_&amp;lt;value&amp;gt;_&amp;lt;value1&amp;gt;`

-Controller type data can be one of the following event type specified bythe  `Controller#` number argument:
+Controller type data can be one of the following event types specified by the  `Controller#` number argument:

 - 0x0..0x7f: regular (7bit) MIDI controller
 - 0x80..0xff: poly after touch by key
 - 0x100: channel after touch
 - 0x101: NoteOn velocity - no real extra events, but modify existing note-on velocities
 - 0x102: NoteOff velocity - no real extra events, but modify existing note-off velocities
-- 0x103: tempo in % (1.0=&amp;gt;100%) - insert tempo events in track zero
+- 0x103: tempo adjustment in % (1.0=100%) based on initial song tempo setting - makes only sense in track zero
 - 0x104: pitchbend
 - 0x105: program change - makes only sense as single event, but can attach dedicated program changes to individual notes
 - 0x200..0x21f: extended (14 bit) MIDI controller
@@ -288,20 +288,20 @@
 The Function argument specifies one of the following data sweep shapes:

 - 0: unused
-- 1: linear sweep from Value to Value1 or single event if Value1=Value or if Value1 is not provided
-- 2: full swing sinusoid [0 , 2pi] sweep from Value to Value with amplitude = Value1
-- 3: half swing sinusoid [0 , pi] sweep from Value to Value with amplitude = Value1
+- 1: linear transition sweep from Value to Value1 or single event if Value1=Value or if Value1 is not provided
+- 2: full swing sinusoid [0 , 2pi] sweep from Value to Value with elongation = Value1 (sign determines swing direction)
+- 3: half swing sinusoid [0 , pi] sweep from Value to Value with elongation = Value1 (sign determines swing direction)
 - 4: half sinuoid [-pi/2 , pi/2] transition sweep from Value to Value1
 - 5: sigmoid transition sweep from Value to Value1

 &amp;gt; Remark: If the function argument is provided as a negative number, the data sweep will be inverted.

-The `Centered` argument determines if the `Value` arguments are provided in centered or uncentered format such as:
-
-- 0: uncentered - normalized values are provided as [0.0 ... 1.0]
-- 1: centered - normalized values are provided as [-1.0 ... 0.0 ... 1.0]
-
-&amp;gt; The centered format makes sense for centered controller types such as pan, balance, pitch-bend, etc. For other controllers such as volume, expression, etc. it makes more sense to use the uncentered format although there is no restriction for one or the other format.
+The `Centered` argument determines if the `Value` arguments are provided in centered or uncentered format:
+
+- 0: uncentered - normalized values provided as [0.0 ... 1.0]
+- 1: centered - normalized values provided as [-1.0 ... 0.0 ... 1.0]
+
+&amp;gt; The centered format makes especially sense for centered controller types such as pan, balance, pitch-bend, etc. while other controllers such as volume, expression, etc. make more sense in uncentered format representation - although there is no restriction for one or the other format type.

 The following example inserts a MIDI controller 7 (volume) series along the given note.

&amp;lt;/value1&amp;gt;&amp;lt;/value&amp;gt;&amp;lt;/centered&amp;gt;&amp;lt;/function&amp;gt;&amp;lt;/controller#&amp;gt;&amp;lt;/event&amp;gt;&amp;lt;/duration&amp;gt;&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Bert Mueller</dc:creator><pubDate>Fri, 14 May 2021 11:59:37 -0000</pubDate><guid>https://sourceforge.net3df8748edb1628cb4aafc16a788d63ca980fcd0a</guid></item><item><title>Home modified by Bert Mueller</title><link>https://sourceforge.net/p/midgen/wiki/Home/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v31
+++ v32
@@ -6,9 +6,9 @@

 # MidGen

-MidGen is a Perl based standard midi file reader/processor/generator. It includes Perl modules and packages to create/read/write and process standard midi (smf) files based on Perl input scripts. Essentially this tool provides a framework, which is specifically designed for experiments with musical pattern, arpeggios, accompaniment styles, arrangements or entire scores. However MidGen is not only limited to musical data processing since the framework provides furthermore access to all smf event types such as Channel-/SysEx-/Escape- and Meta-events. In general there is no limitation since everything which can be represented by smf can get generated, processed and provided by MidGen.
-
-A build-in "micro sequencer" function translates text-based micro-sequences into smf midi data. Since everything runs in perl environment, you can take advantage from programming languages like using variables for micro-sequences, storing arrangement parts in sub-procedures, repeat sequence iterations with loops, etc. together with convenient smf input/output functionality. This approach allows writing music in traditional sequenced format in combination with algorithmic or procedural programming functionalities. In addition, there are many functions for SMF data manipulation implemented such as copy/paste/insert/transpose which are working either on track level or across the entire arrangement. Also you can include and merge additional external smf midi data into your arrangement so that for instance live played parts get merged with generated accompaniment pattern. Essentially there is no limit for creativity since its an open framework were you can easily add additional features, functions, procedures or other extensions with your own ideas.
+MidGen is a Perl based standard midi file reader/processor/generator. It includes Perl modules and packages to create/read/write and process standard midi (smf) files based on Perl input scripts. Essentially this tool provides a framework, which is specifically designed for experiments with musical pattern, arpeggios, accompaniment styles, arrangements or entire scores. However MidGen is not only limited to musical data processing since the framework provides furthermore access to all smf event types such as Channel-/SysEx-/Escape- and Meta-events. In general there is no limitation since everything representable by smf can be generated, processed and provided by MidGen.
+
+For musical data, a build-in "micro sequencer" function translates text-based micro-sequences into smf midi events. Since everything runs in perl environment, you can take advantage from programming languages like using variables for micro-sequences, sequence substitutions, storing arrangement parts in sub-procedures, repeat sequence iterations with loops, etc. together with convenient smf input/output functionality. This approach allows writing music in traditional sequenced format in combination with algorithmic or procedural programming functionalities. In addition, there are many functions for SMF data manipulation implemented such as copy/paste/insert/transpose which are working either on track level or across the entire arrangement. Also you can include and merge additional external smf midi data into your arrangement so that for instance live played parts get merged with generated accompaniment pattern. Essentially there is no limit for creativity since its an open framework were you can easily add features, functions, procedures or other extensions with your own ideas.



@@ -54,7 +54,7 @@

 ## internal smf data structure

-Internally the smf is nothing else than a multidimensional hash structure with integer key values across all hierarchy levels. The top level key represents the track number (except "track" -1 which is used for smf specific information like filename, smf type, PPQ, etc.), the 2nd level key represent the eventtime in ticks based on the smf PPQ setting and the 3rd level key is the event ID representing the event order within a given tick. This allows simple access and iterations across all smf events for easy data manipulation.
+Internally the smf is nothing else than a multidimensional hash structure with integer key values across all hierarchy levels. The top level key represents the track number (except "track" -1 which is used for smf specific information like filename, smf type, PPQ, etc.), the 2nd level key represents the eventtime in ticks based on the smf PPQ setting and the 3rd level key is the event ID representing the event order within a given tick. This allows simple access and iterations across all smf events for easy data manipulation.

 Reading and writing a midi file is as simple as:

@@ -68,7 +68,7 @@
 my %smf = MIDI::Read("filename.mid"); MidiDebug::PrintInfo(\%smf); MIDI::Write(\%smf, "filename_new.mid");
 ```

-Since MidGen has already defined a default smf datastructure called `%main::out` runnig thru MidiDebug::PrintInfo() and MIDI::Write() functions at the very end of the program flow, typically you dont need to care about those functions unless you work with multiple smf structures in parallel. Therefore its also possible to read and write a smf by just running the following instruction:
+Since MidGen has already defined a default smf datastructure handle called `%main::out` runnig thru MidiDebug::PrintInfo() and MIDI::Write() functions at the very end of the program flow, you dont need necessarily taking care about those functions unless you work with multiple smf structures in parallel. Therefore its also possible to read and write a smf by just running the following instruction:

 ```perl
 %main::out = MIDI::Read("filename"); $main::out{-1}{0} = "filename_new.mid";
@@ -88,7 +88,7 @@

 ## Micro-Sequencer

-The micro-sequencer is a central and important function especially written for convenient note- , controller- and other data insertions. Essentially it inserts a sequence of notes and/or controller/meta/sysex events into a specified track, based on a given start-time, scale (e.g. chromatic, major, minor, etc.) and base note (e.g. 60 - middle C). The sequence is provided as a consecutive, white space separated list of `&amp;lt;duration&amp;gt;:&amp;lt;data&amp;gt;` pairs representing duration timestamps with associated event data in text format. The micro-sequencer keeps internally track of timestamps, note-pitches and other data and typically advances in time with each provided event-duration value unless otherwise specified (e.g. for overlap notes or chords). In addition, the sequencer returns the total duration of the provided micro-sequence in whole note units. This allows the caller thread keeping track about the total timestamp if you simply sum up all micro-sequence durations in case they belong logically together. The micro sequencer function is called from Edit package as follow:
+The micro-sequencer is a central and important function especially written for convenient note- , controller- and other data insertions. Essentially it inserts a sequence of notes and/or controller/meta/sysex events into a specified track, based on a given start-time, scale (e.g. chromatic, major, minor, etc.) and base note (e.g. 60 - middle C). The sequence is provided as a consecutive, white space separated list of `&amp;lt;duration&amp;gt;:&amp;lt;data&amp;gt;` pairs representing duration timestamps with associated event data in text format separated by the colon `:` sympol. The micro-sequencer keeps internally track of timestamps, note-pitches and other data and typically advances in time with each provided event-duration value unless otherwise specified (e.g. for overlap notes or chords). In addition, the sequencer returns the total duration of the provided micro-sequence in whole note units. This allows the caller thread keeping track about the total timestamp if you simply sum up all micro-sequence durations in case they belong logically together. The micro sequencer function is called from Edit package as follow:

     &amp;lt;duration&amp;gt; = Edit::Seq(&amp;lt;smf-hash-pointer&amp;gt;, &amp;lt;track&amp;gt;, &amp;lt;start-time&amp;gt;, &amp;lt;base-note&amp;gt;, &amp;lt;scale&amp;gt;, &amp;lt;sequence&amp;gt;);

@@ -161,19 +161,24 @@


 #### Rests
-rests and pauses are simply written by the `%` character symbol.
+rests and pauses are simply represented by the `%` character symbol.

 &lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/Example2.png"/&gt;

 ### repetitions, sub-sequences and loops

-#### repeat event operator
-
-To repeat single events or rests with the same duration and note value, you can just use the `.` (dot) symbol.
-
-&lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img13.png" style=""/&gt;
-
-#### continue event operator
+#### repeat operator
+
+To repeat single events or rests with the same duration and/or note values, you can just use the `.` (dot) symbol for either duration and/or event data values. The following scenarios are possible:
+
+- `&amp;lt;duration&amp;gt;:&amp;lt;event&amp;gt;` - regular duration/event data type pair w/o repeat
+- `&amp;lt;duration&amp;gt;:.`  - repeat the latest event note value with a new applied duration value
+- `.:&amp;lt;event&amp;gt;` or `&amp;lt;event&amp;gt;` - repeat the latest duration value with a new applied event note value. in this case, the duration repeat operator and the colon separator  `.:` is not necessarily required and you can shortcut by just writing the new event value as already done in many examples before.
+- `.:.` or shortcut `.` - repeat the whole event using the latest applied duration and event values (true event repeat)
+
+&lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img21.png" style=""/&gt;
+
+#### continue operator

 The continue event operator `&amp;gt;` is similar to regular repeats, but ignores rest events and simply 'continues' playing with the latest note value. This event type is mainly used in combination with pattern sequence templates.

@@ -228,41 +233,81 @@

 The example above shows how a simple chord triad is setup as a template and beeing used in a small sequence.

-&amp;gt; Remark: Events like `1/1&amp;lt;:0_%` are so called NOP (no operation) events since they do not advance in time neither inserting a note, however they instruct the sequencer to set the current timestamp and the current note value for further sequence events.
+&amp;gt; Remark: Some strange looking events like `1/1&amp;lt;:0_%` are so called NOP (no operation) events since they do not advance in time neither inserting a note since a rest is applied in combination with a note value, however they instruct the sequencer to set the current timestamp and the current note value for further sequence events.

 The following example is very similar and shows how to insert a small arpeggio sequence using templates.

 &lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img16.png" style=""/&gt;

-Now one template example demonstrating how to use subsequences with and without sequencer value restoration. Actually when we simply concatenate a sub-sequence template such as `" &amp;gt; ^2 ^2 . "`  multiple times, the sequencer will increase continously all note values with each insertion. In contrast, if we put the sub-sequence into parentheses, the sequencer will take care about storing and restoring note values when the template gets entered or left. Therefore the resulting sequence is totally different.
+Now one template example demonstrating how to use subsequences with and without sequencer value restoration. Actually when we simply concatenate a sub-sequence template such as `" &amp;gt; ^2 ^2 . "`  multiple times, the sequencer will increase continously all note values with each insertion. In contrast, if we put the sub-sequence into parentheses, the sequencer will take care about preserving and restoring note values when the template gets entered or left. Therefore the resulting sequence is totally different.

 &lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img17.png" style=""/&gt;

-The next example shows the effect of additional square brackets around the template sequence and their effect. In this case not only note values are strored and restored, but also the timestamp values get preserved when the subsequence get entered. In result, the sequencer jumps back in time once the sub-sequence template has been processed and starts over again from the beginning. Therefore the sequence appears now stacked rather than consecutive in time.
+The next example shows the effect of additional square brackets around the template sequence and their effect. In this case not only note values, but also timestamp values get preserved when the subsequence get entered. In result, the sequencer jumps back in time once the sub-sequence template has been processed and starts over again from the beginning. Therefore the sequence appears now stacked rather than consecutive in time.

 &lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img18.png" style=""/&gt;

 ### additional note attribute data

-Each note- or pause-event of the micro sequencer supports additional (optional) attributes such as on/off velocity values and/or attached controller data series. This way you can easily attach additional articulation attributes to each individual note in alignment with note-on and duration timestamps. Note attributes are typically appended to existing event data by additional `_` separations. For example `" 1/4:0_.75_r.25 "` inserts a quarter note with note value 0 (relative to scale and base note), NoteOn velocity 0.75 and release velocity 0.25.
+Each note- or pause-event of the micro sequencer supports additional (optional) attributes such as on/off velocity values and/or attached controller data events or event series. This way you can easily attach additional articulation attributes to each individual note in alignment with note-on and duration timestamps. Note attributes are typically appended to existing event data by undersscore  `_` separations. For example `" 1/4:0_.75_r.25 "` inserts a quarter note with note value 0 (relative to scale and base note), NoteOn velocity 0.75 and release velocity 0.25.

 #### note on velocity

-Note-On velocities are simply written as floating point values in adition to note events. If a note event is not specified, the sequencer will repeat the previous note with the provided velocity values. This can be useful to shortcut for instance percussion sequences.
+Note-On velocities are simply written as normalized (0.0 ... 1.0) floating point values in adition to note events. If a note event is not specified, the sequencer will repeat the previous note with the provided velocity values. This can be useful to shortcut for instance percussion sequences repeating the same note with different velocities.

 &lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img19.png" style=""/&gt;

 #### note off velocity

-Note-Off velocities are specified as `r&amp;lt;velocity&amp;gt;` floating point values. They are rarely used and most sequencers doesnt really display them, but here an Cubase example showing both Note-On and -Off velocities together.
+Note-Off velocities are specified by `r&amp;lt;velocity&amp;gt;` floating point values. They are rarely used and most sequencers doesnt really display them, but here an Cubase list edit example showing both Note-On and -Off velocities together.

 &lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/img20.png" style=""/&gt;

-#### controller data
-
-Attributes are either single events inserted at the current timestamp in sequence or continous event series inserted along the given note duration. Attributes can be any kind of controller, aftertouch, pitchbend, sysex or tempo events.
+#### controller-type  attribute data
+
+Controller-type attribute data are either additional single events inserted together with NoteOn or rest events at the current timestamp position in sequence or a continous event series inserted along the given note duration. They are appended to note or rest events with additional arguments in the following format:
+
+`&amp;lt;duration&amp;gt;:&amp;lt;event&amp;gt;_C&amp;lt;controller#&amp;gt;_&amp;lt;function&amp;gt;_&amp;lt;centered&amp;gt;_&amp;lt;value&amp;gt;_&amp;lt;value1&amp;gt;`
+
+Controller type data can be one of the following event type specified bythe  `Controller#` number argument:
+
+- 0x0..0x7f: regular (7bit) MIDI controller
+- 0x80..0xff: poly after touch by key
+- 0x100: channel after touch
+- 0x101: NoteOn velocity - no real extra events, but modify existing note-on velocities
+- 0x102: NoteOff velocity - no real extra events, but modify existing note-off velocities
+- 0x103: tempo in % (1.0=&amp;gt;100%) - insert tempo events in track zero
+- 0x104: pitchbend
+- 0x105: program change - makes only sense as single event, but can attach dedicated program changes to individual notes
+- 0x200..0x21f: extended (14 bit) MIDI controller
+- 0x300..0x303: extended (14 bit) MIDI controller GP #5-#8
+- 0x304..0x3fff: SysEx callback functions - only available if sysex callback functions are assigned by device specific packages
+- 0x4000..0x7fff: RPN
+- 0x8000..0xbfff: NRPN
+
+The Function argument specifies one of the following data sweep shapes:
+
+- 0: unused
+- 1: linear sweep from Value to Value1 or single event if Value1=Value or if Value1 is not provided
+- 2: full swing sinusoid [0 , 2pi] sweep from Value to Value with amplitude = Value1
+- 3: half swing sinusoid [0 , pi] sweep from Value to Value with amplitude = Value1
+- 4: half sinuoid [-pi/2 , pi/2] transition sweep from Value to Value1
+- 5: sigmoid transition sweep from Value to Value1
+
+&amp;gt; Remark: If the function argument is provided as a negative number, the data sweep will be inverted.
+
+The `Centered` argument determines if the `Value` arguments are provided in centered or uncentered format such as:
+
+- 0: uncentered - normalized values are provided as [0.0 ... 1.0]
+- 1: centered - normalized values are provided as [-1.0 ... 0.0 ... 1.0]
+
+&amp;gt; The centered format makes sense for centered controller types such as pan, balance, pitch-bend, etc. For other controllers such as volume, expression, etc. it makes more sense to use the uncentered format although there is no restriction for one or the other format.
+
+The following example inserts a MIDI controller 7 (volume) series along the given note.

 &lt;img rel="nofollow" src="https://raw.githubusercontent.com/MrBMueller/MidGen/master/img/Example4.png" style=""/&gt;
+
+The following example inserts a MIDI controller 7 (volume) series along the given note.

 ------

&amp;lt;/value1&amp;gt;&amp;lt;/value&amp;gt;&amp;lt;/centered&amp;gt;&amp;lt;/function&amp;gt;&amp;lt;/controller#&amp;gt;&amp;lt;/event&amp;gt;&amp;lt;/duration&amp;gt;&amp;lt;/velocity&amp;gt;&amp;lt;/velocity&amp;gt;&amp;lt;/event&amp;gt;&amp;lt;/event&amp;gt;&amp;lt;/duration&amp;gt;&amp;lt;/event&amp;gt;&amp;lt;/duration&amp;gt;&amp;lt;/sequence&amp;gt;&amp;lt;/scale&amp;gt;&amp;lt;/base-note&amp;gt;&amp;lt;/start-time&amp;gt;&amp;lt;/smf-hash-pointer&amp;gt;&amp;lt;/duration&amp;gt;&amp;lt;/data&amp;gt;&amp;lt;/duration&amp;gt;&amp;lt;/data&amp;gt;&amp;lt;/duration&amp;gt;&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Bert Mueller</dc:creator><pubDate>Sun, 09 May 2021 15:59:58 -0000</pubDate><guid>https://sourceforge.netf6fa460561f935ca1eb0638aa0b27fad039f467a</guid></item><item><title>Home modified by Bert Mueller</title><link>https://sourceforge.net/p/midgen/wiki/Home/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v30
+++ v31
@@ -6,7 +6,9 @@

 # MidGen

-MidGen is a Perl based standard midi file reader/processor/generator. It includes Perl modules and packages to create/read/write and process standard midi (smf) files based on Perl input scripts. Essentially this tool provides a framework, which is specifically designed for experiments with musical pattern, arpeggios, accompaniment styles, arrangements or entire scores. A build-in "micro sequencer" function translates text-based micro-sequences into smf midi data. Since everything runs in perl environment, you can take advantage from programming languages like using variables for micro-sequences, storing arrangement parts in sub-procedures, repeat sequence iterations with loops, etc. together with convenient smf input/output functionality. This approach allows writing music in traditional sequenced format in combination with algorithmic or procedural programming functionalities. In addition, there are many functions for SMF data manipulation implemented such as copy/paste/insert/transpose which are working either on track level or across the entire arrangement. Also you can include and merge additional external smf midi data into your arrangement so that for instance live played parts get merged with generated accompaniment pattern. Essentially there is no limit for creativity since its an open framework were you can easily add additional features, functions, procedures or other extensions with your own ideas.
+MidGen is a Perl based standard midi file reader/processor/generator. It includes Perl modules and packages to create/read/write and process standard midi (smf) files based on Perl input scripts. Essentially this tool provides a framework, which is specifically designed for experiments with musical pattern, arpeggios, accompaniment styles, arrangements or entire scores. However MidGen is not only limited to musical data processing since the framework provides furthermore access to all smf event types such as Channel-/SysEx-/Escape- and Meta-events. In general there is no limitation since everything which can be represented by smf can get generated, processed and provided by MidGen.
+
+A build-in "micro sequencer" function translates text-based micro-sequences into smf midi data. Since everything runs in perl environment, you can take advantage from programming languages like using variables for micro-sequences, storing arrangement parts in sub-procedures, repeat sequence iterations with loops, etc. together with convenient smf input/output functionality. This approach allows writing music in traditional sequenced format in combination with algorithmic or procedural programming functionalities. In addition, there are many functions for SMF data manipulation implemented such as copy/paste/insert/transpose which are working either on track level or across the entire arrangement. Also you can include and merge additional external smf midi data into your arrangement so that for instance live played parts get merged with generated accompaniment pattern. Essentially there is no limit for creativity since its an open framework were you can easily add additional features, functions, procedures or other extensions with your own ideas.



&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Bert Mueller</dc:creator><pubDate>Sun, 25 Apr 2021 13:49:01 -0000</pubDate><guid>https://sourceforge.net92c9d07b9e6843b7ede786a4476aff230709cbf2</guid></item><item><title>Home modified by Bert Mueller</title><link>https://sourceforge.net/p/midgen/wiki/Home/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v29
+++ v30
@@ -52,13 +52,27 @@

 ## internal smf data structure

-Internally the smf is nothing else than a multidimensional hash structure with integer key values across all hierarchy levels. The top level key represents the track number (except "track" -1 which is used for smf specific information), the 2nd level key represent the eventtime in ticks based on the smf PPQ setting and the 3rd level key is the event ID representing the event order within a given tick. This allows simple access and iterations across all smf events for easy data manipulation.
-
-Reading a midi file is as simple as:
+Internally the smf is nothing else than a multidimensional hash structure with integer key values across all hierarchy levels. The top level key represents the track number (except "track" -1 which is used for smf specific information like filename, smf type, PPQ, etc.), the 2nd level key represent the eventtime in ticks based on the smf PPQ setting and the 3rd level key is the event ID representing the event order within a given tick. This allows simple access and iterations across all smf events for easy data manipulation.
+
+Reading and writing a midi file is as simple as:

 ```perl
-my %smf = MIDI::Read("filename.mid");
+my %smf = MIDI::Read("filename.mid"); MIDI::Write(\%smf, "filename_new.mid");
 ```
+
+In addition, you can also display general track overview information on the console output screen plus getting individual event lists per track by calling MidiDebug::PrintInfo() such as:
+
+```perl
+my %smf = MIDI::Read("filename.mid"); MidiDebug::PrintInfo(\%smf); MIDI::Write(\%smf, "filename_new.mid");
+```
+
+Since MidGen has already defined a default smf datastructure called `%main::out` runnig thru MidiDebug::PrintInfo() and MIDI::Write() functions at the very end of the program flow, typically you dont need to care about those functions unless you work with multiple smf structures in parallel. Therefore its also possible to read and write a smf by just running the following instruction:
+
+```perl
+%main::out = MIDI::Read("filename"); $main::out{-1}{0} = "filename_new.mid";
+```
+
+Make sure that you provide a new filename (smf "track" -1, argument 0), else the original smf will be overwritten.

 **timestamps and durations**

&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Bert Mueller</dc:creator><pubDate>Sun, 25 Apr 2021 13:05:56 -0000</pubDate><guid>https://sourceforge.net279bfbc0500e95186bf92f917c93dac0944627de</guid></item></channel></rss>