示例#1
0
        private static void TestRemoveAt()
        {
            Track          a       = new Track();
            ChannelMessage message = new ChannelMessage(ChannelCommand.NoteOff, 0, 60, 0);

            a.Insert(0, message);
            a.Insert(10, message);
            a.Insert(20, message);
            a.Insert(30, message);
            a.Insert(40, message);

            int count = a.Count;

            a.RemoveAt(0);

            Debug.Assert(a.Count == count - 1);

            a.RemoveAt(a.Count - 2);

            Debug.Assert(a.Count == count - 2);
            Debug.Assert(a.GetMidiEvent(0).AbsoluteTicks == 10);
            Debug.Assert(a.GetMidiEvent(a.Count - 2).AbsoluteTicks == 30);

            a.RemoveAt(0);
            a.RemoveAt(0);
            a.RemoveAt(0);

            Debug.Assert(a.Count == 1);
        }
示例#2
0
        private void ReadMetaLyric(string[] ar)
        {
            string sy = string.Empty;

            if (ar.Length != 4)
            {
                if (ar.Length < 4)
                {
                    throw new ArgumentException("Meta Lyric Length");
                }

                for (int i = 3; i < ar.Length; i++)
                {
                    sy += ar[i];
                }
            }
            else
            {
                sy = ar[3];
            }
            // Format: Track, Time, Lyric_t, Text
            int ticks = Convert.ToInt32(ar[1]);

            byte[]      newdata = Encoding.Default.GetBytes(sy);
            MetaMessage mtMsg   = new MetaMessage(MetaType.Lyric, newdata);

            track.Insert(ticks, mtMsg);
            manageMetaLyrics(newdata, ticks);
        }
        private static void TestRemoveAt()
        {
            Track a = new Track();
            ChannelMessage message = new ChannelMessage(ChannelCommand.NoteOff, 0, 60, 0);

            a.Insert(0, message);
            a.Insert(10, message);
            a.Insert(20, message);
            a.Insert(30, message);
            a.Insert(40, message);

            int count = a.Count;

            a.RemoveAt(0);

            Debug.Assert(a.Count == count - 1);

            a.RemoveAt(a.Count - 2);

            Debug.Assert(a.Count == count - 2);
            Debug.Assert(a.GetMidiEvent(0).AbsoluteTicks == 10);
            Debug.Assert(a.GetMidiEvent(a.Count - 2).AbsoluteTicks == 30);

            a.RemoveAt(0);
            a.RemoveAt(0);
            a.RemoveAt(0);

            Debug.Assert(a.Count == 1);
        }
示例#4
0
		private static void TestGunshotTrack(Sequence sequence)
		{
			var track = new Track();

			track.Insert(0, new ChannelMessage(ChannelCommand.ProgramChange, 1, 127));
			track.Insert(0, new ChannelMessage(ChannelCommand.NoteOn, 1, 35, 127));
			track.Insert(100, new ChannelMessage(ChannelCommand.NoteOff, 1, 35, 0));

			track.Insert(101, new ChannelMessage(ChannelCommand.NoteOn, 1, 76, 127));
			track.Insert(200, new ChannelMessage(ChannelCommand.NoteOff, 1, 76, 0));
			sequence.Add(track);
		}
示例#5
0
        private static void TestInsert()
        {
            Track          track            = new Track();
            int            midiEventCount   = 2000;
            int            positionMax      = 32000;
            int            endOfTrackOffset = 1000;
            int            length           = 0;
            int            position         = 0;
            ChannelMessage message          = new ChannelMessage(ChannelCommand.NoteOff, 0, 60, 0);
            Random         r = new Random();

            for (int i = 0; i < midiEventCount; i++)
            {
                position = r.Next(positionMax);

                if (position > length)
                {
                    length = position;
                }

                track.Insert(position, message);
            }

            track.EndOfTrackOffset = endOfTrackOffset;

            length += track.EndOfTrackOffset;

            Debug.Assert(track.Count == midiEventCount + 1);
            Debug.Assert(track.Length == length);
        }
        private static void TestInsert()
        {
            Track track = new Track();
            int midiEventCount = 2000;
            int positionMax = 32000;
            int endOfTrackOffset = 1000;
            int length = 0;
            int position = 0;
            ChannelMessage message = new ChannelMessage(ChannelCommand.NoteOff, 0, 60, 0);
            Random r = new Random();

            for(int i = 0; i < midiEventCount; i++)
            {
                position = r.Next(positionMax);

                if(position > length)
                {
                    length = position;
                }

                track.Insert(position, message);
            }

            track.EndOfTrackOffset = endOfTrackOffset;

            length += track.EndOfTrackOffset;

            Debug.Assert(track.Count == midiEventCount + 1);
            Debug.Assert(track.Length == length);
        }
示例#7
0
        private static void TestMerge()
        {
            Track a = new Track();
            Track b = new Track();

            a.Merge(b);

            Debug.Assert(a.Count == 1);

            ChannelMessage message = new ChannelMessage(ChannelCommand.NoteOff, 0, 60, 0);

            b.Insert(0, message);
            b.Insert(10, message);
            b.Insert(20, message);
            b.Insert(30, message);
            b.Insert(40, message);

            a.Merge(b);

            Debug.Assert(a.Count == 1 + b.Count - 1);

            a.Clear();

            Debug.Assert(a.Count == 1);

            a.Insert(0, message);
            a.Insert(10, message);
            a.Insert(20, message);
            a.Insert(30, message);
            a.Insert(40, message);

            int count = a.Count;

            a.Merge(b);

            Debug.Assert(a.Count == count + b.Count - 1);
            Debug.Assert(a.GetMidiEvent(0).DeltaTicks == 0);
            Debug.Assert(a.GetMidiEvent(1).DeltaTicks == 0);
            Debug.Assert(a.GetMidiEvent(2).DeltaTicks == 10);
            Debug.Assert(a.GetMidiEvent(3).DeltaTicks == 0);
            Debug.Assert(a.GetMidiEvent(4).DeltaTicks == 10);
            Debug.Assert(a.GetMidiEvent(5).DeltaTicks == 0);
            Debug.Assert(a.GetMidiEvent(6).DeltaTicks == 10);
            Debug.Assert(a.GetMidiEvent(7).DeltaTicks == 0);
            Debug.Assert(a.GetMidiEvent(8).DeltaTicks == 10);
            Debug.Assert(a.GetMidiEvent(9).DeltaTicks == 0);
        }
示例#8
0
        public void Build()
        {
            result = new Track();
            buffer.Sort(new TimestampComparer());

            foreach (TimestampedMessage tm in buffer)
            {
                result.Insert(tm.ticks, tm.message);
            }
        }
示例#9
0
        private void ParseChannelMessage()
        {
            if (trackIndex >= trackData.Length)
            {
                throw new MidiFileException("End of track unexpectedly reached.");
            }

            cmBuilder.Command     = ChannelMessage.UnpackCommand(status);
            cmBuilder.MidiChannel = ChannelMessage.UnpackMidiChannel(status);
            cmBuilder.Data1       = trackData[trackIndex];

            trackIndex++;

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

                cmBuilder.Data2 = trackData[trackIndex];

                trackIndex++;
            }

            cmBuilder.Build();
            newTrack.Insert(ticks, cmBuilder.Result);
            runningStatus = status;
        }
