Пример #1
0
        public bool useDefaultInstruments; /** If true, don't change instruments */

        #endregion Fields

        #region Constructors

        public MidiOptions(MidiFile midifile)
        {
            int numtracks = midifile.Tracks.Count;
            tracks = new bool[numtracks];
            mute =  new bool[numtracks];
            instruments = new int[numtracks];
            for (int i = 0; i < tracks.Length; i++) {
            tracks[i] = true;
            mute[i] = false;
            instruments[i] = midifile.Tracks[i].Instrument;
            if (midifile.Tracks[i].InstrumentName == "Percussion") {
                tracks[i] = false;
            }
            }
            useDefaultInstruments = true;
            scrollVert = true;
            largeNoteSize = false;
            if (tracks.Length == 1) {
            twoStaffs = true;
            }
            else {
            twoStaffs = false;
            }
            showNoteLetters = NoteNameNone;
            showLyrics = true;
            showMeasures = false;
            shifttime = 0;
            transpose = 0;
            key = -1;
            time = midifile.Time;
            colors = null;
            shadeColor = Color.FromArgb(210, 205, 220);
            shade2Color = Color.FromArgb(80, 100, 250);
            combineInterval = 40;
            tempo = midifile.Time.Tempo;
            pauseTime = 0;
            playMeasuresInLoop = false;
            playMeasuresInLoopStart = 0;
            playMeasuresInLoopEnd = midifile.EndTime() / midifile.Time.Measure;
        }
Пример #2
0
    public void TestChangeSoundTrack()
    {
        const byte notenum = 60;

        MidiFile midifile = CreateTestChangeSoundMidiFile();

        MidiOptions options = new MidiOptions(midifile);
        options.useDefaultInstruments = false;

        options.tracks[0] = false;
        options.tracks[1] = true;
        options.tracks[2] = false;
        options.instruments[0] = 40;
        options.instruments[1] = 41;
        options.instruments[2] = 42;
        bool ret = midifile.ChangeSound(testfile, options);
        Assert.AreEqual(ret, true);
        MidiFile newmidi = new MidiFile(testfile);
        Assert.AreEqual(newmidi.Tracks.Count, 1);
        Assert.AreEqual(newmidi.Tracks[0].Instrument, 41);
        for (int i = 0; i < 3; i++) {
            MidiNote note = newmidi.Tracks[0].Notes[i];
            Assert.AreEqual(note.Number, notenum + 10 + i);
        }

        File.Delete(testfile);
    }
Пример #3
0
    public void TestChangeSoundTempo()
    {
        MidiFile midifile = CreateTestChangeSoundMidiFile();

        MidiOptions options = new MidiOptions(midifile);
        options.tempo = 0x405060;
        bool ret = midifile.ChangeSound(testfile, options);
        Assert.AreEqual(ret, true);
        MidiFile newmidi = new MidiFile(testfile);
        Assert.AreEqual(newmidi.Tracks.Count, 3);
        Assert.AreEqual(newmidi.Time.Tempo, 0x405060);

        File.Delete(testfile);
    }
Пример #4
0
    public void TestChangeSoundPerChannelTranspose()
    {
        const byte notenum = 60;

        MidiFile midifile = CreateTestChangeSoundPerChannelMidiFile();
        MidiOptions options = new MidiOptions(midifile);
        options.transpose = 10;
        bool ret = midifile.ChangeSound(testfile, options);
        Assert.AreEqual(ret, true);
        MidiFile newmidi = new MidiFile(testfile);

        Assert.AreEqual(newmidi.Tracks.Count, 3);
        for (int tracknum = 0; tracknum < 3; tracknum++) {
            MidiTrack track = newmidi.Tracks[tracknum];
            for (int i = 0; i < 3; i++) {
               MidiNote note = track.Notes[i];
               Assert.AreEqual(note.Number, notenum + tracknum*10 + i + 10);
            }
        }

        File.Delete(testfile);
    }
Пример #5
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();
        }
