Beispiel #1
0
        /// <summary>
        /// Exports the current <see cref="Pattern"/> to track chunk.
        /// </summary>
        /// <param name="tempoMap">Tempo map to process pattern data according with.</param>
        /// <param name="channel">Channel of notes that will be generated by pattern.</param>
        /// <returns>The <see cref="TrackChunk"/> containing notes events generated by the current <see cref="Pattern"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="tempoMap"/> is null.</exception>
        public TrackChunk ToTrackChunk(TempoMap tempoMap, FourBitNumber channel)
        {
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            var context = new PatternContext(tempoMap, channel);
            var result  = InvokeActions(0, context);

            //

            var trackChunk = new TrackChunk();

            using (var notesManager = trackChunk.ManageNotes())
            {
                notesManager.Notes.Add(result.Notes ?? Enumerable.Empty <Note>());
            }

            using (var eventsManager = trackChunk.ManageTimedEvents())
            {
                eventsManager.Events.Add(result.Events ?? Enumerable.Empty <TimedEvent>());
            }

            //

            return(trackChunk);
        }
        public void Decode(string midiFile, int keyNoteOctave)
        {
            try
            {
                DecoderDic        ddic      = new DecoderDic(keyNoteOctave);
                MidiFile          midi      = MidiFile.Read(midiFile);
                List <TrackChunk> trackList = midi.GetTrackChunks().ToList();
                string            result    = "";

                TrackChunk   track       = trackList[0];
                NotesManager noteManager = track.ManageNotes();

                foreach (Note note in noteManager.Notes)
                {
                    result += ddic.GetChar(note.NoteName, note.Octave);
                }
                Console.WriteLine("-----------------------------------------");
                Console.WriteLine("DECODED MIDI FILE MESSAGE: " + result);
                Console.WriteLine("-----------------------------------------");
            }
            catch (IOException)
            {
                Console.WriteLine("[ERROR] Cannot read " + midiFile + "! Maybe is already used by another process?");
                Environment.Exit(-1);
            }
            catch (Exception e)
            {
                Console.WriteLine("[ERROR] Something goes wrong here: " + e.Message);
                Environment.Exit(-1);
            }
        }
Beispiel #3
0
        public static void Test()
        {
            var      midiFile = new MidiFile();
            TempoMap tempoMap = midiFile.GetTempoMap();

            var trackChunk = new TrackChunk();

            using (var notesManager = trackChunk.ManageNotes())
            {
                NotesCollection notes = notesManager.Notes;

                var      g = Enum.GetValues(typeof(NoteName));
                NoteName n = (NoteName)g.GetValue(MainWindow._rnd.Next(g.Length));
                notes.Add(new InterNote(n, 4, LC.ConvertFrom(
                                            new MetricTimeSpan(hours: 0, minutes: 0, seconds: 2), 0, tempoMap)));

                n = (NoteName)g.GetValue(MainWindow._rnd.Next(g.Length));
                notes.Add(new InterNote(n, 3, LC.ConvertFrom(
                                            new MetricTimeSpan(hours: 0, minutes: 0, seconds: 1, milliseconds: 500), 0, tempoMap)));
                n = (NoteName)g.GetValue(MainWindow._rnd.Next(g.Length));

                notes.Add(new InterNote(n, 5, LC.ConvertFrom(
                                            new MetricTimeSpan(hours: 0, minutes: 0, seconds: 3), 0, tempoMap)));
            }

            midiFile.Chunks.Add(trackChunk);

            using (var outputDevice = OutputDevice.GetByName("Microsoft GS Wavetable Synth"))
                using (var playback = midiFile.GetPlayback(outputDevice))
                {
                    // playback.Speed = 2.0;
                    playback.Play();
                }
        }
        private MidiFile WriteToFile(List <Chord> chords, int numberCurPopulaiton)
        {
            var midiFile = new MidiFile();
            var tempoMap = midiFile.GetTempoMap();

            var trackChunk = new TrackChunk();

            using (var notesManager = trackChunk.ManageNotes())
            {
                foreach (var chord in chords)
                {
                    notesManager.Notes.Add(chord.Notes);
                }
            }

            midiFile.Chunks.Add(trackChunk);
            string name      = numberCurPopulaiton + "_" + DateTime.Now.ToString().Replace(':', ',').Replace(' ', '_') + "_" + rnd.Next() + ((char)rnd.Next('A', 'Z' + 1)).ToString() + ".mid";
            string format    = ".mid";
            string directory = @".\curPopulationMIDI\" + name;

            // проверка на существование файла
            while (File.Exists(directory))
            {
                name      = numberCurPopulaiton + "_" + DateTime.Now.ToString().Replace(':', ',').Replace(' ', '_') + "_" + rnd.Next() + ((char)rnd.Next('A', 'Z' + 1)).ToString() + ".mid";
                directory = @".\curPopulationMIDI\" + name;
            }

            filesCurPopulation.Add(new MusicFile(name, format, directory));

            midiFile.Write(directory);
            return(midiFile);
        }
