示例#1
0
        private void addTimeSignature(TimeSignature timeSignature)
        {
            if (currentTimeSignature == timeSignature || timeSignature == null)
            {
                if (currentTimeSignature == null)
                {
                    addTimeSignature(new TimeSignature()
                    {
                        NumberOfBeats = 4, TimeOfBeats = 4
                    });
                }
                return;
            }
            else
            {
                currentTimeSignature = timeSignature;
            }

            TimeSignatureBuilder timeSignatureBuilder = new TimeSignatureBuilder();

            timeSignatureBuilder.Numerator = (byte)currentTimeSignature.NumberOfBeats;
            if (IsPowerOfTwo(currentTimeSignature.TimeOfBeats))
            {
                timeSignatureBuilder.Denominator = 8;
            }
            else
            {
                timeSignatureBuilder.Denominator = (byte)currentTimeSignature.TimeOfBeats;
            }
            timeSignatureBuilder.ClocksPerMetronomeClick         = 24;
            timeSignatureBuilder.ThirtySecondNotesPerQuarterNote = 8;
            timeSignatureBuilder.Build();

            sequence[0].Insert(currentTick, timeSignatureBuilder.Result);
        }
示例#2
0
        public void AddMetaData()
        {
            //create metadata track
            Track t = new Track();

            byte[] tempo              = new byte[3];
            int    ms_per_min         = 60000000;
            int    ms_per_quarternote = ms_per_min / FBPM;

            tempo[0] = (byte)((ms_per_quarternote >> 16) & byte.MaxValue);
            tempo[1] = (byte)((ms_per_quarternote >> 8) & byte.MaxValue);
            tempo[2] = (byte)(ms_per_quarternote & byte.MaxValue);
            TempoChangeBuilder tcBuilder = new TempoChangeBuilder(new MetaMessage(MetaType.Tempo, tempo));

            tcBuilder.Build();
            t.Insert(1, tcBuilder.Result);

            byte[] timesignature = new byte[4];
            timesignature[0] = FTimeSignature.Numerator;
            timesignature[1] = (byte)Math.Log(FTimeSignature.Denominator, 2);
            timesignature[2] = FTimeSignature.MetronomePulse;
            timesignature[3] = FTimeSignature.NumberOf32nds;
            TimeSignatureBuilder tsBuilder = new TimeSignatureBuilder(new MetaMessage(MetaType.TimeSignature, timesignature));

            tsBuilder.Build();
            t.Insert(2, tsBuilder.Result);

            FSequence.Add(t);
        }
        public static MetaMessage BuildMessage(int numerator = 4, int denominator = 4, int clocksPerMetronomeClick = 24, int thirtySecondNotesPerQuarterNote = 8)
        {
            var sb = new TimeSignatureBuilder();

            sb.Numerator                       = (byte)numerator;
            sb.Denominator                     = (byte)denominator;
            sb.ClocksPerMetronomeClick         = (byte)clocksPerMetronomeClick;
            sb.ThirtySecondNotesPerQuarterNote = (byte)thirtySecondNotesPerQuarterNote;
            sb.Build();
            return(sb.Result);
        }
        public List <float> TicksPerQuarter(GeneralMidiInstrument inst, bool throwExceptionIfNotFound = false)
        {
            var messages = this.GetOrderedMessages(inst, throwExceptionIfNotFound);
            var meta     = messages
                           .Where(x => x.MidiMessage is MetaMessage)
                           .Select(x => x.MidiMessage as MetaMessage)
                           .Where(x => x.MetaType == MetaType.TimeSignature);

            var time = new TimeSignatureBuilder();

            return(null);
        }
示例#5
0
        private Sequence CreateSequence()
        {
            if (tunes == null || tunes.Count < 2)
            {
                return(null);
            }

            selectedTune = 1;

            SetDefaultValues();
            nextNote = TimeSpan.Zero;
            SetHeaderValues();
            SetHeaderValues(selectedTune, true);
            StartMeasure();

            sequence        = new Sequence(Ppqn);
            sequence.Format = 1;
            metaTrack       = new Track();
            mainTrack       = new Track();
            sequence.Add(metaTrack);
            TempoChangeBuilder tempoBuilder = new TempoChangeBuilder();

            tempoBuilder.Tempo = Tempo;
            tempoBuilder.Build();
            metaTrack.Insert(0, tempoBuilder.Result);
            TimeSignatureBuilder timeBuilder = new TimeSignatureBuilder();

            timeBuilder.Numerator   = timeSigNumerator;
            timeBuilder.Denominator = timeSigDenominator;
            timeBuilder.Build();
            metaTrack.Insert(0, timeBuilder.Result);
            sequence.Add(mainTrack);

            MetaTextBuilder textBuilder = new MetaTextBuilder();

            textBuilder.Type = MetaType.TrackName;
            textBuilder.Text = "Tempo Track";
            textBuilder.Build();
            metaTrack.Insert(0, textBuilder.Result);

            textBuilder      = new MetaTextBuilder();
            textBuilder.Type = MetaType.TrackName;
            textBuilder.Text = "Tune 1";
            textBuilder.Build();
            mainTrack.Insert(0, textBuilder.Result);

            while (tokenIndex < tokens.Count)
            {
                AddNextNote();
            }

            return(sequence);
        }