Пример #6
0
    public void TestTruncatedFile()
    {
        const byte notenum = 60;
        const byte quarternote = 240;
        const byte numtracks = 1;
        const byte velocity = 80;

        byte[] data = new byte[] {
            77, 84, 104, 100,        /* MThd ascii header */
            0, 0, 0, 6,              /* length of header in bytes */
            0, 1,                    /* one or more simultaneous tracks */
            0, numtracks,
            0, quarternote,
            77, 84, 114, 107,        /* MTrk ascii header */
            0, 0, 0, 30,             /* Length of track, in bytes. Should be 24. */

            /* time_interval, NoteEvent, note number, velocity */
            0,  EventNoteOn,  notenum,   velocity,
            60, EventNoteOff, notenum,   0,
            0,  EventNoteOn,  notenum+1, velocity,
            30, EventNoteOff, notenum+1, 0,
            0,  EventNoteOn,  notenum+2, velocity,
            90, EventNoteOff, notenum+2, 0
        };

        WriteTestFile(data);
        bool got_exception = false;
        try {
            MidiFile midifile = new MidiFile(testfile);
        }
        catch (MidiFileException e) {
            got_exception = true;
        }
        File.Delete(testfile);
        Assert.AreEqual(got_exception, false);
    }
Пример #7
0
    /* Create the MidiFile for the TestChangeSoundPerChannel tests.
     * It has only one track, but multiple channels.
     */
    MidiFile CreateTestChangeSoundPerChannelMidiFile()
    {
        const byte notenum = 60;
        const byte quarternote = 240;
        const byte numtracks = 1;
        const byte velocity = 80;

        byte[] data = new byte[] {
            77, 84, 104, 100,        /* MThd ascii header */
            0, 0, 0, 6,              /* length of header in bytes */
            0, 1,                    /* one or more simultaneous tracks */
            0, numtracks,
            0, quarternote,

            77, 84, 114, 107,        /* MTrk ascii header */
            0, 0, 0, 81,             /* Length of track, in bytes */

            /* Instruments are
             * channel 0 = 0 (Acoustic Piano)
             * channel 1 = 4 (Electric Piano 1)
             * channel 2 = 5 (Electric Piano 2)
             */
            0,  EventProgramChange,   0,
            0,  EventProgramChange+1, 4,
            0,  EventProgramChange+2, 5,

            /* time_interval, NoteEvent, note number, velocity */
            0,  EventNoteOn,    notenum,    velocity,
            0,  EventNoteOn+1,  notenum+10, velocity,
            0,  EventNoteOn+2,  notenum+20, velocity,
            30, EventNoteOff,   notenum,    0,
            0,  EventNoteOff+1, notenum+10,   0,
            0,  EventNoteOff+2, notenum+20,   0,

            30, EventNoteOn,    notenum+1,  velocity,
            0,  EventNoteOn+1,  notenum+11, velocity,
            0,  EventNoteOn+2,  notenum+21, velocity,
            30, EventNoteOff,   notenum+1,    0,
            0,  EventNoteOff+1, notenum+11,   0,
            0,  EventNoteOff+2, notenum+21,   0,

            30, EventNoteOn,    notenum+2,  velocity,
            0,  EventNoteOn+1,  notenum+12, velocity,
            0,  EventNoteOn+2,  notenum+22, velocity,
            30, EventNoteOff,   notenum+2,    0,
            0,  EventNoteOff+1, notenum+12,   0,
            0,  EventNoteOff+2, notenum+22,   0,

        };

        /* Verify that the original midi has 3 tracks, one per channel */
        WriteTestFile(data);
        MidiFile midifile = new MidiFile(testfile);
        Assert.AreEqual(midifile.Tracks.Count, 3);
        Assert.AreEqual(midifile.Tracks[0].Instrument, 0);
        Assert.AreEqual(midifile.Tracks[1].Instrument, 4);
        Assert.AreEqual(midifile.Tracks[2].Instrument, 5);
        for (int tracknum = 0; tracknum < 3; tracknum++) {
            MidiTrack track = midifile.Tracks[tracknum];
            Assert.AreEqual(track.Notes.Count, 3);
            for (int n = 0; n < track.Notes.Count; n++) {
                MidiNote m = track.Notes[n];
                Assert.AreEqual(m.Number, notenum + 10*tracknum + n);
            }
        }
        return midifile;
    }
Пример #8
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);
        }
Пример #9
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);
 }
Пример #10
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);
 }
Пример #11
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);
 }