Beispiel #5
0
        /// <summary>
        /// Randomizes notes contained in the specified <see cref="TrackChunk"/>.
        /// </summary>
        /// <param name="trackChunk"><see cref="TrackChunk"/> to randomize notes in.</param>
        /// <param name="bounds">Bounds to randomize time within.</param>
        /// <param name="tempoMap">Tempo map used to calculate time bounds to randomize within.</param>
        /// <param name="settings">Settings according to which notes should be randomized.</param>
        /// <exception cref="ArgumentNullException"><paramref name="trackChunk"/> is null. -or-
        /// <paramref name="bounds"/> is null. -or- <paramref name="tempoMap"/> is null.</exception>
        public static void RandomizeNotes(this TrackChunk trackChunk, IBounds bounds, TempoMap tempoMap, NotesRandomizingSettings settings = null)
        {
            ThrowIfArgument.IsNull(nameof(trackChunk), trackChunk);
            ThrowIfArgument.IsNull(nameof(bounds), bounds);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            using (var notesManager = trackChunk.ManageNotes())
            {
                new NotesRandomizer().Randomize(notesManager.Notes, bounds, tempoMap, settings);
            }
        }
Beispiel #6
0
        /// <summary>
        /// Quantizes notes contained in the specified <see cref="TrackChunk"/>.
        /// </summary>
        /// <param name="trackChunk"><see cref="TrackChunk"/> to quantize notes in.</param>
        /// <param name="grid">Grid to quantize objects by.</param>
        /// <param name="tempoMap">Tempo map used to calculate times to quantize by.</param>
        /// <param name="settings">Settings according to which notes should be quantized.</param>
        /// <exception cref="ArgumentNullException"><paramref name="trackChunk"/> is null. -or-
        /// <paramref name="grid"/> is null. -or- <paramref name="tempoMap"/> is null.</exception>
        /// <exception cref="InvalidOperationException">Note is going to be moved beyond zero. -or-
        /// Note's end is going to be moved beyond the note's fixed end.</exception>
        public static void QuantizeNotes(this TrackChunk trackChunk, IGrid grid, TempoMap tempoMap, NotesQuantizingSettings settings = null)
        {
            ThrowIfArgument.IsNull(nameof(trackChunk), trackChunk);
            ThrowIfArgument.IsNull(nameof(grid), grid);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            using (var notesManager = trackChunk.ManageNotes())
            {
                new NotesQuantizer().Quantize(notesManager.Notes, grid, tempoMap, settings);
            }
        }
Beispiel #7
0
        private static void SplitTrackChunkNotes(TrackChunk trackChunk, Func <NotesSplitter, IEnumerable <Note>, IEnumerable <Note> > splitOperation)
        {
            using (var notesManager = trackChunk.ManageNotes())
            {
                var notes = notesManager.Notes;

                var notesSplitter = new NotesSplitter();
                var newNotes      = splitOperation(notesSplitter, notes).ToList();

                notes.Clear();
                notes.Add(newNotes);
            }
        }