示例#10
0
        private void ParseChannelMessage()
        {
            if (trackIndex >= trackData.Length)
            {
                throw new MidiFileException("End of track unexpectedly reached.");
            }

            var command = ChannelMessage.UnpackCommand(status);
            var channel = ChannelMessage.UnpackMidiChannel(status);
            var data1   = trackData[trackIndex];

            trackIndex++;
            var data2 = 0;

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

                data2 = trackData[trackIndex];

                trackIndex++;
            }

            newTrack.Insert(ticks, new ChannelMessage(command, data1, data2, channel));
            runningStatus = status;
        }
示例#11
0
        public static void Save(List<List<Event>> allEvents, string path)
        {
            Sequence sequence = new Sequence();

            Dictionary<int, Track> tracks = new Dictionary<int, Track>();

            for (int trackIndex = 0; trackIndex < allEvents.Count; trackIndex++)
            {
                Track track = new Track();
                sequence.Add(track);
                List<Event> trackEvents = allEvents[trackIndex];
                foreach (var midiEvent in trackEvents.Select(trackEvent => new { Tick = trackEvent.Tick, MidiMessage = Convert(trackEvent, track) }))
                {
                    track.Insert(midiEvent.Tick, midiEvent.MidiMessage);
                }
            }

            sequence.Save(path);
        }
示例#12
0
        /// <summary>
        /// Create new track and add it to the list newtracks
        /// </summary>
        private void CreateTrack()
        {
            track = new Track()
            {
                MidiChannel    = Channel,
                Name           = TrackName,
                InstrumentName = InstrumentName,
                ProgramChange  = ProgramChange,
                Volume         = Volume,
                Pan            = Pan,
                Reverb         = Reverb,
            };


            ChannelMessage message = new ChannelMessage(ChannelCommand.ProgramChange, track.MidiChannel, track.ProgramChange, 0);

            track.Insert(0, message);

            newTracks.Add(track);
        }
示例#13
0
		private static void TestPianoTrack(Sequence sequence)
		{
			var track = new Track();

			track.Insert(0, new ChannelMessage(ChannelCommand.ProgramChange, 0, 0));
			track.Insert(0, new ChannelMessage(ChannelCommand.NoteOn, 0, 35, 127));
			track.Insert(100, new ChannelMessage(ChannelCommand.NoteOff, 0, 35, 0));

			track.Insert(101, new ChannelMessage(ChannelCommand.NoteOn, 0, 76, 127));
			track.Insert(200, new ChannelMessage(ChannelCommand.NoteOff, 0, 76, 0));

			for (int i = 0; i < 1000; i += 10)
			{
				track.Insert(i, new ChannelMessage(ChannelCommand.NoteOn, 0, 76, 127));
				track.Insert(i + 9, new ChannelMessage(ChannelCommand.NoteOff, 0, 76));
			}

			sequence.Add(track);
		}
示例#14
0
        public void Start()
        {
            #region Require

            if(disposed)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }

            #endregion           


            List<Track> newTracks = new List<Track>();
            for (int i=0; i<Sequence.Count; i++)
            {
                Track t = new Track();
                foreach (MidiEvent e in Sequence[i].Iterator())
                {
                    bool discard = false;
                    if (e.MidiMessage.MessageType == MessageType.Channel)
                    {
                        ChannelMessage m = (e.MidiMessage as ChannelMessage);
                        if (m.Command == ChannelCommand.Controller && (m.Data1 == (int)ControllerType.Volume || m.Data1 == (int)ControllerType.VolumeFine))
                        {
                            discard = true;
                        }
                    }
                    if (!discard) t.Insert(e.AbsoluteTicks, e.MidiMessage);
                }
                Sequence.Remove(Sequence[i]);
                /*if (i == 0)*/ newTracks.Add(t);
            }
            foreach (Track t in newTracks)
                Sequence.Add(t);
            foreach (MidiEvent e in Sequence[0].Iterator())
            {
                if (e.MidiMessage.MessageType == MessageType.Channel)
                {
                    ChannelMessage m = (e.MidiMessage as ChannelMessage);
                    if (m.Command == ChannelCommand.NoteOn)
                    {
                        int a = e.AbsoluteTicks ;
                    }
                }
            }
            //for (int i=0; i<4; i++)
            //    Sequence[i].Insert(1, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.Volume, 0 ));

            lock(lockObject)
            {


                Stop();

                Position = 0;

                Continue();
            }
        }
示例#15
0
            private void onLoad(object sender, EventArgs args)
            {
                List<Track> newTracks = new List<Track>();
                for (int i = 0; i < sequence1.Count; i++)
                {
                    Track t = new Track();
                    foreach (MidiEvent e in sequence1[i].Iterator())
                    {
                        bool discard = false;
                        if (e.MidiMessage.MessageType == MessageType.Channel)
                        {
                            ChannelMessage m = (e.MidiMessage as ChannelMessage);
                            if (m.Command == ChannelCommand.Controller && (m.Data1 == (int)ControllerType.Volume || m.Data1 == (int)ControllerType.VolumeFine))
                            {
                                discard = true;
                            }
                        }
                        if (!discard) t.Insert(e.AbsoluteTicks, e.MidiMessage);
                    }
                    sequence1.Remove(sequence1[i]);
                    /*if (i == 0)*/
                    newTracks.Add(t);
                }
                foreach (Track t in newTracks)
                    sequence1.Add(t);
                foreach (MidiEvent e in sequence1[0].Iterator())
                {
                    if (e.MidiMessage.MessageType == MessageType.Channel)
                    {
                        ChannelMessage m = (e.MidiMessage as ChannelMessage);
                        if (m.Command == ChannelCommand.NoteOn)
                        {
                            int a = e.AbsoluteTicks;
                        }
                    }
                }
                //for (int i=0; i<4; i++)
                //    Sequence[i].Insert(1, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.Volume, 0 ));


                // then we return to loader code
                if (loadComplete != null)
                    loadComplete();
            }
