Example #1
1
        private void MainForm_Load(object sender, EventArgs e)
        {
            this.Opacity = 0;
            this.BackgroundImageLayout = ImageLayout.Stretch;
            this.WindowState = FormWindowState.Maximized;
            this.FormBorderStyle = FormBorderStyle.None;

            SplashForm sf = new SplashForm();
            sf.ShowDialog();

            this.panel1.AutoScroll = true;
            this.panel1.HorizontalScroll.Enabled = true;
            this.panel1.VerticalScroll.Enabled = true;

            MidiFile midiFile = new MidiFile("E:/Mozart__Rondo_Alla_Turca.mid");
            MidiOptions options = new MidiOptions(midiFile);
            sheetMusic1.Load(midiFile, options);
            float zoom = (float)sheetMusic1.Width / SheetMusic.PageWidth;
            sheetMusic1.SetZoom(zoom);

            this.Opacity = 1;
        }
		public MidiEditorRender() : base(0,1)
		{
			this.midiFile = new MidiFile("testfile.mid");
			this.OnMidiMessage += new MidiMessageHandler(NullMidiMessageHandler);
			this.midiEditorForm = new MidiEditorForm();
			this.editable = true;
			Start();
		}
Example #3
0
        /** Create a new SheetMusic control.
         * MidiFile is the parsed midi file to display.
         * SheetMusic Options are the menu options that were selected.
         *
         * - Apply all the Menu Options to the MidiFile tracks.
         * - Calculate the key signature
         * - For each track, create a list of MusicSymbols (notes, rests, bars, etc)
         * - Vertically align the music symbols in all the tracks
         * - Partition the music notes into horizontal staffs
         */
        public void init(MidiFile file, MidiOptions options)
        {
            if (options == null)
            {
                options = new MidiOptions(file);
            }
            zoom     = 1.0f;
            filename = file.FileName;

            SetColors(options.colors, options.shadeColor, options.shade2Color);
            pen = new Pen(Color.Black, 1);

            List <MidiTrack> tracks = file.ChangeMidiNotes(options);

            SetNoteSize(options.largeNoteSize);
            scrollVert      = options.scrollVert;
            showNoteLetters = options.showNoteLetters;
            TimeSignature time = file.Time;

            if (options.time != null)
            {
                time = options.time;
            }
            if (options.key == -1)
            {
                mainkey = GetKeySignature(tracks);
            }
            else
            {
                mainkey = new KeySignature(options.key);
            }

            numtracks = tracks.Count;

            int lastStart = file.EndTime() + options.shifttime;

            /* Create all the music symbols (notes, rests, vertical bars, and
             * clef changes).  The symbols variable contains a list of music
             * symbols for each track.  The list does not include the left-side
             * Clef and key signature symbols.  Those can only be calculated
             * when we create the staffs.
             */
            List <MusicSymbol>[] symbols = new List <MusicSymbol> [numtracks];
            for (int tracknum = 0; tracknum < numtracks; tracknum++)
            {
                MidiTrack          track  = tracks[tracknum];
                ClefMeasures       clefs  = new ClefMeasures(track.Notes, time.Measure);
                List <ChordSymbol> chords = CreateChords(track.Notes, mainkey, time, clefs);
                symbols[tracknum] = CreateSymbols(chords, clefs, time, lastStart);
            }

            List <LyricSymbol>[] lyrics = null;
            if (options.showLyrics)
            {
                lyrics = GetLyrics(tracks);
            }

            /* Vertically align the music symbols */
            SymbolWidths widths = new SymbolWidths(symbols, lyrics);

            // SymbolWidths widths = new SymbolWidths(symbols);
            AlignSymbols(symbols, widths);

            staffs = CreateStaffs(symbols, mainkey, options, time.Measure);
            CreateAllBeamedChords(symbols, time);
            if (lyrics != null)
            {
                AddLyricsToStaffs(staffs, lyrics);
            }

            /* After making chord pairs, the stem directions can change,
             * which affects the staff height.  Re-calculate the staff height.
             */
            foreach (Staff staff in staffs)
            {
                staff.CalculateHeight();
            }

            BackColor = Color.White;

            SetZoom(1.0f);
        }
Example #4
0
        public void LoadMidi(MidiFile midiFile)
        {
            _tempoChanges = new FastList <MidiFileSequencerTempoChange>();


            // Combine all tracks into 1 track that is organized from lowest to highest absolute time
            if (midiFile.Tracks.Length > 1 || midiFile.Tracks[0].EndTime == 0)
            {
                midiFile.CombineTracks();
            }
            _division    = midiFile.Division;
            _eventIndex  = 0;
            _currentTime = 0;

            // build synth events.
            _synthData = new FastList <SynthEvent>();

            // Converts midi to milliseconds for easy sequencing
            double bpm     = 120;
            var    absTick = 0;
            var    absTime = 0.0;

            var metronomeLength = 0;
            var metronomeTick   = 0;
            var metronomeTime   = 0.0;

            for (int x = 0; x < midiFile.Tracks[0].MidiEvents.Length; x++)
            {
                var mEvent = midiFile.Tracks[0].MidiEvents[x];

                var synthData = new SynthEvent(mEvent);
                _synthData.Add(synthData);
                absTick        += mEvent.DeltaTime;
                absTime        += mEvent.DeltaTime * (60000.0 / (bpm * midiFile.Division));
                synthData.Delta = absTime;

                if (mEvent.Command == MidiEventTypeEnum.Meta && mEvent.Data1 == (int)MetaEventTypeEnum.Tempo)
                {
                    var meta = (MetaNumberEvent)mEvent;
                    bpm = MidiHelper.MicroSecondsPerMinute / (double)meta.Value;
                    _tempoChanges.Add(new MidiFileSequencerTempoChange(bpm, absTick, (int)(absTime)));
                }
                else if (mEvent.Command == MidiEventTypeEnum.Meta && mEvent.Data1 == (int)MetaEventTypeEnum.TimeSignature)
                {
                    var meta = (MetaDataEvent)mEvent;
                    var timeSignatureDenominator = (int)Math.Pow(2, meta.Data[1]);
                    metronomeLength = (int)(_division * (4.0 / timeSignatureDenominator));
                }
                else if (mEvent.Command == MidiEventTypeEnum.ProgramChange)
                {
                    var channel = mEvent.Channel;
                    if (!_firstProgramEventPerChannel.ContainsKey(channel))
                    {
                        _firstProgramEventPerChannel[channel] = synthData;
                    }
                }

                if (metronomeLength > 0)
                {
                    while (metronomeTick < absTick)
                    {
                        var metronome = SynthEvent.NewMetronomeEvent(metronomeLength);
                        _synthData.Add(metronome);
                        metronome.Delta = metronomeTime;

                        metronomeTick += metronomeLength;
                        metronomeTime += metronomeLength * (60000.0 / (bpm * midiFile.Division));
                    }
                }
            }

            _synthData.Sort((a, b) => (int)(a.Delta - b.Delta));
            _endTime = absTime;
            EndTick  = absTick;
        }
Example #5
0
        public void SplitByGrid_PreserveTrackChunks(bool preserveTrackChunks)
        {
            var timedEvents1 = new[]
            {
                new TimedEvent(new NoteOnEvent((SevenBitNumber)50, (SevenBitNumber)100), 90),
                new TimedEvent(new NoteOffEvent((SevenBitNumber)50, (SevenBitNumber)70), 95),
                new TimedEvent(new NoteOnEvent((SevenBitNumber)20, (SevenBitNumber)100), 100),
                new TimedEvent(new NoteOffEvent((SevenBitNumber)20, (SevenBitNumber)100), 200)
            };

            var timedEvents2 = new[]
            {
                new TimedEvent(new NoteOnEvent((SevenBitNumber)21, (SevenBitNumber)100), 100),
                new TimedEvent(new NoteOffEvent((SevenBitNumber)21, (SevenBitNumber)100), 200)
            };

            var midiFile = new MidiFile(
                timedEvents1.ToTrackChunk(),
                timedEvents2.ToTrackChunk());
            var grid     = new SteppedGrid((MidiTimeSpan)100);
            var settings = new SliceMidiFileSettings
            {
                SplitNotes          = false,
                PreserveTimes       = false,
                PreserveTrackChunks = preserveTrackChunks
            };

            var newFiles = midiFile.SplitByGrid(grid, settings).ToList();

            Assert.AreEqual(2, newFiles.Count, "New files count is invalid.");

            Assert.AreEqual(preserveTrackChunks ? 2 : 1, newFiles[0].GetTrackChunks().Count(), "Track chunks count of the first file is invalid.");
            CompareTimedEvents(
                newFiles[0].GetTrackChunks().First().GetTimedEvents(),
                new[]
            {
                new TimedEvent(new NoteOnEvent((SevenBitNumber)50, (SevenBitNumber)100), 90),
                new TimedEvent(new NoteOffEvent((SevenBitNumber)50, (SevenBitNumber)70), 95),
            },
                "First track chunk of first file contains invalid events.");
            if (preserveTrackChunks)
            {
                CompareTimedEvents(
                    newFiles[0].GetTrackChunks().Last().GetTimedEvents(),
                    Enumerable.Empty <TimedEvent>(),
                    "Second track chunk of first file contains invalid events.");
            }

            Assert.AreEqual(2, newFiles[1].GetTrackChunks().Count(), "Track chunks count of the second file is invalid.");
            CompareTimedEvents(
                newFiles[1].GetTrackChunks().First().GetTimedEvents(),
                new[]
            {
                new TimedEvent(new NoteOnEvent((SevenBitNumber)20, (SevenBitNumber)100), 0),
                new TimedEvent(new NoteOffEvent((SevenBitNumber)20, (SevenBitNumber)100), 100)
            },
                "First track chunk of second file contains invalid events.");
            CompareTimedEvents(
                newFiles[1].GetTrackChunks().Last().GetTimedEvents(),
                new[]
            {
                new TimedEvent(new NoteOnEvent((SevenBitNumber)21, (SevenBitNumber)100), 0),
                new TimedEvent(new NoteOffEvent((SevenBitNumber)21, (SevenBitNumber)100), 100)
            },
                "Second track chunk of second file contains invalid events.");
        }
