/// <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); } }
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); }
/// <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); } }
/// <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); } }
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); } }
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); }
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); }
/// <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); } }
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; } } } }
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."); } }
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); } }
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); } }
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); }