示例#16
0
        private Sequence GetSequenceFromWPFStaffs(List <MusicalSymbol> WPFStaffs, Models.Track track)
        {
            List <string> notesOrderWithCrosses = new List <string>()
            {
                "c", "cis", "d", "dis", "e", "f", "fis", "g", "gis", "a", "ais", "b"
            };
            int absoluteTicks = 0;

            Sequence sequence = new Sequence();

            Sanford.Multimedia.Midi.Track metaTrack = new Sanford.Multimedia.Midi.Track();
            sequence.Add(metaTrack);

            // Calculate tempo
            var bar = (Bar)track.GetStaffs().Last().Bars.Last();

            int speed = (60000000 / bar.BarContext.BeatsPerMinute);

            byte[] tempo = new byte[3];
            tempo[0] = (byte)((speed >> 16) & 0xff);
            tempo[1] = (byte)((speed >> 8) & 0xff);
            tempo[2] = (byte)(speed & 0xff);
            metaTrack.Insert(0 /* Insert at 0 ticks*/, new MetaMessage(MetaType.Tempo, tempo));

            Sanford.Multimedia.Midi.Track notesTrack = new Sanford.Multimedia.Midi.Track();
            sequence.Add(notesTrack);

            for (int i = 0; i < WPFStaffs.Count; i++)
            {
                var musicalSymbol = WPFStaffs[i];
                switch (musicalSymbol.Type)
                {
                case MusicalSymbolType.Note:
                    PSAMControlLibrary.Note note = musicalSymbol as PSAMControlLibrary.Note;

                    // Calculate duration
                    double absoluteLength = 1.0 / (double)note.Duration;
                    absoluteLength += (absoluteLength / 2.0) * note.NumberOfDots;

                    double relationToQuartNote  = bar.BarContext.BeatsInBar.Item2 / 4.0;
                    double percentageOfBeatNote = (1.0 / bar.BarContext.BeatsInBar.Item2) / absoluteLength;
                    double deltaTicks           = (sequence.Division / relationToQuartNote) / percentageOfBeatNote;

                    // Calculate height
                    int noteHeight = notesOrderWithCrosses.IndexOf(note.Step.ToLower()) + ((note.Octave + 1) * 12);
                    noteHeight += note.Alter;
                    notesTrack.Insert(absoluteTicks, new ChannelMessage(ChannelCommand.NoteOn, 1, noteHeight, 90));     // Data2 = volume

                    absoluteTicks += (int)deltaTicks;
                    notesTrack.Insert(absoluteTicks, new ChannelMessage(ChannelCommand.NoteOn, 1, noteHeight, 0));     // Data2 = volume

                    break;

                case MusicalSymbolType.TimeSignature:
                    byte[] timeSignature = new byte[4];
                    // timeSignature[0] = (byte)_beatsPerBar;
                    //timeSignature[1] = (byte)(Math.Log(_beatNote) / Math.Log(2));
                    metaTrack.Insert(absoluteTicks, new MetaMessage(MetaType.TimeSignature, timeSignature));
                    break;

                default:
                    break;
                }
            }

            notesTrack.Insert(absoluteTicks, MetaMessage.EndOfTrackMessage);
            metaTrack.Insert(absoluteTicks, MetaMessage.EndOfTrackMessage);
            return(sequence);
        }
示例#17
0
        public override void SaveAsMIDI(string fileName)
        {
            if (NumTracks == 0)
            {
                throw new InvalidDataException("This song has no tracks.");
            }

            CalculateTicks();
            var midi = new Sequence(24)
            {
                Format = 1
            };
            var metaTrack = new Sanford.Multimedia.Midi.Track();

            midi.Add(metaTrack);

            for (int i = 0; i < NumTracks; i++)
            {
                var track = new Sanford.Multimedia.Midi.Track();
                midi.Add(track);

                int endOfPattern = 0, startOfPatternTicks = 0, endOfPatternTicks = 0, shift = 0;
                var playing = new List <M4ANoteCommand>();

                for (int j = 0; j < Commands[i].Count; j++)
                {
                    var e     = Commands[i][j];
                    int ticks = e.AbsoluteTicks + (endOfPatternTicks - startOfPatternTicks);

                    switch (e.Command)
                    {
                    case KeyShiftCommand keysh:
                        shift = keysh.Shift;
                        break;

                    case M4ANoteCommand note:
                        int n = (note.Note + shift).Clamp(0, 0x7F);
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.NoteOn, i, n, note.Velocity));
                        if (note.Duration != -1)
                        {
                            track.Insert(ticks + note.Duration, new ChannelMessage(ChannelCommand.NoteOff, i, n));
                        }
                        else
                        {
                            playing.Add(note);
                        }
                        break;

                    case EndOfTieCommand eot:
                        M4ANoteCommand nc = null;

                        if (eot.Note == -1)
                        {
                            nc = playing.LastOrDefault();
                        }
                        else
                        {
                            nc = playing.LastOrDefault(no => no.Note == eot.Note);
                        }

                        if (nc != null)
                        {
                            n = (nc.Note + shift).Clamp(0, 0x7F);
                            track.Insert(ticks, new ChannelMessage(ChannelCommand.NoteOff, i, n));
                            playing.Remove(nc);
                        }
                        break;

                    case PriorityCommand prio:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.VolumeFine, prio.Priority));
                        break;

                    case VoiceCommand voice:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.ProgramChange, i, voice.Voice));
                        break;

                    case VolumeCommand vol:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.Volume, vol.Volume));
                        break;

                    case PanpotCommand pan:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.Pan, pan.Panpot + 0x40));
                        break;

                    case BendCommand bend:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.PitchWheel, i, 0, bend.Bend + 0x40));
                        break;

                    case BendRangeCommand bendr:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 20, bendr.Range));
                        break;

                    case LFOSpeedCommand lfos:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 21, lfos.Speed));
                        break;

                    case LFODelayCommand lfodl:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 26, lfodl.Delay));
                        break;

                    case ModDepthCommand mod:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.ModulationWheel, mod.Depth));
                        break;

                    case ModTypeCommand modt:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 22, modt.Type));
                        break;

                    case TuneCommand tune:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 24, tune.Tune));
                        break;

                    case LibraryCommand xcmd:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 30, xcmd.Command));
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 29, xcmd.Argument));
                        break;

                    case TempoCommand tempo:
                        var change = new TempoChangeBuilder {
                            Tempo = (60000000 / tempo.Tempo)
                        };
                        change.Build();
                        metaTrack.Insert(ticks, change.Result);
                        break;

                    case CallCommand patt:
                        int callCmd = Commands[i].FindIndex(c => c.GetOffset() == patt.Offset);
                        endOfPattern      = j;
                        endOfPatternTicks = e.AbsoluteTicks;
                        j = callCmd - 1;     // -1 for incoming ++
                        startOfPatternTicks = Commands[i][j + 1].AbsoluteTicks;
                        break;

                    case ReturnCommand _:
                        if (endOfPattern != 0)
                        {
                            j            = endOfPattern;
                            endOfPattern = startOfPatternTicks = endOfPatternTicks = 0;
                        }
                        break;

                    case GoToCommand goTo:
                        if (i == 0)
                        {
                            int jumpCmd = Commands[i].FindIndex(c => c.GetOffset() == goTo.Offset);
                            metaTrack.Insert(Commands[i][jumpCmd].AbsoluteTicks, new MetaMessage(MetaType.Marker, new byte[] { (byte)'[' }));
                            metaTrack.Insert(ticks, new MetaMessage(MetaType.Marker, new byte[] { (byte)']' }));
                        }
                        break;

                    case FinishCommand _:
                        goto endOfTrack;
                    }
                }

                endOfTrack :;
            }
            midi.Save(fileName);
        }
示例#18
0
文件: PitchBar.cs 项目: puthutp/Waver
 public void AddToTrack(Track track, double secondToTickMultiplier)
 {
     int startAbsoluteTick = (int)((StartTime + Program.MIDIPlaybackOffset) / secondToTickMultiplier);
     int endAbsoluteTick = (int)((EndTime + Program.MIDIPlaybackOffset) / secondToTickMultiplier);
     ChannelMessage startMessage = new ChannelMessage(ChannelCommand.NoteOn, 0, NoteIndex - Program.MIDI_OFFSET, Program.MIDIPlayer.Volume);
     ChannelMessage endMessage = new ChannelMessage(ChannelCommand.NoteOff, 0, NoteIndex - Program.MIDI_OFFSET);
     try
     {
         track.Insert(startAbsoluteTick, startMessage);
         track.Insert(endAbsoluteTick, endMessage);
     }
     catch (Exception) { }
 }
