Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #35241 > unrolled thread

Pair matching algorithm "hard?"

Started byJonas Thörnvall <jonas.thornvall@gmail.com>
First post2018-06-20 03:26 -0700
Last post2018-06-20 10:37 -0700
Articles 18 — 3 participants

Back to article view | Back to comp.lang.javascript


Contents

  Pair matching algorithm "hard?" Jonas Thörnvall <jonas.thornvall@gmail.com> - 2018-06-20 03:26 -0700
    Re: Pair matching algorithm "hard?" Jonas Thörnvall <jonas.thornvall@gmail.com> - 2018-06-20 03:31 -0700
      Re: Pair matching algorithm "hard?" Wally W. <ww84wa@aim.com> - 2018-06-20 08:45 -0400
        Re: Pair matching algorithm "hard?" Jonas Thörnvall <jonas.thornvall@gmail.com> - 2018-06-20 10:16 -0700
      Re: Pair matching algorithm "hard?" JJ <jj4public@vfemail.net> - 2018-06-20 20:31 +0700
        Re: Pair matching algorithm "hard?" JJ <jj4public@vfemail.net> - 2018-06-20 20:37 +0700
          Re: Pair matching algorithm "hard?" Jonas Thörnvall <jonas.thornvall@gmail.com> - 2018-06-20 10:22 -0700
          Re: Pair matching algorithm "hard?" Jonas Thörnvall <jonas.thornvall@gmail.com> - 2018-06-20 10:55 -0700
            Re: Pair matching algorithm "hard?" Jonas Thörnvall <jonas.thornvall@gmail.com> - 2018-06-20 11:26 -0700
              Re: Pair matching algorithm "hard?" Jonas Thörnvall <jonas.thornvall@gmail.com> - 2018-06-20 13:12 -0700
                Re: Pair matching algorithm "hard?" Jonas Thörnvall <jonas.thornvall@gmail.com> - 2018-06-20 13:15 -0700
                  Re: Pair matching algorithm "hard?" Jonas Thörnvall <jonas.thornvall@gmail.com> - 2018-06-20 13:20 -0700
                    Re: Pair matching algorithm "hard?" Jonas Thörnvall <jonas.thornvall@gmail.com> - 2018-06-20 13:26 -0700
          Re: Pair matching algorithm "hard?" Jonas Thörnvall <jonas.thornvall@gmail.com> - 2018-06-24 09:17 -0700
            Re: Pair matching algorithm "hard?" Jonas Thörnvall <jonas.thornvall@gmail.com> - 2018-06-24 09:27 -0700
        Re: Pair matching algorithm "hard?" Jonas Thörnvall <jonas.thornvall@gmail.com> - 2018-06-20 10:19 -0700
        Re: Pair matching algorithm "hard?" Jonas Thörnvall <jonas.thornvall@gmail.com> - 2018-06-20 10:28 -0700
          Re: Pair matching algorithm "hard?" Jonas Thörnvall <jonas.thornvall@gmail.com> - 2018-06-20 10:37 -0700

#35241 — Pair matching algorithm "hard?"

FromJonas Thörnvall <jonas.thornvall@gmail.com>
Date2018-06-20 03:26 -0700
SubjectPair matching algorithm "hard?"
Message-ID<81af6402-843a-4d3a-a888-81d9776e6bbe@googlegroups.com>
I have a two valued pair. One value is data let say characters. The other value denotes if it a start or end value. A value can not restart until it ended.

I have written an algorithm that match up the start and ends, but i think i got it overly complicated. In reality the start and end values also carry time, but it is not necessary for the actual algorithm. So it is a stepthru algorithm, you can think of the values as an array arr[].ch and arr[].temporal

C start
Z start
C end
B start
Z end
B end
C start
K start
R start
R end
K end
C end

[toc] | [next] | [standalone]


#35242

FromJonas Thörnvall <jonas.thornvall@gmail.com>
Date2018-06-20 03:31 -0700
Message-ID<1740bf3f-993a-4546-8e60-1f246499e39e@googlegroups.com>
In reply to#35241
Den onsdag 20 juni 2018 kl. 12:26:26 UTC+2 skrev Jonas Thörnvall:
> I have a two valued pair. One value is data let say characters. The other value denotes if it a start or end value. A value can not restart until it ended.
> 
> I have written an algorithm that match up the start and ends, but i think i got it overly complicated. In reality the start and end values also carry time, but it is not necessary for the actual algorithm. So it is a stepthru algorithm, you can think of the values as an array arr[].ch and arr[].temporal
> 
> C start
> Z start
> C end
> B start
> Z end
> B end
> C start
> K start
> R start
> R end
> K end
> C end

Does this look alright?

function listTrackEvents(z){
  eventlist="";
  for (var i=0;i<track[z].midiMess.length;i++){
   //Generate textstring eventlist
   if(track[z].midiMess[i].data0=="128"){ }
   else if(track[z].midiMess[i].data0=="144"){
       notenumber=track[z].midiMess[i].data1;
       note=getNote(notenumber);
       eventlist+=note;
       eventlist+=" t="+track[z].midiMess[i].time.toFixed(3)+"\n"; 
       j=i+1;
       while(track[z].midiMess[j].data1!=notenumber){
         j++;       
       }
       duration=track[z].midiMess[j].time-track[z].midiMess[i].time;
       eventlist+=" Duration "+duration+"\n";
       eventlist+=" Vel "+track[z].midiMess[i].data2+"\n";
    } 
   }
  document.getElementById("events").value=eventlist;
}

[toc] | [prev] | [next] | [standalone]


#35243

FromWally W. <ww84wa@aim.com>
Date2018-06-20 08:45 -0400
Message-ID<53ikidpnfn84q47fnl7arvvrackbk493nk@4ax.com>
In reply to#35242
On Wed, 20 Jun 2018 03:31:03 -0700 (PDT), Jonas Thörnvall wrote:

>Den onsdag 20 juni 2018 kl. 12:26:26 UTC+2 skrev Jonas Thörnvall:
>> I have a two valued pair. One value is data let say characters. The other value denotes if it a start or end value. A value can not restart until it ended.
>> 
>> I have written an algorithm that match up the start and ends, but i think i got it overly complicated. In reality the start and end values also carry time, but it is not necessary for the actual algorithm. So it is a stepthru algorithm, you can think of the values as an array arr[].ch and arr[].temporal
>> 
>> C start
>> Z start
>> C end
>> B start
>> Z end

How do you know "B start" should be listed before "Z end"?

Why can't "K start" be here?

I don't see the value of the ordering in this list if it doesn't
include consideration of the time stamps for the events.

>> B end
>> C start
>> K start
>> R start
>> R end
>> K end
>> C end
>
>Does this look alright?
>
>function listTrackEvents(z){
>  eventlist="";
>  for (var i=0;i<track[z].midiMess.length;i++){
>   //Generate textstring eventlist
>   if(track[z].midiMess[i].data0=="128"){ }
>   else if(track[z].midiMess[i].data0=="144"){
>       notenumber=track[z].midiMess[i].data1;
>       note=getNote(notenumber);
>       eventlist+=note;
>       eventlist+=" t="+track[z].midiMess[i].time.toFixed(3)+"\n"; 
>       j=i+1;
>       while(track[z].midiMess[j].data1!=notenumber){
>         j++;       
>       }
>       duration=track[z].midiMess[j].time-track[z].midiMess[i].time;
>       eventlist+=" Duration "+duration+"\n";
>       eventlist+=" Vel "+track[z].midiMess[i].data2+"\n";
>    } 
>   }
>  document.getElementById("events").value=eventlist;
>}

