Exemplo n.º 1
0
        /* Create a new MIDI file (represented by this instance), including the header chunk and appropriate
         * number of track chunks (with End of Track events).  This does not set delta-time division.
         */
        private MidiHeader Create(int format, int numberOfTracks)
        {
            /* Make sure we start with a clean slate. */
            this.Clear();
            int n = MidiChunkInfo.SizeItem();

            this.Bytes = new byte[n + MidiHeader.SizeItem()];

            /* Start the header chunk. */
            MidiChunkInfo chunkInfo = this.CreateChunkInfo(0, MidiChunkInfo.HeaderType);

            this.Items.Add(chunkInfo);

            /* Finish the header chunk.  (Don't set NumberOfTracks here; AddTrack will set it.) */
            MidiHeader header = new MidiHeader(this, n);

            header.Format = format;
            this.Items.Add(header);

            /* Add each track chunk (with an End of Track meta-event). */
            for (int i = 0; i < numberOfTracks; ++i)
            {
                this.AddTrack();
                this.AddMetaEvent(0, MidiMetaEvent.EndOfTrackType, null);
            }

            /* Delta-time division still needs to be set. */
            return(header);
        }
Exemplo n.º 2
0
        private MidiChunkInfo CreateChunkInfo(int offset, string type)
        {
            MidiChunkInfo chunkInfo = new MidiChunkInfo(this, offset);

            chunkInfo.Type   = type;
            chunkInfo.Length = (type == MidiChunkInfo.HeaderType) ? MidiHeader.SizeItem() : 0;
            if (type == MidiChunkInfo.TrackType)
            {
                ++this.Header.NumberOfTracks;
            }
            return(chunkInfo);
        }
Exemplo n.º 3
0
        /// <summary>Loads an existing MIDI file from disk (into this instance).</summary>
        /// <param name="path">The path of the MIDI file to load.</param>
        public void Load(string path)
        {
            int           n, i, j = 0;
            MidiChunkInfo chunkInfo;
            MidiHeader    header = null;

            /* Make sure we start with a clean slate. */
            this.Clear();
            this.Bytes = File.ReadAllBytes(path);

            /* Process each MidiItem object from the byte array. */
            for (i = 0; i < this.Bytes.Length; i += chunkInfo.Length)
            {
                /* A chunk should begin here. */
                chunkInfo = new MidiChunkInfo(this, i);
                this.Items.Add(chunkInfo);
                i += MidiChunkInfo.SizeItem();

                /* What comes next depends on the chunk type. */
                switch (chunkInfo.Type)
                {
                case MidiChunkInfo.HeaderType:
                    if (header == null)
                    {
                        header = new MidiHeader(this, i);
                        this.Items.Add(header);
                    }
                    else
                    {
                        this.AddErrorText(Properties.Resources.MultipleHeaders, 0);
                    }
                    break;

                case MidiChunkInfo.TrackType: this.ParseEvents(i, chunkInfo.Length, ++j); break;
                }
            }

            /* Check for track number mismatch. */
            n = (header == null) ? 0 : header.NumberOfTracks;
            if (n != j)
            {
                string s = UI.ParseLabel(Properties.Resources.Track).ToLower();
                s = string.Format(Properties.Resources.MismatchFormat, s, n, j);
                this.AddErrorText(s, 0);
            }
        }