Example #6
0
        private void PreviewButton_Click(object sender, EventArgs e)
        {
            if ("Stop" == PreviewButton.Text)
            {
                if (null != _play)
                {
                    _play.Close();
                }
                MidiFileBox.Enabled    = true;
                BrowseButton.Enabled   = true;
                OutputComboBox.Enabled = true;
                PreviewButton.Text     = "Preview";
                return;
            }

            if (null != _play)
            {
                _play.Close();
            }
            MidiFileBox.Enabled    = false;
            BrowseButton.Enabled   = false;
            OutputComboBox.Enabled = false;
            PreviewButton.Text     = "Stop";
            if (_dirty)
            {
                _processedFile = _ProcessFile();
            }
            var mf = _processedFile;

            _play = (OutputComboBox.SelectedItem as MidiOutputDevice).Stream;
            var stm = _play;
            // we use 100 events, which should be safe and allow
            // for some measure of SYSEX messages in the stream
            // without bypassing the 64kb limit
            const int MAX_EVENT_COUNT = 100;
            const int RATE_TICKS      = 500;
            // our current cursor pos
            var pos = 0;
            // for tracking deltas
            var ofs = 0;
            // for tracking the song position
            var songPos = 0;
            // merge our file for playback
            var seq    = MidiSequence.Merge(mf.Tracks);
            var events = seq.Events;
            // the number of events in the seq
            var len = events.Count;
            // stores the next set of events
            var eventList = new List <MidiEvent>(MAX_EVENT_COUNT);

            // open the stream
            stm.Open();
            // start it
            stm.Start();

            // first set the timebase
            stm.TimeBase = mf.TimeBase;
            // set up our send complete handler
            stm.SendComplete += delegate(object s, EventArgs ea)
            {
                try
                {
                    BeginInvoke(new Action(delegate()
                    {
                        // clear the list
                        eventList.Clear();
                        mf = _processedFile;
                        if (_dirty)
                        {
                            if (_reseekDirty)
                            {
                                var time       = _processedFile.Tracks[0].GetContext(songPos, _processedFile.TimeBase).Time;
                                _processedFile = _ProcessFile();
                                songPos        = _processedFile.Tracks[0].GetPositionAtTime(time, _processedFile.TimeBase);
                                mf             = _processedFile;
                                seq            = MidiSequence.Merge(mf.Tracks);
                                events         = new List <MidiEvent>(seq.GetNextEventsAtPosition(songPos, true));
                                len            = events.Count;
                                pos            = 0;
                            }
                            else
                            {
                                _processedFile = _ProcessFile();
                                mf             = _processedFile;
                                seq            = MidiSequence.Merge(mf.Tracks);
                                events         = seq.Events;
                            }
                            Visualizer.Sequence = seq;
                            Visualizer.Width    = Math.Max(VisualizerPanel.Width, Visualizer.Sequence.Length / 4);
                        }


                        ofs = 0;
                        len = events.Count;
                        // iterate through the next events
                        var next = pos + MAX_EVENT_COUNT;
                        for (; pos < next && ofs <= RATE_TICKS; ++pos)

                        {
                            // if it's past the end, loop it
                            if (len <= pos)
                            {
                                pos     = 0;
                                songPos = 0;
                                events  = seq.Events;
                                break;
                            }
                            var ev   = events[pos];
                            ofs     += ev.Position;
                            songPos += pos;
                            if (ev.Position < RATE_TICKS && RATE_TICKS < ofs)
                            {
                                break;
                            }
                            // otherwise add the next event
                            eventList.Add(ev);
                        }
                        // send the list of events
                        if (MidiStreamState.Closed != stm.State && 0 != eventList.Count)
                        {
                            stm.SendDirect(eventList);
                        }
                    }));
                }
                catch { }
            };
            // add the first events
            for (pos = 0; pos < MAX_EVENT_COUNT && ofs <= RATE_TICKS; ++pos)
            {
                // if it's past the end, loop it
                if (len <= pos)
                {
                    pos     = 0;
                    songPos = 0;
                    events  = seq.Events;
                    break;
                }
                var ev = events[pos];
                ofs += ev.Position;
                if (ev.Position < RATE_TICKS && RATE_TICKS < ofs)
                {
                    break;
                }
                // otherwise add the next event
                eventList.Add(ev);
            }
            // send the list of events
            if (0 != eventList.Count)
            {
                stm.SendDirect(eventList);
            }
        }
        public void Extractor()
        {
            int  pan         = 0;
            int  noteLength  = 0;
            int  restLength  = 0;
            int  tempLength  = 0;
            int  totalLength = 0;  //the sum of noteLength and restLength.
            int  trackVolume = 1;  //volume of the MIDI track, can change throughout the track
            int  velocity    = 0;  // velocity of the MIDI note
            int  note        = -1; //stores the value of the next note; -1 is the starting note and is a "rest" that might print only in the beginning;
            bool flagNote    = false;

            int[] MIDILength = new int[] { 0, 0, 0, 0 };

            //checks if the out.asm file already exists and clears its contents
            if (File.Exists(string.Concat(directoryPath, ASMFileName, ".asm")))
            {
                FileStream fileStream = File.Open(string.Concat(directoryPath, ASMFileName, ".asm"), FileMode.Open);
                fileStream.SetLength(0);
                fileStream.Close();
            }

            var midifile     = MidiFile.Read(directoryPath + midiFileName + "." + midiFileExtension);
            var trackChuncks = midifile.GetTrackChunks(); // contains the information for all tracks

            if (TempoTrack)
            {
                NumberOfTracks = trackChuncks.Count() - 1;
                TrackNumber    = -1;
            }
            else
            {
                NumberOfTracks = trackChuncks.Count();
            }

            //finds the TimeDivision and the number of tracks of the MIDI file
            string[] tempDivision = midifile.TimeDivision.ToString().Split(' ');
            TimeDivision = Int32.Parse(tempDivision[0]);
            for (int k = 0; k < allowedNotetypes.Length; k++)
            {
                unitaryLengthArray[k] = Convert.ToInt32((double)TimeDivision / (48 / allowedNotetypes[k]));
            }
            unitaryLength = unitaryLengthArray[BaseNotetypeLocation];

            AllTrackList = new List <MIDINote> [NumberOfTracks]; //creates the AllTrackList with NumberOfTracks Length
            // Reads each track in sequence
            foreach (var track in trackChuncks)
            {
                TrackNumber++;
                trackVolume = 1; //resets trackvolume for the new track

                //loops through events
                foreach (MidiEvent Level2 in track.Events)
                {
                    //get the Delta Time of the event
                    tempLength  = (int)Level2.DeltaTime;
                    totalLength = noteLength + tempLength + restLength;

                    switch (Level2.EventType.ToString())
                    {
                    case "ControlChange":
                    {
                        ControlChangeEvent TempEvent = (ControlChangeEvent)Level2;
                        //tests and changes stereopanning
                        if (TempEvent.ControlNumber == 10)
                        {
                            pan = TempEvent.ControlValue;
                        }
                        //sets new trackvolume to define the intensity of this track. Can vary multiple times during the same music.
                        if (TempEvent.ControlNumber == 7)
                        {
                            trackVolume = TempEvent.ControlValue;
                        }
                        break;
                    }

                    //only relevant for the first track
                    case "TimeSignature":
                    {
                        TimeSignatureEvent TempEvent = (TimeSignatureEvent)Level2;
                        timeSignature = TempEvent.Numerator * 16 / TempEvent.Denominator;
                        break;
                    }

                    case "SetTempo":
                    {
                        SetTempoEvent TempEvent = (SetTempoEvent)Level2;
                        Tempo = Convert.ToInt32(TempEvent.MicrosecondsPerQuarterNote) / 3138;;
                        break;
                    }

                    case "NoteOn":
                    {
                        //register the currently "saved" note
                        // we are on a rest

                        NoteEvent TempEvent = (NoteEvent)Level2;
                        flagNote    = true;
                        restLength += tempLength;
                        if ((restLength >= unitaryLength & TrackNumber != 4) || (restLength >= unitaryLength * 16))         //the noise channel only prints rests if its bigger than 16 times the UL
                        {
                            if (IgnoreRests)
                            {
                                NoteListTemp.Add(new MIDINote(noteLength + restLength, MIDILength[TrackNumber - 1], note, pan, velocity, trackVolume));
                            }
                            else
                            {
                                NoteListTemp.Add(new MIDINote(noteLength, MIDILength[TrackNumber - 1], note, pan, velocity, trackVolume));
                                NoteListTemp.Add(new MIDINote(restLength, MIDILength[TrackNumber - 1] + noteLength, 0, pan, velocity, trackVolume));
                            }
                        }
                        else
                        {
                            NoteListTemp.Add(new MIDINote(totalLength, MIDILength[TrackNumber - 1], note, pan, velocity, trackVolume));
                        }

                        //i++; //debug
                        //NoteListTemp.ElementAt(i-1).ShowNotes(); //debug

                        MIDILength[TrackNumber - 1] += totalLength;
                        noteLength = restLength = tempLength = totalLength = 0;

                        //setup for the next note
                        note     = TempEvent.NoteNumber;
                        velocity = TempEvent.Velocity;
                        break;
                    }

                    case "NoteOff":
                    {
                        //NoteEvent TempEvent = (NoteEvent)Level2;
                        flagNote    = true;
                        noteLength += tempLength;
                        break;
                    }

                    default:
                    {
                        break;
                    }
                    }
                    if (!flagNote & tempLength > unitaryLength)
                    {
                        restLength += tempLength;
                    }
                    else if (!flagNote)
                    {
                        noteLength += tempLength;
                    }
                    flagNote = false;
                }

                //last note print
                if (TrackNumber > 0)
                {
                    NoteListTemp.Add(new MIDINote(totalLength, MIDILength[TrackNumber - 1], note, pan, velocity, trackVolume));
                }

                //We've reached the end of the track
                noteLength = restLength = totalLength = 0;
                note       = -1;

                if (TrackNumber > 0)
                {
                    AllTrackList[TrackNumber - 1] = new List <MIDINote>(NoteListTemp);
                    //for(int i=0;i<NoteListTemp.Count;i++)
                    //{
                    //    Console.WriteLine(NoteListTemp.ElementAt(i));
                    //}
                    NoteListTemp.Clear();
                }
            }
        }
 public static Program ToProgram(this MidiFile midiFile) => new MidiConverter(midiFile).Program;
        /// <summary>
        /// Play current song.
        /// </summary>
        public void Play(SongFiles song)
        {
            if (!InitSynth())
                return;

            // Stop if playing another song
            Stop();

            // Load song data
            string filename = EnumToFilename(song);
            byte[] songData = LoadSong(filename);
            if (songData == null)
                return;

            // Create song
            MidiFile midiFile = new MidiFile(new MyMemoryFile(songData, filename));
            if (midiSequencer.LoadMidi(midiFile))
            {
                midiSequencer.Play();
                currentMidiName = filename;
                playEnabled = true;
            }
        }