If you sort by time, nothing in the report begins/ends out of sequence
(assuming the clocks at all processes are synchronized). If you need
the occurrences of begins/ends for 'Process C' in a separate list from
'Process Z', they can can be peeled from the time-sorted list.

Otherwise, can you be sure the list of data starts before any process
begins? That is, if 'Process C' has already begun before the data
collection starts, the first data you will see from 'Process C' is
"end" ... with no preceeding "begin." I don't know how you would
detect/reconcile that without sorting by time.

[toc] | [prev] | [next] | [standalone]


#35246

FromJonas Thörnvall <jonas.thornvall@gmail.com>
Date2018-06-20 10:16 -0700
Message-ID<f6e2fd34-62a6-430a-ad0a-d40e663ab750@googlegroups.com>
In reply to#35243
Den onsdag 20 juni 2018 kl. 14:45:00 UTC+2 skrev Wally W.:
> On Wed, 20 Jun 2018 03:31:03 -0700 (PDT), Jonas Thörnvall wrote:
> 
> >Den onsdag 20 juni 2018 kl. 12:26:26 UTC+2 skrev Jonas Thörnvall:
> >> I have a two valued pair. One value is data let say characters. The other value denotes if it a start or end value. A value can not restart until it ended.
> >> 
> >> I have written an algorithm that match up the start and ends, but i think i got it overly complicated. In reality the start and end values also carry time, but it is not necessary for the actual algorithm. So it is a stepthru algorithm, you can think of the values as an array arr[].ch and arr[].temporal
> >> 
> >> C start
> >> Z start
> >> C end
> >> B start
> >> Z end
> 
> How do you know "B start" should be listed before "Z end"?
> 
> Why can't "K start" be here?
> 
> I don't see the value of the ordering in this list if it doesn't
> include consideration of the time stamps for the events.
> 
> >> B end
> >> C start
> >> K start
> >> R start
> >> R end
> >> K end
> >> C end
> >
> >Does this look alright?
> >
> >function listTrackEvents(z){
> >  eventlist="";
> >  for (var i=0;i<track[z].midiMess.length;i++){
> >   //Generate textstring eventlist
> >   if(track[z].midiMess[i].data0=="128"){ }
> >   else if(track[z].midiMess[i].data0=="144"){
> >       notenumber=track[z].midiMess[i].data1;
> >       note=getNote(notenumber);
> >       eventlist+=note;
> >       eventlist+=" t="+track[z].midiMess[i].time.toFixed(3)+"\n"; 
> >       j=i+1;
> >       while(track[z].midiMess[j].data1!=notenumber){
> >         j++;       
> >       }
> >       duration=track[z].midiMess[j].time-track[z].midiMess[i].time;
> >       eventlist+=" Duration "+duration+"\n";
> >       eventlist+=" Vel "+track[z].midiMess[i].data2+"\n";
> >    } 
> >   }
> >  document.getElementById("events").value=eventlist;
> >}
> 
> If you sort by time, nothing in the report begins/ends out of sequence
> (assuming the clocks at all processes are synchronized). If you need
> the occurrences of begins/ends for 'Process C' in a separate list from
> 'Process Z', they can can be peeled from the time-sorted list.
> 
> Otherwise, can you be sure the list of data starts before any process
> begins? That is, if 'Process C' has already begun before the data
> collection starts, the first data you will see from 'Process C' is
> "end" ... with no preceeding "begin." I don't know how you would
> detect/reconcile that without sorting by time.

It is just an example a note **on** always come before a note **off** using the same key  on the keyboard.

[toc] | [prev] | [next] | [standalone]


#35244

FromJJ <jj4public@vfemail.net>
Date2018-06-20 20:31 +0700
Message-ID<13th7ihqnys6m.1py2jfza3m6y2.dlg@40tude.net>
In reply to#35242
On Wed, 20 Jun 2018 03:31:03 -0700 (PDT), Jonas Thörnvall wrote:

> Den onsdag 20 juni 2018 kl. 12:26:26 UTC+2 skrev Jonas Thörnvall:
>> I have a two valued pair. One value is data let say characters. The other value denotes if it a start or end value. A value can not restart until it ended.
>> 
>> I have written an algorithm that match up the start and ends, but i think i got it overly complicated. In reality the start and end values also carry time, but it is not necessary for the actual algorithm. So it is a stepthru algorithm, you can think of the values as an array arr[].ch and arr[].temporal
>> 
>> C start
>> Z start
>> C end
>> B start
>> Z end
>> B end
>> C start
>> K start
>> R start
>> R end
>> K end
>> C end
> 
> Does this look alright?
> 
> function listTrackEvents(z){
>   eventlist="";
>   for (var i=0;i<track[z].midiMess.length;i++){
>    //Generate textstring eventlist
>    if(track[z].midiMess[i].data0=="128"){ }
>    else if(track[z].midiMess[i].data0=="144"){
>        notenumber=track[z].midiMess[i].data1;
>        note=getNote(notenumber);
>        eventlist+=note;
>        eventlist+=" t="+track[z].midiMess[i].time.toFixed(3)+"\n"; 
>        j=i+1;
>        while(track[z].midiMess[j].data1!=notenumber){
>          j++;       
>        }
>        duration=track[z].midiMess[j].time-track[z].midiMess[i].time;
>        eventlist+=" Duration "+duration+"\n";
>        eventlist+=" Vel "+track[z].midiMess[i].data2+"\n";
>     } 
>    }
>   document.getElementById("events").value=eventlist;
> }

You forgot to take account of the MIDI channel.

Use an "note" cache for all 16 MIDI channels. e.g.

  var noteCache = [
    {}, {}, {}, {}, {}, {}, {}, {},
    {}, {}, {}, {}, {}, {}, {}, {}
  ];

When encountering a Channel event, store the event's channel number to e.g.
`channelNum` variable.

When encountering a NoteOn event, store it in the cache. e.g.

  if (message.event === msgNoteOn) {
    noteCache[channelNum][message.noteNumber] = message.time;
  }

When encountering a NoteOff event, check it from the "note" cache. If found,
calculate the duration, then remove it from the cache. e.g.

  if (message.event === msgNoteOff) {
    if (message.noteNumber in noteCache[channelNum]) {
      duration = message.time - noteCache[channelNum][message.noteNumber];
      delete noteCache[channelNum][message.noteNumber];
    }
  }

[toc] | [prev] | [next] | [standalone]


#35245

FromJJ <jj4public@vfemail.net>
Date2018-06-20 20:37 +0700
Message-ID<tjnfx3qu3mm2.12e6bqr1lkr2i$.dlg@40tude.net>
In reply to#35244
On Wed, 20 Jun 2018 20:31:22 +0700, JJ wrote:
> 
> You forgot to take account of the MIDI channel.
[snip]