Exemplo n.º 4
0
        /// <summary>Initializes a new instance of the MidiHeaderDialog class.</summary>
        /// <param name="header">
        /// MidiHeader object representing the MIDI header (MThd) chunk to edit, or null to create a new one.
        /// </param>
        public MidiHeaderDialog(MidiHeader header)
            : base(header)
        {
            Label      label;
            int        i = 0, j;
            MarginType marginType;

            /* If a new (file) header is being created, prompt for a file name. */
            if (this.ForNewItem)
            {
                /* Initialize the "File name" label. */
                label = UI.CreateLabel(MarginType.Top, Properties.Resources.FileName, true);
                this.AddUIElement(label);

                /* Initialize the "File name" text box. */
                this.FileNameTextBox              = new TextBox();
                this.FileNameTextBox.TabIndex     = ++i;
                this.FileNameTextBox.Margin       = new Thickness(0, 0, UI.HalfSpace, 0);
                this.FileNameTextBox.GotFocus    += UI.TextBox_GotFocus;
                this.FileNameTextBox.TextChanged += this.FileNameTextBox_TextChanged;
                label.Target        = this.FileNameTextBox;
                this.InitialElement = this.FileNameTextBox;

                /* Initialize the browse button. */
                Button button = new Button();
                button.TabIndex = ++i;
                button.Margin   = new Thickness(UI.HalfSpace, 0, 0, 0);
                button.Content  = "  ...  ";
                button.Click   += this.BrowseButton_Click;

                /* Build out a dock panel to contain the file name text box and browse button. */
                DockPanel.SetDock(button, Dock.Right);
                DockPanel dockPanel = new DockPanel();
                dockPanel.Children.Add(button);
                dockPanel.Children.Add(this.FileNameTextBox);
                dockPanel.Margin = new Thickness(UI.TripleSpace, UI.HalfSpace, UI.TripleSpace, UI.UnitSpace);
                this.AddUIElement(dockPanel);

                /* Set the margin type for the next label. */
                marginType = MarginType.Standard;
            }
            else
            {
                marginType = MarginType.Top;
            }

            /* Initialize the "Format" label. */
            label = UI.CreateLabel(marginType, Properties.Resources.Format, true);

            /* Initialize the "Format" combo box. */
            this.FormatComboBox          = new ComboBox();
            this.FormatComboBox.TabIndex = ++i;
            this.FormatComboBox.Margin   = new Thickness(UI.TripleSpace, UI.HalfSpace, UI.TripleSpace, UI.UnitSpace);
            this.FormatComboBox.Items.Add(Properties.Resources.Format0);
            this.FormatComboBox.Items.Add(Properties.Resources.Format1);
            this.FormatComboBox.Items.Add(Properties.Resources.Format2);
            this.FormatComboBox.SelectionChanged += this.FormatComboBox_SelectionChanged;
            label.Target = this.FormatComboBox;

            /* Initialize the "Number of tracks" label. */
            this.NumberOfTracksLabel = UI.CreateLabel(MarginType.Standard, Properties.Resources.NumberOfTracks, true);

            /* Initialize the "Number of tracks" text box. */
            this.NumberOfTracksTextBox               = new TextBox();
            this.NumberOfTracksTextBox.TabIndex      = ++i;
            this.NumberOfTracksTextBox.Margin        = new Thickness(UI.TripleSpace, UI.HalfSpace, UI.TripleSpace, UI.UnitSpace);
            this.NumberOfTracksTextBox.TextAlignment = TextAlignment.Right;
            this.NumberOfTracksTextBox.GotFocus     += UI.TextBox_GotFocus;
            this.NumberOfTracksTextBox.TextChanged  += this.NumberOfTracksTextBox_TextChanged;
            this.NumberOfTracksLabel.Target          = this.NumberOfTracksTextBox;

            /* Initialize the "Metrical time" radio button. */
            this.MetricalTimeRadioButton          = new RadioButton();
            this.MetricalTimeRadioButton.TabIndex = ++i;
            this.MetricalTimeRadioButton.Margin   = new Thickness(UI.TripleSpace, UI.TripleSpace, UI.TripleSpace, UI.UnitSpace);
            this.MetricalTimeRadioButton.Content  = Properties.Resources.MetricalTime;
            this.MetricalTimeRadioButton.Checked += this.MetricalTimeRadioButton_Checked;

            /* Initialize the "Ticks per quarter note" label. */
            this.TicksPerQuarterNoteLabel           = UI.CreateLabel(MarginType.Indent, Properties.Resources.TicksPerQuarterNote, true);
            this.TicksPerQuarterNoteLabel.IsEnabled = false;

            /* Initialize the "Ticks per quarter note" text box. */
            this.TicksPerQuarterNoteTextBox               = new TextBox();
            this.TicksPerQuarterNoteTextBox.TabIndex      = ++i;
            this.TicksPerQuarterNoteTextBox.Margin        = new Thickness(UI.IndentSpace, UI.HalfSpace, UI.TripleSpace, UI.UnitSpace);
            this.TicksPerQuarterNoteTextBox.TextAlignment = TextAlignment.Right;
            this.TicksPerQuarterNoteTextBox.IsEnabled     = false;
            this.TicksPerQuarterNoteTextBox.GotFocus     += UI.TextBox_GotFocus;
            this.TicksPerQuarterNoteTextBox.TextChanged  += this.TicksPerQuarterNoteTextBox_TextChanged;
            this.TicksPerQuarterNoteLabel.Target          = this.TicksPerQuarterNoteTextBox;

            /* Initialize the "Time-code-based time" radio button. */
            this.TimeCodeBasedTimeRadioButton          = new RadioButton();
            this.TimeCodeBasedTimeRadioButton.TabIndex = ++i;
            this.TimeCodeBasedTimeRadioButton.Margin   =
                new Thickness(UI.TripleSpace, UI.DoubleSpace, UI.TripleSpace, UI.UnitSpace);
            this.TimeCodeBasedTimeRadioButton.Content  = Properties.Resources.TimeCodeBasedTime;
            this.TimeCodeBasedTimeRadioButton.Checked += this.TimeCodeBasedTimeRadioButton_Checked;

            /* Initialize the "Frames per second" label. */
            this.FramesPerSecondLabel           = UI.CreateLabel(MarginType.Indent, Properties.Resources.FramesPerSecond, true);
            this.FramesPerSecondLabel.IsEnabled = false;

            /* Initialize the "Frames per second" combo box. */
            this.FramesPerSecondComboBox          = new ComboBox();
            this.FramesPerSecondComboBox.TabIndex = ++i;
            this.FramesPerSecondComboBox.Margin   = new Thickness(UI.IndentSpace, UI.HalfSpace, UI.TripleSpace, UI.UnitSpace);
            for (j = 0; j < MidiHeaderDialog.FramesPerSecondCount; ++j)
            {
                this.FramesPerSecondComboBox.Items.Add(MidiHeaderDialog.FramesPerSecondStrings[j]);
            }
            this.FramesPerSecondComboBox.IsEnabled         = false;
            this.FramesPerSecondComboBox.SelectionChanged += this.FramesPerSecondComboBox_SelectionChanged;
            this.FramesPerSecondLabel.Target = this.FramesPerSecondComboBox;

            /* Initialize the "Ticks per frame" label. */
            this.TicksPerFrameLabel           = UI.CreateLabel(MarginType.Indent, Properties.Resources.TicksPerFrame, true);
            this.TicksPerFrameLabel.IsEnabled = false;

            /* Initialize the "Ticks per frame" text box. */
            this.TicksPerFrameTextBox               = new TextBox();
            this.TicksPerFrameTextBox.TabIndex      = ++i;
            this.TicksPerFrameTextBox.Margin        = new Thickness(UI.IndentSpace, UI.HalfSpace, UI.TripleSpace, UI.TripleSpace);
            this.TicksPerFrameTextBox.TextAlignment = TextAlignment.Right;
            this.TicksPerFrameTextBox.IsEnabled     = false;
            this.TicksPerFrameTextBox.GotFocus     += UI.TextBox_GotFocus;
            this.TicksPerFrameTextBox.TextChanged  += this.TicksPerFrameTextBox_TextChanged;
            this.TicksPerFrameLabel.Target          = this.TicksPerFrameTextBox;

            /* Build out the stack panel, which will serve as the content for the "Delta-time division" group box. */
            StackPanel stackPanel = new StackPanel();

            stackPanel.Children.Add(this.MetricalTimeRadioButton);
            stackPanel.Children.Add(this.TicksPerQuarterNoteLabel);
            stackPanel.Children.Add(this.TicksPerQuarterNoteTextBox);
            stackPanel.Children.Add(this.TimeCodeBasedTimeRadioButton);
            stackPanel.Children.Add(this.FramesPerSecondLabel);
            stackPanel.Children.Add(this.FramesPerSecondComboBox);
            stackPanel.Children.Add(this.TicksPerFrameLabel);
            stackPanel.Children.Add(this.TicksPerFrameTextBox);

            /* Build out the "Delta-time division" group box. */
            GroupBox groupBox = new GroupBox();

            groupBox.Header  = Properties.Resources.DeltaTimeDivision;
            groupBox.Content = stackPanel;
            groupBox.Margin  = new Thickness(UI.TripleSpace, UI.UnitSpace, UI.TripleSpace, UI.UnitSpace);

            /* Build out the window and its content. */
            this.AddUIElement(label);
            this.AddUIElement(this.FormatComboBox);
            this.AddUIElement(this.NumberOfTracksLabel);
            this.AddUIElement(this.NumberOfTracksTextBox);
            this.AddUIElement(groupBox);
            this.BuildOut(UI.ClientWidth, MidiHeaderDialog.TitleString);

            /* The OK button should start out disabled and stay that way until all required input is entered. */
            this.OkButton.IsEnabled = false;

            /* If a MidiHeader object was supplied, use it to set initial values. */
            if (this.ForNewItem)
            {
                return;
            }
            this.InitialElement = this.FormatComboBox;
            this.NumberOfTracksTextBox.IsEnabled = false;
            this.NumberOfTracksLabel.IsEnabled   = false;
            this.NumberOfTracksTextBox.Text      = header.NumberOfTracks.ToString();
            this.FormatComboBox.SelectedIndex    = header.Format;
            if (header.TicksPerQuarterNote < 0)
            {
                this.TimeCodeBasedTimeRadioButton.IsChecked = true;
                for (j = 0; j < MidiHeaderDialog.FramesPerSecondCount; ++j)
                {
                    if (MidiHeaderDialog.FramesPerSecondValues[j] == header.FramesPerSecond)
                    {
                        this.FramesPerSecondComboBox.SelectedIndex = j; break;
                    }
                }
                this.TicksPerFrameTextBox.Text = header.TicksPerFrame.ToString();
            }
            else
            {
                this.MetricalTimeRadioButton.IsChecked = true;
                this.TicksPerQuarterNoteTextBox.Text   = header.TicksPerQuarterNote.ToString();
            }
        }