示例#6
0
        /// <summary>
        /// Adds a MIDI message which sets the time signature
        /// </summary>
        /// <param name="numerator"></param>
        /// <param name="denominator"></param>
        public void SetTimeSignature(byte numerator, byte denominator)
        {
            TimeSignatureBuilder builder = new TimeSignatureBuilder
            {
                Numerator                       = numerator,
                Denominator                     = denominator,
                ClocksPerMetronomeClick         = MetronomePulse,
                ThirtySecondNotesPerQuarterNote = ThirtySecondNotesPerQuarterNote
            };

            builder.Build();
            QueueMessage(builder.Result);
        }
示例#7
0
        public Token Convert(LilypondTokenEnumerator enumerator)
        {
            enumerator.Next();
            var signature = enumerator.Current;

            string[] parts   = signature.TokenText.Split('/');
            var      builder = new TimeSignatureBuilder();

            if (int.TryParse(parts[0], out int count) && int.TryParse(parts[1], out int denominator))
            {
                builder.WithCount(count);
                builder.WithDenominator(denominator);
            }
            return(builder.Build());
        }
示例#8
0
    private void ParseMetaMessage()
    {
        if (trackIndex >= trackData.Length)
        {
            throw new MidiFileException("End of track unexpectedly reached.");
        }

        MetaType type = (MetaType)trackData[trackIndex];

        trackIndex++;

        if (trackIndex >= trackData.Length)
        {
            throw new MidiFileException("End of track unexpectedly reached.");
        }

        if (type == MetaType.EndOfTrack)
        {
            newTrack.EndOfTrackOffset = ticks - previousTicks;

            trackIndex++;
        }
        else
        {
            byte[] data = new byte[ReadVariableLengthValue()];
            Array.Copy(trackData, trackIndex, data, 0, data.Length);
            MetaMessage metaMsg = new MetaMessage(type, data);
            // Record the time signature information
            if (type == MetaType.TimeSignature)
            {
                TimeSignatureBuilder timeSignature = new TimeSignatureBuilder(metaMsg);
                timeSignatureNumerator   = timeSignature.Numerator;
                timeSignatureDenominator = timeSignature.Denominator;
            }
            // Record the track name
            else if (type == MetaType.TrackName)
            {
                MetaTextBuilder trackName = new MetaTextBuilder(metaMsg);
                newTrack.Name = trackName.Text;
            }
            newTrack.Insert(ticks, new MetaMessage(type, data));

            trackIndex += data.Length;
        }
    }
        public GuitarTimeSignature(GuitarMessageList owner, MidiEvent ev)
            : base(owner, ev, null, GuitarMessageType.GuitarTimeSignature)
        {
            if (ev == null)
            {
                SetDownTick(0);
            }
            else
            {
                SetDownEvent(ev);

                var builder = new TimeSignatureBuilder((MetaMessage)ev.Clone());

                Numerator               = builder.Numerator;
                Denominator             = builder.Denominator;
                ClocksPerMetronomeClick = builder.ClocksPerMetronomeClick;

                ThirtySecondNotesPerQuarterNote = builder.ThirtySecondNotesPerQuarterNote;
            }
        }
示例#10
0
        private void ProcessTimeSignature(MetaMessage message)
        {
            var builder = new TimeSignatureBuilder(message);

            this.TimeSignature = new TimeSignature(builder.Numerator, builder.Denominator);
        }