Example #10
0
        public static RBSongResource MakeRBSong(DataArray array, MidiFile mf)
        {
            var drumBank = array.Array("drum_bank")?.Any(1)
                           .Replace("sfx", "fusion/patches")
                           .Replace("_bank.milo", ".fusion")
                           ?? "fusion/patches/kit01.fusion";
            var animations = ExtractVenuePropAnimsFromMidi(mf);

            return(new RBSongResource
            {
                Version = 0xE,
                Entity = new Entity
                {
                    Version = 0x14,
                    Layers = new[] {
                        new EntityLayer
                        {
                            Version = 0x14,
                            fileSlotIndex = 0,
                            TotalObjectLayers = 1,
                            Objects = new GameObject[]
                            {
                                new GameObject
                                {
                                    Id = new GameObjectId {
                                        Index = 0, Layer = 0
                                    },
                                    Rev = 2,
                                    Name = "root",
                                    Components = new Component[] {
                                        editorComponent,
                                        entityHeaderComponent,
                                        new Component
                                        {
                                            Rev = 3,
                                            Name1 = "RBSongMetadata",
                                            Name2 = "RBSongMetadata",
                                            Unknown2 = 4,
                                            Props = new[]
                                            {
                                                new Property("tempo", new SymbolValue("medium")),
                                                new Property("vocal_tonic_note", new LongValue(array.Array("vocal_tonic_note")?.Int(1) ?? 0)),
                                                new Property("vocal_track_scroll_duration_ms", new LongValue(array.Array("song_scroll_speed")?.Int(1) ?? 2300)),
                                                new Property("global_tuning_offset", new FloatValue(array.Array("tuning_offset_cents")?.Number(1) ?? 0)),
                                                new Property("band_fail_sound_event", new SymbolValue("")),
                                                new Property("vocal_percussion_patch", new ResourcePathValue("fusion/patches/vox_perc_tambourine.fusion")),
                                                new Property("drum_kit_patch", new ResourcePathValue(drumBank)),
                                                new Property("improv_solo_patch", new SymbolValue("gtrsolo_amer_03")),
                                                new Property("dynamic_drum_fill_override", new IntValue(10)),
                                                new Property("improv_solo_volume_db", new FloatValue(-9))
                                            }
                                        },
                                        new Component
                                        {
                                            Rev = 3,
                                            Name1 = "RBVenueAuthoring",
                                            Name2 = "RBVenueAuthoring",
                                            Unknown2 = 0,
                                            Props = new[]
                                            {
                                                new Property("part2_instrument", new IntValue(2)),
                                                new Property("part3_instrument", new IntValue(0)),
                                                new Property("part4_instrument", new IntValue(1))
                                            }
                                        }
                                    }
                                }
                            }
                        },
                    }
                },
                InlineLayerNames = new string[] { "" },
                InlineResourceLayers = new[] {
                    new Resource[] {
                        new PropAnimResource()
                        {
                            Path = "venue_authoring_data",
                            Version = 0xE,
                            InlineLayerNames = new string[] { "" },
                            InlineResourceLayers = new Resource[][] { new Resource[] { } },
                            Entity = new Entity
                            {
                                Version = 0x14,
                                Layers = new[]
                                {
                                    new EntityLayer
                                    {
                                        Version = 0x14,
                                        fileSlotIndex = 0,
                                        TotalObjectLayers = (short)animations.Length,
                                        Objects = animations,
                                    }
                                }
                            }
                        }
                    }
                }
            });
        }