示例#19
0
        static void Main(string[] args)
        {
            bool outputMidiVelocity = false;

            //var filename = "01-v-drac.s3m";
            //S3MFile f = S3MFile.Parse(filename);
            //var tempo = 60000000 / (f.Header.InitialTempo);
            //byte numerator = 4;
            //byte denominator = 4;
            //var speed = 3;
            //var skip = 0;

            var filename = "02-v-bewm.s3m";
            S3MFile f = S3MFile.Parse(filename);
            var tempo = 60000000 / (f.Header.InitialTempo);
            byte numerator = 4;
            byte denominator = 4;
            var speed = 3;
            var skip = 0;
            outputMidiVelocity = true;

            /*
            var filename = "V-OPTION.S3M";
            S3MFile f = S3MFile.Parse(filename);
            var tempo = 60000000 / (f.Header.InitialTempo);
            byte numerator = 6;
            byte denominator = 8;
            var speed = 3;
            var skip = 4;
              */
            /*
            var filename = "V-FALCON.S3M";
            S3MFile f = S3MFile.Parse(filename);
            var tempo = 60000000 / (1 * f.Header.InitialTempo);
            byte numerator = 4;
            byte denominator = 4;
            var speed = 3;
            var skip = 0;
            */
            /*
            var filename = "V-CONTRA.IT";
            S3MFile f = S3MFile.Parse(filename);
            var tempo = 60000000 / (1 * f.Header.InitialTempo);
            byte numerator = 4;
            byte denominator = 4;
            var speed = 3;
            var skip = 0;
             * */

            /*
            var filename = "V-BLAST.S3M";
            S3MFile f = S3MFile.Parse(filename);
            var tempo = 60000000 / (1 * f.Header.InitialTempo);
            byte numerator = 4;
            byte denominator = 4;
            var speed = 3;
            var skip = 0;*/

            Sequence s = new Sequence();
            Track t1 = new Track();
            Track t2 = new Track();
            Track t3 = new Track();
            Track drums = new Track();
            Track kick = new Track();
            Track timeTrack = new Track();
            s.Add(timeTrack);
            s.Add(t1);
            s.Add(t2);
            s.Add(t3);
            //s.Add(drums);
            //s.Add(kick);

            var drumPC = new ChannelMessageBuilder();
            drumPC.MidiChannel = 09;
            drumPC.Command = ChannelCommand.ProgramChange;
            drumPC.Data1 = 0;// 79 + ce.Instrument;
            drumPC.Build();
            drums.Insert(0, drumPC.Result);

            kick.Insert(0, drumPC.Result);

            TimeSignatureBuilder tsb = new TimeSignatureBuilder();
            tsb.Numerator = numerator;
            tsb.Denominator = denominator;
            tsb.ClocksPerMetronomeClick = 24;
            tsb.ThirtySecondNotesPerQuarterNote = 8;

            tsb.Build();

            timeTrack.Insert(0, tsb.Result);

            TempoChangeBuilder tcb = new TempoChangeBuilder();
            tcb.Tempo = tempo;
            tcb.Build();

            timeTrack.Insert(0, tcb.Result);

            var outputPatterns = new int[] { 5, 6, 7};

            //var c1 = (from p in f.OrderedPatterns
            //          where patterns.Contains(p.PatternNumber)
            //          select p)
            //         .SelectMany(p => p.Channels)
            //         .Where(c => c.ChannelNumber == 1)
            //         .SelectMany(ce => ce.ChannelEvents);

            //var c2 = (from p in f.OrderedPatterns
            //          where patterns.Contains(p.PatternNumber)
            //          select p)
            //         .SelectMany(p => p.Channels)
            //         .Where(c => c.ChannelNumber == 2)
            //         .SelectMany(ce => ce.ChannelEvents);

            //var c3 = (from p in f.OrderedPatterns
            //          where patterns.Contains(p.PatternNumber)
            //          select p)
            //         .SelectMany(p => p.Channels)
            //         .Where(c => c.ChannelNumber == 3)
            //         .SelectMany(ce => ce.ChannelEvents);

            var patterns = from p in f.OrderedPatterns.Skip(skip) /*where outputPatterns.Contains(p.PatternNumber) */select p;
            //.SelectMany(p => p.Rows);

            Dictionary<int, TrackInfo> tracks = new Dictionary<int, TrackInfo>();
            tracks.Add(1, new TrackInfo(t1));
            tracks[1].Channel = 0;
            tracks.Add(2, new TrackInfo(t2));
            tracks[2].Channel = 1;
            tracks.Add(3, new TrackInfo(t3));
            tracks[3].Channel = 2;
            var di = new TrackInfo(drums);
            di.Channel = 9;
            var mapper = new Func<ChannelEvent, int>(ce =>
            {
                switch (ce.Instrument)
                {
                    case 6:
                        return 42;
                    case 8:
                        return 35;
                    case 9:
                        return 38;
                    case 10:
                        return 47;
                    default:
                        Debug.Fail(ce.Instrument.ToString());
                        return 0;

                }
            });
            di.NoteMapper = mapper;
            var kickInfo = new TrackInfo(kick);
            kickInfo.Channel = 9;
            kickInfo.NoteMapper = mapper;
            tracks.Add(4, di);
            tracks.Add(5, kickInfo);

            var tick = 0;
            foreach (var pattern in patterns)
            {
                bool breakPattern = false;
                foreach (var row in pattern.Rows)
                {
                    //if ((row.RowNumber-1) % 16 == 0)
                    //{
                    //    drums.Insert(tick, kickOn);
                    //    drums.Insert(tick + speed, kickOff);
                    //}
                    foreach (var ce in row.ChannelEvents)
                    {
                        if (ce == null)
                        {
                            //Console.Out.WriteLine("skip");
                            continue;
                        }

                        if (ce.Command == 3)
                        {
                            var modulo = row.RowNumber % 32;
                            if (modulo != 0)
                            {
                                // sad to say, not sure why mod 8 but divide by 16 works
                                var m8 = row.RowNumber % 8;
                                if (m8 == 0)
                                {
                                    var restore = tsb.Result;
                                    tsb.Numerator = (byte)(row.RowNumber / 16);
                                    tsb.Build();
                                    var change = tsb.Result;
                                    timeTrack.Insert(tick, change);
                                    timeTrack.Insert(tick + 3, restore);
                                }

                            }
                            //Debugger.Break();
                            // pattern break
                            // figure out the time signature of the pattern up to this point
                            // then go back and insert a time signature change message at the beginning
                            // of the pattern
                            // and another one at the end to revert
                            //var restore = tsb.Result;
                            //tsb.Numerator = 2;
                            //tsb.Build();
                            //var change = tsb.Result;
                            //timeTrack.Insert(rowStartTick, change);
                            //timeTrack.Insert(tick + 3, restore);
                            breakPattern = true;
                        }

                        if (!tracks.ContainsKey(ce.ChannelNumber)) continue;
                        TrackInfo ti = tracks[ce.ChannelNumber];

                        if (ce.Note == -1 )
                        {
                            // skip
                        }
                        else if( ce.Note == 0xFF)
                        {
                            // re-use current note, but change instrument

                            //Console.Out.WriteLine("skip");
                        }
                        else if (ce.Note == 0xFE) //off
                        {
                            if (ti.LastPitch != -1)
                            {
                                NoteOff(tick, ti);
                            }
                        }
                        else
                        {
                            //if (ce.Volume != -1 && ce.Volume < 32) continue;
                            if (ti.LastPitch != -1)
                            {
                                NoteOff(tick, ti);
                            }

                            //p = ProgramChange(ti.Track, tick, p, ce);

                            var delay = 0;
                            if (ce.Command == 19)
                            {
                                if (208 <= ce.Data && ce.Data <= 214)  // HACK: 214 is a guess at the top range of SD commands
                                {
                                    delay = ce.Data - 208;
                                    Debug.Assert(delay >= 0);
                                }
                            }

                            NoteOn(tick + delay, ti, ce);

                        }

                    }
                    tick += speed;
                    if (breakPattern)
                    {
                        break;
                    }
                }
            }

            foreach (var pair in tracks)
            {
                if (pair.Value.LastPitch != -1)
                {
                    NoteOff(tick, pair.Value);
                }
            }

            foreach (MidiEvent m in drums.Iterator().Take(5))
            {
                if (m.MidiMessage is ChannelMessage)
                {
                    ChannelMessage cm = (ChannelMessage)m.MidiMessage;
                    Console.Out.WriteLine("{0} {1}", m.AbsoluteTicks, cm.Command);
                }
            }

            s.Save(Path.ChangeExtension(filename, ".mid"));
            /*
            var tick = 0;
            var speed = 3;
            var lastNote = -1;
            var p = -1;
            foreach (var ce in c1)
            {
                if (ce == null || ce.Note == -1 || ce.Note == 0xFF)
                {
                    tick += speed;
                    Console.Out.WriteLine("skip");
                    continue;
                }
                else if (ce.Note == 0xFE) //off
                {
                    lastNote = NoteOff(t, tick, lastNote);
                }
                else
                {
                    if (lastNote != -1)
                    {
                        lastNote = NoteOff(t, tick, lastNote);
                    }

                    p = ProgramChange(t, tick, p, ce);

                    var delay = 0;
                    if (ce.Command == 19)
                    {
                        if (208 <= ce.Data && ce.Data <= 214)  // HACK: 214 is a guess at the top range of SD commands
                        {
                            delay = ce.Data - 208;
                            Debug.Assert(delay >= 0);
                        }
                    }

                    lastNote = NoteOn(t, tick + delay, ce.Note);

                }
                tick += speed;
            }
            lastNote = NoteOff(t, tick, lastNote);
             *
             * */
        }
        IEnumerable<Data1ChannelEventList> checkForInvalidNotes(GuitarMessageList owner, Track track, IEnumerable<int> data1List)
        {
            var ret = new List<Data1ChannelEventList>();
            try
            {
                var notesOnData2Zero = track.ChanMessages.Where(x => x.Data2 == 0 && x.Command == ChannelCommand.NoteOn).ToList();
                if (notesOnData2Zero.Any())
                {
                    track.Remove(notesOnData2Zero);

                    foreach (var x in notesOnData2Zero)
                    {
                        track.Insert(x.AbsoluteTicks, new ChannelMessage(ChannelCommand.NoteOff, x.Data1, 0, x.Channel));
                    }
                }

                if (track.Name.IsGuitarTrackName6())
                {
                    var bassTrainers = track.Meta.Where(x => x.Text.IsTrainerBass()).ToList();
                    var guitarTrainers = track.Meta.Where(x => x.Text.IsTrainerGuitar()).ToList();

                    if (bassTrainers.Any())
                    {
                        bassTrainers.ForEach(x => track.Remove(x));
                    }
                }

                if (track.Name.IsBassTrackName6())
                {
                    var bassTrainers = track.Meta.Where(x => x.Text.IsTrainerBass()).ToList();

                    var guitarTrainers = track.Meta.Where(x => x.Text.IsTrainerGuitar()).ToList();
                    if (guitarTrainers.Any())
                    {
                        guitarTrainers.ForEach(x => track.Remove(x));
                    }
                }

                ret.AddRange(track.GetCleanMessageList(data1List, owner));

            }
            catch (Exception ex)
            {
                ex.Message.OutputDebug();
            }

            return ret;
        }
        private static void TestMerge()
        {
            Track a = new Track();
            Track b = new Track();

            a.Merge(b);

            Debug.Assert(a.Count == 1);

            ChannelMessage message = new ChannelMessage(ChannelCommand.NoteOff, 0, 60, 0);

            b.Insert(0, message);
            b.Insert(10, message);
            b.Insert(20, message);
            b.Insert(30, message);
            b.Insert(40, message);

            a.Merge(b);

            Debug.Assert(a.Count == 1 + b.Count - 1);

            a.Clear();

            Debug.Assert(a.Count == 1);

            a.Insert(0, message);
            a.Insert(10, message);
            a.Insert(20, message);
            a.Insert(30, message);
            a.Insert(40, message);

            int count = a.Count;

            a.Merge(b);

            Debug.Assert(a.Count == count + b.Count - 1);
            Debug.Assert(a.GetMidiEvent(0).DeltaTicks == 0);
            Debug.Assert(a.GetMidiEvent(1).DeltaTicks == 0);
            Debug.Assert(a.GetMidiEvent(2).DeltaTicks == 10);
            Debug.Assert(a.GetMidiEvent(3).DeltaTicks == 0);
            Debug.Assert(a.GetMidiEvent(4).DeltaTicks == 10);
            Debug.Assert(a.GetMidiEvent(5).DeltaTicks == 0);
            Debug.Assert(a.GetMidiEvent(6).DeltaTicks == 10);
            Debug.Assert(a.GetMidiEvent(7).DeltaTicks == 0);
            Debug.Assert(a.GetMidiEvent(8).DeltaTicks == 10);
            Debug.Assert(a.GetMidiEvent(9).DeltaTicks == 0);
        }