Пример #12
0
        private Image volumeImage; /** The volume image */

        #endregion Fields

        #region Constructors

        /** 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 = "";
        }
Пример #13
0
        /** The MidiFile and/or SheetMusic has changed. Stop any playback sound,
         *  and store the current midifile and sheet music.
         */
        public void SetMidiFile(MidiFile file, MidiOptions opt, SheetMusic s)
        {
            /* If we're paused, and using the same midi file, redraw the
             * highlighted notes.
             */
            if ((file == midifile && midifile != null && playstate == paused)) {
            options = opt;
            sheet = s;
            sheet.ShadeNotes((int)currentPulseTime, (int)-10, false);

            /* We have to wait some time (200 msec) for the sheet music
             * to scroll and redraw, before we can re-shade.
             */
            Timer redrawTimer = new Timer();
            redrawTimer.Interval = 200;
            redrawTimer.Tick += new EventHandler(ReShade);
            redrawTimer.Enabled = true;
            redrawTimer.Start();
            }
            else {
            this.Stop(null, null);
            midifile = file;
            options = opt;
            sheet = s;
            }
            this.DeleteSoundFile();
        }
Пример #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);
        }
Пример #15
0
    public void TestChangeSoundTranspose()
    {
        const byte notenum = 60;

        MidiFile midifile = CreateTestChangeSoundMidiFile();

        MidiOptions options = new MidiOptions(midifile);
        options.transpose = 10;
        bool ret = midifile.ChangeSound(testfile, options);
        Assert.AreEqual(ret, true);
        MidiFile newmidi = new MidiFile(testfile);
        Assert.AreEqual(newmidi.Tracks.Count, 3);

        for (int tracknum = 0; tracknum < 3; tracknum++) {
            MidiTrack track = newmidi.Tracks[tracknum];
            List<MidiNote> notes = track.Notes;
            Assert.AreEqual(notes.Count, 3);

            Assert.AreEqual(notes[0].StartTime, 0);
            Assert.AreEqual(notes[0].Number, notenum + 10*tracknum + 10);
            Assert.AreEqual(notes[0].Duration, 60);

            Assert.AreEqual(notes[1].StartTime, 60);
            Assert.AreEqual(notes[1].Number, notenum + 10*tracknum + 11);
            Assert.AreEqual(notes[1].Duration, 30);

            Assert.AreEqual(notes[2].StartTime, 90);
            Assert.AreEqual(notes[2].Number, notenum + 10*tracknum + 12);
            Assert.AreEqual(notes[2].Duration, 90);
        }

        File.Delete(testfile);
    }
