public IEnumerable<NoteEvent> Convert(IEnumerable<Cell> cells) { NoteEvent lastNoteEvent = null; int speed = 3; foreach (var cell in cells) { if (cell.Event == null) { tick++; continue; } ChannelEvent ce = cell.Event; if (ce.Instrument != -1) { if (ce.Note == 0xFF) // nil, use current { if (lastNoteEvent != null && ce.Instrument == lastNoteEvent.Channel) { // volume may change // ignore for now // TODO } else { // if there's a note playing on currentInstrument // stop it // then start new note playing on ce.Instrument if (lastNoteEvent != null && lastNoteEvent.Type == NoteEvent.EventType.NoteOn) { NoteEvent offEvent = lastNoteEvent.Clone(tick); offEvent.Type = NoteEvent.EventType.NoteOff; lastNoteEvent = offEvent; yield return offEvent; } lastNoteEvent = new NoteEvent(tick, NoteEvent.EventType.NoteOn, ce.Instrument, GetNoteOffPitch(lastNoteEvent, ce), GetMissingVelocity(ce)); this[ce.ChannelNumber].Volume = lastNoteEvent.Velocity; this[ce.ChannelNumber].Pitch = lastNoteEvent.Pitch; yield return lastNoteEvent; } } else if (ce.Note == 0xFE) // note off { lastNoteEvent = new NoteEvent(tick, NoteEvent.EventType.NoteOff, ce.Instrument, GetNoteOffPitch(lastNoteEvent, ce), GetMissingVelocity(ce)); this[ce.ChannelNumber].Volume = lastNoteEvent.Velocity; this[ce.ChannelNumber].Pitch = lastNoteEvent.Pitch; yield return lastNoteEvent; } else // note start { if (lastNoteEvent != null && lastNoteEvent.Type == NoteEvent.EventType.NoteOn) { NoteEvent offEvent = lastNoteEvent.Clone(tick); offEvent.Type = NoteEvent.EventType.NoteOff; lastNoteEvent = offEvent; yield return offEvent; } lastNoteEvent = new NoteEvent(tick, NoteEvent.EventType.NoteOn, ce.Instrument, ChannelNoteToMidiPitch(ce.Note), GetMissingVelocity(ce)); this[ce.ChannelNumber].Volume = lastNoteEvent.Velocity; this[ce.ChannelNumber].Pitch = lastNoteEvent.Pitch; yield return lastNoteEvent; } } tick += speed; } if (lastNoteEvent != null && lastNoteEvent.Type == NoteEvent.EventType.NoteOn) { NoteEvent offEvent = lastNoteEvent.Clone(tick); offEvent.Type = NoteEvent.EventType.NoteOff; lastNoteEvent = offEvent; yield return offEvent; } }
private static NoteEvent GenerateNoteOnEvent(Channel channel, ChannelEvent channelEvent,int tick) { int volume = channelEvent.HasVolume ? channelEvent.Volume : channel.DefaultVolume; channel.Instrument = channelEvent.HasInstrument ? channelEvent.Instrument : channel.Instrument; NoteEvent noteOnEvent = new NoteEvent(tick, NoteEvent.EventType.NoteOn, channelEvent.Instrument, channelEvent.Note, volume); channel.CurrentNote = noteOnEvent; return noteOnEvent; }
private int GetNoteOffPitch(NoteEvent lastNoteEvent, ChannelEvent ce) { if (lastNoteEvent == null) { return this[ce.ChannelNumber].Pitch; } return lastNoteEvent.Pitch; }