示例#22
0
        private static int ProgramChange(Track t, int tick, int p, int channel, ChannelEvent ce)
        {
            if (p != ce.Instrument)
            {
                Console.Out.WriteLine("PC  " + ce.Instrument);
                ChannelMessageBuilder pc = new ChannelMessageBuilder();
                pc.MidiChannel = channel;
                pc.Command = ChannelCommand.ProgramChange;
                pc.Data1 = 0;// 79 + ce.Instrument;
                pc.Build();

                t.Insert(tick, pc.Result);
                p = ce.Instrument;
            }
            return p;
        }
        public void CreateChordNameEvents(GuitarDifficulty difficulty,
            int[] GuitarTuning, int[] BassTuning, Track ownerTrack)
        {
            var x108 = Generate108().Where(x => x.Chord != null).ToList();

            foreach (var item in x108)
            {
                if (item.Chord.Notes.Count() > 1)
                {
                    ChordNameMeta name = null;
                    if (ownerTrack.Name.IsBassTrackName())
                    {
                        name = item.Chord.GetTunedChordName(BassTuning);
                    }
                    else
                    {
                        name = item.Chord.GetTunedChordName(GuitarTuning);
                    }

                    int data1 = -1;
                    var useUserChordName = false;
                    var chordName = string.Empty;
                    var hideChordName = false;

                    item.Chord.RootNoteConfig.IfNotNull(x => useUserChordName = x.UseUserChordName);
                    item.Chord.RootNoteConfig.IfNotNull(x => chordName = x.UserChordName);
                    item.Chord.RootNoteConfig.IfNotNull(x => data1 = x.RootNoteData1);
                    item.Chord.RootNoteConfig.IfNotNull(x => hideChordName = x.HideNoteName);

                    if (difficulty == GuitarDifficulty.Expert)
                    {
                        if (hideChordName || (data1 == -1 && (name == null || (name != null && name.ToneName.ToToneNameData1() == ToneNameData1.NotSet))))
                        {
                            ownerTrack.Insert(item.Ticks.Down, new ChannelMessage(ChannelCommand.NoteOn, Utility.ChordNameHiddenData1, 100 + item.Fret));
                            ownerTrack.Insert(item.Ticks.Up, new ChannelMessage(ChannelCommand.NoteOff, Utility.ChordNameHiddenData1, 0));
                        }
                        else
                        {
                            if (data1 == -1)
                            {
                                data1 = name.ToneName.ToToneNameData1().ToInt();
                            }
                            ownerTrack.Insert(item.Ticks.Down, new ChannelMessage(ChannelCommand.NoteOn, data1, 100 + item.Fret));
                            ownerTrack.Insert(item.Ticks.Up, new ChannelMessage(ChannelCommand.NoteOff, data1, 0));
                        }
                    }

                    var chordNameText = Utility.CreateChordNameText(item.Chord.Difficulty, useUserChordName ? chordName : name.ToStringEx());

                    if (chordNameText.IsNotEmpty())
                    {
                        ownerTrack.Insert(item.Chord.AbsoluteTicks, new MetaMessage(MetaType.Text, chordNameText));
                    }
                }
            }
        }
