public static MIDIMessage newUsing(int cs, int c, int n, int v) { MIDIMessage m = new MIDIMessage(); m.createNote(cs, c, n, v); return(m); }
private static int ConvertHMPToMIDI(ProgramCall prog) { if (prog.HmqMode != FMMode.None) { PrintHelp(); return(2); } MIDISequence midi; try { midi = MIDISequence.LoadHMP(ReadFile(prog.SourceFile)); } catch (Exception ex) { Console.Error.WriteLine("Could not load HMP!"); Console.Error.WriteLine(ex.ToString()); return(2); } midi.Convert(MIDIFormat.Type1); midi.PulsesPerQuarter = 60; midi.AdjustPPQ(480); if (prog.Flags.HasFlag(ProgramFlags.FaithfulConversionToMIDI)) { // add track volume 0 to all tracks without them // (this is how the original SOS engine works) foreach (MIDITrack trk in midi.Tracks) { IEnumerable <MIDIMessage> messages = trk.GetAllEvents().Select(e => e.Data); if (!messages.OfType <MIDIControlChangeMessage>().Where(m => m.Controller == MIDIControl.ChannelVolumeMSB).Any()) { MIDIMessage chm = messages.Where(m => !m.IsExtendedEvent).FirstOrDefault(); if (chm != null) { trk.AddEvent(new MIDIEvent(0, new MIDIControlChangeMessage(chm.Channel, MIDIControl.ChannelVolumeMSB, 0)), true); } } } } try { if (!Overwrite(prog.Flags, prog.TargetFile)) { return(0); } WriteFile(midi, prog.TargetFile); } catch (Exception ex) { Console.Error.WriteLine("Could not save MIDI!"); Console.Error.WriteLine(ex.ToString()); return(2); } Console.Out.WriteLine("Successfully converted and saved MIDI file"); return(0); }
/// <summary> /// Stops all notes currently being played, on all channels. /// </summary> private void StopAllNotes() { MIDIMessage mst = new MIDIMessage(); mst.Status = MessageType.ControlChange; mst.ControlType = ControlChangeType.AllNotesOff; midiOut.Send(mst); }
/// <summary> /// Changes the volume of the current channel. /// </summary> /// <param name="newVolume">The volume to adjust the channel to.</param> private void ChangeVolume(int newVolume) { MIDIMessage mst = new MIDIMessage(); mst.Channel = channelID; mst.Status = MessageType.ControlChange; mst.ControlType = ControlChangeType.ChannelVolume; mst.ControlValue = Utility.Clamp(newVolume, Constants.Volume.MinValue, Constants.Volume.MaxValue);; SendEvent(mst); }
/// <summary> /// Changes the pan (location of sound between left and right speakers). /// </summary> /// <param name="newPan">The pan value (0-127 inclusive).</param> private void ChangePan(int newPan) { MIDIMessage mst = new MIDIMessage(); mst.Status = MessageType.ControlChange; mst.Channel = channelID; mst.ControlType = ControlChangeType.Pan; mst.ControlValue = Utility.Clamp(newPan, Constants.Pan.MinValue, Constants.Pan.MaxValue); SendEvent(mst); }
void sendMidi(MIDIMessage message, Bundle rinfo) { // Log.d("MIDIPort","sendMidi(message)"); if (!isListening) { Log.d(TAG, "not listening..."); return; } addToOutboundQueue(message.generateBuffer(), rinfo); }
public void Close() { MIDIMessage ms = new MIDIMessage(); ms.ControlType = ControlChangeType.AllNotesOff; midiOut.Send(ms.RawData); midiOut.Close(); for (int i = 0; i < Config.Channel.Count; i++) { mixer.Gate(i, false); } waveOut.Stop(); }
public void Send(MIDIMessage message) { if (noteMode[message.Channel] == NoteStyle.Regular || noteMode[message.Channel] == NoteStyle.Drums) { if (noteMode[message.Channel] == NoteStyle.Drums) { message.Channel = 9; } midiOut.Send(message.RawData); } else { switch (message.Status) { case MessageType.NoteOn: { mixer.SetFrequency(message.Channel, frequencyTable[message.Data1]); mixer.SetVelocity(message.Channel, message.Data2 / 127.0f); mixer.Gate(message.Channel, true); } break; case MessageType.NoteOff: { mixer.Gate(message.Channel, false); } break; case MessageType.ControlChange: { switch (message.ControlType) { case ControlChangeType.ChannelVolume: { float adjustedAmplitude = message.ControlValue / 127.0f; mixer.SetAmplitude(message.Channel, adjustedAmplitude); } break; default: break; } } break; } } }
/// <summary> /// Enables a vibrato effect (pitch fluctuation). /// </summary> /// <param name="depth">The depth of the vibrato.</param> /// <param name="range">The effective range over which the vibrato varies.</param> /// <param name="speed">The speed of the variance in the vibrato.</param> /// <param name="delay">The delay of the start of the vibrato.</param> private void EnableVibrato(int depth, int range, int speed, int delay) { // TODO: Not sure how to handle sustain level just yet. MIDIMessage message = new MIDIMessage(); message.Channel = channelID; message.Status = MessageType.ControlChange; message.ControlType = ControlChangeType.SoundController08; // Vibrato Depth message.ControlValue = depth & 0xFF; SendEvent(message); message.ControlType = ControlChangeType.SoundController07; // Vibrato Rate message.ControlValue = range & 0xFF; SendEvent(message); message.ControlType = ControlChangeType.SoundController09; // Vibrato Delay message.ControlValue = delay & 0xFF; SendEvent(message); }
/// <summary> /// Changes the instrument on the specified channel. /// </summary> /// <param name="newInstrument">The instrument to change to.</param> private void ChangeInstrument(int newInstrument) { // Note: These instrument ranges map to the same thing: // 144-151 (7 square waves plus one noise) // 152-159 // 160-167 // 168-175 instrument = newInstrument; if (instrument < 128) { ChangeNoteStyle(channelID, NoteStyle.Regular); noteStyle = NoteStyle.Regular; MIDIMessage mst = new MIDIMessage(); mst.Channel = channelID; mst.Status = MessageType.ProgramChange; mst.Data1 = instrument; SendEvent(mst); } else if (instrument > 143 & instrument < 176) { while (instrument > 151) { instrument -= 8; } if (instrument == 151) { ChangeNoteStyle(channelID, NoteStyle.Noise); noteStyle = NoteStyle.Noise; } else { ChangeNoteStyle(channelID, NoteStyle.PSG); noteStyle = NoteStyle.PSG; ChangeDuty(channelID, .125f * (instrument - 143)); } } else { ChangeNoteStyle(channelID, NoteStyle.Drums); noteStyle = NoteStyle.Drums; } }
private void MidiOutProc(IntPtr handle, MIDIMessage msg, IntPtr user, IntPtr param1, IntPtr param2) { if (msg == MIDIMessage.MOM_OPEN) { this.RaiseMessageReceived(MidiMessageEventType.Opened, null); return; } if (msg == MIDIMessage.MOM_CLOSE) { this.RaiseMessageReceived(MidiMessageEventType.Closed, null); return; } if (msg == MIDIMessage.MOM_DONE) { this._sysexMsg = new MidiSysExMessage(false, handle, param1, this._sysexMsg); if (this._sysexMsg.IsDone) { this.RaiseMessageReceived(MidiMessageEventType.SystemExclusiveDone, this._sysexMsg); } } }
/// <summary> /// Stops a note. /// </summary> /// <param name="baseNote">The base note value.</param> /// <param name="forcePSG">If true, force the note being stopped to be a PSG note.</param> private void StopNote(int baseNote, bool forcePSG = false) { isNoteBeingPlayed = false; MIDIMessage message = new MIDIMessage(); message.Status = MessageType.NoteOn; message.Data1 = baseNote; message.Data2 = 0; message.Channel = channelID; if (noteStyle == NoteStyle.Drums) { if (message.Data1 < 0x23) { message.Data1 = 0x23; } else if (message.Data1 > 0x51) { message.Data1 = 0x51; } } SendEvent(message); }
public void EnableEnvelope(int channel, int attack, int decay, int sustain, int release) { if (noteMode[channel] == NoteStyle.Regular || noteMode[channel] == NoteStyle.Drums) { // TODO: Not sure how to handle sustain level just yet. MIDIMessage message = new MIDIMessage(); message.Channel = channel; message.Status = MessageType.ControlChange; message.ControlType = ControlChangeType.SoundController04; // Attack message.ControlValue = attack; midiOut.Send(message.RawData); message.ControlType = ControlChangeType.SoundController06; // Decay message.ControlValue = decay; midiOut.Send(message.RawData); message.ControlType = ControlChangeType.SoundController03; // Release message.ControlValue = release; midiOut.Send(message.RawData); } else { mixer.SetEnvelope(channel, attack, decay, sustain, release); } }
/// <summary> /// Stops all notes currently being played, on all channels. /// </summary> private void StopAllNotes() { MIDIMessage mst = new MIDIMessage(); mst.Status = MessageType.ControlChange; mst.ControlType = ControlChangeType.AllNotesOff; this.midiOut.Send(mst); }
private void MidiInProc(IntPtr handle, MIDIMessage msg, IntPtr user, IntPtr param1, IntPtr param2) { if (msg == MIDIMessage.MIM_OPEN) { this.RaiseMessageReceived(MidiMessageEventType.Opened, null); return; } if (msg == MIDIMessage.MIM_CLOSE) { this.FlushShortMsgStack(); this.RaiseMessageReceived(MidiMessageEventType.Closed, null); return; } if (msg == MIDIMessage.MIM_DATA || msg == MIDIMessage.MIM_MOREDATA) { this._shortMsg = new MidiShortMessage(param1, param2, this._shortMsg); if ((this._shortMsg.MessageType & this.MessageFilter) == MIDIMessageType.Unknown) { this._pairedResult = this.IsPairedControllerMessage(this._shortMsg); if (this._pairedResult == 0) { this.FlushShortMsgStack(); this.RaiseMessageReceived(MidiMessageEventType.ShortMessage, this._shortMsg); return; } if (this._pairedResult == -1) { this._shortMsgOnStack = this._shortMsg; return; } this._shortMsgOnStack = null; this.RaiseMessageReceived(MidiMessageEventType.ShortMessage, this._shortMsg); return; } } else { if (msg == MIDIMessage.MIM_LONGDATA) { this.FlushShortMsgStack(); this._sysexMsg = new MidiSysExMessage(true, handle, param1, this._sysexMsg); if (this._sysexMsg.IsDone && (this._sysexMsg.MessageType & this.MessageFilter) == MIDIMessageType.Unknown) { this.RaiseMessageReceived(MidiMessageEventType.SystemExclusive, this._sysexMsg); } this.AddSysExBuffer(); return; } if (msg == MIDIMessage.MIM_ERROR) { this.FlushShortMsgStack(); if (this.ProcessErrorMessages) { MidiShortMessage midiShortMessage = new MidiShortMessage(param1, param2); if ((midiShortMessage.MessageType & this.MessageFilter) == MIDIMessageType.Unknown) { this.RaiseMessageReceived(MidiMessageEventType.ShortMessageError, midiShortMessage); return; } } } else if (msg == MIDIMessage.MIM_LONGERROR) { this.FlushShortMsgStack(); MidiSysExMessage midiSysExMessage = new MidiSysExMessage(true, handle, param1); if (midiSysExMessage.IsDone && this.ProcessErrorMessages && (midiSysExMessage.MessageType & this.MessageFilter) == MIDIMessageType.Unknown) { this.RaiseMessageReceived(MidiMessageEventType.SystemExclusiveError, midiSysExMessage); } this.AddSysExBuffer(); } } }
/// <summary> /// Changes the instrument on the specified channel. /// </summary> /// <param name="newInstrument">The instrument to change to.</param> private void ChangeInstrument(int newInstrument) { // Note: These instrument ranges map to the same thing: // 144-151 (7 square waves plus one noise) // 152-159 // 160-167 // 168-175 this.instrument = newInstrument; if (this.instrument < 128) { ChangeNoteStyle(this.channelID, NoteStyle.Regular); noteStyle = NoteStyle.Regular; MIDIMessage mst = new MIDIMessage(); mst.Channel = channelID; mst.Status = MessageType.ProgramChange; mst.Data1 = this.instrument; SendEvent(mst); } else if (this.instrument > 143 & this.instrument < 176) { while (this.instrument > 151) { this.instrument -= 8; } if (this.instrument == 151) { ChangeNoteStyle(this.channelID, NoteStyle.Noise); noteStyle = NoteStyle.Noise; } else { ChangeNoteStyle(this.channelID, NoteStyle.PSG); noteStyle = NoteStyle.PSG; ChangeDuty(this.channelID, .125f * (this.instrument - 143)); } } else { ChangeNoteStyle(this.channelID, NoteStyle.Drums); noteStyle = NoteStyle.Drums; } }
/// <summary> /// Stops a note. /// </summary> /// <param name="baseNote">The base note value.</param> /// <param name="forcePSG">If true, force the note being stopped to be a PSG note.</param> private void StopNote(int baseNote, bool forcePSG = false) { this.isNoteBeingPlayed = false; MIDIMessage message = new MIDIMessage(); message.Status = MessageType.NoteOn; message.Data1 = baseNote; message.Data2 = 0; message.Channel = channelID; if (this.noteStyle == NoteStyle.Drums) { if (message.Data1 < 0x23) { message.Data1 = 0x23; } else if (message.Data1 > 0x51) { message.Data1 = 0x51; } } SendEvent(message); }
private static extern int midiOutMessage(IntPtr handle, MIDIMessage msg, IntPtr param1, IntPtr param2);
public void Send(MIDIMessage message) { if (noteMode[message.Channel] == NoteStyle.Regular || noteMode[message.Channel] == NoteStyle.Drums) { if (noteMode[message.Channel] == NoteStyle.Drums) { message.Channel = 9; } this.midiOut.Send(message.RawData); } else { switch (message.Status) { case MessageType.NoteOn: { this.mixer.SetFrequency(message.Channel, this.frequencyTable[message.Data1]); this.mixer.SetVelocity(message.Channel, message.Data2 / 127.0f); this.mixer.Gate(message.Channel, true); } break; case MessageType.NoteOff: { this.mixer.Gate(message.Channel, false); } break; case MessageType.ControlChange: { switch (message.ControlType) { case ControlChangeType.ChannelVolume: { float adjustedAmplitude = message.ControlValue / 127.0f; mixer.SetAmplitude(message.Channel, adjustedAmplitude); } break; default: break; } } break; } } }
public void EnableEnvelope(int channel, int attack, int decay, int sustain, int release) { if (noteMode[channel] == NoteStyle.Regular || noteMode[channel] == NoteStyle.Drums) { // TODO: Not sure how to handle sustain level just yet. MIDIMessage message = new MIDIMessage(); message.Channel = channel; message.Status = MessageType.ControlChange; message.ControlType = ControlChangeType.SoundController04; // Attack message.ControlValue = attack; this.midiOut.Send(message.RawData); message.ControlType = ControlChangeType.SoundController06; // Decay message.ControlValue = decay; this.midiOut.Send(message.RawData); message.ControlType = ControlChangeType.SoundController03; // Release message.ControlValue = release; this.midiOut.Send(message.RawData); } else { this.mixer.SetEnvelope(channel, attack, decay, sustain, release); } }
/// <summary> /// Changes the pan (location of sound between left and right speakers). /// </summary> /// <param name="pan">The pan value (0-127 inclusive).</param> private void ChangePan(int pan) { MIDIMessage mst = new MIDIMessage(); mst.Status = MessageType.ControlChange; mst.Channel = channelID; mst.ControlType = ControlChangeType.Pan; mst.ControlValue = pan; SendEvent(mst); }
private static int ConvertMIDIToHMP(ProgramCall prog) { MIDISequence midi; try { midi = MIDISequence.LoadMIDI(ReadFile(prog.SourceFile)); } catch (Exception ex) { Console.Error.WriteLine("Could not load MIDI!"); Console.Error.WriteLine(ex.ToString()); return(2); } midi.Convert(MIDIFormat.HMI); // ============================== // clean up MIDI sequence for HMP // ============================== // remove tempo changes but hard-apply them onto the track midi.NormalizeTempo(); // set PPQ to 60 and adjust timings midi.AdjustPPQ(60); // add track volume messages to tracks that don't have them, otherwise they get muted foreach (MIDITrack trk in midi.Tracks) { IEnumerable <MIDIMessage> messages = trk.GetAllEvents().Select(e => e.Data); if (!messages.OfType <MIDIControlChangeMessage>().Where(m => m.Controller == MIDIControl.ChannelVolumeMSB).Any()) { MIDIMessage chm = messages.Where(m => !m.IsExtendedEvent).FirstOrDefault(); if (chm != null) { trk.AddEvent(new MIDIEvent(0, new MIDIControlChangeMessage(chm.Channel, MIDIControl.ChannelVolumeMSB, 127)), true); } } } // remove SysEx and meta events, as well as forbidden control change events foreach (MIDITrack trk in midi.Tracks) { trk.RemoveMessages(m => m.IsExtendedEvent || m is MIDIControlChangeMessage cm && forbiddenControls.Contains(cm.Controller)); } try { if (!Overwrite(prog.Flags, prog.TargetFile)) { return(0); } WriteFile(midi, prog.TargetFile); } catch (Exception ex) { Console.Error.WriteLine("Could not save HMP!"); Console.Error.WriteLine(ex.ToString()); return(2); } if (prog.HmqMode != FMMode.None) { string outHmq = Path.ChangeExtension(prog.TargetFile, ".hmq"); Console.WriteLine("Preparing HMQ for"); Console.Write(" "); switch (prog.HmqMode) { case FMMode.Melodic: Console.Write("MELODIC.BNK DRUM.BNK"); midi.RemapProgram(programMapMelodic); break; case FMMode.Intmelo: Console.Write("INTMELO.BNK INTDRUM.BNK"); midi.RemapProgram(programMapIntmelo); break; case FMMode.Hammelo: Console.Write("HAMMELO.BNK HAMDRUM.BNK"); midi.RemapProgram(programMapHammelo); break; case FMMode.Rickmelo: Console.Write("RICKMELO.BNK RICKDRUM.BNK"); midi.RemapProgram(programMapRickmelo); break; case FMMode.D2melod: Console.Write("D2MELOD.BNK D2DRUMS.BNK"); midi.RemapProgram(programMapD2melod); break; } Console.WriteLine(""); try { if (!Overwrite(prog.Flags, outHmq)) { return(0); } WriteFile(midi, outHmq); } catch (Exception ex) { Console.Error.WriteLine("Could not save HMQ!"); Console.Error.WriteLine(ex.ToString()); return(2); } } Console.Out.WriteLine("Successfully converted and saved HMP file(s)"); return(0); }
/// <summary> /// Changes the volume of the current channel. /// </summary> /// <param name="newVolume">The volume to adjust the channel to.</param> private void ChangeVolume(int newVolume) { if (newVolume < 0) { newVolume = 0; } if (newVolume > 127) { newVolume = 127; } MIDIMessage mst = new MIDIMessage(); mst.Channel = channelID; mst.Status = MessageType.ControlChange; mst.ControlType = ControlChangeType.ChannelVolume; mst.ControlValue = newVolume; SendEvent(mst); }
public static int MIDI_OutMessage(IntPtr handle, MIDIMessage msg, IntPtr param1, IntPtr param2) { return(Midi.midiOutMessage(handle, msg, param1, param2)); }
public void Close() { MIDIMessage ms = new MIDIMessage(); ms.ControlType = ControlChangeType.AllNotesOff; this.midiOut.Send(ms.RawData); this.midiOut.Close(); for (int i = 0; i < 8; i++) { this.mixer.Gate(i, false); } this.waveOut.Stop(); }