Beispiel #8
0
        public void InitPlay()
        {
            _midiFile = new MidiFile();
            TempoMap tempoMap = _midiFile.GetTempoMap();

            var trackChunk = new TrackChunk();

            using (var notesManager = trackChunk.ManageNotes())
            {
                NotesCollection notes = notesManager.Notes;
                var             len   = LC.ConvertFrom(new MetricTimeSpan(hours: 0, minutes: 0, seconds: 1), 0, tempoMap);

                notes.Add(new InterNote(Note, Octave, len));
            }


            _midiFile.Chunks.Add(trackChunk);
        }
Beispiel #9
0
        private MidiFile To(MusicItem data)
        {
            var midiFile = new MidiFile();
            var tempoMap = midiFile.GetTempoMap();

            var trackChunk = new TrackChunk();

            using (var notesManager = trackChunk.ManageNotes())
            {
                var length = LengthConverter.ConvertFrom(
                    2 * MusicalTimeSpan.Eighth.Triplet(),
                    0,
                    tempoMap);
                var note = new Melanchall.DryWetMidi.Interaction.Note(NoteName.A, 4, length);
                notesManager.Notes.Add(note);
            }

            midiFile.Chunks.Add(trackChunk);
            return(midiFile);
        }
Beispiel #10
0
        /// <summary>
        /// Merges nearby notes in the specified <see cref="TrackChunk"/>.
        /// </summary>
        /// <param name="trackChunk"><see cref="TrackChunk"/> to merge nearby notes in.</param>
        /// <param name="tempoMap">Tempo map used to calculate distances between notes.</param>
        /// <param name="settings">Settings according to which notes should be merged.</param>
        /// <param name="filter">Filter for notes to merge.</param>
        /// <exception cref="ArgumentNullException">
        /// <para>One of the following errors occured:</para>
        /// <list type="bullet">
        /// <item>
        /// <description><paramref name="trackChunk"/> is <c>null</c>.</description>
        /// </item>
        /// <item>
        /// <description><paramref name="tempoMap"/> is <c>null</c>.</description>
        /// </item>
        /// </list>
        /// </exception>
        public static void MergeNotes(this TrackChunk trackChunk,
                                      TempoMap tempoMap,
                                      NotesMergingSettings settings = null,
                                      Predicate <Note> filter       = null)
        {
            ThrowIfArgument.IsNull(nameof(trackChunk), trackChunk);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            using (var notesManager = trackChunk.ManageNotes())
            {
                var notes = notesManager.Notes;

                var notesMerger = new NotesMerger();
                var newNotes    = notesMerger.Merge(notes.Where(n => filter == null || filter(n)), tempoMap, settings)
                                  .ToList();

                notes.Clear();
                notes.Add(newNotes);
            }
        }
Beispiel #11
0
        private static void Merge(TrackChunk trackChunk)
        {
            using (var notesManager = trackChunk.ManageNotes())
            {
                var notes        = notesManager.Notes;
                var currentNotes = new Dictionary <FourBitNumber, Dictionary <SevenBitNumber, Note> >();

                foreach (var note in notes.ToList())
                {
                    var channel = note.Channel;

                    Dictionary <SevenBitNumber, Note> currentNotesByNoteNumber;
                    if (!currentNotes.TryGetValue(channel, out currentNotesByNoteNumber))
                    {
                        currentNotes.Add(channel, currentNotesByNoteNumber = new Dictionary <SevenBitNumber, Note>());
                    }

                    Note currentNote;
                    if (!currentNotesByNoteNumber.TryGetValue(note.NoteNumber, out currentNote))
                    {
                        currentNotesByNoteNumber.Add(note.NoteNumber, currentNote = note);
                        continue;
                    }

                    var currentEndTime = currentNote.Time + currentNote.Length;
                    if (note.Time <= currentEndTime)
                    {
                        var endTime = Math.Max(note.Time + note.Length, currentEndTime);
                        currentNote.Length = endTime - currentNote.Time;

                        notes.Remove(note);
                    }
                    else
                    {
                        currentNotesByNoteNumber[note.NoteNumber] = note;
                    }
                }
            }
        }