Also... do not assume that a MIDI track is exclusively for a specific MIDI
channel. A Channel event may exist in any MIDI track. MIDI tracks are simply
a separation of MIDI events in a `MID` file format. They do not exist in the
MIDI protocol.

[toc] | [prev] | [next] | [standalone]


#35248

FromJonas Thörnvall <jonas.thornvall@gmail.com>
Date2018-06-20 10:22 -0700
Message-ID<fd6b6bfb-86cd-41a4-a755-10e74d7199d4@googlegroups.com>
In reply to#35245
Den onsdag 20 juni 2018 kl. 15:37:30 UTC+2 skrev JJ:
> On Wed, 20 Jun 2018 20:31:22 +0700, JJ wrote:
> > 
> > You forgot to take account of the MIDI channel.
> [snip]
> 
> Also... do not assume that a MIDI track is exclusively for a specific MIDI
> channel. A Channel event may exist in any MIDI track. MIDI tracks are simply
> a separation of MIDI events in a `MID` file format. They do not exist in the
> MIDI protocol.

Off course i do not do that you can assign any channel, and any "Pr" instrument  to any track "have not implemented banks yet", in my program even any output midi port/module but that is of course not supported by midi itself. 

[toc] | [prev] | [next] | [standalone]


#35251

FromJonas Thörnvall <jonas.thornvall@gmail.com>
Date2018-06-20 10:55 -0700
Message-ID<e9db53f2-e854-401b-910d-9583192b870c@googlegroups.com>
In reply to#35245
Den onsdag 20 juni 2018 kl. 15:37:30 UTC+2 skrev JJ:
> On Wed, 20 Jun 2018 20:31:22 +0700, JJ wrote:
> > 
> > You forgot to take account of the MIDI channel.
> [snip]
> 
> Also... do not assume that a MIDI track is exclusively for a specific MIDI
> channel. A Channel event may exist in any MIDI track. MIDI tracks are simply
> a separation of MIDI events in a `MID` file format. They do not exist in the
> MIDI protocol.

My editor work like this i have a mixdown channel 0, the code i showed is for listing indivitual channels. But of course i need to make note on note off  channel dependent in the end. Otherwise it will be hard to list and edit the omnitrack.

"Basicly i downmix to create an omni track zero before playup, its a slow progress programming this so i am not quite there yet", but well on the way.

But as you say when sorting events in the downmix track, you will have to also check channel of note. And even same output port.

function sendMidiChannel(){
    //Set midichannel on the track
    channelC=document.getElementById("out_channel").selectedIndex+1;
    if (channelC==1) {NOTE_ON=0x90; NOTE_OFF=0x80;}
    else if (channelC==2) {NOTE_ON=0x91; NOTE_OFF=0x81;}
    else if (channelC==3) {NOTE_ON=0x92;NOTE_OFF=0x82;}
    else if (channelC==4) {NOTE_ON=0x93;NOTE_OFF=0x83;}
    else if (channelC==5) {NOTE_ON=0x94;NOTE_OFF=0x84;}
    else if (channelC==6) {NOTE_ON=0x95;NOTE_OFF=0x85;}
    else if (channelC==7) {NOTE_ON=0x96;NOTE_OFF=0x86;}
    else if (channelC==8) {NOTE_ON=0x97;NOTE_OFF=0x87;}
    else if (channelC==9) {NOTE_ON=0x98;NOTE_OFF=0x88;}
    else if (channelC==10) {NOTE_ON=0x99;NOTE_OFF=0x89;}
    else if (channelC==11) {NOTE_ON=0xA0;NOTE_OFF=0x8A;}
    else if (channelC==12) {NOTE_ON=0xA1;NOTE_OFF=0x8B;}
    else if (channelC==13) {NOTE_ON=0xA2;NOTE_OFF=0x8C;}
    else if (channelC==14) {NOTE_ON=0xA3;NOTE_OFF=0x8D;}
    else if (channelC==15) {NOTE_ON=0xA4;NOTE_OFF=0x8E;}
    else if (channelC==16) {NOTE_ON=0xA5;NOTE_OFF=0x8F;}
    
}

[toc] | [prev] | [next] | [standalone]


#35253

FromJonas Thörnvall <jonas.thornvall@gmail.com>
Date2018-06-20 11:26 -0700
Message-ID<bfd4f39f-f6dd-4c35-a780-f59df2f24ebf@googlegroups.com>
In reply to#35251
Den onsdag 20 juni 2018 kl. 19:56:02 UTC+2 skrev Jonas Thörnvall:
> Den onsdag 20 juni 2018 kl. 15:37:30 UTC+2 skrev JJ:
> > On Wed, 20 Jun 2018 20:31:22 +0700, JJ wrote:
> > > 
> > > You forgot to take account of the MIDI channel.
> > [snip]
> > 
> > Also... do not assume that a MIDI track is exclusively for a specific MIDI
> > channel. A Channel event may exist in any MIDI track. MIDI tracks are simply
> > a separation of MIDI events in a `MID` file format. They do not exist in the
> > MIDI protocol.
> 
> My editor work like this i have a mixdown channel 0, the code i showed is for listing indivitual channels. But of course i need to make note on note off  channel dependent in the end. Otherwise it will be hard to list and edit the omnitrack.
> 
> "Basicly i downmix to create an omni track zero before playup, its a slow progress programming this so i am not quite there yet", but well on the way.
> 
> But as you say when sorting events in the downmix track, you will have to also check channel of note. And even same output port.
> 
> function sendMidiChannel(){
>     //Set midichannel on the track
>     channelC=document.getElementById("out_channel").selectedIndex+1;
>     if (channelC==1) {NOTE_ON=0x90; NOTE_OFF=0x80;}
>     else if (channelC==2) {NOTE_ON=0x91; NOTE_OFF=0x81;}
>     else if (channelC==3) {NOTE_ON=0x92;NOTE_OFF=0x82;}
>     else if (channelC==4) {NOTE_ON=0x93;NOTE_OFF=0x83;}
>     else if (channelC==5) {NOTE_ON=0x94;NOTE_OFF=0x84;}
>     else if (channelC==6) {NOTE_ON=0x95;NOTE_OFF=0x85;}
>     else if (channelC==7) {NOTE_ON=0x96;NOTE_OFF=0x86;}
>     else if (channelC==8) {NOTE_ON=0x97;NOTE_OFF=0x87;}
>     else if (channelC==9) {NOTE_ON=0x98;NOTE_OFF=0x88;}
>     else if (channelC==10) {NOTE_ON=0x99;NOTE_OFF=0x89;}
>     else if (channelC==11) {NOTE_ON=0xA0;NOTE_OFF=0x8A;}
>     else if (channelC==12) {NOTE_ON=0xA1;NOTE_OFF=0x8B;}
>     else if (channelC==13) {NOTE_ON=0xA2;NOTE_OFF=0x8C;}
>     else if (channelC==14) {NOTE_ON=0xA3;NOTE_OFF=0x8D;}
>     else if (channelC==15) {NOTE_ON=0xA4;NOTE_OFF=0x8E;}
>     else if (channelC==16) {NOTE_ON=0xA5;NOTE_OFF=0x8F;}
>     
> }