Пример #16
0
    /* Create the midi file used by the TestChangeSound() methods */
    public MidiFile CreateTestChangeSoundMidiFile()
    {
        const byte notenum = 60;
        const byte quarternote = 240;
        const byte numtracks = 3;
        const byte velocity = 80;

        byte[] data = new byte[] {
            77, 84, 104, 100,        /* MThd ascii header */
            0, 0, 0, 6,              /* length of header in bytes */
            0, 1,                    /* one or more simultaneous tracks */
            0, numtracks,
            0, quarternote,

            77, 84, 114, 107,        /* MTrk ascii header */
            0, 0, 0, 34,             /* Length of track, in bytes */

            /* tempo event, len=3, tempo = 0x0032ff */
            0,  MetaEvent,    MetaEventTempo, 3, 0x0, 0x32, 0xff,
            /* instrument = 4 (Electric Piano 1) */
            0,  EventProgramChange, 4,

            /* time_interval, NoteEvent, note number, velocity */
            0,  EventNoteOn,  notenum,   velocity,
            60, EventNoteOff, notenum,   0,
            0,  EventNoteOn,  notenum+1, velocity,
            30, EventNoteOff, notenum+1, 0,
            0,  EventNoteOn,  notenum+2, velocity,
            90, EventNoteOff, notenum+2, 0,

            77, 84, 114, 107,        /* MTrk ascii header */
            0, 0, 0, 34,             /* Length of track, in bytes */

            /* tempo event, len=3, tempo = 0xa0b0cc */
            0,  MetaEvent,    MetaEventTempo, 3, 0xa0, 0xb0, 0xcc,
            /* instrument = 5 (Electric Piano 2) */
            0,  EventProgramChange, 5,

            /* time_interval, NoteEvent, note number, velocity */
            0,  EventNoteOn,  notenum+10, velocity,
            60, EventNoteOff, notenum+10, 0,
            0,  EventNoteOn,  notenum+11, velocity,
            30, EventNoteOff, notenum+11, 0,
            0,  EventNoteOn,  notenum+12, velocity,
            90, EventNoteOff, notenum+12, 0,

            77, 84, 114, 107,        /* MTrk ascii header */
            0, 0, 0, 34,             /* Length of track, in bytes */

            /* tempo event, len=3, tempo = 0x121244 */
            0,  MetaEvent,    MetaEventTempo, 3, 0x12, 0x12, 0x44,
            /* instrument = 0 (Acoustic Grand Piano) */
            0,  EventProgramChange, 0,

            /* time_interval, NoteEvent, note number, velocity */
            0,  EventNoteOn,  notenum+20, velocity,
            60, EventNoteOff, notenum+20, 0,
            0,  EventNoteOn,  notenum+21, velocity,
            30, EventNoteOff, notenum+21, 0,
            0,  EventNoteOn,  notenum+22, velocity,
            90, EventNoteOff, notenum+22, 0,

        };

        WriteTestFile(data);

        /* Verify the original Midi File */
        MidiFile midifile = new MidiFile(testfile);
        Assert.AreEqual(midifile.Tracks.Count, 3);
        Assert.AreEqual(midifile.Tracks[0].Instrument, 4);
        Assert.AreEqual(midifile.Tracks[1].Instrument, 5);
        Assert.AreEqual(midifile.Tracks[2].Instrument, 0);
        for (int tracknum = 0; tracknum < 3; tracknum++) {
            MidiTrack track = midifile.Tracks[tracknum];
            List<MidiNote> notes = track.Notes;
            Assert.AreEqual(notes.Count, 3);

            Assert.AreEqual(notes[0].StartTime, 0);
            Assert.AreEqual(notes[0].Number, notenum + 10*tracknum);
            Assert.AreEqual(notes[0].Duration, 60);

            Assert.AreEqual(notes[1].StartTime, 60);
            Assert.AreEqual(notes[1].Number, notenum + 10*tracknum + 1);
            Assert.AreEqual(notes[1].Duration, 30);

            Assert.AreEqual(notes[2].StartTime, 90);
            Assert.AreEqual(notes[2].Number, notenum + 10*tracknum + 2);
            Assert.AreEqual(notes[2].Duration, 90);
        }
        return midifile;
    }
Пример #17
0
    public void TestMultipleTracks()
    {
        const byte notenum = 60;
        const byte quarternote = 240;
        const byte numtracks = 3;
        const byte velocity = 80;

        byte[] data = new byte[] {
            77, 84, 104, 100,        /* MThd ascii header */
            0, 0, 0, 6,              /* length of header in bytes */
            0, 1,                    /* one or more simultaneous tracks */
            0, numtracks,
            0, quarternote,

            77, 84, 114, 107,        /* MTrk ascii header */
            0, 0, 0, 24,             /* Length of track, in bytes */

            /* time_interval, NoteEvent, note number, velocity */
            0,  EventNoteOn,  notenum,   velocity,
            60, EventNoteOff, notenum,   0,
            0,  EventNoteOn,  notenum+1, velocity,
            30, EventNoteOff, notenum+1, 0,
            0,  EventNoteOn,  notenum+2, velocity,
            90, EventNoteOff, notenum+2, 0,

            77, 84, 114, 107,        /* MTrk ascii header */
            0, 0, 0, 24,             /* Length of track, in bytes */

            /* time_interval, NoteEvent, note number, velocity */
            0,  EventNoteOn,  notenum+1, velocity,
            60, EventNoteOff, notenum+1, 0,
            0,  EventNoteOn,  notenum+2, velocity,
            30, EventNoteOff, notenum+2, 0,
            0,  EventNoteOn,  notenum+3, velocity,
            90, EventNoteOff, notenum+3, 0,

            77, 84, 114, 107,        /* MTrk ascii header */
            0, 0, 0, 24,             /* Length of track, in bytes */

            /* time_interval, NoteEvent, note number, velocity */
            0,  EventNoteOn,  notenum+2, velocity,
            60, EventNoteOff, notenum+2, 0,
            0,  EventNoteOn,  notenum+3, velocity,
            30, EventNoteOff, notenum+3, 0,
            0,  EventNoteOn,  notenum+4, velocity,
            90, EventNoteOff, notenum+4, 0,

        };

        WriteTestFile(data);
        MidiFile midifile = new MidiFile(testfile);
        File.Delete(testfile);

        Assert.AreEqual(midifile.Tracks.Count, numtracks);
        Assert.AreEqual(midifile.Time.Numerator, 4);
        Assert.AreEqual(midifile.Time.Denominator, 4);
        Assert.AreEqual(midifile.Time.Quarter, quarternote);
        Assert.AreEqual(midifile.Time.Measure, quarternote * 4);

        for (int tracknum = 0; tracknum < numtracks; tracknum++) {
            MidiTrack track = midifile.Tracks[tracknum];
            List<MidiNote> notes = track.Notes;
            Assert.AreEqual(notes.Count, 3);

            Assert.AreEqual(notes[0].StartTime, 0);
            Assert.AreEqual(notes[0].Number, notenum + tracknum);
            Assert.AreEqual(notes[0].Duration, 60);

            Assert.AreEqual(notes[1].StartTime, 60);
            Assert.AreEqual(notes[1].Number, notenum + tracknum + 1);
            Assert.AreEqual(notes[1].Duration, 30);

            Assert.AreEqual(notes[2].StartTime, 90);
            Assert.AreEqual(notes[2].Number, notenum + tracknum + 2);
            Assert.AreEqual(notes[2].Duration, 90);
        }
    }