示例#24
0
        public override void SaveAsMIDI(string fileName)
        {
            if (NumTracks == 0)
            {
                throw new InvalidDataException("Questa canzone non ha tracce.");
            }

            CalculateTicks();
            var midi = new Sequence(24)
            {
                Format = 1
            };
            var metaTrack = new Sanford.Multimedia.Midi.Track();

            midi.Add(metaTrack);

            for (int i = 0; i < NumTracks; i++)
            {
                var track = new Sanford.Multimedia.Midi.Track();
                midi.Add(track);

                int endOfPattern = 0, startOfPatternTicks = 0, endOfPatternTicks = 0, shift = 0;
                var playing = new List <M4ANoteCommand>();

                for (int j = 0; j < Commands[i].Count; j++)
                {
                    var e     = Commands[i][j];
                    int ticks = e.AbsoluteTicks + (endOfPatternTicks - startOfPatternTicks);

                    if (e.Command is KeyShiftCommand keysh)
                    {
                        shift = keysh.Shift;
                    }
                    else if (e.Command is M4ANoteCommand note)
                    {
                        int n = (note.Note + shift).Clamp(0, 0x7F);
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.NoteOn, i, n, note.Velocity));
                        if (note.Duration != -1)
                        {
                            track.Insert(ticks + note.Duration, new ChannelMessage(ChannelCommand.NoteOff, i, n));
                        }
                        else
                        {
                            playing.Add(note);
                        }
                    }
                    else if (e.Command is EndOfTieCommand eot)
                    {
                        M4ANoteCommand nc = null;

                        if (eot.Note == -1)
                        {
                            nc = playing.LastOrDefault();
                        }
                        else
                        {
                            nc = playing.LastOrDefault(n => n.Note == eot.Note);
                        }

                        if (nc != null)
                        {
                            int no = (nc.Note + shift).Clamp(0, 0x7F);
                            track.Insert(ticks, new ChannelMessage(ChannelCommand.NoteOff, i, no));
                            playing.Remove(nc);
                        }
                    }
                    else if (e.Command is VoiceCommand voice)
                    {
                        // TODO: Fork and remove restriction
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.ProgramChange, i, voice.Voice & 0x7F));
                    }
                    else if (e.Command is VolumeCommand vol)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.Volume, vol.Volume));
                    }
                    else if (e.Command is PanpotCommand pan)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.Pan, pan.Panpot + 0x40));
                    }
                    else if (e.Command is BendCommand bend)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.PitchWheel, i, 0, bend.Bend + 0x40));
                    }
                    else if (e.Command is BendRangeCommand bendr)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 20, bendr.Range));
                    }
                    else if (e.Command is LFOSpeedCommand lfos)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 21, lfos.Speed));
                    }
                    else if (e.Command is LFODelayCommand lfodl)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 26, lfodl.Delay));
                    }
                    else if (e.Command is ModDepthCommand mod)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.ModulationWheel, mod.Depth));
                    }
                    else if (e.Command is ModTypeCommand modt)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 22, modt.Type));
                    }
                    else if (e.Command is TuneCommand tune)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 24, tune.Tune));
                    }
                    else if (e.Command is TempoCommand tempo)
                    {
                        var change = new TempoChangeBuilder {
                            Tempo = (60000000 / tempo.Tempo)
                        };
                        change.Build();
                        metaTrack.Insert(ticks, change.Result);
                    }
                    else if (e.Command is CallCommand patt)
                    {
                        int callCmd = Commands[i].FindIndex(c => c.GetOffset() == patt.Offset);
                        endOfPattern      = j;
                        endOfPatternTicks = e.AbsoluteTicks;
                        j = callCmd - 1; // -1 for incoming ++
                        startOfPatternTicks = Commands[i][j + 1].AbsoluteTicks;
                    }
                    else if (e.Command is ReturnCommand)
                    {
                        if (endOfPattern != 0)
                        {
                            j            = endOfPattern;
                            endOfPattern = startOfPatternTicks = endOfPatternTicks = 0;
                        }
                    }
                    else if (i == 0 && e.Command is GoToCommand goTo)
                    {
                        int jumpCmd = Commands[i].FindIndex(c => c.GetOffset() == goTo.Offset);
                        metaTrack.Insert(Commands[i][jumpCmd].AbsoluteTicks, new MetaMessage(MetaType.Marker, new byte[] { (byte)'[' }));
                        metaTrack.Insert(ticks, new MetaMessage(MetaType.Marker, new byte[] { (byte)']' }));
                    }
                    else if (e.Command is FinishCommand fine)
                    {
                        // TODO: Fix ticks before end of track event
                        // Library automatically is updating track.EndOfTrackOffset for us
                        break;
                    }
                }
            }
            midi.Save(fileName);
        }
