示例#1
0
        private void SaveMuzak(string filename)
        {
            AudioSynthesis.Sequencer.MidiFileSequencer mseq = st.mseq;
            MidiMessage[] mdata = mseq.mdata;

            double time     = 0;
            int    maxPixel = this.Width;

            Dictionary <int, MidiMessage> last     = new Dictionary <int, MidiMessage>();
            Dictionary <int, double>      lastTime = new Dictionary <int, double>();



            Dictionary <byte, int> priorities = noteViewer1.ChannelPriorities;



            //<midiFreq,
            int[] axisPlayingPriority = new int[nAxes];
            Array.Clear(axisPlayingPriority, 0, nAxes);

            Dictionary <int, Tuple <int, List <Tuple <int, int> > > > muzak = new Dictionary <int, Tuple <int, List <Tuple <int, int> > > >();
            //muzak = Dictionary<timestamp, Tuple<Duration, List<Tuple<priority, midiFreq>>>>
            //i.e. the song is divided into pieces of time, where each slice has a number of notes that should play.
            //We'll try to play them in priority order, depending on chords and what was playing previously...

            SortedDictionary <int, List <MuzakNote> > currentNotes = new SortedDictionary <int, List <MuzakNote> >();


            int lastTimeStamp = 0;

            foreach (MidiMessage mm in mdata)
            {
                if (mm.channel == 255)
                {
                    continue;
                }

                time = (double)mm.delta;
                if (!noteViewer1.ChannelPriorities.ContainsKey(mm.channel))
                {
                    continue;
                }


                bool startOk = time >= noteViewer1.startTime || noteViewer1.startTime < 0;
                bool endOk   = time <= noteViewer1.endTime || noteViewer1.endTime < 0;
                if (startOk && endOk)
                {
                    if (lastTime.Count == 0)
                    {
                        foreach (var c in channels)
                        {
                            lastTime.Add(c, time);
                        }
                    }

                    if (!last.ContainsKey(mm.channel))
                    {
                        last.Add(mm.channel, new MidiMessage(mm.channel, 0, 0, 0));
                    }



                    long us = (long)(time - lastTime[mm.channel]);



                    if (mm.command == (int)MidiEventTypeEnum.NoteOn || mm.command == (int)MidiEventTypeEnum.NoteOff)
                    {
                        int currentTimeStamp = mm.delta;
                        int timeDelta        = currentTimeStamp - lastTimeStamp;
                        if (timeDelta > 0)
                        {
                            List <Tuple <int, int> > timeSlice = new List <Tuple <int, int> >();
                            muzak.Add(lastTimeStamp, new Tuple <int, List <Tuple <int, int> > >(timeDelta, timeSlice));

                            //muzak = Dictionary<timestamp, List<Tuple<priority, midiFreq>>>
                            //i.e. the song is divided into pieces of time, where each slice has a number of notes that should play.
                            //We'll try to play them in priority order, depending on chords and what was playing previously...


                            foreach (var x in currentNotes)
                            {
                                int pri = x.Key;
                                foreach (var note in x.Value)
                                {
                                    timeSlice.Add(new Tuple <int, int>(pri, note.midiFreq));
                                }
                            }


                            lastTimeStamp = mm.delta;
                        }
                        //List<List<MuzakNote>> toOutput = new List<List<MuzakNote>>();
                        //foreach (int pri in currentNotes.Keys)
                        //{
                        //    toOutput.Add(currentNotes[pri]);

                        //    Console.Write(String.Join(", ", currentNotes[pri]) + " | ");
                        //}
                        //Console.WriteLine("");
                    }

                    if (mm.command == (int)MidiEventTypeEnum.NoteOn)
                    {
                        int pri     = priorities[mm.channel];
                        var toStart = new MuzakNote(mm.data1, pri, mm.channel);

                        if (currentNotes.ContainsKey(pri))
                        {
                            currentNotes[pri].Add(toStart);
                        }
                        else
                        {
                            currentNotes.Add(pri, new List <MuzakNote>()
                            {
                                toStart
                            });
                        }
                    }
                    else if (mm.command == (int)MidiEventTypeEnum.NoteOff)
                    {
                        MuzakNote toEnd         = null;
                        bool      multipleNotes = false;
                        foreach (var notes in currentNotes.Values)
                        {
                            foreach (var note in notes)
                            {
                                if (note.channel == mm.channel && note.midiFreq == mm.data1)
                                {
                                    toEnd         = note;
                                    multipleNotes = notes.Count > 1;
                                }
                            }
                        }

                        if (toEnd != null)
                        {
                            if (multipleNotes)
                            {
                                currentNotes[toEnd.priority].Remove(toEnd); //Remove note from list at this priority
                            }
                            else
                            {
                                currentNotes.Remove(toEnd.priority); //Remove this entire priority
                            }
                        }
                    }

                    last[mm.channel]     = mm;
                    lastTime[mm.channel] = time;
                }
            }


            WriteMuzak(filename, muzak);
        }
示例#2
0
        public static MuzakNote Delay(long _length, byte _channel)
        {
            MuzakNote n = new MuzakNote(0, _length, 0, _channel);

            return(n);
        }