Пример #18
0
    public void TestChangeSoundPerChannelInstruments()
    {
        MidiFile midifile = CreateTestChangeSoundPerChannelMidiFile();
        MidiOptions options = new MidiOptions(midifile);
        options.useDefaultInstruments = false;
        for (int tracknum = 0; tracknum < 3; tracknum++) {
            options.instruments[tracknum] = 40 + tracknum;
        }
        bool ret = midifile.ChangeSound(testfile, options);
        Assert.AreEqual(ret, true);
        MidiFile newmidi = new MidiFile(testfile);

        Assert.AreEqual(newmidi.Tracks.Count, 3);
        Assert.AreEqual(newmidi.Tracks[0].Instrument, 40);
        Assert.AreEqual(newmidi.Tracks[1].Instrument, 41);
        Assert.AreEqual(newmidi.Tracks[2].Instrument, 42);

        File.Delete(testfile);
    }
Пример #19
0
    public void TestVariousEvents()
    {
        const byte notenum = 60;
        const byte quarternote = 240;
        const byte numtracks = 1;
        const byte velocity = 80;

        byte[] data = new byte[] {
            77, 84, 104, 100,        /* MThd ascii header */
            0, 0, 0, 6,              /* length of header in bytes */
            0, 1,                    /* one or more simultaneous tracks */
            0, numtracks,
            0, quarternote,
            77, 84, 114, 107,        /* MTrk ascii header */
            0, 0, 0, 39,             /* Length of track, in bytes */

            /*  time_interval, NoteEvent, note number, velocity */
            0,  EventNoteOn,  notenum,   velocity,
            60, EventNoteOff, notenum,   0,
            0,  EventKeyPressure, notenum, 10,
            0,  EventControlChange, 10, 10,
            0,  EventNoteOn,  notenum+1, velocity,
            30, EventNoteOff, notenum+1, 0,
            0,  EventProgramChange, 10,
            0,  EventPitchBend, 0, 0,
            0,  EventNoteOn,  notenum+2, velocity,
            90, EventNoteOff, notenum+2, 0
        };

        WriteTestFile(data);
        MidiFile midifile = new MidiFile(testfile);
        File.Delete(testfile);

        Assert.AreEqual(midifile.Tracks.Count, 1);
        Assert.AreEqual(midifile.Time.Numerator, 4);
        Assert.AreEqual(midifile.Time.Denominator, 4);
        Assert.AreEqual(midifile.Time.Quarter, quarternote);
        Assert.AreEqual(midifile.Time.Measure, quarternote * 4);

        MidiTrack track = midifile.Tracks[0];
        List<MidiNote> notes = track.Notes;
        Assert.AreEqual(notes.Count, 3);

        Assert.AreEqual(notes[0].StartTime, 0);
        Assert.AreEqual(notes[0].Number, notenum);
        Assert.AreEqual(notes[0].Duration, 60);

        Assert.AreEqual(notes[1].StartTime, 60);
        Assert.AreEqual(notes[1].Number, notenum+1);
        Assert.AreEqual(notes[1].Duration, 30);

        Assert.AreEqual(notes[2].StartTime, 90);
        Assert.AreEqual(notes[2].Number, notenum+2);
        Assert.AreEqual(notes[2].Duration, 90);
    }