示例#11
0
        private void importMIDIToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (importDlg.ShowDialog(this)
                == System.Windows.Forms.DialogResult.Cancel)
            {
                return;
            }

            List <PNote> notes   = new List <PNote>();
            PNote        curNote = PNote.Default;
            float        tempo   = 1;
            float        timeSig = 4f;

            // first, we pull midi data
            Sequence s = new Sequence(importDlg.FileName);

            // quickly see if there's a piano track first
            // and get the tempo as well
            int piano = -1;

            for (int it = 0; it < s.Count; it++)
            {
                Track t = s[it];
                foreach (MidiEvent me in t.Iterator())
                {
                    switch (me.MidiMessage.MessageType)
                    {
                    case MessageType.Channel:
                    {
                        ChannelMessage m = (ChannelMessage)me.MidiMessage;
                        if (m.Command == ChannelCommand.ProgramChange)
                        {
                            if ((GeneralMidiInstrument)m.Data1 == GeneralMidiInstrument.AcousticGrandPiano)
                            {
                                piano = it;
                            }
                        }
                    }
                    break;

                    case MessageType.Meta:
                    {
                        MetaMessage m = (MetaMessage)me.MidiMessage;
                        if (m.MetaType == MetaType.Tempo)
                        {
                            tempo = (new TempoChangeBuilder(m)).Tempo;
                        }
                        else if (m.MetaType == MetaType.TimeSignature)
                        {
                            timeSig = new TimeSignatureBuilder(m).Denominator;
                        }
                    }
                    break;
                    }
                    if (piano >= 0)
                    {
                        break;
                    }
                }
                if (piano >= 0)
                {
                    break;
                }
            }

            // didn't find one, so just try 0th track anyway
            if (piano == -1)
            {
                piano = 0;
            }

            // now, pull all notes (and tempo)
            // and make sure it's a channel that has content
            for (int it = piano; it < s.Count; it++)
            {
                Track t = s[it];

                int delta = 0;
                foreach (MidiEvent me in t.Iterator())
                {
                    delta += me.DeltaTicks;

                    switch (me.MidiMessage.MessageType)
                    {
                    case MessageType.Channel:
                    {
                        ChannelMessage m = (ChannelMessage)me.MidiMessage;
                        switch (m.Command)
                        {
                        case ChannelCommand.NoteOn:
                            if (curNote.Note != "")
                            {
                                curNote.Length = delta / 1000F;
                                delta          = 0;
                                notes.Add(curNote);
                            }

                            curNote.Note = note2Piano(m.Data1);
                            break;
                        }
                    }
                    break;

                    case MessageType.Meta:
                    {
                        MetaMessage m = (MetaMessage)me.MidiMessage;
                        if (m.MetaType == MetaType.Tempo)
                        {
                            tempo = (new TempoChangeBuilder(m)).Tempo;
                        }
                    }
                    break;
                    }
                }

                // make sure we get last note
                if (curNote.Note != "")
                {
                    curNote.Length = delta / 1000F;
                    notes.Add(curNote);
                }

                // we found a track with content!
                if (notes.Count > 0)
                {
                    break;
                }
            }

            // compress redundant accidentals/octaves
            char[] notemods = new char[7];
            int[]  noteocts = new int[7];
            for (int i = 0; i < 7; i++)
            {
                notemods[i] = 'n';
                noteocts[i] = 3;
            }
            for (int i = 0; i < notes.Count; i++)
            {
                string noteStr  = notes[i].Note;
                int    cur_note = noteStr[0] - 0x41;
                char   mod      = noteStr[1];
                int    oct      = int.Parse(noteStr.Substring(2));

                noteStr = noteStr.Substring(0, 1);
                if (mod != notemods[cur_note])
                {
                    noteStr           += new string(mod, 1);
                    notemods[cur_note] = mod;
                }
                if (oct != noteocts[cur_note])
                {
                    noteStr           += oct.ToString();
                    noteocts[cur_note] = oct;
                }

                notes[i] = new PNote(notes[i].Length, noteStr);
            }

            // now, we find what the "beat" length should be,
            // by counting numbers of times for each length, and finding statistical mode
            Dictionary <float, int> scores = new Dictionary <float, int>();

            foreach (PNote n in notes)
            {
                if (n.Length != 0)
                {
                    if (scores.Keys.Contains(n.Length))
                    {
                        scores[n.Length]++;
                    }
                    else
                    {
                        scores.Add(n.Length, 1);
                    }
                }
            }
            float winner = 1;
            int   score  = 0;

            foreach (KeyValuePair <float, int> kv in scores)
            {
                if (kv.Value > score)
                {
                    winner = kv.Key;
                    score  = kv.Value;
                }
            }
            // realign all of them to match beat length
            for (int i = 0; i < notes.Count; i++)
            {
                notes[i] = new PNote(notes[i].Length / winner, notes[i].Note);
            }

            // compress chords down
            for (int i = 0; i < notes.Count; i++)
            {
                if (notes[i].Length == 0 && i < notes.Count - 1)
                {
                    notes[i + 1] = new PNote(notes[i + 1].Length, notes[i].Note + "-" + notes[i + 1].Note);
                    notes.RemoveAt(i);
                    i--;
                }
            }

            // add in time
            for (int i = 0; i < notes.Count; i++)
            {
                float len = notes[i].Length;
                notes[i] = new PNote(len, notes[i].Note + (len != 1 ? "/" + (1 / len).ToString("0.##") : ""));
            }

            // what is the bpm, anyway?
            int rpm = (int)(28800000 / tempo / winner); // 60 * 1,000,000 * .48  the .48 is because note lengths for some reason midi makes the beat note be .48 long

            // now, output!
            string line      = "";
            string output    = "";
            int    lineCount = 1;

            foreach (PNote n in notes)
            {
                if (line.Length + n.Note.Length + 1 > 51)
                {
                    output += line.Substring(0, line.Length - 1) + "\r\n";
                    line    = "";
                    if (lineCount == 500)
                    {
                        break;
                    }
                    lineCount++;
                }
                line += n.Note + ",";
            }
            if (line.Length > 0)
            {
                output += line.Substring(0, line.Length - 1);
            }
            OutputTxt.Text = "BPM: " + rpm.ToString() + "\r\n" + output;
            OutputTxt.SelectAll();
        }