private static void TriggerEvent(MidiEvent evnt, int track) { if (evnt is TempoMetaMidiEvent) { TempoMetaMidiEvent tempoEvent = (TempoMetaMidiEvent)evnt; SetTrackTempo(track, tempoEvent.Value); } else if (evnt is EndOfTrackMetaMidiEvent) { //Loop?? _trackEventIndex[track] = 0; } else if (evnt is ControllerVoiceMidiEvent) { ControllerVoiceMidiEvent ccEvent = (ControllerVoiceMidiEvent)evnt; OnCC(track, ccEvent.Channel, ccEvent.Number, ccEvent.Value); } else if (evnt is OnNoteVoiceMidiEvent) { OnNoteVoiceMidiEvent voiceEvent = (OnNoteVoiceMidiEvent)evnt; OnNoteOn(track, voiceEvent.Channel, voiceEvent.Note, voiceEvent.Velocity); } else if (evnt is OffNoteVoiceMidiEvent) { OffNoteVoiceMidiEvent voiceEvent = (OffNoteVoiceMidiEvent)evnt; OnNoteOff(track, voiceEvent.Channel, voiceEvent.Note); } }
private OffNoteVoiceMidiEvent CreateOffNoteFromOnNote(OnNoteVoiceMidiEvent onNote) { if (onNote.Velocity != 0) { throw new Exception("The OnNoteVoiceMidiEvent used to create the artificial OffNoteVoiceMidiEvent MUST have a Velocity of 0."); } return(new OffNoteVoiceMidiEvent(onNote.DeltaTime, onNote.Channel, onNote.Note, onNote.Velocity)); }
/// <summary> /// Generates a midi sequence to be written to a file. /// </summary> /// <param name="allowableOctaves"></param> /// <param name="allowablePitches"></param> /// <param name="allowableDurations"></param> /// <returns></returns> public MidiSequence Generate(int[] allowableOctaves, int[] allowablePitches, int[] allowableDurations) { try { // create list of tracks List <MidiTrack> tracks = new List <MidiTrack>(); // randomized values for notes Random octaveRandom = new Random(); Random pitchRandom = new Random(); Random durationRandom = new Random(); // event list for on and off notes List <MidiEvent> events = new List <MidiEvent>(); for (int i = 0; i < _totalNotes; i++) { // create the not and set the pitch and octave Note note = new Note { Octave = allowableOctaves[octaveRandom.Next(0, allowableOctaves.Length)] }; note.Pitch = note.Pitches[allowablePitches[pitchRandom.Next(0, allowablePitches.Length)]]; note.Duration = note.Durations[allowableDurations[durationRandom.Next(0, allowableDurations.Length)]]; // create the note on and off from properties inside class OnNoteVoiceMidiEvent on = note.CreateNoteOn(); OffNoteVoiceMidiEvent off = note.CreateNoteOff(); // add the events to the midievent list events.Add(on); events.Add(off); } // create track MidiTrack track = CreateTrack(events); // add track to list tracks.Add(track); // create sequence MidiSequence midi = CreateSequence(tracks); return(midi); } catch (Exception) { throw; } }
/// <summary> /// Give me something completely random. /// </summary> /// <returns></returns> public MidiSequence Randomize() { try { // create list of tracks List <MidiTrack> tracks = new List <MidiTrack>(); // randomized values for notes Random random = new Random(); // event list for on and off notes List <MidiEvent> events = new List <MidiEvent>(); for (int i = 0; i < _totalNotes; i++) { // create the not and set the pitch and octave Note note = new Note { Octave = random.Next(1, 8), }; note.Pitch = note.Pitches[random.Next(0, 11)]; note.Duration = note.Durations[random.Next(0, 13)]; // create the note on and off from properties inside class OnNoteVoiceMidiEvent on = note.CreateNoteOn(); OffNoteVoiceMidiEvent off = note.CreateNoteOff(); // add the events to the midievent list events.Add(on); events.Add(off); } // list of denoms int[] denominators = { 1, 2, 4, 8, 16, 32 }; // create track with the randomly generate midi events MidiTrack track = CreateTrack(events); // add track to list tracks.Add(track); // create sequence MidiSequence midi = CreateSequence(tracks); return(midi); } catch (Exception) { throw; } }
public static MidiSequence Generate(List <int> allowableOctaves, List <int> allowablePitches, List <int> allowableDurations, string trackName, int amountToGenerate, GeneralMidiInstrument instrument, TimeSignature time, int tempo) { try { // create list of tracks List <MidiTrack> tracks = new List <MidiTrack>(); // randomized values for notes Random octaveRandom = new Random(); Random pitchRandom = new Random(); Random durationRandom = new Random(); // event list for on and off notes List <MidiEvent> events = new List <MidiEvent>(); for (int i = 0; i < amountToGenerate; i++) { // create the not and set the pitch and octave Note note = new Note(); note.Octave = allowableOctaves[octaveRandom.Next(0, allowableOctaves.Count)]; note.Pitch = note.Pitches[allowablePitches[pitchRandom.Next(0, allowablePitches.Count)]]; note.Duration = note.Durations[allowableDurations[durationRandom.Next(0, allowableDurations.Count)]]; // create the note on and off from properties inside class OnNoteVoiceMidiEvent on = note.CreateNoteOn(); OffNoteVoiceMidiEvent off = note.CreateNoteOff(); // add the events to the midievent list events.Add(on); events.Add(off); } // create track with the randomly generate midi events MidiTrack track = CreateTrack(trackName, instrument, tempo, time, events); // add track to list tracks.Add(track); // create sequence MidiSequence midi = CreateSequence(tracks); return(midi); } catch (Exception) { throw; } }
/// <summary> /// Completely random. /// </summary> /// <param name="trackName"></param> /// <param name="amountToGenerate"></param> /// <returns></returns> public static MidiSequence Randomize(string trackName, int amountToGenerate, GeneralMidiInstrument instrument) { try { // create list of tracks List <MidiTrack> tracks = new List <MidiTrack>(); // randomized values for notes Random random = new Random(); // event list for on and off notes List <MidiEvent> events = new List <MidiEvent>(); for (int i = 0; i < amountToGenerate; i++) { // create the not and set the pitch and octave Note note = new Note(); note.Octave = random.Next(1, 8); note.Pitch = note.Pitches[random.Next(0, 11)]; note.Duration = note.Durations[random.Next(0, 13)]; // create the note on and off from properties inside class OnNoteVoiceMidiEvent on = note.CreateNoteOn(); OffNoteVoiceMidiEvent off = note.CreateNoteOff(); // add the events to the midievent list events.Add(on); events.Add(off); } // list of denoms int[] denominators = { 1, 2, 4, 8, 16, 32 }; // create track with the randomly generate midi events MidiTrack track = CreateTrack(trackName, instrument, random.Next(30, 300), new TimeSignature((byte)random.Next(1, 32), denominators[random.Next(0, 5)]), events); // add track to list tracks.Add(track); // create sequence MidiSequence midi = CreateSequence(tracks); return(midi); } catch (Exception) { throw; } }
/// <summary>Parse a voice event from the data stream.</summary> /// <param name="deltaTime">The previously parsed delta-time for this event.</param> /// <param name="messageType">The previously parsed type of message we're expecting to find.</param> /// <param name="channel">The previously parsed channel for this message.</param> /// <param name="data">The data stream from which to read the event information.</param> /// <param name="pos">The position of the start of the event information.</param> /// <returns>The parsed voice MIDI event.</returns> private static MidiEvent ParseVoiceEvent(long deltaTime, byte messageType, byte channel, byte[] data, ref long pos) { try { MidiEvent tempEvent = null; // Create the correct voice event based on its message id/type switch (messageType) { // NOTE OFF case OffNoteVoiceMidiEvent.CategoryId: tempEvent = new OffNoteVoiceMidiEvent(deltaTime, channel, data[pos], data[pos + 1]); pos += 2; break; // NOTE ON case OnNoteVoiceMidiEvent.CategoryId: tempEvent = new OnNoteVoiceMidiEvent(deltaTime, channel, data[pos], data[pos + 1]); pos += 2; break; // AFTERTOUCH case AftertouchNoteVoiceMidiEvent.CategoryId: tempEvent = new AftertouchNoteVoiceMidiEvent(deltaTime, channel, data[pos], data[pos + 1]); pos += 2; break; // CONTROLLER case ControllerVoiceMidiEvent.CategoryId: tempEvent = new ControllerVoiceMidiEvent(deltaTime, channel, data[pos], data[pos + 1]); pos += 2; break; // PROGRAM CHANGE case ProgramChangeVoiceMidiEvent.CategoryId: tempEvent = new ProgramChangeVoiceMidiEvent(deltaTime, channel, data[pos]); pos += 1; break; // CHANNEL PRESSURE case ChannelPressureVoiceMidiEvent.CategoryId: tempEvent = new ChannelPressureVoiceMidiEvent(deltaTime, channel, data[pos]); pos += 1; break; // PITCH WHEEL case PitchWheelVoiceMidiEvent.CategoryId: int position = ((data[pos] << 8) | data[pos + 1]); byte upper, lower; MidiEvent.Split14BitsToBytes(position, out upper, out lower); tempEvent = new PitchWheelVoiceMidiEvent(deltaTime, channel, upper, lower); pos += 2; break; // UH OH! default: Validate.ThrowOutOfRange("messageType", messageType, 0x8, 0xE); break; } // Return the newly parsed event return(tempEvent); } // Something bad happened; wrap it in a parser exception catch (Exception exc) { throw new MidiParserException("Unable to parse voice MIDI event.", exc, pos); } }
void Output(OutputType type) { switch (type) { case OutputType.Midi: /*List<MidiEvent> midiEvents = new List<MidiEvent> (); * * double max = 0; * for (int i = 0; i < notes.Count; i++) { * double d = notes[i].duration * 4; * double t1 = notes[i].time * 4; * double t2 = t1 + d; * max = t2 > max ? t2 : max; * * NoteOnEvent note = new NoteOnEvent (Convert.ToInt64 (t1), 1, notes[i].noteNumber + 40, 127, Convert.ToInt32(d)); * midiEvents.Add (note); * } * MidiEvent endMarker = new NoteEvent (Convert.ToInt64(max), 1, MidiCommandCode.StopSequence, 0, 0); * midiEvents.Add (endMarker); * * MidiEventCollection collection = new MidiEventCollection (0, 1); * collection.AddTrack (midiEvents); * * MidiFile.Export ("C:/Users/Jonas/OneDrive/GIP/Proef/Output/midi.mid", collection);*/ MidiTrack track = new MidiTrack(); long maxTime = 0; //string path = "C:/Users/Jonas/Desktop/result.txt"; double previousTime = 0; for (int i = 0; i < notes.Count; i++) { string path = "C:/Users/Jonas/Desktop/result.txt"; File.AppendAllText(path, string.Format("{0} at {1}\n", DecodeNote(notes[i].noteNumber + 44, NoteNotation.Short), notes[i].time)); double d = 1; double t1 = notes[i].time * 20 - previousTime; double t2 = t1 + d; if (t1 < 0) { continue; } previousTime = t2; MidiEvent onEvent = new OnNoteVoiceMidiEvent(Convert.ToInt64(t1), 1, (byte)(44 + notes[i].noteNumber), 63); MidiEvent offEvent = new OffNoteVoiceMidiEvent(Convert.ToInt64(t2), 1, (byte)(44 + notes[i].noteNumber), 0); long t2long = (long)t2; maxTime = (t2long > maxTime) ? t2long : maxTime; track.Events.Add(onEvent); track.Events.Add(offEvent); } MidiEvent endMarker = new EndOfTrackMetaMidiEvent(maxTime); track.Events.Add(endMarker); MidiSequence sequence = new MidiSequence(Format.Zero, 1000); sequence.Tracks.Add(track); FileStream stream = new FileStream("C:/Users/Jonas/OneDrive/GIP/Proef/Output/midi.mid", FileMode.OpenOrCreate); sequence.Save(stream); stream.Close(); break; case OutputType.Audio: double longest = 0; for (int i = 0; i < notes.Count; i++) { double time = notes[i].time + notes[i].duration; longest = Math.Max(time, longest); } double[] newSamples = new double[(int)Math.Ceiling(longest * rawAudio.sampleRate)]; for (int i = 0; i < notes.Count; i++) { int startIndex = (int)Math.Floor(notes[i].time * rawAudio.sampleRate); int endIndex = (int)Math.Floor((notes[i].time + notes[i].duration) * rawAudio.sampleRate); double freq = 110 * Math.Pow(1.059463094359295, notes[i].noteNumber); double amp = notes[i].amplitude; for (int j = startIndex; j < endIndex; j++) { double time = j * rawAudio.SampleLength + notes[i].time; double value = Math.Sin(time * freq * 2 * Math.PI) * amp; //double maxAmp = Math.Min (1, 5 * Math.Min (Math.Abs (time - notes[i].time), Math.Abs (time - (notes[i].time + notes[i].duration)))); newSamples[j] += value; } } for (int i = 0; i < newSamples.Length; i++) { newSamples[i] = Math.Max(Math.Min(1, newSamples[i]), -1); } int avgSpread = 35; double[] smoothSamples = new double[newSamples.Length - avgSpread]; for (int i = 0; i < newSamples.Length - avgSpread; i++) { double tot = 0; for (int j = 0; j < avgSpread; j++) { tot += newSamples[i + j]; } smoothSamples[i] = tot / avgSpread; } Song song = new Song(smoothSamples, rawAudio.channels, rawAudio.sampleRate); // GIPIO.SaveSong (song, GIPIO.outputPath + "test.wav"); producedAudio = song; break; case OutputType.Wavelet: pixels = new uint[allAmps.Count * allAmps[0].Length]; for (int x = 0; x < allAmps.Count; x++) { for (int y = 0; y < allAmps[0].Length; y++) { double i = allAmps[x][y]; // i *= 2; i = Math.Min(1, i); // double r = -2 * (i - 1.0) * (2 * (i - 1.0)) + 1; // double g = -2 * (i - 0.5) * (2 * (i - 0.5)) + 1; // double b = -2 * (i - 0.0) * (2 * (i - 0.0)) + 1; double r, g, b; r = g = b = i; uint red = (uint)Math.Round(r * 255); uint green = (uint)Math.Round(g * 255); uint blue = (uint)Math.Round(b * 255); int index = (allAmps[0].Length - y - 1) * allAmps.Count + x; pixels[index] = (uint)((255 << 24) + (red << 16) + (green << 8) + blue); } } DrawWavelet(); break; } }