Example #11
0
        static GameObject[] ExtractVenuePropAnimsFromMidi(MidiFile mf)
        {
            var   objs      = new List <GameObject>();
            short index     = 1;
            var   editorCom = new Component
            {
                Rev      = 3,
                Name1    = "Editor",
                Name2    = "Editor",
                Unknown2 = 2,
                Props    = new[] { new Property("capabilities", new UIntValue(62)) }
            };

            objs.Add(new GameObject
            {
                Id = new GameObjectId {
                    Index = 0, Layer = 0
                },
                Rev        = 2,
                Name       = "root",
                Components = new[]
                {
                    editorComponent,
                    entityHeaderComponent,
                    new Component
                    {
                        Rev      = 3,
                        Name1    = "PropAnim",
                        Name2    = "PropAnim",
                        Unknown2 = 0,
                        Props    = StructValue.FromData(
                            StructType.FromData(DTX.FromDtaString(
                                                    @"(props 
                            (frame_range_start float)
                            (frame_range_end float)
                            (time_units int)
                            (is_looping bool))")),
                            DTX.FromDtaString(
                                @"(frame_range_start 3.402823E+38)
                          (frame_range_end -3.402823E+38)
                          (time_units 0)
                          (is_looping 0)")).Props
                    }
                }
            });
            var tracks  = new Midi.MidiHelper().ProcessTracks(mf);
            var partMap = new Dictionary <string, string> {
                { "PART BASS", "bass_intensity" },
                { "PART GUITAR", "guitar_intensity" },
                { "PART DRUMS", "drum_intensity" },
                { "PART VOCALS", "mic_intensity" },
#if DEBUG
                { "PART KEYS", "keyboard_intensity" },
#endif
            };
            var intensityMap = new Dictionary <string, string>
            {
                // All
                { "[idle_realtime]", "idle_realtime" },
                { "[idle]", "idle" },
                { "[idle_intense]", "idle_intense" },
                { "[play]", "play" },
                { "[mellow]", "mellow" },
                { "[intense]", "intense" },
                // Guitar/bass only
                { "[play_solo]", "play_solo" },
                // Vocal only
                { "[tambourine_start]", "tambourine_start" },
                { "[tambourine_end]", "tambourine_end" },
                { "[cowbell_start]", "cowbell_start" },
                { "[cowbell_end]", "cowbell_end" },
                { "[clap_start]", "clap_start" },
                { "[clap_end]", "clap_end" },
                // Drum only
                { "[ride_side_true]", "ride_side_true" },
                { "[ride_side_false]", "ride_side_false" },
            };

            void AddAnimTrack(StructValue props)
            {
                objs.Add(new GameObject
                {
                    Id = new GameObjectId {
                        Index = index, Layer = index++
                    },
                    Rev        = 2,
                    Name       = "Keys type 11",
                    Components = new[]
                    {
                        editorCom,
                        new Component
                        {
                            Rev      = 3,
                            Name1    = "PropKeysSymCom",
                            Name2    = "PropKeys",
                            Unknown2 = 0,
                            Props    = props.Props
                        }
                    }
                });
            }

            StructValue MakeAnimProps(string drivenProp, List <Tuple <float, string> > frames)
            {
                var propkeys = DTX.FromDtaString(
                    "(keys ()) " +
                    "(interpolation 0) " +
                    $"(driven_prop (0 0 RBVenueAuthoring 0 1 {drivenProp}))");
                var keyframes = propkeys.Array("keys").Array(1);

                foreach (var(frame, key) in frames)
                {
                    var keyframe = new DataArray();
                    keyframe.AddNode(new DataAtom(frame));
                    keyframe.AddNode(DataSymbol.Symbol(key));
                    keyframes.AddNode(keyframe);
                }
                return(StructValue.FromData(propKeysType, propkeys));
            }

            foreach (var track in tracks)
            {
                if (!partMap.ContainsKey(track.Name))
                {
                    continue;
                }
                var frames = new List <Tuple <float, string> >();
                foreach (var n in track.Items)
                {
                    if (n is Midi.MidiText t)
                    {
                        if (intensityMap.ContainsKey(t.Text))
                        {
                            frames.Add(Tuple.Create((float)n.StartTicks / mf.TicksPerQN, intensityMap[t.Text]));
                        }
                    }
                }
                AddAnimTrack(MakeAnimProps(partMap[track.Name], frames));
            }
            AddAnimTrack(MakeAnimProps("shot_bg", new List <Tuple <float, string> > {
                Tuple.Create(0f, "coop_all_far")
            }));
            AddAnimTrack(MakeAnimProps("shot_bk", new List <Tuple <float, string> > {
                Tuple.Create(0f, "coop_all_far")
            }));
            AddAnimTrack(MakeAnimProps("shot_gk", new List <Tuple <float, string> > {
                Tuple.Create(0f, "coop_all_far")
            }));
            AddAnimTrack(MakeAnimProps("crowd", new List <Tuple <float, string> > {
                Tuple.Create(0f, "crowd_realtime")
            }));
            AddAnimTrack(MakeAnimProps("world_event", new List <Tuple <float, string> > {
                Tuple.Create(0f, "none")
            }));
            //AddAnimTrack(MakeAnimProps("part2_sing", new List<Tuple<float, string>> {Tuple.Create(0f, "singalong_off") }));
            //AddAnimTrack(MakeAnimProps("part3_sing", new List<Tuple<float, string>> {Tuple.Create(0f, "singalong_off") }));
            //AddAnimTrack(MakeAnimProps("part4_sing", new List<Tuple<float, string>> {Tuple.Create(0f, "singalong_off") }));
            AddAnimTrack(MakeAnimProps("lightpreset", new List <Tuple <float, string> > {
                Tuple.Create(0f, "silhouettes")
            }));
            AddAnimTrack(MakeAnimProps("postproc", new List <Tuple <float, string> > {
                Tuple.Create(0f, "profilm_a")
            }));
            AddAnimTrack(MakeAnimProps("lightpreset_keyframe", new List <Tuple <float, string> > {
                Tuple.Create(0f, "next")
            }));
            AddAnimTrack(MakeAnimProps("spot_bass", new List <Tuple <float, string> > {
                Tuple.Create(0f, "off")
            }));
            AddAnimTrack(MakeAnimProps("spot_guitar", new List <Tuple <float, string> > {
                Tuple.Create(0f, "off")
            }));
            AddAnimTrack(MakeAnimProps("spot_drums", new List <Tuple <float, string> > {
                Tuple.Create(0f, "off")
            }));
            //AddAnimTrack(MakeAnimProps("spot_keyboard", new List<Tuple<float, string>> {Tuple.Create(0f, "off") }));
            AddAnimTrack(MakeAnimProps("spot_vocal", new List <Tuple <float, string> > {
                Tuple.Create(0f, "off")
            }));
            //AddAnimTrack(MakeAnimProps("shot_5", new List<Tuple<float, string>> {Tuple.Create(0f, "coop_all_far") }));
            AddAnimTrack(MakeAnimProps("stagekit_fog", new List <Tuple <float, string> > {
                Tuple.Create(0f, "off")
            }));
            return(objs.ToArray());
        }
Example #12
0
        public void Load(string path)
        {
            LoadedMidi = new MidiFile(path, false);
            // Parse the midi for info; we want to start by getting a list of all the channels
            // We also need to know the highest and lowest note for each Instrument/Channel (screw tracks)
            // And of course, that gives us overall highest/lowest
            MidiChannelMap = new Dictionary <int, MidiChannel>();
            MidiTrackMap   = new Dictionary <int, MidiTrack>();
            MidiChannels   = new List <MidiChannel>();
            MidiTracks     = new List <MidiTrack>();

            for (int i = 0; i < LoadedMidi.Tracks; i++)
            {
                var newTrack = new MidiTrack("Untitled", i);
                MidiTrackMap[i] = newTrack;
                MidiTracks.Add(newTrack);
                var e = LoadedMidi.Events[i];
                foreach (var ie in e)
                {
                    if (ie is TextEvent)
                    {
                        var me = ie as TextEvent;
                        if (me.MetaEventType == MetaEventType.SequenceTrackName)
                        {
                            MidiTrackMap[i].TrackName = me.Text;
                        }
                    }
                    else if (ie is PatchChangeEvent)
                    {
                        // These are the correct events, they happen at the start to set the instrument for a channel
                        // Note that specifically channel 10 is usually interpreted as drums, and the instrument they set on it is arbitrary
                        var    patchChange    = ie as PatchChangeEvent;
                        string instrumentName = "Drums";
                        if (ie.Channel != 10)
                        {
                            instrumentName = PatchChangeEvent.GetPatchName(patchChange.Patch);
                        }
                        var channel = new MidiChannel(instrumentName, ie.Channel);
                        MidiChannelMap[ie.Channel] = channel;
                        MidiChannels.Add(channel);
                    }
                    else if (ie is NoteOnEvent)
                    {
                        var         noteEvent = ie as NoteOnEvent;
                        MidiChannel channel;
                        if (!MidiChannelMap.ContainsKey(ie.Channel))
                        {
                            // We got a note for a channel that never had an instrument set
                            // Initialize it as piano
                            channel = new MidiChannel("Piano (Default)", ie.Channel);
                            MidiChannelMap[ie.Channel] = channel;
                            MidiChannels.Add(channel);
                        }
                        else
                        {
                            channel = MidiChannelMap[ie.Channel];
                        }

                        // If the OffEvent is null, that means this is itself an off event... otherwise it links to the one that ends it
                        if (noteEvent.OffEvent != null && noteEvent.Velocity > 0)
                        {
                            if (channel.HighestNote == null || noteEvent.NoteNumber > channel.HighestNote.Number)
                            {
                                channel.HighestNote = new MidiNote(noteEvent.NoteNumber);
                            }
                            if (channel.LowestNote == null || noteEvent.NoteNumber < channel.LowestNote.Number)
                            {
                                channel.LowestNote = new MidiNote(noteEvent.NoteNumber);
                            }
                        }
                    }
                }
            }
        }
Example #13
0
        /** Set the MidiFile to use.
         *  Save the list of midi notes. Each midi note includes the note Number
         *  and StartTime (in pulses), so we know which notes to shade given the
         *  current pulse time.
         */
        public void SetMidiFile(MidiFile midifile, MidiOptions options)
        {
            if (midifile == null) {
            notes = null;
            useTwoColors = false;
            return;
            }

            List<MidiTrack> tracks = midifile.ChangeMidiNotes(options);
            MidiTrack track = MidiFile.CombineToSingleTrack(tracks);
            notes = track.Notes;

            maxShadeDuration = midifile.Time.Quarter * 2;

            /* We want to know which track the note came from.
             * Use the 'channel' field to store the track.
             */
            for (int tracknum = 0; tracknum < tracks.Count; tracknum++) {
            foreach (MidiNote note in tracks[tracknum].Notes) {
                note.Channel = tracknum;
            }
            }

            /* When we have exactly two tracks, we assume this is a piano song,
             * and we use different colors for highlighting the left hand and
             * right hand notes.
             */
            useTwoColors = false;
            if (tracks.Count == 2) {
            useTwoColors = true;
            }

            showNoteLetters = options.showNoteLetters;
            this.Invalidate();
        }
Example #14
0
        private ComboBox[] instrumentChoices; /** The instruments to use per track */

        #endregion Fields

        #region Constructors

        /** Create a new InstrumentDialog.  Call the ShowDialog() method
         * to display the dialog.
         */
        public InstrumentDialog(MidiFile midifile)
        {
            /* Create the dialog box */
            dialog = new Form();
            Font font = dialog.Font;
            dialog.Font = new Font(font.FontFamily, font.Size * 1.4f);
            int unit = dialog.Font.Height;
            int xstart = unit * 2;
            int ystart = unit * 2;
            int labelheight = unit * 2;
            int maxwidth = 0;

            dialog.Text = "Choose Instruments For Each Track";
            dialog.MaximizeBox = false;
            dialog.MinimizeBox = false;
            dialog.ShowInTaskbar = false;
            dialog.Icon = new Icon(GetType(), "NotePair.ico");
            dialog.AutoScroll = true;

            List<MidiTrack> tracks = midifile.Tracks;
            instrumentChoices = new ComboBox[tracks.Count];

            /* For each midi track, create a label with the track number
             * ("Track 2"), and a ComboBox containing all the possible
             * midi instruments. Add the text "(default)" to the instrument
             * specified in the midi file.
             */
            for (int i = 0; i < tracks.Count; i++) {
            int num = i+1;
            Label label = new Label();
            label.Parent = dialog;
            label.Text = "Track " + num;
            label.TextAlign = ContentAlignment.MiddleRight;
            label.Location = new Point(xstart, ystart + i*labelheight);
            label.AutoSize = true;
            maxwidth = Math.Max(maxwidth, label.Width);
            }
            for (int i = 0; i < tracks.Count; i++) {
            instrumentChoices[i] = new ComboBox();
            instrumentChoices[i].DropDownStyle = ComboBoxStyle.DropDownList;
            instrumentChoices[i].Parent = dialog;
            instrumentChoices[i].Location = new Point(xstart + maxwidth * 3/2, ystart + i*labelheight);
            instrumentChoices[i].Size = new Size(labelheight * 8, labelheight);

            for (int instr = 0; instr < MidiFile.Instruments.Length; instr++) {
                string name = MidiFile.Instruments[instr];
                if (tracks[i].Instrument == instr) {
                    name += " (default)";
                }
                instrumentChoices[i].Items.Add(name);
            }
            instrumentChoices[i].SelectedIndex = tracks[i].Instrument;
            }

            /* Create the "Set All To Piano" button */
            Button allPiano = new Button();
            allPiano.Parent = dialog;
            allPiano.Text = "Set All To Piano";
            allPiano.Location = new Point(xstart + maxwidth * 3/2,
                                      ystart + tracks.Count * labelheight);
            allPiano.Click += new EventHandler(SetAllPiano);
            allPiano.Size = new Size(labelheight * 5, labelheight);

            /* Create the OK and Cancel buttons */
            int ypos = ystart + (tracks.Count + 3) * labelheight;
            Button ok = new Button();
            ok.Parent = dialog;
            ok.Text = "OK";
            ok.Location = new Point(xstart, ypos);
            ok.DialogResult = DialogResult.OK;

            Button cancel = new Button();
            cancel.Parent = dialog;
            cancel.Text = "Cancel";
            cancel.Location = new Point(ok.Location.X + ok.Width + labelheight/2, ypos);
            cancel.DialogResult = DialogResult.Cancel;

            dialog.Size = new Size(instrumentChoices[0].Location.X + instrumentChoices[0].Width + 50,
                               cancel.Location.Y + cancel.Size.Height + 50);
        }
Example #15
0
        /** Create a new SheetMusic control, using the given midi filename.
         *  The options can be null.
         */
        public SheetMusic(string filename, MidiOptions options)
        {
            MidiFile file = new MidiFile(filename);

            init(file, options);
        }
        /// <summary>
        /// Gets timed events contained in the specified <see cref="MidiFile"/>.
        /// </summary>
        /// <param name="file"><see cref="MidiFile"/> to search for events.</param>
        /// <returns>Collection of timed events contained in <paramref name="file"/> ordered by time.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="file"/> is <c>null</c>.</exception>
        public static IEnumerable <TimedEvent> GetTimedEvents(this MidiFile file)
        {
            ThrowIfArgument.IsNull(nameof(file), file);

            return(file.GetTrackChunks().GetTimedEvents());
        }
Example #17
0
        /** Create a new MidiPlayer, displaying the play/stop buttons, the
         *  speed bar, and volume bar.  The midifile and sheetmusic are initially null.
         */
        public MidiPlayer()
        {
            this.Font = new Font("Arial", 10, FontStyle.Bold);
            loadButtonImages();
            int buttonheight = this.Font.Height * 2;

            this.midifile    = null;
            this.options     = null;
            this.sheet       = null;
            playstate        = stopped;
            startTime        = DateTime.Now.TimeOfDay;
            startPulseTime   = 0;
            currentPulseTime = 0;
            prevPulseTime    = -10;
            errormsg         = new StringBuilder(256);
            ToolTip tip;

            /* Create the rewind button */
            rewindButton            = new Button();
            rewindButton.Parent     = this;
            rewindButton.Image      = rewindImage;
            rewindButton.ImageAlign = ContentAlignment.MiddleCenter;
            rewindButton.Size       = new Size(buttonheight, buttonheight);
            rewindButton.Location   = new Point(buttonheight / 2, buttonheight / 2);
            rewindButton.Click     += new EventHandler(Rewind);
            tip = new ToolTip();
            tip.SetToolTip(rewindButton, "Rewind");

            /* Create the play button */
            playButton            = new Button();
            playButton.Parent     = this;
            playButton.Image      = playImage;
            playButton.ImageAlign = ContentAlignment.MiddleCenter;
            playButton.Size       = new Size(buttonheight, buttonheight);
            playButton.Location   = new Point(buttonheight / 2, buttonheight / 2);
            playButton.Location   = new Point(rewindButton.Location.X + rewindButton.Width + buttonheight / 2,
                                              rewindButton.Location.Y);
            playButton.Click += new EventHandler(PlayPause);
            playTip           = new ToolTip();
            playTip.SetToolTip(playButton, "Play");

            /* Create the stop button */
            stopButton            = new Button();
            stopButton.Parent     = this;
            stopButton.Image      = stopImage;
            stopButton.ImageAlign = ContentAlignment.MiddleCenter;
            stopButton.Size       = new Size(buttonheight, buttonheight);
            stopButton.Location   = new Point(playButton.Location.X + playButton.Width + buttonheight / 2,
                                              playButton.Location.Y);
            stopButton.Click += new EventHandler(Stop);
            tip = new ToolTip();
            tip.SetToolTip(stopButton, "Stop");

            /* Create the fastFwd button */
            fastFwdButton            = new Button();
            fastFwdButton.Parent     = this;
            fastFwdButton.Image      = fastFwdImage;
            fastFwdButton.ImageAlign = ContentAlignment.MiddleCenter;
            fastFwdButton.Size       = new Size(buttonheight, buttonheight);
            fastFwdButton.Location   = new Point(stopButton.Location.X + stopButton.Width + buttonheight / 2,
                                                 stopButton.Location.Y);
            fastFwdButton.Click += new EventHandler(FastForward);
            tip = new ToolTip();
            tip.SetToolTip(fastFwdButton, "Fast Forward");



            /* Create the Speed bar */
            Label speedLabel = new Label();

            speedLabel.Parent    = this;
            speedLabel.Text      = "Speed: ";
            speedLabel.TextAlign = ContentAlignment.MiddleRight;
            speedLabel.Height    = buttonheight;
            speedLabel.Width     = buttonheight * 2;
            speedLabel.Location  = new Point(fastFwdButton.Location.X + fastFwdButton.Width + buttonheight / 2,
                                             fastFwdButton.Location.Y);

            speedBar               = new TrackBar();
            speedBar.Parent        = this;
            speedBar.Minimum       = 1;
            speedBar.Maximum       = 100;
            speedBar.TickFrequency = 10;
            speedBar.TickStyle     = TickStyle.BottomRight;
            speedBar.LargeChange   = 10;
            speedBar.Value         = 100;
            speedBar.Width         = buttonheight * 5;
            speedBar.Location      = new Point(speedLabel.Location.X + speedLabel.Width + 2,
                                               speedLabel.Location.Y);
            tip = new ToolTip();
            tip.SetToolTip(speedBar, "Adjust the speed");

            /* Create the Volume bar */
            Label volumeLabel = new Label();

            volumeLabel.Parent     = this;
            volumeLabel.Image      = volumeImage;
            volumeLabel.ImageAlign = ContentAlignment.MiddleRight;
            volumeLabel.Height     = buttonheight;
            volumeLabel.Width      = buttonheight * 2;
            volumeLabel.Location   = new Point(speedBar.Location.X + speedBar.Width + buttonheight / 2,
                                               speedBar.Location.Y);

            volumeBar               = new TrackBar();
            volumeBar.Parent        = this;
            volumeBar.Minimum       = 1;
            volumeBar.Maximum       = 100;
            volumeBar.TickFrequency = 10;
            volumeBar.TickStyle     = TickStyle.BottomRight;
            volumeBar.LargeChange   = 10;
            volumeBar.Value         = 100;
            volumeBar.Width         = buttonheight * 5;
            volumeBar.Location      = new Point(volumeLabel.Location.X + volumeLabel.Width + 2,
                                                volumeLabel.Location.Y);
            volumeBar.Scroll += new EventHandler(ChangeVolume);
            tip = new ToolTip();
            tip.SetToolTip(volumeBar, "Adjust the volume");

            Height = buttonheight * 2;

            /* Initialize the timer used for playback, but don't start
             * the timer yet (enabled = false).
             */
            timer          = new Timer();
            timer.Enabled  = false;
            timer.Interval = 100;  /* 100 millisec */
            timer.Tick    += new EventHandler(TimerCallback);

            tempSoundFile = "";
        }
Example #18
0
            public MidiDecoder(byte[] data, bool loop)
            {
                midi = new MidiFile(new MemoryStream(data));

                this.loop = loop;
            }
Example #19
0
        public void SplitByGridAndRemoveEmptyPartsAndMergeIntoNewFile()
        {
            var timedEvents1 = new[]
            {
                new TimedEvent(new TextEvent("A1"), 0),
                new TimedEvent(new SetTempoEvent(100000), 10),
                new TimedEvent(new TextEvent("B1"), 90),
                new TimedEvent(new TextEvent("C1"), 210),
                new TimedEvent(new NoteOnEvent(), 270),
                new TimedEvent(new NoteOffEvent(), 320)
            };

            var timedEvents2 = new[]
            {
                new TimedEvent(new TextEvent("A2"), 10),
                new TimedEvent(new TextEvent("B2"), 70),
                new TimedEvent(new TextEvent("C2"), 260)
            };

            var trackChunk1 = timedEvents1.ToTrackChunk();
            var trackChunk2 = timedEvents2.ToTrackChunk();
            var midiFile    = new MidiFile(trackChunk1, trackChunk2);

            var grid     = new SteppedGrid((MidiTimeSpan)100);
            var settings = new SliceMidiFileSettings
            {
                SplitNotes          = false,
                PreserveTimes       = false,
                PreserveTrackChunks = true,
                Markers             = new SliceMidiFileMarkers
                {
                    PartStartMarkerEventFactory = () => new MarkerEvent("S"),
                    PartEndMarkerEventFactory   = () => new MarkerEvent("F"),
                    EmptyPartMarkerEventFactory = () => new MarkerEvent("E")
                }
            };

            var newFiles = midiFile.SplitByGrid(grid, settings).ToList();

            Assert.AreEqual(4, newFiles.Count, "New files count is invalid.");

            //

            var nonEmptyParts = newFiles.Where(f =>
            {
                var newTimedEvents = f.GetTimedEvents().ToArray();
                return(newTimedEvents.Any() && !newTimedEvents.Any(e => MidiEvent.Equals(e.Event, new MarkerEvent("E"))));
            })
                                .ToArray();

            Assert.AreEqual(3, nonEmptyParts.Length, "Non-empty new files count is invalid.");

            //

            var trackChunksCount = midiFile.GetTrackChunks().Count();
            var newTrackChunks   = new List <TrackChunk>();

            for (var i = 0; i < trackChunksCount; i++)
            {
                var trackChunk = new TrackChunk();

                foreach (var part in nonEmptyParts)
                {
                    trackChunk.Events.AddRange(part.GetTrackChunks().ElementAt(i).Events);
                }

                newTrackChunks.Add(trackChunk);
            }

            var resultFile = new MidiFile(newTrackChunks)
            {
                TimeDivision = midiFile.TimeDivision
            };

            //

            var equalityCheckSettings = new MidiEventEqualityCheckSettings
            {
                CompareDeltaTimes = false
            };

            resultFile.RemoveTimedEvents(e =>
                                         MidiEvent.Equals(e.Event, new MarkerEvent("S"), equalityCheckSettings) ||
                                         MidiEvent.Equals(e.Event, new MarkerEvent("F"), equalityCheckSettings) ||
                                         MidiEvent.Equals(e.Event, new MarkerEvent("E"), equalityCheckSettings));

            //

            CompareTimedEvents(
                resultFile.GetTimedEvents(),
                new[]
            {
                new TimedEvent(new TextEvent("A1"), 0),
                new TimedEvent(new SetTempoEvent(100000), 10),
                new TimedEvent(new TextEvent("A2"), 10),
                new TimedEvent(new TextEvent("B2"), 70),
                new TimedEvent(new TextEvent("B1"), 90),
                new TimedEvent(new SetTempoEvent(100000), 100),
                new TimedEvent(new TextEvent("C1"), 110),
                new TimedEvent(new TextEvent("C2"), 160),
                new TimedEvent(new NoteOnEvent(), 170),
                new TimedEvent(new SetTempoEvent(100000), 200),
                new TimedEvent(new NoteOffEvent(), 220)
            },
                "Result file contains invalid events.");
        }
Example #20
0
 public void FileLoad(string path)
 {
     _midiFile = new MidiFile(path);
 }
Example #21
0
 public MIDI(MidiFile midi)
 {
     this.midi = midi;
 }
Example #22
0
        public static List <HitsoundLayer> ImportMidi(string path, double offset = 0, bool instruments = true, bool keysounds = true, bool lengths = true, double lengthRoughness = 1, bool velocities = true, double velocityRoughness = 1)
        {
            List <HitsoundLayer> hitsoundLayers = new List <HitsoundLayer>();

            var strictMode = false;
            var mf         = new MidiFile(path, strictMode);

            Console.WriteLine(
                $@"Format {mf.FileFormat}, " +
                $@"Tracks {mf.Tracks}, " +
                $@"Delta Ticks Per Quarter Note {mf.DeltaTicksPerQuarterNote}");

            List <TempoEvent> tempos = new List <TempoEvent>();

            foreach (var track in mf.Events)
            {
                tempos.AddRange(track.OfType <TempoEvent>());
            }
            tempos = tempos.OrderBy(o => o.AbsoluteTime).ToList();

            List <double> cumulativeTime = CalculateCumulativeTime(tempos, mf.DeltaTicksPerQuarterNote);

            Dictionary <int, int> channelBanks   = new Dictionary <int, int>();
            Dictionary <int, int> channelPatches = new Dictionary <int, int>();

            // Loop through every event of every track
            for (int track = 0; track < mf.Tracks; track++)
            {
                foreach (var midiEvent in mf.Events[track])
                {
                    if (midiEvent is PatchChangeEvent pc)
                    {
                        channelPatches[pc.Channel] = pc.Patch;
                    }
                    else if (midiEvent is ControlChangeEvent co)
                    {
                        if (co.Controller == MidiController.BankSelect)
                        {
                            channelBanks[co.Channel] = (co.ControllerValue * 128) + (channelBanks.ContainsKey(co.Channel) ? (byte)channelBanks[co.Channel] : 0);
                        }
                        else if (co.Controller == MidiController.BankSelectLsb)
                        {
                            channelBanks[co.Channel] = co.ControllerValue + (channelBanks.ContainsKey(co.Channel) ? channelBanks[co.Channel] >> 8 * 128 : 0);
                        }
                    }
                    else if (MidiEvent.IsNoteOn(midiEvent))
                    {
                        var on = midiEvent as NoteOnEvent;

                        double time   = CalculateTime(on.AbsoluteTime, tempos, cumulativeTime, mf.DeltaTicksPerQuarterNote);
                        double length = on.OffEvent != null
                            ? CalculateTime(on.OffEvent.AbsoluteTime,
                                            tempos,
                                            cumulativeTime,
                                            mf.DeltaTicksPerQuarterNote) -
                                        time
                            : -1;

                        length = RoundLength(length, lengthRoughness);

                        bool keys = keysounds || on.Channel == 10;

                        int bank = instruments
                            ? on.Channel == 10 ? 128 :
                                   channelBanks.ContainsKey(on.Channel) ? channelBanks[on.Channel] : 0
                            : -1;
                        int patch = instruments && channelPatches.ContainsKey(on.Channel)
                            ? channelPatches[on.Channel]
                            : -1;
                        int instrument = -1;
                        int key        = keys ? on.NoteNumber : -1;
                        length = lengths ? length : -1;
                        int velocity = velocities ? on.Velocity : -1;
                        velocity = (int)RoundVelocity(velocity, velocityRoughness);

                        string lengthString = Math.Round(length).ToString(CultureInfo.InvariantCulture);
                        string filename     = $"{bank}\\{patch}\\{instrument}\\{key}\\{lengthString}\\{velocity}.wav";

                        string instrumentName = on.Channel == 10 ? "Percussion" :
                                                patch >= 0 && patch <= 127 ? PatchChangeEvent.GetPatchName(patch) : "Undefined";
                        string keyName = on.NoteName;

                        string name = instrumentName;
                        if (keysounds)
                        {
                            name += "," + keyName;
                        }
                        if (lengths)
                        {
                            name += "," + lengthString;
                        }
                        if (velocities)
                        {
                            name += "," + velocity;
                        }


                        var sampleArgs = new SampleGeneratingArgs(filename, bank, patch, instrument, key, length, velocity);
                        var importArgs = new LayerImportArgs(ImportType.MIDI)
                        {
                            Path              = path,
                            Bank              = bank,
                            Patch             = patch,
                            Key               = key,
                            Length            = length,
                            LengthRoughness   = lengthRoughness,
                            Velocity          = velocity,
                            VelocityRoughness = velocityRoughness
                        };

                        // Find the hitsoundlayer with this path
                        HitsoundLayer layer = hitsoundLayers.Find(o => o.ImportArgs == importArgs);

                        if (layer != null)
                        {
                            // Find hitsound layer with this path and add this time
                            layer.Times.Add(time + offset);
                        }
                        else
                        {
                            // Add new hitsound layer with this path
                            HitsoundLayer newLayer = new HitsoundLayer(name, SampleSet.Normal, Hitsound.Normal, sampleArgs, importArgs);
                            newLayer.Times.Add(time + offset);

                            hitsoundLayers.Add(newLayer);
                        }
                    }
                }
            }
            // Stretch the velocities to reach 127
            int maxVelocity = hitsoundLayers.Max(o => o.SampleArgs.Velocity);

            foreach (var hsl in hitsoundLayers)
            {
                hsl.SampleArgs.Velocity = (int)Math.Round(hsl.SampleArgs.Velocity / (float)maxVelocity * 127);
            }

            // Sort the times
            hitsoundLayers.ForEach(o => o.Times = o.Times.OrderBy(t => t).ToList());

            // Sort layers by name
            hitsoundLayers = hitsoundLayers.OrderBy(o => o.Name).ToList();

            return(hitsoundLayers);
        }
Example #23
0
        public static List <List <MidiEvent> > MidiFileToMidiEvents(string filename)
        {
            MidiFile midiFile = null;

            try
            {
                midiFile = new MidiFile(filename);
            }
            catch (Exception ex)
            {
                Debug.Log("Error Loading Midi:\n" + ex.Message);
                return(null);
            }
            List <List <MidiEvent> > list = new List <List <MidiEvent> >();
            byte  noteIndex = 0;
            float num       = 60f / (float)((int)midiFile.BeatsPerMinute * midiFile.MidiHeader.DeltaTiming);

            MidiTrack[] tracks = midiFile.Tracks;
            foreach (MidiTrack midiTrack in tracks)
            {
                float                        num2       = 0f;
                List <MidiEvent>             list2      = new List <MidiEvent>();
                Dictionary <int, float>      dictionary = new Dictionary <int, float>();
                CSharpSynth.Midi.MidiEvent[] midiEvents = midiTrack.MidiEvents;
                foreach (CSharpSynth.Midi.MidiEvent midiEvent in midiEvents)
                {
                    Debug.Log("ch: " + midiEvent.channel + " p1: " + midiEvent.parameter1 + " p2: " + midiEvent.parameter2 + " dt: " + midiEvent.deltaTime);
                    if (midiEvent.midiChannelEvent == MidiHelper.MidiChannelEvent.Note_On || midiEvent.midiChannelEvent == MidiHelper.MidiChannelEvent.Note_Off)
                    {
                        num2     += (float)(double)midiEvent.deltaTime * num;
                        noteIndex = midiEvent.parameter1;
                        try
                        {
                            if (dictionary.ContainsKey(noteIndex) && midiEvent.midiChannelEvent == MidiHelper.MidiChannelEvent.Note_Off)
                            {
                                MidiEvent midiEvent2 = list2.LastOrDefault((MidiEvent n) => n.noteIndex == noteIndex);
                                if (midiEvent2 != null)
                                {
                                    midiEvent2.duration = num2 - dictionary[noteIndex];
                                    dictionary.Remove(noteIndex);
                                }
                            }
                            else if (midiEvent.midiChannelEvent == MidiHelper.MidiChannelEvent.Note_On)
                            {
                                list2.Add(new MidiEvent
                                {
                                    startTime = num2,
                                    noteIndex = noteIndex
                                });
                                dictionary.Add(noteIndex, num2);
                            }
                        }
                        catch (Exception message)
                        {
                            Debug.Log(message);
                            Debug.Log(num2);
                            Debug.Log(noteIndex);
                            Debug.Log(midiEvent);
                        }
                    }
                }
                list.Add(list2);
                Debug.Log("convertedNotes.Count: " + list2.Count);
                Debug.Log("convertedNotes: " + list2);
                foreach (MidiEvent item in list2)
                {
                    Debug.Log(string.Format("noteIndex = {0},            startTime = {1},            duration = {2}", item.noteIndex, item.startTime, item.duration));
                }
            }
            return(list);
        }
Example #24
0
        void _UpdateMidiFile()
        {
            var exists = false;

            try
            {
                if (File.Exists(MidiFileBox.Text))
                {
                    exists = true;
                }
            }
            catch { }
            TrackList.Items.Clear();
            if (!exists)
            {
                TracksLabel.Text      = "";
                MidiFileBox.ForeColor = Color.Red;
                _file                           = null;
                TrackList.Enabled               = false;
                PreviewButton.Enabled           = false;
                UnitsCombo.Enabled              = false;
                StartCombo.Enabled              = false;
                OffsetUpDown.Enabled            = false;
                LengthUpDown.Enabled            = false;
                StretchUpDown.Enabled           = false;
                MergeTracksCheckBox.Enabled     = false;
                CopyTimingPatchCheckBox.Enabled = false;
                AdjustTempoCheckBox.Enabled     = false;
                ResampleUpDown.Enabled          = false;
                NormalizeCheckBox.Enabled       = false;
                LevelsUpDown.Enabled            = false;
                TransposeUpDown.Enabled         = false;
                WrapCheckBox.Enabled            = false;
                DrumsCheckBox.Enabled           = false;
                SaveAsButton.Enabled            = false;
                TempoUpDown.Enabled             = false;
                Visualizer.Sequence             = null;
                Visualizer.Size                 = VisualizerPanel.Size;
            }
            else
            {
                MidiFileBox.ForeColor = SystemColors.WindowText;
                using (Stream stm = File.OpenRead(MidiFileBox.Text))
                    _file = MidiFile.ReadFrom(stm);
                var i = 0;
                foreach (var trk in _file.Tracks)
                {
                    var s = trk.Name;
                    if (string.IsNullOrEmpty(s))
                    {
                        s = "Track #" + i.ToString();
                    }
                    TrackList.Items.Add(s, true);
                    ++i;
                }
                var sig = _file.TimeSignature;
                var key = _file.KeySignature;
                TracksLabel.Text                = string.Format(_tracksLabelFormat, sig.Numerator, sig.Denominator, key);
                TrackList.Enabled               = true;
                PreviewButton.Enabled           = true;
                UnitsCombo.Enabled              = true;
                StartCombo.Enabled              = true;
                OffsetUpDown.Enabled            = true;
                LengthUpDown.Enabled            = true;
                StretchUpDown.Enabled           = true;
                MergeTracksCheckBox.Enabled     = true;
                CopyTimingPatchCheckBox.Enabled = true;
                AdjustTempoCheckBox.Enabled     = true;
                ResampleUpDown.Enabled          = true;
                NormalizeCheckBox.Enabled       = true;
                LevelsUpDown.Enabled            = true;
                TransposeUpDown.Enabled         = true;
                WrapCheckBox.Enabled            = true;
                DrumsCheckBox.Enabled           = true;
                SaveAsButton.Enabled            = true;
                TempoUpDown.Enabled             = true;

                StretchUpDown.Value             = 1;
                UnitsCombo.SelectedIndex        = 0;
                StartCombo.SelectedIndex        = 0;
                ResampleUpDown.Value            = _file.TimeBase;
                UnitsCombo.SelectedIndex        = 0;
                LengthUpDown.Maximum            = _file.Length / (decimal)_file.TimeBase;
                OffsetUpDown.Maximum            = LengthUpDown.Maximum - 1;
                LengthUpDown.Value              = LengthUpDown.Maximum;
                OffsetUpDown.Value              = 0;
                AdjustTempoCheckBox.Checked     = false;
                MergeTracksCheckBox.Checked     = false;
                NormalizeCheckBox.Checked       = false;
                CopyTimingPatchCheckBox.Checked = true;
                LevelsUpDown.Value              = 1;
                TransposeUpDown.Value           = 0;
                WrapCheckBox.Checked            = false;
                DrumsCheckBox.Checked           = false;
                TempoUpDown.Value   = (decimal)_file.Tempo;
                _dirty              = true;
                _processedFile      = null;
                Visualizer.Sequence = MidiSequence.Merge(_file.Tracks);
                Visualizer.Width    = Math.Max(VisualizerPanel.Width, Visualizer.Sequence.Length / 4);
            }
        }
Example #25
0
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                Error();
            }
            try
            {
                string[] flags = new string[args.Length - 2];
                Array.Copy(args, 2, flags, 0, flags.Length);
                ArgList  al        = new ArgList(flags);
                MidiFile workpiece = new MidiFile();
                workpiece.loadMidiFromFile(args[0]);

                if (al.checkFlag("quantize-bpm"))
                {
                    Console.WriteLine("Quantizing Tempo Events");
                    Filters.QuantizeTempo(workpiece);
                }

                if (al.checkFlag("trim"))
                {
                    Console.WriteLine("Removing redundant Events...");
                    Filters.Trim(workpiece);
                }

                if (al.checkFlag("clear-ctrl"))
                {
                    Console.WriteLine("Clearing Controller Events");
                    Filters.ClearCtrl(workpiece, al.getOption("clear-ctrl"));
                }

                if (al.checkFlag("full-maximize"))
                {
                    Console.WriteLine("Fully maximizing Volume and Velocity");
                    Filters.FullMaximize(workpiece);
                }
                else if (al.checkFlag("maximize"))
                {
                    Console.WriteLine("Maximizing Volume and Velocity");
                    Filters.Maximize(workpiece);
                }

                if (al.checkFlag("map"))
                {
                    Console.WriteLine("Mapping Instruments...");
                    Filters.InstrMap(workpiece, al.getOption("map"));
                }

                if (File.Exists(args[1]))
                {
                    File.Delete(args[1]);
                }
                workpiece.saveMidiToFile(args[1]);
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.Message);
                Error();
            }
        }