But a good thing i can make changes to listTrackEvent without any mapping, because my track object already invoke the "multi channel" data. 
Actually it seem the channel data is already in the midiMessage;
So i do not think i need to check that"note on note off" is already recorded  channel dependent in the midi data. But when i list and sort i have to consider it, "nut not while downmix and play", the info is already there.

function newTrack(m) {
   track[m] ={
     outport:[],
     portname : [],
     midichannel:[],
     program:[],
     midiMess:[],
     //CONFIGURATION OF midiMess:[{time:0,data0:0,data1:0,data2:0}]
   };
    return track;
}

[toc] | [prev] | [next] | [standalone]


#35255

FromJonas Thörnvall <jonas.thornvall@gmail.com>
Date2018-06-20 13:12 -0700
Message-ID<fea358b2-dcac-4315-9998-baba1cadd06f@googlegroups.com>
In reply to#35253
Den onsdag 20 juni 2018 kl. 20:26:52 UTC+2 skrev Jonas Thörnvall:
> Den onsdag 20 juni 2018 kl. 19:56:02 UTC+2 skrev Jonas Thörnvall:
> > Den onsdag 20 juni 2018 kl. 15:37:30 UTC+2 skrev JJ:
> > > On Wed, 20 Jun 2018 20:31:22 +0700, JJ wrote:
> > > > 
> > > > You forgot to take account of the MIDI channel.
> > > [snip]
> > > 
> > > Also... do not assume that a MIDI track is exclusively for a specific MIDI
> > > channel. A Channel event may exist in any MIDI track. MIDI tracks are simply
> > > a separation of MIDI events in a `MID` file format. They do not exist in the
> > > MIDI protocol.
> > 
> > My editor work like this i have a mixdown channel 0, the code i showed is for listing indivitual channels. But of course i need to make note on note off  channel dependent in the end. Otherwise it will be hard to list and edit the omnitrack.
> > 
> > "Basicly i downmix to create an omni track zero before playup, its a slow progress programming this so i am not quite there yet", but well on the way.
> > 
> > But as you say when sorting events in the downmix track, you will have to also check channel of note. And even same output port.
> > 
> > function sendMidiChannel(){
> >     //Set midichannel on the track
> >     channelC=document.getElementById("out_channel").selectedIndex+1;
> >     if (channelC==1) {NOTE_ON=0x90; NOTE_OFF=0x80;}
> >     else if (channelC==2) {NOTE_ON=0x91; NOTE_OFF=0x81;}
> >     else if (channelC==3) {NOTE_ON=0x92;NOTE_OFF=0x82;}
> >     else if (channelC==4) {NOTE_ON=0x93;NOTE_OFF=0x83;}
> >     else if (channelC==5) {NOTE_ON=0x94;NOTE_OFF=0x84;}
> >     else if (channelC==6) {NOTE_ON=0x95;NOTE_OFF=0x85;}
> >     else if (channelC==7) {NOTE_ON=0x96;NOTE_OFF=0x86;}
> >     else if (channelC==8) {NOTE_ON=0x97;NOTE_OFF=0x87;}
> >     else if (channelC==9) {NOTE_ON=0x98;NOTE_OFF=0x88;}
> >     else if (channelC==10) {NOTE_ON=0x99;NOTE_OFF=0x89;}
> >     else if (channelC==11) {NOTE_ON=0xA0;NOTE_OFF=0x8A;}
> >     else if (channelC==12) {NOTE_ON=0xA1;NOTE_OFF=0x8B;}
> >     else if (channelC==13) {NOTE_ON=0xA2;NOTE_OFF=0x8C;}
> >     else if (channelC==14) {NOTE_ON=0xA3;NOTE_OFF=0x8D;}
> >     else if (channelC==15) {NOTE_ON=0xA4;NOTE_OFF=0x8E;}
> >     else if (channelC==16) {NOTE_ON=0xA5;NOTE_OFF=0x8F;}
> >     
> > }
> 
> But a good thing i can make changes to listTrackEvent without any mapping, because my track object already invoke the "multi channel" data. 
> Actually it seem the channel data is already in the midiMessage;
> So i do not think i need to check that"note on note off" is already recorded  channel dependent in the midi data. But when i list and sort i have to consider it, "nut not while downmix and play", the info is already there.
> 
> function newTrack(m) {
>    track[m] ={
>      outport:[],
>      portname : [],
>      midichannel:[],
>      program:[],
>      midiMess:[],
>      //CONFIGURATION OF midiMess:[{time:0,data0:0,data1:0,data2:0}]
>    };
>     return track;
> }

But your mapping approach probably far to advanced for me. I probably go for the range since "i think it only needed for listing/editing not for playing"

if(track[z].midiMess[i].data0>"127" && track[z].midiMess[i].data0<"144"){ 
midiChannelToLookFor=track[z].midiMess[i].data0;
//And the note value is already there ;)
}

What do you think, my solution seem simpler?

[toc] | [prev] | [next] | [standalone]


#35256