示例#25
0
        public override void SaveAsMIDI(string fileName)
        {
            if (NumTracks == 0)
            {
                throw new InvalidDataException("Questa canzone non ha tracce.");
            }

            CalculateTicks();
            var midi = new Sequence(96)
            {
                Format = 1
            };
            var metaTrack = new Sanford.Multimedia.Midi.Track();

            midi.Add(metaTrack);

            for (int i = 0; i < NumTracks; i++)
            {
                var track = new Sanford.Multimedia.Midi.Track();
                midi.Add(track);

                FreeNoteCommand freeNote    = null;
                MidiEvent       freeNoteOff = null;

                for (int j = 0; j < Commands[i].Count; j++)
                {
                    var e = Commands[i][j];

                    // Extended note ended ended and wasn't renewed
                    if (freeNoteOff != null && freeNoteOff.AbsoluteTicks < e.AbsoluteTicks * 2)
                    {
                        freeNote    = null;
                        freeNoteOff = null;
                    }

                    if (e.Command is VolumeCommand vol)
                    {
                        track.Insert(e.AbsoluteTicks * 2, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.Volume, vol.Volume / 2));
                    }
                    else if (e.Command is VoiceCommand voice)
                    {
                        // TODO: Fork and remove restriction
                        track.Insert(e.AbsoluteTicks * 2, new ChannelMessage(ChannelCommand.ProgramChange, i, voice.Voice & 0x7F));
                    }
                    else if (e.Command is PanpotCommand pan)
                    {
                        track.Insert(e.AbsoluteTicks * 2, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.Pan, pan.Panpot / 2 + 0x40));
                    }
                    else if (e.Command is BendCommand bend)
                    {
                        track.Insert(e.AbsoluteTicks * 2, new ChannelMessage(ChannelCommand.PitchWheel, i, 0, bend.Bend / 2 + 0x40));
                    }
                    else if (e.Command is BendRangeCommand bendr)
                    {
                        track.Insert(e.AbsoluteTicks * 2, new ChannelMessage(ChannelCommand.Controller, i, 20, bendr.Range / 2));
                    }
                    else if (e.Command is MLSSNoteCommand note)
                    {
                        // Extended note is playing and it should be extended by this note
                        if (freeNote != null && freeNote.Note - 0x80 == note.Note)
                        {
                            // Move the note off command
                            track.Move(freeNoteOff, freeNoteOff.AbsoluteTicks + note.Duration * 2);
                        }
                        // Extended note is playing but this note is different OR there is no extended note playing
                        // Either way we play a new note and forget that one
                        else
                        {
                            track.Insert(e.AbsoluteTicks * 2, new ChannelMessage(ChannelCommand.NoteOn, i, note.Note, 0x7F));
                            track.Insert(e.AbsoluteTicks * 2 + note.Duration * 2, new ChannelMessage(ChannelCommand.NoteOff, i, note.Note));
                            freeNote    = null;
                            freeNoteOff = null;
                        }
                    }
                    else if (e.Command is FreeNoteCommand free)
                    {
                        // Extended note is playing and it should be extended
                        if (freeNote != null && freeNote.Note == free.Note)
                        {
                            // Move the note off command
                            track.Move(freeNoteOff, freeNoteOff.AbsoluteTicks + free.Duration * 2);
                        }
                        // Extended note is playing but this note is different OR there is no extended note playing
                        // Either way we play a new note and forget that one
                        else
                        {
                            track.Insert(e.AbsoluteTicks * 2, new ChannelMessage(ChannelCommand.NoteOn, i, free.Note - 0x80, 0x7F));
                            track.Insert(e.AbsoluteTicks * 2 + free.Duration * 2, new ChannelMessage(ChannelCommand.NoteOff, i, free.Note - 0x80));
                            freeNote    = free;
                            freeNoteOff = track.GetMidiEvent(track.Count - 2); // -1 would be the end of track event
                        }
                    }
                    else if (i == 0 && e.Command is TempoCommand tempo)
                    {
                        var change = new TempoChangeBuilder {
                            Tempo = (60000000 / tempo.Tempo)
                        };
                        change.Build();
                        metaTrack.Insert(e.AbsoluteTicks * 2, change.Result);
                    }
                    else if (i == 0 && e.Command is GoToCommand goTo)
                    {
                        int jumpCmd = Commands[i].FindIndex(c => c.GetOffset() == goTo.Offset);
                        metaTrack.Insert(Commands[i][jumpCmd].AbsoluteTicks * 2, new MetaMessage(MetaType.Marker, new byte[] { (byte)'[' }));
                        metaTrack.Insert(e.AbsoluteTicks * 2, new MetaMessage(MetaType.Marker, new byte[] { (byte)']' }));
                    }
                    else if (e.Command is FinishCommand fine)
                    {
                        // TODO: Fix ticks before end of track event
                        // Library automatically is updating track.EndOfTrackOffset for us
                        break;
                    }
                }
            }
            midi.Save(fileName);
        }
        private void UpdateTrack(Track track)
        {
            try
            {

                TrackProperties.FirstOrDefault(x => x.Track == track).IfObjectNotNull(trackProp =>
                {

                    if (trackProp.Track.ChanMessages.Count() > 5)
                    {

                        if (!trackProp.Scale.IsNull())
                        {
                            track.Remove(track.ChanMessages.ToList());

                            var ev = trackProp.Events.Chords.ToList();

                            var scale = trackProp.Scale;
                            if (scale < 0.001)
                                scale = 0.001;

                            var offset = trackProp.Offset;

                            var firstTime = ev.First().TimePair;
                            var firstTick = ev.First().TickPair;

                            ev.ForEach(x =>
                            {
                                x.Notes.ForEach(n =>
                                {
                                    var scaledLength = x.TimeLength * scale;
                                    var scaledStart = (x.StartTime - firstTime.Down) * scale + offset;

                                    var downTick = EditorPro.GuitarTrack.TimeToTick(scaledStart);
                                    var upTick = EditorPro.GuitarTrack.TimeToTick(scaledStart + scaledLength);
                                    var data1 = Utility.GetStringLowE(GuitarDifficulty.Expert) + n.NoteString;
                                    track.Insert((int)(downTick), new ChannelMessage(ChannelCommand.NoteOn, data1, n.NoteFretDown + 100, n.Channel));
                                    track.Insert((int)(upTick), new ChannelMessage(ChannelCommand.NoteOff, data1, 0, n.Channel));
                                });
                            });

                        }
                    }

                });
            }
            catch { }
        }