Example #26
0
        public void SplitByNotes_EmptyFile()
        {
            var midiFile = new MidiFile();

            Assert.IsFalse(midiFile.SplitByNotes().Any(), "Empty file splitting produced non-empty result.");
        }
Example #27
0
        /// <summary>
        /// Convert neb steps to midi file.
        /// </summary>
        /// <param name="steps"></param>
        /// <param name="midiFileName"></param>
        /// <param name="channels">Map of channel number to channel name.</param>
        /// <param name="bpm">Beats per minute.</param>
        /// <param name="info">Extra info to add to midi file.</param>
        public static void ExportToMidi(StepCollection steps, string midiFileName, Dictionary <int, string> channels, double bpm, string info)
        {
            int exportPpq = 96;

            // Events per track.
            Dictionary <int, IList <MidiEvent> > trackEvents = new();

            ///// Meta file stuff.
            MidiEventCollection events = new(1, exportPpq);

            ///// Add Header chunk stuff.
            IList <MidiEvent> lhdr = events.AddTrack();

            //lhdr.Add(new TimeSignatureEvent(0, 4, 2, (int)ticksPerClick, 8));
            //TimeSignatureEvent me = new TimeSignatureEvent(long absoluteTime, int numerator, int denominator, int ticksInMetronomeClick, int no32ndNotesInQuarterNote);
            //  - numerator of the time signature (as notated).
            //  - denominator of the time signature as a negative power of 2 (ie 2 represents a quarter-note, 3 represents an eighth-note, etc).
            //  - number of MIDI clocks between metronome clicks.
            //  - number of notated 32nd-notes in a MIDI quarter-note (24 MIDI Clocks). The usual value for this parameter is 8.

            //lhdr.Add(new KeySignatureEvent(0, 0, 0));
            //  - number of flats (-ve) or sharps (+ve) that identifies the key signature (-7 = 7 flats, -1 = 1 //flat, 0 = key of C, 1 = 1 sharp, etc).
            //  - major (0) or minor (1) key.
            //  - abs time.

            // Tempo.
            lhdr.Add(new TempoEvent(0, 0)
            {
                Tempo = bpm
            });

            // General info.
            lhdr.Add(new TextEvent("Midi file created by Nebulator.", MetaEventType.TextEvent, 0));
            lhdr.Add(new TextEvent(info, MetaEventType.TextEvent, 0));

            lhdr.Add(new MetaEvent(MetaEventType.EndTrack, 0, 0));

            ///// Make one midi event collection per track.
            foreach (int channel in channels.Keys)
            {
                IList <MidiEvent> le = events.AddTrack();
                trackEvents.Add(channel, le);
                le.Add(new TextEvent(channels[channel], MetaEventType.SequenceTrackName, 0));
                // >> 0 SequenceTrackName G.MIDI Acou Bass
            }

            // Make a transformer.
            MidiTime mt = new()
            {
                InternalPpq = Time.SubdivsPerBeat,
                MidiPpq     = exportPpq,
                Tempo       = bpm
            };

            // Run through the main steps and create a midi event per.
            foreach (Time time in steps.Times)
            {
                long mtime = mt.InternalToMidi(time.TotalSubdivs);

                foreach (Step step in steps.GetSteps(time))
                {
                    MidiEvent evt;

                    switch (step)
                    {
                    case StepNoteOn stt:
                        evt = new NoteEvent(mtime,
                                            stt.ChannelNumber,
                                            MidiCommandCode.NoteOn,
                                            (int)MathUtils.Constrain(stt.NoteNumber, 0, Definitions.MAX_MIDI),
                                            (int)(MathUtils.Constrain(stt.VelocityToPlay, 0, 1.0) * Definitions.MAX_MIDI));
                        trackEvents[step.ChannelNumber].Add(evt);

                        if (stt.Duration.TotalSubdivs > 0)     // specific duration
                        {
                            evt = new NoteEvent(mtime + mt.InternalToMidi(stt.Duration.TotalSubdivs),
                                                stt.ChannelNumber,
                                                MidiCommandCode.NoteOff,
                                                (int)MathUtils.Constrain(stt.NoteNumber, 0, Definitions.MAX_MIDI),
                                                0);
                            trackEvents[step.ChannelNumber].Add(evt);
                        }
                        break;

                    case StepNoteOff stt:
                        evt = new NoteEvent(mtime,
                                            stt.ChannelNumber,
                                            MidiCommandCode.NoteOff,
                                            (int)MathUtils.Constrain(stt.NoteNumber, 0, Definitions.MAX_MIDI),
                                            0);
                        trackEvents[step.ChannelNumber].Add(evt);
                        break;

                    case StepControllerChange stt:
                        if (stt.ControllerId == ControllerDef.NoteControl)
                        {
                            // Shouldn't happen, ignore.
                        }
                        else if (stt.ControllerId == ControllerDef.PitchControl)
                        {
                            evt = new PitchWheelChangeEvent(mtime,
                                                            stt.ChannelNumber,
                                                            (int)MathUtils.Constrain(stt.Value, 0, Definitions.MAX_MIDI));
                            trackEvents[step.ChannelNumber].Add(evt);
                        }
                        else     // CC
                        {
                            evt = new ControlChangeEvent(mtime,
                                                         stt.ChannelNumber,
                                                         (MidiController)stt.ControllerId,
                                                         (int)MathUtils.Constrain(stt.Value, 0, Definitions.MAX_MIDI));
                            trackEvents[step.ChannelNumber].Add(evt);
                        }
                        break;

                    case StepPatch stt:
                        evt = new PatchChangeEvent(mtime,
                                                   stt.ChannelNumber,
                                                   (int)stt.Patch);
                        trackEvents[step.ChannelNumber].Add(evt);
                        break;

                    default:
                        break;
                    }
                }
            }

            // Finish up channels with end marker.
            foreach (IList <MidiEvent> let in trackEvents.Values)
            {
                long ltime = let.Last().AbsoluteTime;
                let.Add(new MetaEvent(MetaEventType.EndTrack, 0, ltime));
            }

            MidiFile.Export(midiFileName, events);
        }
    }