FromJonas Thörnvall <jonas.thornvall@gmail.com>
Date2018-06-20 13:15 -0700
Message-ID<0d76bb0e-4c1e-4324-864f-d972a6f76946@googlegroups.com>
In reply to#35255
Den onsdag 20 juni 2018 kl. 22:12:13 UTC+2 skrev Jonas Thörnvall:
> Den onsdag 20 juni 2018 kl. 20:26:52 UTC+2 skrev Jonas Thörnvall:
> > Den onsdag 20 juni 2018 kl. 19:56:02 UTC+2 skrev Jonas Thörnvall:
> > > Den onsdag 20 juni 2018 kl. 15:37:30 UTC+2 skrev JJ:
> > > > On Wed, 20 Jun 2018 20:31:22 +0700, JJ wrote:
> > > > > 
> > > > > You forgot to take account of the MIDI channel.
> > > > [snip]
> > > > 
> > > > Also... do not assume that a MIDI track is exclusively for a specific MIDI
> > > > channel. A Channel event may exist in any MIDI track. MIDI tracks are simply
> > > > a separation of MIDI events in a `MID` file format. They do not exist in the
> > > > MIDI protocol.
> > > 
> > > My editor work like this i have a mixdown channel 0, the code i showed is for listing indivitual channels. But of course i need to make note on note off  channel dependent in the end. Otherwise it will be hard to list and edit the omnitrack.
> > > 
> > > "Basicly i downmix to create an omni track zero before playup, its a slow progress programming this so i am not quite there yet", but well on the way.
> > > 
> > > But as you say when sorting events in the downmix track, you will have to also check channel of note. And even same output port.
> > > 
> > > function sendMidiChannel(){
> > >     //Set midichannel on the track
> > >     channelC=document.getElementById("out_channel").selectedIndex+1;
> > >     if (channelC==1) {NOTE_ON=0x90; NOTE_OFF=0x80;}
> > >     else if (channelC==2) {NOTE_ON=0x91; NOTE_OFF=0x81;}
> > >     else if (channelC==3) {NOTE_ON=0x92;NOTE_OFF=0x82;}
> > >     else if (channelC==4) {NOTE_ON=0x93;NOTE_OFF=0x83;}
> > >     else if (channelC==5) {NOTE_ON=0x94;NOTE_OFF=0x84;}
> > >     else if (channelC==6) {NOTE_ON=0x95;NOTE_OFF=0x85;}
> > >     else if (channelC==7) {NOTE_ON=0x96;NOTE_OFF=0x86;}
> > >     else if (channelC==8) {NOTE_ON=0x97;NOTE_OFF=0x87;}
> > >     else if (channelC==9) {NOTE_ON=0x98;NOTE_OFF=0x88;}
> > >     else if (channelC==10) {NOTE_ON=0x99;NOTE_OFF=0x89;}
> > >     else if (channelC==11) {NOTE_ON=0xA0;NOTE_OFF=0x8A;}
> > >     else if (channelC==12) {NOTE_ON=0xA1;NOTE_OFF=0x8B;}
> > >     else if (channelC==13) {NOTE_ON=0xA2;NOTE_OFF=0x8C;}
> > >     else if (channelC==14) {NOTE_ON=0xA3;NOTE_OFF=0x8D;}
> > >     else if (channelC==15) {NOTE_ON=0xA4;NOTE_OFF=0x8E;}
> > >     else if (channelC==16) {NOTE_ON=0xA5;NOTE_OFF=0x8F;}
> > >     
> > > }
> > 
> > But a good thing i can make changes to listTrackEvent without any mapping, because my track object already invoke the "multi channel" data. 
> > Actually it seem the channel data is already in the midiMessage;
> > So i do not think i need to check that"note on note off" is already recorded  channel dependent in the midi data. But when i list and sort i have to consider it, "nut not while downmix and play", the info is already there.
> > 
> > function newTrack(m) {
> >    track[m] ={
> >      outport:[],
> >      portname : [],
> >      midichannel:[],
> >      program:[],
> >      midiMess:[],
> >      //CONFIGURATION OF midiMess:[{time:0,data0:0,data1:0,data2:0}]
> >    };
> >     return track;
> > }
> 
> But your mapping approach probably far to advanced for me. I probably go for the range since "i think it only needed for listing/editing not for playing"
> 
> if(track[z].midiMess[i].data0>"127" && track[z].midiMess[i].data0<"144"){ 
> midiChannelToLookFor=track[z].midiMess[i].data0;
> //And the note value is already there ;)
> }
> 
> What do you think, my solution seem simpler?

Well i guess i have to add 16 when i look for note off.
OffNoteToLookFor=track[z].midiMess[i].data0+16;

[toc] | [prev] | [next] | [standalone]


#35257

FromJonas Thörnvall <jonas.thornvall@gmail.com>
Date2018-06-20 13:20 -0700
Message-ID<5b3646a2-e950-43b4-9e4b-a7a02e9f39d7@googlegroups.com>
In reply to#35256
Den onsdag 20 juni 2018 kl. 22:15:52 UTC+2 skrev Jonas Thörnvall:
> Den onsdag 20 juni 2018 kl. 22:12:13 UTC+2 skrev Jonas Thörnvall:
> > Den onsdag 20 juni 2018 kl. 20:26:52 UTC+2 skrev Jonas Thörnvall:
> > > Den onsdag 20 juni 2018 kl. 19:56:02 UTC+2 skrev Jonas Thörnvall:
> > > > Den onsdag 20 juni 2018 kl. 15:37:30 UTC+2 skrev JJ:
> > > > > On Wed, 20 Jun 2018 20:31:22 +0700, JJ wrote:
> > > > > > 
> > > > > > You forgot to take account of the MIDI channel.
> > > > > [snip]
> > > > > 
> > > > > Also... do not assume that a MIDI track is exclusively for a specific MIDI
> > > > > channel. A Channel event may exist in any MIDI track. MIDI tracks are simply
> > > > > a separation of MIDI events in a `MID` file format. They do not exist in the
> > > > > MIDI protocol.
> > > > 
> > > > My editor work like this i have a mixdown channel 0, the code i showed is for listing indivitual channels. But of course i need to make note on note off  channel dependent in the end. Otherwise it will be hard to list and edit the omnitrack.
> > > > 
> > > > "Basicly i downmix to create an omni track zero before playup, its a slow progress programming this so i am not quite there yet", but well on the way.
> > > > 
> > > > But as you say when sorting events in the downmix track, you will have to also check channel of note. And even same output port.
> > > > 
> > > > function sendMidiChannel(){
> > > >     //Set midichannel on the track
> > > >     channelC=document.getElementById("out_channel").selectedIndex+1;
> > > >     if (channelC==1) {NOTE_ON=0x90; NOTE_OFF=0x80;}
> > > >     else if (channelC==2) {NOTE_ON=0x91; NOTE_OFF=0x81;}
> > > >     else if (channelC==3) {NOTE_ON=0x92;NOTE_OFF=0x82;}
> > > >     else if (channelC==4) {NOTE_ON=0x93;NOTE_OFF=0x83;}
> > > >     else if (channelC==5) {NOTE_ON=0x94;NOTE_OFF=0x84;}
> > > >     else if (channelC==6) {NOTE_ON=0x95;NOTE_OFF=0x85;}
> > > >     else if (channelC==7) {NOTE_ON=0x96;NOTE_OFF=0x86;}
> > > >     else if (channelC==8) {NOTE_ON=0x97;NOTE_OFF=0x87;}
> > > >     else if (channelC==9) {NOTE_ON=0x98;NOTE_OFF=0x88;}
> > > >     else if (channelC==10) {NOTE_ON=0x99;NOTE_OFF=0x89;}
> > > >     else if (channelC==11) {NOTE_ON=0xA0;NOTE_OFF=0x8A;}
> > > >     else if (channelC==12) {NOTE_ON=0xA1;NOTE_OFF=0x8B;}
> > > >     else if (channelC==13) {NOTE_ON=0xA2;NOTE_OFF=0x8C;}
> > > >     else if (channelC==14) {NOTE_ON=0xA3;NOTE_OFF=0x8D;}
> > > >     else if (channelC==15) {NOTE_ON=0xA4;NOTE_OFF=0x8E;}
> > > >     else if (channelC==16) {NOTE_ON=0xA5;NOTE_OFF=0x8F;}
> > > >     
> > > > }
> > > 
> > > But a good thing i can make changes to listTrackEvent without any mapping, because my track object already invoke the "multi channel" data. 
> > > Actually it seem the channel data is already in the midiMessage;
> > > So i do not think i need to check that"note on note off" is already recorded  channel dependent in the midi data. But when i list and sort i have to consider it, "nut not while downmix and play", the info is already there.
> > > 
> > > function newTrack(m) {
> > >    track[m] ={
> > >      outport:[],
> > >      portname : [],
> > >      midichannel:[],
> > >      program:[],
> > >      midiMess:[],
> > >      //CONFIGURATION OF midiMess:[{time:0,data0:0,data1:0,data2:0}]
> > >    };
> > >     return track;
> > > }
> > 
> > But your mapping approach probably far to advanced for me. I probably go for the range since "i think it only needed for listing/editing not for playing"
> > 
> > if(track[z].midiMess[i].data0>"127" && track[z].midiMess[i].data0<"144"){ 
> > midiChannelToLookFor=track[z].midiMess[i].data0;
> > //And the note value is already there ;)
> > }
> > 
> > What do you think, my solution seem simpler?
> 
> Well i guess i have to add 16 when i look for note off.
> OffNoteToLookFor=track[z].midiMess[i].data0+16;

