public void OpenFile(string path) { midi = MidiFile.Read(path, new ReadingSettings { NoHeaderChunkPolicy = NoHeaderChunkPolicy.Ignore, NotEnoughBytesPolicy = NotEnoughBytesPolicy.Ignore, InvalidChannelEventParameterValuePolicy = InvalidChannelEventParameterValuePolicy.ReadValid, InvalidChunkSizePolicy = InvalidChunkSizePolicy.Ignore, InvalidMetaEventParameterValuePolicy = InvalidMetaEventParameterValuePolicy.SnapToLimits, MissedEndOfTrackPolicy = MissedEndOfTrackPolicy.Ignore, UnexpectedTrackChunksCountPolicy = UnexpectedTrackChunksCountPolicy.Ignore, ExtraTrackChunkPolicy = ExtraTrackChunkPolicy.Read, UnknownChunkIdPolicy = UnknownChunkIdPolicy.ReadAsUnknownChunk, SilentNoteOnPolicy = SilentNoteOnPolicy.NoteOff }); Tmap = midi.GetTempoMap(); }
private static void WriteTrackChunkEnd( StreamWriter streamWriter, int trackNumber, long time, MidiFileCsvConversionSettings settings, TempoMap tempoMap) { switch (settings.CsvLayout) { case MidiFileCsvLayout.DryWetMidi: return; case MidiFileCsvLayout.MidiCsv: WriteRecord(streamWriter, trackNumber, time, MidiCsvRecordTypes.File.TrackChunkEnd, settings, tempoMap); break; } }
private void SplitByGrid_MultipleSteps(IEnumerable <TObject> inputObjects, ITimeSpan gridStart, IEnumerable <ITimeSpan> gridSteps, Dictionary <TObject, IEnumerable <TimeAndLength> > expectedParts, TempoMap tempoMap) { var expectedObjects = expectedParts .SelectMany(p => p.Value.Select(tl => CloneAndChangeTimeAndLength( p.Key, TimeConverter.ConvertFrom(tl.Time, tempoMap), LengthConverter.ConvertFrom(tl.Length, tl.Time, tempoMap)))) .ToArray(); var actualObjects = Splitter.SplitByGrid(inputObjects, new SteppedGrid(gridStart, gridSteps), tempoMap).ToArray(); ObjectMethods.AssertCollectionsAreEqual(expectedObjects, actualObjects); }
private static MarkablePlaybackEvent GetPlaybackEventWithNoteTag( Note note, TimedEvent timedEvent, TempoMap tempoMap) { var playbackEvent = new MarkablePlaybackEvent( timedEvent.Event, timedEvent.TimeAs <MetricTimeSpan>(tempoMap), timedEvent.Time); TimeSpan noteStartTime = note.TimeAs <MetricTimeSpan>(tempoMap); TimeSpan noteEndTime = TimeConverter.ConvertTo <MetricTimeSpan>(note.Time + note.Length, tempoMap); playbackEvent.Metadata = new NotePlaybackEventMetadata(note, noteStartTime, noteEndTime); return(playbackEvent); }
/// <summary> /// Merges nearby notes in the specified collection of notes. /// </summary> /// <param name="notes">Collection of notes to merge 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> /// <returns>Collection of notes which produced from the input one by merging nearby notes.</returns> /// <exception cref="ArgumentNullException"><paramref name="notes"/> is null.</exception> public IEnumerable <Note> Merge(IEnumerable <Note> notes, TempoMap tempoMap, NotesMergingSettings settings = null) { ThrowIfArgument.IsNull(nameof(notes), notes); settings = settings ?? new NotesMergingSettings(); var currentNotes = new Dictionary <NoteId, NoteHolder>(); var toleranceType = settings.Tolerance.GetType(); foreach (var note in notes.Where(n => n != null).OrderBy(n => n.Time)) { var noteId = note.GetNoteId(); NoteHolder currentNoteHolder; if (!currentNotes.TryGetValue(noteId, out currentNoteHolder)) { currentNotes.Add(noteId, CreateNoteHolder(note, settings)); continue; } var currentEndTime = currentNoteHolder.EndTime; var distance = Math.Max(0, note.Time - currentEndTime); var convertedDistance = LengthConverter.ConvertTo((MidiTimeSpan)distance, toleranceType, currentEndTime, tempoMap); if (convertedDistance.CompareTo(settings.Tolerance) <= 0) { var endTime = Math.Max(note.Time + note.Length, currentEndTime); currentNoteHolder.EndTime = endTime; currentNoteHolder.MergeVelocities(note); } else { yield return(currentNotes[noteId].GetResultNote()); currentNotes[noteId] = CreateNoteHolder(note, settings); } } foreach (var note in currentNotes.Values) { yield return(note.GetResultNote()); } }
static string NoteToString(Note note, TempoMap tempoMap) { string representation = "\t\t\t{"; //find the note name string name = note.NoteName.ToString(); //convert the sharp into notation that the synth recognizes if (name.Contains("Sharp")) { name = name[0] + "s"; } representation += ".note = \"" + name + "\""; //find the note octave int octave = note.Octave; representation += ", .octave = " + octave; //find the note duration MetricTimeSpan noteDuration = LengthConverter.ConvertTo <MetricTimeSpan>(note.Length, note.Time, tempoMap); double seconds = noteDuration.TotalMicroseconds * MICROSECONDS_TO_SECONDS; representation += ", .duration = " + seconds; //find the note peak and sustain intensity double peakIntensity = System.Math.Pow(INTENSITY_SENSITIVITY, note.Velocity); double sustainIntensity = peakIntensity * SUSTAINABILITY; representation += ", .peak_intensity = " + peakIntensity + ", .sustain_intensity = " + sustainIntensity; //find the adsr envelope double adPercent = AD_SLOPE * (System.Math.Abs(note.Velocity) - 127) + MIN_AD_PERCENT; double aPercent = adPercent * AD_PROPORTION; double dPercent = adPercent - aPercent; double rPercent = R_SLOPE * (System.Math.Abs(note.Velocity) - 127) + MIN_R_PERCENT; double sPercent = 1 - aPercent - dPercent - rPercent; representation += ", .adsr_envelope = (double[]) {" + aPercent + ", " + dPercent + ", " + sPercent + ", " + rPercent + "}"; representation += "}"; return(representation); }
private static QuantizedTime FindNearestTime(IReadOnlyList <long> grid, long time, TimeSpanType distanceCalculationType, double quantizingLevel, TempoMap tempoMap) { var distanceToGridTime = -1L; var convertedDistanceToGridTime = TimeSpanUtilities.GetMaxTimeSpan(distanceCalculationType); var gridTime = -1L; for (int i = 0; i < grid.Count; i++) { var currentGridTime = grid[i]; var distance = Math.Abs(time - currentGridTime); var convertedDistance = LengthConverter.ConvertTo(distance, distanceCalculationType, Math.Min(time, currentGridTime), tempoMap); if (convertedDistance.CompareTo(convertedDistanceToGridTime) >= 0) { break; } distanceToGridTime = distance; convertedDistanceToGridTime = convertedDistance; gridTime = currentGridTime; } // var shift = convertedDistanceToGridTime.Multiply(quantizingLevel); var convertedTime = TimeConverter.ConvertTo(time, distanceCalculationType, tempoMap); var newTime = TimeConverter.ConvertFrom( gridTime > time ? convertedTime.Add(shift, TimeSpanMode.TimeLength) : convertedTime.Subtract(shift, TimeSpanMode.TimeLength), tempoMap); // return(new QuantizedTime(newTime, gridTime, shift, distanceToGridTime, convertedDistanceToGridTime)); }
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 void CheckRecordedEvents( IReadOnlyList <TimedEvent> recordedEvents, IReadOnlyList <TimeSpan> expectedTimes, TempoMap tempoMap) { for (var i = 0; i < recordedEvents.Count; i++) { var recordedEvent = recordedEvents[i]; var expectedTime = expectedTimes[i]; var convertedRecordedTime = (TimeSpan)recordedEvent.TimeAs <MetricTimeSpan>(tempoMap); var offsetFromExpectedTime = (convertedRecordedTime - expectedTime).Duration(); Assert.LessOrEqual( offsetFromExpectedTime, SendReceiveUtilities.MaximumEventSendReceiveDelay, $"Event was recorded at wrong time (at {convertedRecordedTime} instead of {expectedTime})."); } }
public static void ConvertToCsv(IEnumerable <Note> notes, Stream stream, TempoMap tempoMap, NoteCsvConversionSettings settings) { using (var csvWriter = new CsvWriter(stream, settings.CsvDelimiter)) { foreach (var note in notes.Where(n => n != null)) { csvWriter.WriteRecord(new object[] { note.TimeAs(settings.TimeType, tempoMap), note.Channel, NoteCsvConversionUtilities.FormatNoteNumber(note.NoteNumber, settings.NoteNumberFormat), note.LengthAs(settings.NoteLengthType, tempoMap), note.Velocity, note.OffVelocity }); } } }
/// <summary> Constructs an IMidiFile instance based on a MIDI file stream.</summary> /// <param name="stream"> stream of the midi file content. </param> /// <param name="disposeStream"> Set true if stream is to be closed by the constructor once it's done reading the file. </param> internal DryWetMidiAdapter(Stream stream, bool disposeStream = false) { // initialization Stream = stream; stream.Position = 0; _midiContent = MidiFile.Read(stream); _tempoMap = _midiContent.GetTempoMap(); IList <TrackChunk> trackChunks = _midiContent.GetTrackChunks().ToList(); _metadataTrack = trackChunks.First(); _metaEvents = _metadataTrack.Events.ToList(); // set midi title property Title = (((from e in _metaEvents where e.EventType == MidiEventType.SequenceTrackName select e).First()) as BaseTextEvent)?.Text ?? "Undefined"; // set key signature property TimeSignatureEvent timeSignatureEvent = (from e in _metaEvents where e.EventType == MidiEventType.TimeSignature select e)?.First() as TimeSignatureEvent; KeySignature = MusicTheoryFactory.CreateDuration(timeSignatureEvent.Numerator, timeSignatureEvent.Denominator, false); // set number of bars property BarBeatFractionTimeSpan duration = _midiContent.GetDuration <BarBeatFractionTimeSpan>(); NumberOfBars = (int)duration.Bars + (int)Math.Ceiling(duration.Beats / timeSignatureEvent.Numerator); // set BPM property BeatsPerMinute = (byte)(_midiContent.GetTempoMap()?.Tempo.AtTime(0).BeatsPerMinute); // set MIDI pitch range IEnumerable <DWMidiI.Note> notes = _midiContent.GetNotes(); LowestPitch = (NotePitch)(byte)(notes.Min(note => note.NoteNumber)); HighestPitch = (NotePitch)(byte)(notes.Max(note => note.NoteNumber)); // dispose stream if requested if (disposeStream) { stream.Dispose(); } }
private void parseNotes(IEnumerable <Note> noteList, TempoMap tempoMap) { foreach (var note in noteList) { int nr = Int32.Parse(note.Channel.ToString()); if (nr == instrument.channel) { string name = note.NoteName.ToString(); int octave = note.Octave; MidiTime time = new MidiTime(note.Time, tempoMap); MidiTime length = new MidiTime(note.Length, tempoMap); int velocity = Int32.Parse(note.Velocity.ToString()); int velocityOff = Int32.Parse(note.OffVelocity.ToString()); int noteNr = Int32.Parse(note.NoteNumber.ToString()); MidiNote midiNote = new MidiNote(name, octave, time, length, velocity, velocityOff, noteNr); this.notes.Add(midiNote); } } }
private static void WriteRecord( StreamWriter streamWriter, int?trackNumber, long?time, string type, MidiFileCsvConversionSettings settings, TempoMap tempoMap, params object[] parameters) { var convertedTime = time == null ? null : TimeConverter.ConvertTo(time.Value, settings.TimeType, tempoMap); var processedParameters = parameters.SelectMany(ProcessParameter); streamWriter.WriteLine(CsvUtilities.MergeCsvValues( settings.CsvDelimiter, new object[] { trackNumber, convertedTime, type }.Concat(processedParameters))); }
private void Merge(IEnumerable <Note> inputNotes, IEnumerable <Note> expectedNotes, TempoMap tempoMap, VelocityMergingPolicy velocityMergingPolicy = VelocityMergingPolicy.First, VelocityMergingPolicy offVelocityMergingPolicy = VelocityMergingPolicy.Last, ITimeSpan tolerance = null) { var settings = new NotesMergingSettings { VelocityMergingPolicy = velocityMergingPolicy, OffVelocityMergingPolicy = offVelocityMergingPolicy, Tolerance = tolerance ?? new MidiTimeSpan() }; var actualNotes = new NotesMerger().Merge(inputNotes, tempoMap, settings); MidiAsserts.AreEqual( expectedNotes.OrderBy(n => n.Time), actualNotes.OrderBy(n => n.Time), "Merging detached notes failed."); // var trackChunk = inputNotes.ToTrackChunk(); trackChunk.MergeNotes(tempoMap, settings); MidiAsserts.AreEqual( expectedNotes.OrderBy(n => n.Time), trackChunk.GetNotes(), "Merging notes inside a track chunk failed."); // var midiFile = inputNotes.ToFile(); midiFile.MergeNotes(settings); MidiAsserts.AreEqual( expectedNotes.OrderBy(n => n.Time), midiFile.GetNotes(), "Merging notes inside a file failed."); }
public void OpenFile(byte[] s) { midi = MidiFile.Read(new MemoryStream(s), new ReadingSettings { NoHeaderChunkPolicy = NoHeaderChunkPolicy.Ignore, NotEnoughBytesPolicy = NotEnoughBytesPolicy.Ignore, InvalidChannelEventParameterValuePolicy = InvalidChannelEventParameterValuePolicy.ReadValid, InvalidChunkSizePolicy = InvalidChunkSizePolicy.Ignore, InvalidMetaEventParameterValuePolicy = InvalidMetaEventParameterValuePolicy.SnapToLimits, MissedEndOfTrackPolicy = MissedEndOfTrackPolicy.Ignore, UnexpectedTrackChunksCountPolicy = UnexpectedTrackChunksCountPolicy.Ignore, ExtraTrackChunkPolicy = ExtraTrackChunkPolicy.Read, UnknownChunkIdPolicy = UnknownChunkIdPolicy.ReadAsUnknownChunk, SilentNoteOnPolicy = SilentNoteOnPolicy.NoteOff, TextEncoding = Encoding.Default, InvalidSystemCommonEventParameterValuePolicy = InvalidSystemCommonEventParameterValuePolicy.SnapToLimits, }); Tmap = midi.GetTempoMap(); }
public static void UpdateBpm(MidiFile rawMidi, SongItem songItem) { if (rawMidi == null) { Debug.LogError("Cannot find the midi file"); return; } songItem.notes.Clear(); var detectedTempoMap = rawMidi.GetTempoMap(); var tempoMap = songItem.useCurrentBpmMidiImport ? TempoMap.Create(detectedTempoMap.TimeDivision, Tempo.FromBeatsPerMinute(songItem.bpm), detectedTempoMap.TimeSignature.AtTime(0)) : detectedTempoMap; if (!songItem.useCurrentBpmMidiImport) { songItem.bpm = (int)rawMidi.GetTempoMap().Tempo.AtTime(0).BeatsPerMinute; } Debug.Log($"Updating Midi Data {tempoMap.TimeDivision}, {songItem.bpm}bpm"); int count = 0; foreach (var note in rawMidi.GetNotes()) { count++; var beat = GetMetricTimeSpanTotal(note.TimeAs <MetricTimeSpan>(tempoMap)) * songItem.bpm / 60; var beatLength = GetMetricTimeSpanTotal(note.LengthAs <MetricTimeSpan>(tempoMap)) * songItem.bpm / 60; // Debug.Log(RoundToNearestBeat(beat)); songItem.notes.Add(new SongItem.MidiNote() { noteName = ParseEnum <SongItem.NoteName>(note.NoteName.ToString()), noteOctave = note.Octave, time = GetMetricTimeSpanTotal(note.TimeAs <MetricTimeSpan>(tempoMap)), noteLength = GetMetricTimeSpanTotal(note.LengthAs <MetricTimeSpan>(tempoMap)), //This two is for recalculating the currect time when the bpm is changed beatIndex = SongItem.RoundToNearestBeat(beat), beatLengthIndex = SongItem.RoundToNearestBeat(beatLength), }); } Debug.Log(count + " Note(s) detected from Midi file"); EditorUtility.SetDirty(songItem); }
private static void WriteHeader( StreamWriter streamWriter, MidiFile midiFile, MidiFileCsvConversionSettings settings, TempoMap tempoMap) { MidiFileFormat?format = null; try { format = midiFile.OriginalFormat; } catch { } var trackChunksCount = midiFile.GetTrackChunks().Count(); switch (settings.CsvLayout) { case MidiFileCsvLayout.DryWetMidi: WriteRecord(streamWriter, null, null, DryWetMidiRecordTypes.File.Header, settings, tempoMap, format, midiFile.TimeDivision.ToInt16()); break; case MidiFileCsvLayout.MidiCsv: WriteRecord(streamWriter, 0, 0, MidiCsvRecordTypes.File.Header, settings, tempoMap, format != null ? (ushort)format.Value : (trackChunksCount > 1 ? 1 : 0), trackChunksCount, midiFile.TimeDivision.ToInt16()); break; } }
public void Run() { MidiFile file = MidiFile.Read(midiPath); IEnumerable <Note> notes = file.GetNotes(); TempoMap tempoMap = file.GetTempoMap(); foreach (var note in notes) { MetricTimeSpan metricTime = note.TimeAs <MetricTimeSpan>(tempoMap); MetricTimeSpan metricLength = note.LengthAs <MetricTimeSpan>(tempoMap); } using (StreamWriter newTask = new StreamWriter(this.txtPath, false)) { foreach (var note in notes) { MetricTimeSpan metricTime = note.TimeAs <MetricTimeSpan>(tempoMap); MetricTimeSpan metricLength = note.LengthAs <MetricTimeSpan>(tempoMap); } } }
/// <summary> /// Performs additional actions before the new time will be set to an object. /// </summary> /// <remarks> /// Inside this method the new time can be changed or quantizing of an object can be cancelled. /// </remarks> /// <param name="obj">Object to quantize.</param> /// <param name="quantizedTime">Holds information about new time for an object.</param> /// <param name="grid">Grid to quantize object by.</param> /// <param name="tempoMap">Tempo map used to quantize object.</param> /// <param name="settings">Settings according to which object should be quantized.</param> /// <returns>An object indicating whether the new time should be set to the object /// or not. Also returned object contains that new time.</returns> protected override TimeProcessingInstruction OnObjectQuantizing( TObject obj, QuantizedTime quantizedTime, IGrid grid, TempoMap tempoMap, TSettings settings) { var newTime = quantizedTime.NewTime; switch (settings.QuantizingTarget) { case LengthedObjectTarget.Start: return(CorrectObjectOnStartQuantizing(obj, newTime, tempoMap, settings)); case LengthedObjectTarget.End: return(CorrectObjectOnEndQuantizing(obj, newTime, tempoMap, settings)); } return(new TimeProcessingInstruction(newTime)); }
private List <VoiceLine> GetVoices(MidiFile midiFile) { List <VoiceLine> voiceLines = new List <VoiceLine>(); TempoMap tempoMap = midiFile.GetTempoMap(); var tracks = midiFile.GetTrackChunks(); int i = 0; foreach (var track in tracks) { var notes = (List <Melanchall.DryWetMidi.Smf.Interaction.Note>)track.GetNotes(); if (notes.Count > 0) { voiceLines.Add(new VoiceLine(GetBars(notes, tempoMap), i, notes)); } i++; } return(voiceLines); }
public static Songs.Model.Song readMidi(string fileName) { var midiFile = MidiFile.Read(fileName); List <SongNote> notes = new List <SongNote>(); TempoMap tempoMap = midiFile.GetTempoMap(); foreach (var trackChunk in midiFile.GetTrackChunks()) { using (var notesManager = trackChunk.ManageNotes()) { foreach (Melanchall.DryWetMidi.Smf.Interaction.Note midiNote in notesManager.Notes) { SongNote note = new SongNote(midiNote.NoteName, midiNote.Octave, midiNote.Time / 1000f, (midiNote.Time + midiNote.Length) / 1000f); notes.Add(note); } } } return(new Songs.Model.Song(notes)); }
/// <summary> /// Initializes a new instance of the <see cref="Playback"/> with the specified /// collection of MIDI events collections, tempo map and output MIDI device to play events through. /// </summary> /// <param name="events">Collection of MIDI events collections to play.</param> /// <param name="tempoMap">Tempo map used to calculate events times.</param> /// <param name="outputDevice">Output MIDI device to play <paramref name="events"/> through.</param> /// <exception cref="ArgumentNullException"><paramref name="events"/> is null. -or- /// <paramref name="tempoMap"/> is null. -or- <paramref name="outputDevice"/> is null.</exception> public Playback(IEnumerable <IEnumerable <MidiEvent> > events, TempoMap tempoMap, OutputDevice outputDevice) { ThrowIfArgument.IsNull(nameof(events), events); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); ThrowIfArgument.IsNull(nameof(outputDevice), outputDevice); var playbackEvents = GetPlaybackEvents(events, tempoMap); _duration = playbackEvents.LastOrDefault()?.Time ?? TimeSpan.Zero; _durationInTicks = playbackEvents.LastOrDefault()?.RawTime ?? 0; _eventsEnumerator = playbackEvents.GetEnumerator(); _eventsEnumerator.MoveNext(); TempoMap = tempoMap; OutputDevice = outputDevice; _clock = new MidiClock(ClockInterval); _clock.Tick += OnClockTick; }
/// <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); } }
public void Conversion_Metric_Math_Subtract_TempoChanged() { TempoMap tempoMap = null; using (var tempoMapManager = new TempoMapManager()) { tempoMapManager.SetTempo(new MetricTime(0, 1, 5), new Tempo(20000)); tempoMapManager.SetTempo(new MetricTime(0, 1, 50), new Tempo(2400)); tempoMap = tempoMapManager.TempoMap; } var mathLength = new MathLength(new MetricLength(0, 0, 20), new MetricLength(0, 0, 50)); var mathTime = new MathTime(new MetricTime(0, 2, 0), mathLength, MathOperation.Subtract); Assert.AreEqual(TimeConverter.ConvertFrom(new MetricTime(0, 0, 50), tempoMap), TimeConverter.ConvertFrom(mathTime, tempoMap)); }
public static IEnumerable <NoteInfo> GetNotesInfo(string filePath, out TempoMap tempoMap) { var midiFile = MidiFile.Read(filePath); Debug.Log("Time div: " + midiFile.TimeDivision); tempoMap = midiFile.GetTempoMap(); var programChanges = new Dictionary <FourBitNumber, Dictionary <long, SevenBitNumber> >(); foreach (var timedEvent in midiFile.GetTimedEvents()) { var programChangeEvent = timedEvent.Event as ProgramChangeEvent; //Debug.Log("Seconds: " + timedEvent.TimeAs<MetricTimeSpan>(tempoMap).Seconds); if (programChangeEvent == null) { continue; } var channel = programChangeEvent.Channel; Dictionary <long, SevenBitNumber> changes; if (!programChanges.TryGetValue(channel, out changes)) { programChanges.Add(channel, changes = new Dictionary <long, SevenBitNumber>()); } changes[timedEvent.Time] = programChangeEvent.ProgramNumber; } // collect notes info return(midiFile.GetNotes() .Select(n => new NoteInfo { ProgramNumber = GetProgramNumber(n.Channel, n.Time, programChanges), Time = n.Time, Length = n.Length, NoteNumber = n.NoteNumber })); }
public void ResetSong() { mutex = true; paused = true; songStarted = false; if (!midiPath.Contains(".mid")) { midiPath = Application.streamingAssetsPath + "/Songs/" + midiPath + ".mid"; } MidiFile midiFile = MidiFile.Read(midiPath); tempoMap = midiFile.GetTempoMap(); notes = new List <Note>(midiFile.GetNotes()); startTime = Time.time; songTime = 0 - delay; earlySongTime = 0; noteIndex = 0; earlyNoteIndex = 0; mutex = false; }
/// <summary> /// Gets points in time of the current grid. /// </summary> /// <param name="tempoMap">Tempo map used to get grid's times.</param> /// <returns>Collection of points in time of the current grid.</returns> /// <exception cref="ArgumentNullException"><paramref name="tempoMap"/> is null.</exception> public IEnumerable <long> GetTimes(TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); if (!Steps.Any()) { yield break; } var time = TimeConverter.ConvertFrom(Start, tempoMap); yield return(time); while (true) { foreach (var step in Steps) { time += LengthConverter.ConvertFrom(step, time, tempoMap); yield return(time); } } }
private static void TestSimpleTempoMap(TempoMap tempoMap, TimeDivision expectedTimeDivision, Tempo expectedTempo, TimeSignature expectedTimeSignature) { Assert.AreEqual(expectedTimeDivision, tempoMap.TimeDivision, "Unexpected time division."); Assert.AreEqual(expectedTempo, tempoMap.Tempo.AtTime(0), "Unexpected tempo at the start of tempo map."); Assert.AreEqual(expectedTempo, tempoMap.Tempo.AtTime(1000), "Unexpected tempo at the arbitrary time of tempo map."); Assert.AreEqual(expectedTimeSignature, tempoMap.TimeSignature.AtTime(0), "Unexpected time signature at the start of tempo map."); Assert.AreEqual(expectedTimeSignature, tempoMap.TimeSignature.AtTime(1000), "Unexpected time signature at the arbitrary time of tempo map."); }
public void CreateTxt() { MidiFile file = MidiFile.Read(midiPath); IEnumerable <Note> notes = file.GetNotes(); TempoMap tempoMap = file.GetTempoMap(); foreach (var note in notes) { MetricTimeSpan metricTime = note.TimeAs <MetricTimeSpan>(tempoMap); MetricTimeSpan metricLength = note.LengthAs <MetricTimeSpan>(tempoMap); } using (StreamWriter newTask = new StreamWriter(this.txtPath, false)) { foreach (var note in notes) { MetricTimeSpan metricTime = note.TimeAs <MetricTimeSpan>(tempoMap); MetricTimeSpan metricLength = note.LengthAs <MetricTimeSpan>(tempoMap); var name = note.NoteName; var value = note.NoteNumber; newTask.WriteLine(metricTime + "," + metricLength + "," + name + "," + value); } } }
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); } }
public void SetMidiData(MidiData md) { Mfd = md; _tm = new TempoMap(Mfd); Stop(); Reset(); Eot = 0; Drumtracks = new List<int>(); if (Mfd != null) Mc = new MidiClock(120, Mfd.Resolution.Resolution); var cnt = 0; if (Mfd != null) foreach (var lst in Mfd.Tracks) { if ((lst.Channel.GetValueOrDefault() == 9) && !Drumtracks.Contains(cnt)) Drumtracks.Add(cnt); if (Eot < lst.TickLength) Eot = lst.TickLength; cnt++; } IsLoaded = true; }