Пример #20
0
    public void TestChangeSoundPerChannelPauseTime()
    {
        const byte notenum = 60;

        MidiFile midifile = CreateTestChangeSoundPerChannelMidiFile();
        MidiOptions options = new MidiOptions(midifile);
        options.pauseTime = 50;
        bool ret = midifile.ChangeSound(testfile, options);
        Assert.AreEqual(ret, true);
        MidiFile newmidi = new MidiFile(testfile);

        Assert.AreEqual(newmidi.Tracks.Count, 3);
        for (int tracknum = 0; tracknum < 3; tracknum++) {
            MidiTrack track = newmidi.Tracks[tracknum];
            Assert.AreEqual(track.Notes.Count, 2);
            for (int i = 0; i < 2; i++) {
                MidiNote note = track.Notes[i];
                Assert.AreEqual(note.Number, notenum + 10*tracknum + 1 + i);
                Assert.AreEqual(note.StartTime, 60 * (i+1) - 50);
            }
        }
        File.Delete(testfile);
    }
Пример #21
0
        /* Command-line program to print out a parsed Midi file. Used for debugging.
         * To run:
         * - Change Main2 to Main
         * - csc MidiNote.cs MidiEvent.cs MidiTrack.cs MidiFileReader.cs MidiOptions.cs
         *   MidiFile.cs MidiException.cs TimeSignature.cs
         * - MidiFile.exe file.mid
         *
         */
        public static void Main2(string[] arg)
        {
            if (arg.Length == 0) {
            Console.WriteLine("Usage: MidiFile <filename>");
            return;
            }

            MidiFile f = new MidiFile(arg[0]);
            Console.Write(f.ToString());
        }
Пример #22
0
    public void TestChangeSoundPerChannelTracks()
    {
        const byte notenum = 60;

        MidiFile midifile = CreateTestChangeSoundPerChannelMidiFile();
        MidiOptions options = new MidiOptions(midifile);
        options.tracks[0] = false;
        options.tracks[1] = true;
        options.tracks[2] = false;

        bool ret = midifile.ChangeSound(testfile, options);
        Assert.AreEqual(ret, true);
        MidiFile newmidi = new MidiFile(testfile);

        Assert.AreEqual(newmidi.Tracks.Count, 1);

        MidiTrack track = newmidi.Tracks[0];
        Assert.AreEqual(track.Notes.Count, 3);
        for (int i = 0; i < track.Notes.Count; i++) {
            MidiNote note = track.Notes[i];
            Assert.AreEqual(note.Number, notenum + 10 + i);
        }

        File.Delete(testfile);
    }
Пример #23
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);
        }
Пример #24
0
        /**
         * Read the midi file into a MidiFile instance.
         * Create a SheetMusic control based on the MidiFile.
         * Add the sheetmusic control to this form.
         * Enable all the menu items.
         *
         * If any error occurs while reading the midi file,
         * display a MessageBox with the error message.
         */
        public void OpenMidiFile(string filename)
        {
            try {
            midifile = new MidiFile(filename);
            DisableMenus();
            EnableMenus();
            string displayName = Path.GetFileName(filename);
            displayName = displayName.Replace("__", ": ");
            displayName = displayName.Replace("_", " ");
            Text = displayName + " - Midi Sheet Music";
            instrumentDialog = new InstrumentDialog(midifile);
            playMeasuresDialog = new PlayMeasuresDialog(midifile);
            RedrawSheetMusic();
            }
            catch (MidiFileException e) {
            filename = Path.GetFileName(filename);
            string message = "";
            message += "MidiSheetMusic was unable to open the file "
                       + filename;
            message += "\nIt does not appear to be a valid midi file.\n" + e.Message;

            MessageBox.Show(message, "Error Opening File",
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
            midifile = null;
            DisableMenus();
            }
            catch (System.IO.IOException e) {
            filename = Path.GetFileName(filename);
            string message = "";
            message += "MidiSheetMusic was unable to open the file "
                       + filename;
            message += "because:\n" + e.Message + "\n";

            MessageBox.Show(message, "Error Opening File",
                            MessageBoxButtons.OK, MessageBoxIcon.Error);

            midifile = null;
            DisableMenus();
            }
        }