Example #28
0
        /** Create a new SheetMusic control, using the given raw midi byte[] data.
         *  The options can be null.
         */
        public SheetMusic(byte[] data, string title, MidiOptions options)
        {
            MidiFile file = new MidiFile(data, title);

            init(file, options);
        }
 private static void ResizeByRatio(MidiFile midiFile, double ratio)
 {
     midiFile.ProcessTimedEvents(e => e.Time = MathUtilities.RoundToLong(e.Time * ratio));
 }
Example #30
0
 /** Create a new SheetMusic control, using the given parsed MidiFile.
  *  The options can be null.
  */
 public SheetMusic(MidiFile file, MidiOptions options)
 {
     init(file, options);
 }
        /// <summary>
        /// Checks whether the specified <see cref="MidiFile"/> is empty or not. <see cref="MidiFile"/>
        /// is empty when it doesn't contain MIDI events.
        /// </summary>
        /// <param name="midiFile"><see cref="MidiFile"/> to check emptiness of.</param>
        /// <returns>A value indicating whether <paramref name="midiFile"/> is empty or not.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="midiFile"/> is <c>null</c>.</exception>
        public static bool IsEmpty(this MidiFile midiFile)
        {
            ThrowIfArgument.IsNull(nameof(midiFile), midiFile);

            return(!midiFile.GetEvents().Any());
        }
