/// <summary> /// Reads the event based on the <paramref name="status"/>. /// </summary> /// <param name="status">First byte of the tot event.</param> /// <returns>Returns true when successful.</returns> private bool ReadEvent(byte status) { var data = new MidiData(); if ((status & 0x80) == 0) { // copy running status from last event data.Status = MidiData.GetStatus(MidiEvent); data.Parameter1 = status; } else { data.Status = status; if (data.HasParameter1) { data.Parameter1 = SafeReadByte(); } } if (data.HasParameter2) { data.Parameter2 = SafeReadByte(); } MidiEvent = data; return(true); }
/// <summary> /// Creates a new channel (short) midi message object. /// </summary> /// <param name="command">The channel command.</param> /// <param name="channel">The (zero-based) channel number.</param> /// <param name="parameter1">The (optional) first parameter of the midi message.</param> /// <param name="parameter2">The (optional) second parameter of the midi message.</param> /// <returns>Never returns null.</returns> public MidiChannelMessage CreateChannelMessage(MidiChannelCommand command, byte channel, byte parameter1, byte parameter2) { Check.IfArgumentOutOfRange <byte>(channel, 0, 15, nameof(channel)); var data = new MidiData { Status = (byte)((int)command | channel), Parameter1 = parameter1, Parameter2 = parameter2 }; var message = (MidiChannelMessage)Lookup(data); if (message == null) { if (command == MidiChannelCommand.ControlChange) { message = new MidiControllerMessage(data); } else { message = new MidiChannelMessage(data); } Add(message); } return(message); }
private static void InitDomain() { var track = new MidiTrack(); track.Insert(new TempoEvent() { Tempo = 120, Tick = 0 }); for (int i = 0; i < time.Length; i++) { byte note = 60; if (i > 2 && i % 4 == 1) { note = 67; } if (i > 2 && i % 4 == 2) { note = 64; } track.Insert(new NoteEvent() { Note = note, Tick = time[i], Gate = resolution, Velocity = 64 }); } //midiDataにtrackを対応付け midiData = new MidiData(); midiData.Tracks.Add(track); midiData.Resolution.Resolution = resolution; // テンポマップを作成 domain = new MidiFileDomain(midiData); SetTime(); }
/// <summary> /// Creates a new short midi message object. /// </summary> /// <param name="message">A full short midi message with the lower 3 bytes filled.</param> /// <returns>Never returns null.</returns> public MidiShortMessage CreateShortMessage(int message) { MidiShortMessage result = Lookup(message); if (result == null) { int statusChannel = MidiData.GetStatus(message); byte status = (byte)(statusChannel & (byte)0xF0); if (status == 0xF0) { if (statusChannel >= 0xF8) { result = new MidiSysRealtimeMessage(message); } else { result = new MidiSysCommonMessage(message); } } else if (status == (byte)MidiChannelCommand.ControlChange) { result = new MidiControllerMessage(message); } else { result = new MidiChannelMessage(message); } Add(result); } return(result); }
private void OnMidiData(MidiData data) { foreach (var mapping in midiSettingUseCase.GetCurrent().Item2) { if (data.Number != mapping.MidiNumber) { continue; } switch (mapping.MidiSendType) { case MidiSendType.Bypass: SendThrough(data, mapping); break; case MidiSendType.OnOnly: SendOnOnly(data, mapping); break; default: throw new ArgumentOutOfRangeException(); } mapping.prevValue = data.Value; } }
private void SendOnOnly(MidiData data, MidiMappingSettingViewModel mapping) { if (mapping.prevValue > 127 / 2f) { return; } if (data.Value <= 127 / 2f) { return; } var endPoints = endPointSettingUseCase.GetCurrent(); foreach (var endPoint in endPoints) { if (!endPoint.ConnectionEnabled) { continue; } sendToEndpointUseCase.Send(endPoint.EndPoint, mapping.OscAddressConversion, data.Value.ToString(), CommandType.Osc); } }
public void ParseMidiSong(byte[] midiSong, SongDataModel songModel) { //read midi file var data = new MidiData(); MidiParser.ParseNotesData(midiSong, ref data); LevelDataModel lv = new LevelDataModel(); lv.noteData = data.notesData[NoteTrack]; lv.playbackData = data.notesData[PlaybackTrack]; lv.playbackData.Sort((x, y) => (x.timeAppear.CompareTo(y.timeAppear))); lv.noteData.Sort((x, y) => (x.timeAppear.CompareTo(y.timeAppear))); lv.BPM = data.beatsPerMinute; lv.denominator = data.denominator; lv.tickPerQuarterNote = (int)data.deltaTickPerQuarterNote; var ticksPerTile = songModel.tickPerTile; var minTickPerTile = Mathf.FloorToInt(ticksPerTile * (1 - tickTolerance)); var maxTickPerTile = Mathf.CeilToInt(ticksPerTile * (1 + tickTolerance)); StartCoroutine(PrepareTileData(lv, minTickPerTile, maxTickPerTile, songModel)); }
/// <summary> /// Writes a midi (short) event to the stream. /// </summary> /// <param name="deltaTime">Must be greater or equal to zero.</param> /// <param name="data">The midi short event data.</param> public void WriteMidiEvent(long deltaTime, int data) { Check.IfArgumentOutOfRange(deltaTime, 0, uint.MaxValue, "deltaTime"); var midiData = new MidiData(data); var status = midiData.Status; this.WriteVariableLength((uint)deltaTime); // running status if (status != this.lastStatus) { this.lastStatus = status; this.writer.Write((byte)status); } if (midiData.HasParameter1) { this.writer.Write(midiData.Parameter1); if (midiData.HasParameter2) { this.writer.Write(midiData.Parameter2); } } }
/// <summary> /// Creates a new channel (short) midi message object. /// </summary> /// <param name="command">The channel command.</param> /// <param name="channel">The (zero-based) channel number.</param> /// <param name="parameter1">The (optional) first parameter of the midi message.</param> /// <param name="parameter2">The (optional) second parameter of the midi message.</param> /// <returns>Never returns null.</returns> public MidiChannelMessage CreateChannelMessage(MidiChannelCommand command, byte channel, byte parameter1, byte parameter2) { Contract.Requires(channel >= 0 && channel <= 15); Contract.Ensures(Contract.Result <MidiChannelMessage>() != null); Check.IfArgumentOutOfRange <byte>(channel, 0, 15, "channel"); MidiData data = new MidiData(); data.Status = (byte)((int)command | channel); data.Parameter1 = parameter1; data.Parameter2 = parameter2; MidiChannelMessage message = (MidiChannelMessage)this.Lookup(data); if (message == null) { if (command == MidiChannelCommand.ControlChange) { message = new MidiControllerMessage(data); } else { message = new MidiChannelMessage(data); } this.Add(message); } return(message); }
/// <summary> /// MIDIの初期化 /// </summary> /// <param name="portnum"></param> public MidiManager() { int NumOfMode = ModeList.Length; //モードの数だけトラック配列の要素数を用意する tracks = new MidiTrack[NumOfMode]; //モードの数だけコード進行配列の要素数を用意する chordProgList = new List <Chord> [NumOfMode]; //コード進行配列の初期化 for (int i = 0; i < NumOfMode; i++) { tracks[i] = new MidiTrack(); chordProgList[i] = new List <Chord>(); } //Modeの数だけコード進行配列の初期化 for (int mode = 0; mode < NumOfMode; mode++) { tracks[mode].Insert(new TempoEvent() { Tempo = 120, Tick = 0 }); //コードの開始位置を0に初期化 int ChordTickFromStart = 0; //入力コード進行(chordProgress)からコード進行リストを初期化する foreach (String chordName in inputedChord) { //Chordの初期化 Chord chord = new Chord(chordName, ChordTickFromStart, mode); //Chordをインスタンス化 chordProgList[mode].Add(chord); //Modeに対応するインデックスのコード進行配列chordを追加 ChordTickFromStart += chord.Gate; //次のchordの開始タイミングにする //Trackの初期化 tracks[mode].Insert(chord.Base); //ベース音の挿入 foreach (var note in chord.NoteList) { tracks[mode].Insert(note); //伴奏音の挿入 } } } port = new MidiOutPort(0); try { port.Open(); } catch { Console.WriteLine("no such port exists"); return; } //midiDataにtrackを対応付け midiData = new MidiData(); midiData.Tracks.Add(tracks[MODE_QUARTER]); // テンポマップを作成 domain = new MidiFileDomain(midiData); }
public void Status_Param2Set_DoesNotOverwrite() { var eventData = new MidiData(Value32); eventData.Parameter1 = Param2Value; Assert.AreEqual(StatusValue, eventData.Status); }
public void Param2_StatusSet_DoesNotOverwrite() { var eventData = new MidiData(Value32); eventData.Status = StatusValue; Assert.AreEqual(Param2Value, eventData.Parameter2); }
public void Param1_Param2Set_DoesNotOverwrite() { var eventData = new MidiData(Value32); eventData.Parameter2 = Param2Value; Assert.AreEqual(Param1Value, eventData.Parameter1); }
public ParseScore(string fileName, uint tempo, bool debug = false) { Debug = debug; MidiFile = new MidiData(tempo, debug); Sequence = new Sequence(); ProcessFile(fileName); }
public static void InitAccompanimentDomain() { var track = new MidiTrack(); track.Insert(new TempoEvent() { Tempo = 120, Tick = 0 }); for (int i = 0; i < 5; i++) { byte note = 60; track.Insert(new NoteEvent() { Note = note, Tick = BGMtime[i], Gate = resolution, Velocity = 64, Channel = 0 }); } for (int i = 5; i < BGMtime.Length; i++) { int byteIndex = (i - 5) / 4; foreach (byte note in Chord.MidiNumber[byteIndex]) { track.Insert(new NoteEvent() { Note = note, Tick = BGMtime[i], Gate = resolution, Velocity = 64, Channel = 0 }); } } for (int i = 0; i < Chord.NoteList.Length; i++) { int length = Chord.MidiNumber[i].Length * 3; Chord.NoteList[i] = new byte[length]; for (int j = 0; j < 3; j++) { Chord.NoteList[i][j] = (byte)(Chord.MidiNumber[i][j] - 12); Chord.NoteList[i][j + 3] = Chord.MidiNumber[i][j]; Chord.NoteList[i][j + 6] = (byte)(Chord.MidiNumber[i][j] + 12); } } foreach (var notes in Chord.NoteList) { for (int i = 0; i < notes.Length; i++) { Console.Write(notes[i] + ", "); } Console.WriteLine(); } //midiDataにtrackを対応付け BGMmidiData = new MidiData(); BGMmidiData.Tracks.Add(track); BGMmidiData.Resolution.Resolution = resolution; // テンポマップを作成 BGMdomain = new MidiFileDomain(BGMmidiData); }
public void LoadSong(byte[] midiData) { data = new MidiData(); if (midiData == null) { return; } MidiParser.ParseNotesData(midiData, ref data); notesData = data.notesData[0]; BuildNoteData(); }
public void ShortData(int data, long timestamp) { MidiData curData = new MidiData(data); byte[] cmd = { curData.Status, curData.Parameter1, curData.Parameter2 }; try { mahPort.sendCommand(cmd); } catch (Exception) { } }
private void sendTest() { var channel = (byte)(0 | 1 | 2); var noteOn = (byte)(NoteOn | channel); var eventData = new MidiData(noteOn); eventData.Parameter1 = 127 / 2; eventData.Parameter2 = 127; var note1 = eventData.Data; _outPort.ShortData(eventData.Data); }
/// <summary> /// Constructs a new instance on the specified message <paramref name="data"/>. /// </summary> /// <param name="data">Only the least significant byte is set.</param> public MidiSysRealtimeMessage(int data) { Data = MidiData.GetData8(data); ByteLength = 1; if (Enum.IsDefined(typeof(MidiSysRealtimeTypes), Data)) { RealtimeType = (MidiSysRealtimeTypes)Enum.ToObject(typeof(MidiSysRealtimeTypes), Data); } else { RealtimeType = MidiSysRealtimeTypes.Invalid; } }
/// <summary> /// Constructs a new instance on the specified message <paramref name="data"/>. /// </summary> /// <param name="data">Only the least significant byte is set.</param> public MidiSysCommonMessage(int data) { Data = MidiData.GetData8(data); ByteLength = 1; if (Enum.IsDefined(typeof(MidiSysCommonType), Data)) { this.CommonType = (MidiSysCommonType)Enum.ToObject(typeof(MidiSysCommonType), Data); } else { this.CommonType = MidiSysCommonType.Invalid; } }
static MidiData ReadMidiFile(Stream midiStream) { MidiData midiData = new MidiData(); Sequence midiSequence = new Sequence(midiStream); midiData.length = 4 * midiSequence.GetLength() / midiSequence.Division; foreach (Sanford.Multimedia.Midi.Track midiTrack in midiSequence) { ReadMidiTrack(midiData, midiTrack, midiSequence.Division); } return(midiData); }
private void SaveButton_Click(object sender, RoutedEventArgs e) { MakeLyric(TargetTrack, Measures); SaveFileDialog fileDialog = new SaveFileDialog { Filter = "MIDIファイル|*.mid", InitialDirectory = Path.GetDirectoryName(MidiFileName), FileName = Path.GetFileName(MidiFileName), }; bool dialogResult = fileDialog.ShowDialog(this) ?? false; //戻り値がnullの場合、falseを代入 if (dialogResult) { MidiData?.SaveAsSMF(fileDialog.FileName); //nullなら実行されない } }
/// <summary> /// This will send the short midi message to the next sender chain component. /// </summary> /// <param name="data">The sort midi message.</param> /// <remarks>If the status of this midi message is the same as the previous, /// the status is removed from the <paramref name="data"/>.</remarks> public void ShortData(int data) { if (EnableRunningStatus) { MidiData eventData = new MidiData(data); if (eventData.Status == RunningStatus) { data = eventData.RunningStatusData; } else { RunningStatus = eventData.Status; } } NextSenderShortData(data); }
/// <summary> /// Constructs a new instance for the specified <paramref name="data"/>. /// </summary> /// <param name="data">Lower/least significant (max) 3 bytes are filled.</param> public MidiChannelMessage(int data) { Data = MidiData.GetData24(data); if ((Status & 0xF0) == 0xF0) { throw new ArgumentException("Status MSB of data is not MidiChannelCommand.", nameof(data)); } if (Command == MidiChannelCommand.ChannelPressure || Command == MidiChannelCommand.ProgramChange) { ByteLength = 2; } else { ByteLength = 3; } }
private void clearOtherMIDIout() { lock (outLock) { if (outPort.IsOpen) { MidiData midiData = new MidiData(); midiData.Parameter2 = 0; for (int i = 0; i < 16; i++) { midiData.Status = (byte)(0xB0 | i); midiData.Parameter1 = 121; outPort.ShortData(midiData); midiData.Parameter1 = 123; outPort.ShortData(midiData); } } } }
private void readInput() { MidiData midiData = new MidiData(); try { while (true) { byte[] command = mahPort.getCommand(); if (Monitor.TryEnter(outLock)) { try { if (outPort.IsOpen) { if (command.Length == 3) { midiData.Status = command[0]; midiData.Parameter1 = command[1]; midiData.Parameter2 = command[2]; outPort.ShortData(midiData); } else if (command.Length == 2) { midiData.Status = command[0]; midiData.Parameter1 = command[1]; midiData.Parameter2 = 0; //unused outPort.ShortData(midiData); } } } finally { Monitor.Exit(outLock); } } } } catch (TeVirtualMIDIException) { clearOtherMIDIout(); } }
static void ReadMidiTrack(MidiData midiData, Sanford.Multimedia.Midi.Track midiTrack, int sequencerDivision) { Dictionary <int, float> noteTimes = new Dictionary <int, float>(); Dictionary <int, float> noteVelocities = new Dictionary <int, float>(); for (int i = 0; i < midiTrack.Count; ++i) { MidiEvent midiEvent = midiTrack.GetMidiEvent(i); if (midiEvent.MidiMessage.GetBytes().Length < 3) { continue; } byte midiType = (byte)(midiEvent.MidiMessage.GetBytes()[0] & 0xFF); byte note = (byte)(midiEvent.MidiMessage.GetBytes()[1] & 0xFF); byte velocity = (byte)(midiEvent.MidiMessage.GetBytes()[2] & 0xFF); float time = (4.0f * midiEvent.AbsoluteTicks) / sequencerDivision; if (midiType == (byte)ChannelCommand.NoteOff || (midiType == (byte)ChannelCommand.NoteOn) && velocity == 0) { if (noteTimes.ContainsKey(note)) { Note noteObject = new Note(); noteObject.note = note; noteObject.start = noteTimes[note]; noteObject.end = time; noteObject.velocity = noteVelocities[note]; midiData.notes.Add(noteObject); noteTimes.Remove(note); noteVelocities.Remove(note); } } else if (midiType == (byte)ChannelCommand.NoteOn) { noteTimes[note] = time; noteVelocities[note] = Mathf.Min(1.0f, velocity / 127.0f); } } }
/// <summary> /// Creates a new midi controller message object. /// </summary> /// <param name="channel">The (zero-based) midi channel number.</param> /// <param name="controller">The type of continuous controller.</param> /// <param name="value">The (optional) parameter (usually value) of the controller.</param> /// <returns>Returns a new instance.</returns> public MidiControllerMessage CreateControllerMessage(byte channel, MidiControllerType controller, byte value) { Check.IfArgumentOutOfRange <byte>(channel, 0, 15, nameof(channel)); var data = new MidiData { Status = (byte)((int)MidiChannelCommand.ControlChange | channel), Parameter1 = (byte)controller, Parameter2 = value }; var message = (MidiControllerMessage)Lookup(data); if (message == null) { message = new MidiControllerMessage(data); Add(message); } return(message); }
// Use this for initialization void Start() { Arduino.global.Setup(ConfigurePins); foreach (RelayBlender rb in blenders) { noteToBlender.Add(rb.note, rb); } //load a midi FileStream file = System.IO.File.OpenRead(Application.dataPath + "/midi_test.mid"); MidiData midiData = FileParser.parse(file); print(midiData.header.time_division); foreach (Midi.Chunks.TrackChunk tc in midiData.tracks) { midiEvents = new List <Midi.Events.MidiEvent>(tc.events); break; } }
/// <summary> /// Creates a new midi controller message object. /// </summary> /// <param name="channel">The (zero-based) midi channel number.</param> /// <param name="controller">The type of continuous controller.</param> /// <param name="value">The (optional) parameter (usually value) of the controller.</param> /// <returns>Returns a new instance.</returns> public MidiControllerMessage CreateControllerMessage(byte channel, MidiControllerType controller, byte value) { Contract.Ensures(Contract.Result <MidiControllerMessage>() != null); Check.IfArgumentOutOfRange <byte>(channel, 0, 15, "channel"); MidiData data = new MidiData(); data.Status = (byte)((int)MidiChannelCommand.ControlChange | channel); data.Parameter1 = (byte)controller; data.Parameter2 = value; MidiControllerMessage message = (MidiControllerMessage)this.Lookup(data); if (message == null) { message = new MidiControllerMessage(data); this.Add(message); } return(message); }
public void ShortData(int data, long timestamp) { MidiData curData = new MidiData(data); byte[] cmd = { curData.Status, curData.Parameter1, curData.Parameter2 }; try { mahPort.sendCommand(cmd); } catch(Exception) { } }
public void Play(MidiData midiData) { State = MidiPlayerState.Paused; while (thread != null && thread.IsAlive) ; this.midiData = midiData; Position = 0; TempoModifier = 0; Play(); NotifyPropertyChanged(nameof(Length)); NotifyPropertyChanged(nameof(Channels)); NotifyPropertyChanged(nameof(TempoModifier)); }
private void playN(int N) { var midiData = new MidiData(); midiData.Status = 0x90; // note-on for channel 1 midiData.Parameter1 = (byte)note[N - 1]; // note number midiData.Parameter2 = 100; // velocity midiOut.ShortData(midiData); }
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; }
public Sequencer(MidiData md) : this() { SetMidiData(md); }