Beispiel #12
0
        public void Notes_Overlapped()
        {
            var trackChunk = new TrackChunk(
                new NoteOnEvent((SevenBitNumber)30, (SevenBitNumber)70),
                new NoteOnEvent((SevenBitNumber)60, (SevenBitNumber)50),
                new NoteOffEvent((SevenBitNumber)60, (SevenBitNumber)0)
            {
                DeltaTime = 100
            },
                new NoteOnEvent((SevenBitNumber)40, (SevenBitNumber)70),
                new NoteOffEvent((SevenBitNumber)40, (SevenBitNumber)0)
            {
                DeltaTime = 100
            },
                new NoteOffEvent((SevenBitNumber)30, (SevenBitNumber)0));

            var expectedNotes = new[]
            {
                new Note((SevenBitNumber)30, 200, 0)
                {
                    Velocity = (SevenBitNumber)70
                },
                new Note((SevenBitNumber)60, 100, 0)
                {
                    Velocity = (SevenBitNumber)50
                },
                new Note((SevenBitNumber)40, 100, 100)
                {
                    Velocity = (SevenBitNumber)70
                }
            };

            using (var notesManager = trackChunk.ManageNotes())
            {
                var notes = notesManager.Notes;
                MidiAsserts.AreEqual(expectedNotes, notes, "Notes are invalid.");
            }
        }
Beispiel #13
0
            private static MidiFile CreateTestFile()
            {
                const int trackChunksNumber  = 50;
                const int notesPerTrackChunk = 1000;
                const int noteLength         = 100;

                var midiFile = new MidiFile();

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

                    using (var notesManager = trackChunk.ManageNotes())
                    {
                        notesManager.Notes.Add(Enumerable.Range(0, notesPerTrackChunk)
                                               .Select(j => new Note((SevenBitNumber)(j % SevenBitNumber.MaxValue), noteLength, j)));
                    }

                    midiFile.Chunks.Add(trackChunk);
                }

                return(midiFile);
            }
        public void Encode(string textToEncode, string outputFileName, int keyNoteOctave)
        {
            try
            {
                if (File.Exists(outputFileName))
                {
                    File.Delete(outputFileName);
                }
                EncoderDic encoderDic = new EncoderDic(keyNoteOctave);
                MidiFile   midi       = new MidiFile();
                TempoMap   tempo      = midi.GetTempoMap();

                TrackChunk trackChunk = new TrackChunk();
                using (NotesManager notesManager = trackChunk.ManageNotes())
                {
                    int timePos = 0;
                    for (int i = 0; i < textToEncode.Length; i++)
                    {
                        Note note = new Note(encoderDic.GetNoteName(textToEncode[i]), encoderDic.GetOctave(textToEncode[i]), LengthConverter.ConvertFrom(2 * MusicalTimeSpan.Eighth.Triplet(), 0, tempo), timePos);
                        //(Tipo de nota, octava, longitud de la nota, posicion en el tiempo);
                        timePos += 65;
                        notesManager.Notes.Add(note);
                    }
                }
                midi.Chunks.Add(trackChunk);
                midi.Write(outputFileName);
            }catch (IOException)
            {
                Console.WriteLine("[ERROR] Cannot create " + outputFileName + "! Maybe is already used by another process?");
                Environment.Exit(-1);
            }
            catch (Exception e)
            {
                Console.WriteLine("[ERROR] Something goes wrong here: " + e.Message);
                Environment.Exit(-1);
            }
        }