Example #32
0
        static void Main(string[] args)
        {
            var output = new SoundioOutput();

            for (var i = 0; i < output.Devices.Count; i++)
            {
                Console.WriteLine($"[{i}] {output.Devices[i].Name}");
            }

            Console.Write("Device Index > ");
            var outputIndex = int.Parse(Console.ReadLine());

            Console.Write("Latency(ms) > ");
            var intervalMs = Double.Parse(Console.ReadLine());

            output.DesiredLatency = TimeSpan.FromMilliseconds(intervalMs);
            output.Initialize(output.Devices[outputIndex], new AudioFormat(48000, 1, 16));
            Output = output;
            Console.WriteLine("Output device initialized");
            Console.WriteLine($"Actual Latency : {output.ActualLatency.TotalMilliseconds}ms");

            Source = new PeriodicFunctionsSource(output.Format.SampleRate)
            {
                Function = FunctionType.Sin,
                Volume   = 1,
            };

            var midi = new MidiPlayer(output.Format.SampleRate, new Synthesizer(output.Format.SampleRate));

            midi.OscillatorConfigs.Add(new Oscillator()
            {
                Function = KSynthesizer.Sources.FunctionType.Sin, Volume = 0.3f
            });
            midi.Open(MidiFile.Read("sample.mid"));

            Source.SetFrequency(Frequency);
            RecordFilter = new RecordFilter(midi);

            Output.Buffer += OutputOnBuffer;
            Output.Play();
            Console.WriteLine("Player started");

            bool exit = false;

            while (!exit)
            {
                var key = Console.ReadKey();
                Console.WriteLine();
                switch (key.Key)
                {
                case ConsoleKey.P:
                    Playing = !Playing;
                    Console.WriteLine(Playing ? "Resumed" : "Paused");
                    break;

                case ConsoleKey.R:
                    if (RecordFilter.IsRecording)
                    {
                        RecordFilter.StopRecording();
                    }
                    else
                    {
                        var now  = DateTime.Now;
                        var name = $"{now.Ticks}.wav";
                        RecordFilter.StartRecording(new FileStream(name, FileMode.Create, FileAccess.Write), true, false);
                        Console.WriteLine("Output : " + name);
                    }
                    Console.WriteLine(RecordFilter.IsRecording ? "Recording Started" : "Recording Stopped");
                    break;

                case ConsoleKey.UpArrow:
                    Frequency += 100;
                    Source.SetFrequency(Frequency);
                    Console.WriteLine($"Frequency : {Frequency}Hz");
                    break;

                case ConsoleKey.DownArrow:
                    Frequency -= 100;
                    if (Frequency <= 300)
                    {
                        Frequency = 300;
                    }
                    Source.SetFrequency(Frequency);
                    Console.WriteLine($"Frequency : {Frequency}Hz");
                    break;

                case ConsoleKey.Escape:
                    exit = true;
                    break;

                default:
                    Console.WriteLine("Unknown Key");
                    break;
                }
            }

            output.Dispose();
            Console.WriteLine("Exited");
        }
        public static List <MidiEvent> GetEventsOfType(string base64encodedMidiFile, MidiEventType type)
        {
            var midiFile = MidiFile.Read(base64encodedMidiFile);

            return(GetEventsOfType(midiFile, type));
        }
        /// <summary>
        /// Removes all the <see cref="TimedEvent"/> that match the conditions defined by the specified predicate.
        /// </summary>
        /// <param name="file"><see cref="MidiFile"/> to search for events to remove.</param>
        /// <param name="match">The predicate that defines the conditions of the <see cref="TimedEvent"/> to remove.</param>
        /// <exception cref="ArgumentNullException"><paramref name="file"/> is <c>null</c>.</exception>
        public static void RemoveTimedEvents(this MidiFile file, Predicate <TimedEvent> match = null)
        {
            ThrowIfArgument.IsNull(nameof(file), file);

            file.GetTrackChunks().RemoveTimedEvents(match);
        }
 public MidiConverter(MidiFile file)
 {
     ReadMidiFile(file);
 }