示例#27
0
        private void ParseChannelMessage()
        {
            if (trackIndex >= trackData.Length)
            {
                //throw new MidiFileException("End of track unexpectedly reached.");
                Console.Write("\nERROR: End of track unexpectedly reached (TrackReader.cs ParseChannelMessage)");
                return;
            }

            cmBuilder.Command     = ChannelMessage.UnpackCommand(status);
            cmBuilder.MidiChannel = ChannelMessage.UnpackMidiChannel(status);
            cmBuilder.Data1       = trackData[trackIndex];

            // PROGRAM CHANGE
            if (cmBuilder.Command == ChannelCommand.ProgramChange)
            {
                newTrack.ProgramChange = cmBuilder.Data1;
                newTrack.MidiChannel   = cmBuilder.MidiChannel;
            }

            trackIndex++;

            if (ChannelMessage.DataBytesPerType(cmBuilder.Command) == 2)
            {
                if (trackIndex >= trackData.Length)
                {
                    //throw new MidiFileException("End of track unexpectedly reached.");
                    Console.Write("\nERROR: End of track unexpectedly reached (TrackReader.cs ParseChannelMessage)");
                    return;
                }

                // FAB : 07/08/2014
                if (trackData[trackIndex] <= 127)
                {
                    cmBuilder.Data2 = trackData[trackIndex];
                }
                else
                {
                    cmBuilder.Data2 = 127;
                }

                if (cmBuilder.Data1 == 0x07)
                {
                    // Volume de la piste
                    newTrack.Volume = cmBuilder.Data2;
                }
                else if (cmBuilder.Data1 == 0x5B)
                {
                    // Reverb 91
                    // FAB 2017
                    newTrack.Reverb = cmBuilder.Data2;
                }
                else if (cmBuilder.Data1 == 0x0A)
                {
                    // pan 10
                    // FAB 2017
                    newTrack.Pan = cmBuilder.Data2;
                }

                // Collecte des notes
                if (cmBuilder.Command == ChannelCommand.NoteOn)
                {
                    newTrack.ContainsNotes = true;
                    newTrack.Visible       = true;

                    // Data1 = Note number
                    // Data2 = Velocity
                    if (ticks >= 0 && cmBuilder.Data2 > 0)
                    {
                        // FAB :
                        // Add a MidiNote to this track.  This is called for each NoteOn event */
                        newTrack.MidiChannel = cmBuilder.MidiChannel;

                        MidiNote note = new MidiNote(ticks, newTrack.MidiChannel, cmBuilder.Data1, 0, cmBuilder.Data2, false);
                        newTrack.Notes.Add(note);
                    }
                    else
                    {
                        // FAB
                        if (newTrack.Notes.Count > 0)
                        {
                            newTrack.MidiChannel = cmBuilder.MidiChannel;
                            NoteOff(newTrack.MidiChannel, cmBuilder.Data1, ticks);
                        }
                    }
                }
                else if (ticks >= 0 && cmBuilder.Command == ChannelCommand.NoteOff)
                {
                    // FAB
                    newTrack.ContainsNotes = true;
                    newTrack.Visible       = true;

                    newTrack.MidiChannel = cmBuilder.MidiChannel;
                    NoteOff(newTrack.MidiChannel, cmBuilder.Data1, ticks);
                }
                trackIndex++;
            }
            cmBuilder.Build();
            newTrack.Insert(ticks, cmBuilder.Result);

            runningStatus = status;
        }
示例#28
0
 private void Message(ChannelMessage message)
 {
     _track.Insert((int)_player.ElapsedTicks, message);
 }
示例#29
0
文件: UCEditor.cs 项目: puthutp/Waver
 private void SetMIDITempo()
 {
     Track setTempoTrack = new Track();
     setTempoTrack.Insert(0, new MetaMessage(MetaType.TimeSignature, TimeSignatureData));
     setTempoTrack.Insert(0, new MetaMessage(MetaType.Tempo, SetTempoData));
     sequence.Add(setTempoTrack);
 }
示例#30
0
        internal void SaveAsMIDI(string fileName)
        {
            if (NumTracks == 0)
            {
                throw new InvalidDataException("This song has no tracks.");
            }
            if (ROM.Instance.Game.Engine.Type != EngineType.M4A)
            {
                throw new PlatformNotSupportedException("Exporting to MIDI from this game engine is not supported at this time.");
            }

            CalculateTicks();
            var midi = new Sequence(Engine.GetTicksPerBar() / 4)
            {
                Format = 2
            };

            for (int i = 0; i < NumTracks; i++)
            {
                var track = new Sanford.Multimedia.Midi.Track();
                midi.Add(track);

                int endOfPattern = 0, startOfPatternTicks = 0, endOfPatternTicks = 0, shift = 0;
                var playing = new List <M4ANoteCommand>();

                for (int j = 0; j < Commands[i].Count; j++)
                {
                    var e     = Commands[i][j];
                    int ticks = (int)(e.AbsoluteTicks + (endOfPatternTicks - startOfPatternTicks));

                    if (e.Command is KeyShiftCommand keysh)
                    {
                        shift = keysh.Shift;
                    }
                    else if (e.Command is M4ANoteCommand note)
                    {
                        int n = (note.Note + shift).Clamp(0, 127);
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.NoteOn, i, n, note.Velocity));
                        if (note.Duration != -1)
                        {
                            track.Insert(ticks + note.Duration, new ChannelMessage(ChannelCommand.NoteOff, i, n));
                        }
                        else
                        {
                            playing.Add(note);
                        }
                    }
                    else if (e.Command is EndOfTieCommand eot)
                    {
                        M4ANoteCommand nc = null;

                        if (eot.Note == -1)
                        {
                            nc = playing.LastOrDefault();
                        }
                        else
                        {
                            nc = playing.LastOrDefault(n => n.Note == eot.Note);
                        }

                        if (nc != null)
                        {
                            int no = (nc.Note + shift).Clamp(0, 127);
                            track.Insert(ticks, new ChannelMessage(ChannelCommand.NoteOff, i, no));
                            playing.Remove(nc);
                        }
                    }
                    else if (e.Command is VoiceCommand voice)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.ProgramChange, i, voice.Voice));
                    }
                    else if (e.Command is VolumeCommand vol)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.Volume, vol.Volume));
                    }
                    else if (e.Command is PanpotCommand pan)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.Pan, pan.Panpot + 0x40));
                    }
                    else if (e.Command is BendCommand bend)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.PitchWheel, i, 0, bend.Bend + 0x40));
                    }
                    else if (e.Command is BendRangeCommand bendr)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 20, bendr.Range));
                    }
                    else if (e.Command is LFOSpeedCommand lfos)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 21, lfos.Speed));
                    }
                    else if (e.Command is LFODelayCommand lfodl)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 26, lfodl.Delay));
                    }
                    else if (e.Command is ModDepthCommand mod)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.ModulationWheel, mod.Depth));
                    }
                    else if (e.Command is ModTypeCommand modt)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 22, modt.Type));
                    }
                    else if (e.Command is TuneCommand tune)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 24, tune.Tune));
                    }
                    else if (e.Command is TempoCommand tempo)
                    {
                        var change = new TempoChangeBuilder {
                            Tempo = (60000000 / tempo.Tempo)
                        };
                        change.Build();
                        track.Insert(ticks, change.Result);
                    }
                    else if (e.Command is CallCommand patt)
                    {
                        int callCmd = Commands[i].FindIndex(c => c.Offset == patt.Offset);
                        endOfPattern      = j;
                        endOfPatternTicks = (int)e.AbsoluteTicks;
                        j = callCmd - 1; // -1 for incoming ++
                        startOfPatternTicks = (int)Commands[i][j + 1].AbsoluteTicks;
                    }
                    else if (e.Command is ReturnCommand)
                    {
                        if (endOfPattern != 0)
                        {
                            j            = endOfPattern;
                            endOfPattern = startOfPatternTicks = endOfPatternTicks = 0;
                        }
                    }
                    else if (i == 0 && e.Command is GoToCommand goTo)
                    {
                        track.Insert(ticks, new MetaMessage(MetaType.Marker, new byte[] { (byte)']' }));
                        int jumpCmd = Commands[i].FindIndex(c => c.Offset == goTo.Offset);
                        track.Insert((int)Commands[i][jumpCmd].AbsoluteTicks, new MetaMessage(MetaType.Marker, new byte[] { (byte)'[' }));
                    }
                    else if (e.Command is FinishCommand fine)
                    {
                        track.Insert(ticks, new MetaMessage(MetaType.EndOfTrack, new byte[0]));
                        break;
                    }
                }
            }
            midi.Save(fileName);
        }