So...
 while(track[z].midiMess[j].data1!=notenumber && OffNoteToLookFor!=track[z].midiMess[j].data1){//Search until match pair }

[toc] | [prev] | [next] | [standalone]


#35258

FromJonas Thörnvall <jonas.thornvall@gmail.com>
Date2018-06-20 13:26 -0700
Message-ID<6ae07872-4144-4305-8daf-17ea49b39e78@googlegroups.com>
In reply to#35257
Den onsdag 20 juni 2018 kl. 22:20:24 UTC+2 skrev Jonas Thörnvall:
> Den onsdag 20 juni 2018 kl. 22:15:52 UTC+2 skrev Jonas Thörnvall:
> > Den onsdag 20 juni 2018 kl. 22:12:13 UTC+2 skrev Jonas Thörnvall:
> > > Den onsdag 20 juni 2018 kl. 20:26:52 UTC+2 skrev Jonas Thörnvall:
> > > > Den onsdag 20 juni 2018 kl. 19:56:02 UTC+2 skrev Jonas Thörnvall:
> > > > > Den onsdag 20 juni 2018 kl. 15:37:30 UTC+2 skrev JJ:
> > > > > > On Wed, 20 Jun 2018 20:31:22 +0700, JJ wrote:
> > > > > > > 
> > > > > > > You forgot to take account of the MIDI channel.
> > > > > > [snip]
> > > > > > 
> > > > > > Also... do not assume that a MIDI track is exclusively for a specific MIDI
> > > > > > channel. A Channel event may exist in any MIDI track. MIDI tracks are simply
> > > > > > a separation of MIDI events in a `MID` file format. They do not exist in the
> > > > > > MIDI protocol.
> > > > > 
> > > > > My editor work like this i have a mixdown channel 0, the code i showed is for listing indivitual channels. But of course i need to make note on note off  channel dependent in the end. Otherwise it will be hard to list and edit the omnitrack.
> > > > > 
> > > > > "Basicly i downmix to create an omni track zero before playup, its a slow progress programming this so i am not quite there yet", but well on the way.
> > > > > 
> > > > > But as you say when sorting events in the downmix track, you will have to also check channel of note. And even same output port.
> > > > > 
> > > > > function sendMidiChannel(){
> > > > >     //Set midichannel on the track
> > > > >     channelC=document.getElementById("out_channel").selectedIndex+1;
> > > > >     if (channelC==1) {NOTE_ON=0x90; NOTE_OFF=0x80;}
> > > > >     else if (channelC==2) {NOTE_ON=0x91; NOTE_OFF=0x81;}
> > > > >     else if (channelC==3) {NOTE_ON=0x92;NOTE_OFF=0x82;}
> > > > >     else if (channelC==4) {NOTE_ON=0x93;NOTE_OFF=0x83;}
> > > > >     else if (channelC==5) {NOTE_ON=0x94;NOTE_OFF=0x84;}
> > > > >     else if (channelC==6) {NOTE_ON=0x95;NOTE_OFF=0x85;}
> > > > >     else if (channelC==7) {NOTE_ON=0x96;NOTE_OFF=0x86;}
> > > > >     else if (channelC==8) {NOTE_ON=0x97;NOTE_OFF=0x87;}
> > > > >     else if (channelC==9) {NOTE_ON=0x98;NOTE_OFF=0x88;}
> > > > >     else if (channelC==10) {NOTE_ON=0x99;NOTE_OFF=0x89;}
> > > > >     else if (channelC==11) {NOTE_ON=0xA0;NOTE_OFF=0x8A;}
> > > > >     else if (channelC==12) {NOTE_ON=0xA1;NOTE_OFF=0x8B;}
> > > > >     else if (channelC==13) {NOTE_ON=0xA2;NOTE_OFF=0x8C;}
> > > > >     else if (channelC==14) {NOTE_ON=0xA3;NOTE_OFF=0x8D;}
> > > > >     else if (channelC==15) {NOTE_ON=0xA4;NOTE_OFF=0x8E;}
> > > > >     else if (channelC==16) {NOTE_ON=0xA5;NOTE_OFF=0x8F;}
> > > > >     
> > > > > }
> > > > 
> > > > But a good thing i can make changes to listTrackEvent without any mapping, because my track object already invoke the "multi channel" data. 
> > > > Actually it seem the channel data is already in the midiMessage;
> > > > So i do not think i need to check that"note on note off" is already recorded  channel dependent in the midi data. But when i list and sort i have to consider it, "nut not while downmix and play", the info is already there.
> > > > 
> > > > function newTrack(m) {
> > > >    track[m] ={
> > > >      outport:[],
> > > >      portname : [],
> > > >      midichannel:[],
> > > >      program:[],
> > > >      midiMess:[],
> > > >      //CONFIGURATION OF midiMess:[{time:0,data0:0,data1:0,data2:0}]
> > > >    };
> > > >     return track;
> > > > }
> > > 
> > > But your mapping approach probably far to advanced for me. I probably go for the range since "i think it only needed for listing/editing not for playing"
> > > 
> > > if(track[z].midiMess[i].data0>"127" && track[z].midiMess[i].data0<"144"){ 
> > > midiChannelToLookFor=track[z].midiMess[i].data0;
> > > //And the note value is already there ;)
> > > }
> > > 
> > > What do you think, my solution seem simpler?
> > 
> > Well i guess i have to add 16 when i look for note off.
> > OffNoteToLookFor=track[z].midiMess[i].data0+16;
> 
> So...
>  while(track[z].midiMess[j].data1!=notenumber && OffNoteToLookFor!=track[z].midiMess[j].data1){//Search until match pair }

Sorry see now the on start at 144+16 and Off 128+16 but in principle the approach is correct.

[toc] | [prev] | [next] | [standalone]


#35298

FromJonas Thörnvall <jonas.thornvall@gmail.com>
Date2018-06-24 09:17 -0700
Message-ID<df96b044-5afd-4a89-a604-7c2958f7d2ac@googlegroups.com>
In reply to#35245
Den onsdag 20 juni 2018 kl. 15:37:30 UTC+2 skrev JJ:
> On Wed, 20 Jun 2018 20:31:22 +0700, JJ wrote:
> > 
> > You forgot to take account of the MIDI channel.
> [snip]
> 
> Also... do not assume that a MIDI track is exclusively for a specific MIDI
> channel. A Channel event may exist in any MIDI track. MIDI tracks are simply
> a separation of MIDI events in a `MID` file format. They do not exist in the
> MIDI protocol.

Well i took the 15 munutes to fix it today, i think it is correct. But it also check what output port the midievent use. So this sequensers tracks can use both different mididevices and midichannels on same track.

function listTrackMain(z){
  console.log(z);
  eventlist="";var j=0;y=80;x=20;
  containerMain();
  listMainSetting();
  for (var i=0;i<track[z].midiMess.length;i++){
   eventlist="";
   //Generate textstring eventlist
   if(track[z].midiMess[i].data0=="128"){ }
   else if(track[z].midiMess[i].data0=="144"){
       listport=track[z].midiMess[i].outport;
       listchannel=track[z].midiMess[i].midichannel;
       notenumber=track[z].midiMess[i].data1;
       note=getNote(notenumber);
       j=i+1;
       while(track[z].midiMess[j].data1!=notenumber && listport!=track[z].midiMess[j].outport && listchannel!=track[z].midiMess[j].midichannel){
         j++;       
       }
       duration=track[z].midiMess[j].time.toFixed(3)-track[z].midiMess[i].time.toFixed(3);
       eventlist+=note+"  t="+track[z].midiMess[i].time.toFixed(3)+"  Duration "+duration+"  Vel "+track[z].midiMess[i].data2+"\n";
       printEventMain(eventlist,x,y);
       y=y+20;
    } 
  }
}

[toc] | [prev] | [next] | [standalone]


#35299

FromJonas Thörnvall <jonas.thornvall@gmail.com>
Date2018-06-24 09:27 -0700
Message-ID<77160443-3b01-4099-bf4c-0db60f0fcd95@googlegroups.com>
In reply to#35298
Den söndag 24 juni 2018 kl. 18:17:40 UTC+2 skrev Jonas Thörnvall:
> Den onsdag 20 juni 2018 kl. 15:37:30 UTC+2 skrev JJ:
> > On Wed, 20 Jun 2018 20:31:22 +0700, JJ wrote:
> > > 
> > > You forgot to take account of the MIDI channel.
> > [snip]
> > 
> > Also... do not assume that a MIDI track is exclusively for a specific MIDI
> > channel. A Channel event may exist in any MIDI track. MIDI tracks are simply
> > a separation of MIDI events in a `MID` file format. They do not exist in the
> > MIDI protocol.
> 
> Well i took the 15 munutes to fix it today, i think it is correct. But it also check what output port the midievent use. So this sequensers tracks can use both different mididevices and midichannels on same track.
> 
> function listTrackMain(z){
>   console.log(z);
>   eventlist="";var j=0;y=80;x=20;
>   containerMain();
>   listMainSetting();
>   for (var i=0;i<track[z].midiMess.length;i++){
>    eventlist="";
>    //Generate textstring eventlist
>    if(track[z].midiMess[i].data0=="128"){ }
>    else if(track[z].midiMess[i].data0=="144"){
>        listport=track[z].midiMess[i].outport;
>        listchannel=track[z].midiMess[i].midichannel;
>        notenumber=track[z].midiMess[i].data1;
>        note=getNote(notenumber);
>        j=i+1;
>        while(track[z].midiMess[j].data1!=notenumber && listport!=track[z].midiMess[j].outport && listchannel!=track[z].midiMess[j].midichannel){
>          j++;       
>        }
>        duration=track[z].midiMess[j].time.toFixed(3)-track[z].midiMess[i].time.toFixed(3);
>        eventlist+=note+"  t="+track[z].midiMess[i].time.toFixed(3)+"  Duration "+duration+"  Vel "+track[z].midiMess[i].data2+"\n";
>        printEventMain(eventlist,x,y);
>        y=y+20;
>     } 
>   }
> }

I also realised on the way that my strange "out of sequence choppy playup" was due to i did not pair the playup events "off notes", rather silly really.

But of course sending ***in my case outport*** with every event at playup represent an overhead. So depending upon how timeconsuming it tend to be, we will see if i really use multioutputport tracks. 

Did midistandard evolve beyond sending each midichannel to a separate device, could you adress the device/outputport by ID?

The sequenser in my korg N364 seem only to be aware of midichannels, that does not mean there was not sequensers that could use device ID's? 

[toc] | [prev] | [next] | [standalone]


#35247

FromJonas Thörnvall <jonas.thornvall@gmail.com>
Date2018-06-20 10:19 -0700
Message-ID<374aa467-b685-49a8-b1a4-6c2cd52689fa@googlegroups.com>
In reply to#35244
Den onsdag 20 juni 2018 kl. 15:31:28 UTC+2 skrev JJ:
> On Wed, 20 Jun 2018 03:31:03 -0700 (PDT), Jonas Thörnvall wrote:
> 
> > Den onsdag 20 juni 2018 kl. 12:26:26 UTC+2 skrev Jonas Thörnvall:
> >> I have a two valued pair. One value is data let say characters. The other value denotes if it a start or end value. A value can not restart until it ended.
> >> 
> >> I have written an algorithm that match up the start and ends, but i think i got it overly complicated. In reality the start and end values also carry time, but it is not necessary for the actual algorithm. So it is a stepthru algorithm, you can think of the values as an array arr[].ch and arr[].temporal
> >> 
> >> C start
> >> Z start
> >> C end
> >> B start
> >> Z end
> >> B end
> >> C start
> >> K start
> >> R start
> >> R end
> >> K end
> >> C end
> > 
> > Does this look alright?
> > 
> > function listTrackEvents(z){
> >   eventlist="";
> >   for (var i=0;i<track[z].midiMess.length;i++){
> >    //Generate textstring eventlist
> >    if(track[z].midiMess[i].data0=="128"){ }
> >    else if(track[z].midiMess[i].data0=="144"){
> >        notenumber=track[z].midiMess[i].data1;
> >        note=getNote(notenumber);
> >        eventlist+=note;
> >        eventlist+=" t="+track[z].midiMess[i].time.toFixed(3)+"\n"; 
> >        j=i+1;
> >        while(track[z].midiMess[j].data1!=notenumber){
> >          j++;       
> >        }
> >        duration=track[z].midiMess[j].time-track[z].midiMess[i].time;
> >        eventlist+=" Duration "+duration+"\n";
> >        eventlist+=" Vel "+track[z].midiMess[i].data2+"\n";
> >     } 
> >    }
> >   document.getElementById("events").value=eventlist;
> > }
> 
> You forgot to take account of the MIDI channel.
> 
> Use an "note" cache for all 16 MIDI channels. e.g.
> 
>   var noteCache = [
>     {}, {}, {}, {}, {}, {}, {}, {},
>     {}, {}, {}, {}, {}, {}, {}, {}
>   ];
> 
> When encountering a Channel event, store the event's channel number to e.g.
> `channelNum` variable.
> 
> When encountering a NoteOn event, store it in the cache. e.g.
> 
>   if (message.event === msgNoteOn) {
>     noteCache[channelNum][message.noteNumber] = message.time;
>   }
> 
> When encountering a NoteOff event, check it from the "note" cache. If found,
> calculate the duration, then remove it from the cache. e.g.
> 
>   if (message.event === msgNoteOff) {
>     if (message.noteNumber in noteCache[channelNum]) {
>       duration = message.time - noteCache[channelNum][message.noteNumber];
>       delete noteCache[channelNum][message.noteNumber];
>     }
>   }

Oh this is just **listing** maybe later for the editor. I list the notes in order, and find the note off. So these are already recorded notes.

[toc] | [prev] | [next] | [standalone]


#35249

FromJonas Thörnvall <jonas.thornvall@gmail.com>
Date2018-06-20 10:28 -0700
Message-ID<a93219a4-aa9c-48f3-92e5-3e1f8d2ea371@googlegroups.com>
In reply to#35244
Den onsdag 20 juni 2018 kl. 15:31:28 UTC+2 skrev JJ:
> On Wed, 20 Jun 2018 03:31:03 -0700 (PDT), Jonas Thörnvall wrote:
> 
> > Den onsdag 20 juni 2018 kl. 12:26:26 UTC+2 skrev Jonas Thörnvall:
> >> I have a two valued pair. One value is data let say characters. The other value denotes if it a start or end value. A value can not restart until it ended.
> >> 
> >> I have written an algorithm that match up the start and ends, but i think i got it overly complicated. In reality the start and end values also carry time, but it is not necessary for the actual algorithm. So it is a stepthru algorithm, you can think of the values as an array arr[].ch and arr[].temporal
> >> 
> >> C start
> >> Z start
> >> C end
> >> B start
> >> Z end
> >> B end
> >> C start
> >> K start
> >> R start
> >> R end
> >> K end
> >> C end
> > 
> > Does this look alright?
> > 
> > function listTrackEvents(z){
> >   eventlist="";
> >   for (var i=0;i<track[z].midiMess.length;i++){
> >    //Generate textstring eventlist
> >    if(track[z].midiMess[i].data0=="128"){ }
> >    else if(track[z].midiMess[i].data0=="144"){
> >        notenumber=track[z].midiMess[i].data1;
> >        note=getNote(notenumber);
> >        eventlist+=note;
> >        eventlist+=" t="+track[z].midiMess[i].time.toFixed(3)+"\n"; 
> >        j=i+1;
> >        while(track[z].midiMess[j].data1!=notenumber){
> >          j++;       
> >        }
> >        duration=track[z].midiMess[j].time-track[z].midiMess[i].time;
> >        eventlist+=" Duration "+duration+"\n";
> >        eventlist+=" Vel "+track[z].midiMess[i].data2+"\n";
> >     } 
> >    }
> >   document.getElementById("events").value=eventlist;
> > }
> 
> You forgot to take account of the MIDI channel.
> 
> Use an "note" cache for all 16 MIDI channels. e.g.
> 
>   var noteCache = [
>     {}, {}, {}, {}, {}, {}, {}, {},
>     {}, {}, {}, {}, {}, {}, {}, {}
>   ];
> 
> When encountering a Channel event, store the event's channel number to e.g.
> `channelNum` variable.
> 
> When encountering a NoteOn event, store it in the cache. e.g.
> 
>   if (message.event === msgNoteOn) {
>     noteCache[channelNum][message.noteNumber] = message.time;
>   }
> 
> When encountering a NoteOff event, check it from the "note" cache. If found,
> calculate the duration, then remove it from the cache. e.g.
> 
>   if (message.event === msgNoteOff) {
>     if (message.noteNumber in noteCache[channelNum]) {
>       duration = message.time - noteCache[channelNum][message.noteNumber];
>       delete noteCache[channelNum][message.noteNumber];
>     }
>   }

Regarding the note cache, you seem to assume my program function is for "multichannel **recording**" but is just for listing the recorded events in the editor, regarding multichannel recording i am not quite there yet, but i see your point. I would like to make this sequenser a webmidi thingy in the end. And then each user must be able to assign a channel to play.

[toc] | [prev] | [next] | [standalone]


#35250

FromJonas Thörnvall <jonas.thornvall@gmail.com>
Date2018-06-20 10:37 -0700
Message-ID<77006b91-c121-4d94-9ae0-ff2fcaf56409@googlegroups.com>
In reply to#35249
Den onsdag 20 juni 2018 kl. 19:28:09 UTC+2 skrev Jonas Thörnvall:
> Den onsdag 20 juni 2018 kl. 15:31:28 UTC+2 skrev JJ:
> > On Wed, 20 Jun 2018 03:31:03 -0700 (PDT), Jonas Thörnvall wrote:
> > 
> > > Den onsdag 20 juni 2018 kl. 12:26:26 UTC+2 skrev Jonas Thörnvall:
> > >> I have a two valued pair. One value is data let say characters. The other value denotes if it a start or end value. A value can not restart until it ended.
> > >> 
> > >> I have written an algorithm that match up the start and ends, but i think i got it overly complicated. In reality the start and end values also carry time, but it is not necessary for the actual algorithm. So it is a stepthru algorithm, you can think of the values as an array arr[].ch and arr[].temporal
> > >> 
> > >> C start
> > >> Z start
> > >> C end
> > >> B start
> > >> Z end
> > >> B end
> > >> C start
> > >> K start
> > >> R start
> > >> R end
> > >> K end
> > >> C end
> > > 
> > > Does this look alright?
> > > 
> > > function listTrackEvents(z){
> > >   eventlist="";
> > >   for (var i=0;i<track[z].midiMess.length;i++){
> > >    //Generate textstring eventlist
> > >    if(track[z].midiMess[i].data0=="128"){ }
> > >    else if(track[z].midiMess[i].data0=="144"){
> > >        notenumber=track[z].midiMess[i].data1;
> > >        note=getNote(notenumber);
> > >        eventlist+=note;
> > >        eventlist+=" t="+track[z].midiMess[i].time.toFixed(3)+"\n"; 
> > >        j=i+1;
> > >        while(track[z].midiMess[j].data1!=notenumber){
> > >          j++;       
> > >        }
> > >        duration=track[z].midiMess[j].time-track[z].midiMess[i].time;
> > >        eventlist+=" Duration "+duration+"\n";
> > >        eventlist+=" Vel "+track[z].midiMess[i].data2+"\n";
> > >     } 
> > >    }
> > >   document.getElementById("events").value=eventlist;
> > > }
> > 
> > You forgot to take account of the MIDI channel.
> > 
> > Use an "note" cache for all 16 MIDI channels. e.g.
> > 
> >   var noteCache = [
> >     {}, {}, {}, {}, {}, {}, {}, {},
> >     {}, {}, {}, {}, {}, {}, {}, {}
> >   ];
> > 
> > When encountering a Channel event, store the event's channel number to e.g.
> > `channelNum` variable.
> > 
> > When encountering a NoteOn event, store it in the cache. e.g.
> > 
> >   if (message.event === msgNoteOn) {
> >     noteCache[channelNum][message.noteNumber] = message.time;
> >   }
> > 
> > When encountering a NoteOff event, check it from the "note" cache. If found,
> > calculate the duration, then remove it from the cache. e.g.
> > 
> >   if (message.event === msgNoteOff) {
> >     if (message.noteNumber in noteCache[channelNum]) {
> >       duration = message.time - noteCache[channelNum][message.noteNumber];
> >       delete noteCache[channelNum][message.noteNumber];
> >     }
> >   }
> 
> Regarding the note cache, you seem to assume my program function is for "multichannel **recording**" but is just for listing the recorded events in the editor, regarding multichannel recording i am not quite there yet, but i see your point. I would like to make this sequenser a webmidi thingy in the end. And then each user must be able to assign a channel to play.

A SF2 host working direct out of browser or a VSTI host in javascript would be nice.

I see there is a SF2 host in javascript, but it requires installation by the user. For sure one must be able to make a SF2 host right out of the browser.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.javascript


csiph-web