Example #36
0
        /** Create a new SheetMusic control, using the given midi filename.
         *  The options can be null.
         */
        //public SheetMusic(string filename, MidiOptions options) {
        // MidiFile file = new MidiFile(filename);
        // init(file, options);
        //}
        /** Create a new SheetMusic control, using the given raw midi byte[] data.
         *  The options can be null.
         */
        //public SheetMusic(byte[] data, string title, MidiOptions options) {
        //    MidiFile file = new MidiFile(data, title);
        //     init(file, options);
        // }
        /** Create a new SheetMusic control.
         * MidiFile is the parsed midi file to display.
         * SheetMusic Options are the menu options that were selected.
         *
         * - Apply all the Menu Options to the MidiFile tracks.
         * - Calculate the key signature
         * - For each track, create a list of MusicSymbols (notes, rests, bars, etc)
         * - Vertically align the music symbols in all the tracks
         * - Partition the music notes into horizontal staffs
         */
        public void Load(MidiFile file, MidiOptions options)
        {
            if (options == null) {
            options = new MidiOptions(file);
            }
            zoom = 1.0f;
            filename = file.FileName;

            SetColors(options.colors, options.shadeColor, options.shade2Color);
            pen = new Pen(Color.Black, 1);

            List<MidiTrack> tracks = file.ChangeMidiNotes(options);
            SetNoteSize(options.largeNoteSize);
            scrollVert = options.scrollVert;
            showNoteLetters= options.showNoteLetters;
            TimeSignature time = file.Time;
            if (options.time != null) {
            time = options.time;
            }
            if (options.key == -1) {
            mainkey = GetKeySignature(tracks);
            }
            else {
            mainkey = new KeySignature(options.key);
            }

            numtracks = tracks.Count;

            int lastStart = file.EndTime() + options.shifttime;

            /* Create all the music symbols (notes, rests, vertical bars, and
             * clef changes).  The symbols variable contains a list of music
             * symbols for each track.  The list does not include the left-side
             * Clef and key signature symbols.  Those can only be calculated
             * when we create the staffs.
             */
            List<MusicSymbol>[] symbols = new List<MusicSymbol> [ numtracks ];
            for (int tracknum = 0; tracknum < numtracks; tracknum++) {
            MidiTrack track = tracks[tracknum];
            ClefMeasures clefs = new ClefMeasures(track.Notes, time.Measure);
            List<ChordSymbol> chords = CreateChords(track.Notes, mainkey, time, clefs);
            symbols[tracknum] = CreateSymbols(chords, clefs, time, lastStart);
            }

            List<LyricSymbol>[] lyrics = null;
            if (options.showLyrics) {
            lyrics = GetLyrics(tracks);
            }

            /* Vertically align the music symbols */
            SymbolWidths widths = new SymbolWidths(symbols, lyrics);
            // SymbolWidths widths = new SymbolWidths(symbols);
            AlignSymbols(symbols, widths);

            staffs = CreateStaffs(symbols, mainkey, options, time.Measure);
            CreateAllBeamedChords(symbols, time);
            if (lyrics != null) {
            AddLyricsToStaffs(staffs, lyrics);
            }

            /* After making chord pairs, the stem directions can change,
             * which affects the staff height.  Re-calculate the staff height.
             */
            foreach (Staff staff in staffs) {
            staff.CalculateHeight();
            }

            braces = CreateBraceSymbols(staffs);

            BackColor = Color.White;

            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true); // ��ֹ��������.
            SetStyle(ControlStyles.DoubleBuffer, true);
        }
Example #37
0
        private NumericUpDown startMeasure; /** The starting measure */

        #endregion Fields

        #region Constructors

        /** Create a new PlayMeasuresDialog. Call the ShowDialog() method
         *  to display the dialog.
         */
        public PlayMeasuresDialog(MidiFile midifile)
        {
            int lastStart = midifile.EndTime();
            int lastMeasure = 1 + lastStart / midifile.Time.Measure;

            /* Create the dialog box */
            dialog = new Form();
            dialog.Text = "Play Selected Measures in a Loop";
            dialog.MaximizeBox = false;
            dialog.MinimizeBox = false;
            dialog.ShowInTaskbar = false;
            dialog.Icon = new Icon(GetType(), "NotePair.ico");
            dialog.AutoScroll = true;

            Font font = dialog.Font;
            dialog.Font = new Font(font.FontFamily, font.Size * 1.4f);
            int labelheight = dialog.Font.Height * 2;
            int xpos = labelheight/2;
            int ypos = labelheight/2;

            enable = new CheckBox();
            enable.Parent = dialog;
            enable.Text = "Play Selected Measures in a Loop";
            enable.Checked = false;
            enable.Location = new Point(xpos, ypos);
            enable.Size = new Size(labelheight*9, labelheight);

            ypos += labelheight * 3/2;

            Label label = new Label();
            label.Parent = dialog;
            label.Text = "Start Measure";
            label.Location = new Point(xpos, ypos);
            label.Size = new Size(labelheight * 3, labelheight);

            xpos += labelheight * 4;

            startMeasure = new NumericUpDown();
            startMeasure.Parent = dialog;
            startMeasure.Minimum = 1;
            startMeasure.Maximum = lastMeasure;
            startMeasure.Value = 1;
            startMeasure.Location = new Point(xpos, ypos);
            startMeasure.Size = new Size(labelheight*2, labelheight);

            xpos = labelheight/2;
            ypos += labelheight * 3/2;

            label = new Label();
            label.Parent = dialog;
            label.Text = "End Measure";
            label.Location = new Point(xpos, ypos);
            label.Size = new Size(labelheight * 3, labelheight);

            xpos += labelheight * 4;
            endMeasure = new NumericUpDown();
            endMeasure.Parent = dialog;
            endMeasure.Minimum = 1;
            endMeasure.Maximum = lastMeasure;
            endMeasure.Value = lastMeasure;
            endMeasure.Location = new Point(xpos, ypos);
            endMeasure.Size = new Size(labelheight*2, labelheight);

            /* Create the OK and Cancel buttons */
            xpos = labelheight/2;
            ypos += labelheight * 3/2;
            Button ok = new Button();
            ok.Parent = dialog;
            ok.Text = "OK";
            ok.Location = new Point(xpos, ypos);
            ok.DialogResult = DialogResult.OK;

            dialog.Size = new Size(labelheight * 10,
                               labelheight * 8);
        }