Beispiel #15
0
        private void btnSave_Click(object sender, EventArgs e)
        {
            if (Path.GetExtension(filePath) == ".mid")
            {
                var chunks      = song.GetTrackChunks().ToArray();
                var tempoMap    = song.GetTempoMap();
                var fixedMidi   = new MidiFile();
                var headerChunk = new TrackChunk();

                int i       = 0;
                var t0Notes = chunks[0].GetNotes().ToArray();
                if (t0Notes.Length == 0)    // check if there are notes in Track0
                {
                    i = 1;
                    var timedEvents = chunks[0].GetTimedEvents().ToArray();
                    var title       = timedEvents.Where(t => t.Event.EventType == MidiEventType.SequenceTrackName);
                    if (title.Count() == 1)
                    {
                        headerChunk.AddTimedEvents(title);
                    }
                }

                fixedMidi.Chunks.Add(headerChunk);
                fixedMidi.ReplaceTempoMap(tempoMap);

                for (int ch = 0; i < chunks.Count(); i++, ch++)
                {
                    var newChunk    = new TrackChunk();
                    var timedEvents = chunks[i].GetTimedEvents();

                    using (var timedEventsManager = newChunk.ManageTimedEvents())
                    {
                        foreach (var timedEvent in timedEvents)
                        {
                            var eventType = timedEvent.Event.EventType;
                            if (eventType == MidiEventType.SequenceTrackName)
                            {
                                timedEventsManager.Events.Add(timedEvent);
                            }
                            else if (eventType == MidiEventType.ProgramChange)
                            {
                                var pcEvent = timedEvent.Event as ProgramChangeEvent;
                                pcEvent.Channel = (FourBitNumber)ch;
                                timedEventsManager.Events.AddEvent(pcEvent, timedEvent.Time);
                            }
                        }
                    }

                    using (var notesManager = newChunk.ManageNotes())
                    {
                        var notes = chunks[i].GetNotes().ToArray();
                        foreach (var n in notes)
                        {
                            var newNote = n;
                            newNote.Channel = (FourBitNumber)ch;   // change channel of the notes in track
                            notesManager.Notes.Add(newNote);
                        }
                    }

                    fixedMidi.Chunks.Add(newChunk);
                }

                string outputFilename = Path.GetFileNameWithoutExtension(filePath) + "_fix.mid";
                WriteMidiToFile(fixedMidi, outputFilename);
                textBox1.AppendText("Wrote to file: " + outputFilename + Environment.NewLine);
            }
            else if (Path.GetExtension(filePath) == ".mml")
            {
                string outputFilename = Path.GetFileNameWithoutExtension(filePath) + "_fix.mml";
                File.WriteAllText(outputFilename, sb.ToString());
                textBox1.AppendText("Wrote to file: " + outputFilename + Environment.NewLine);
            }
        }
Beispiel #16
0
        public static MidiFile ToMidiFile(this Bitmap bitmap, TimeSpan songLength)
        {
            bool newPixelSet    = true;
            var  metricTimeSpan = new MetricTimeSpan(songLength);

            var      midiFile = new MidiFile();
            TempoMap tempoMap = midiFile.GetTempoMap();

            long maxLength = TimeConverter.ConvertFrom(metricTimeSpan, tempoMap);

            List <MidiPixelSet> pixelSet = new List <MidiPixelSet>();

            MidiPixelSet midiPixelSet = new();

            for (int i = 0; i < bitmap.Width; i++)
            {
                for (int j = 0; j < bitmap.Height; j++)
                {
                    var pixel = bitmap.GetPixel(i, j);

                    if (pixel.A == 0)
                    {
                        break;
                    }


                    if (newPixelSet)
                    {
                        midiPixelSet      = new();
                        midiPixelSet.Tone = new(pixel.R, pixel.G, pixel.B);
                    }
                    else
                    {
                        midiPixelSet.Timing = new(pixel.R, pixel.G, pixel.B, maxLength);
                        pixelSet.Add(midiPixelSet);
                    }

                    newPixelSet = !newPixelSet;
                }
            }

            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(pixelSet[i].Tone.NoteNumber);
            }



            var trackChunk = new TrackChunk();
            int count      = 0;

            using (var notesManager = trackChunk.ManageNotes())
            {
                NotesCollection notes = notesManager.Notes;
                pixelSet.ForEach(x =>
                {
                    count++;
                    notes.Add(new Note(x.Tone.NoteNumber, x.Tone.Length, x.Timing.Time));
                });
            }

            midiFile.Chunks.Add(trackChunk);
            return(midiFile);
        }