コード例 #1
0
        /// <summary>
        /// Generate a new <see cref="VolumeCommand"/>.
        /// </summary>
        /// <param name="volume">The target volume to apply.</param>
        /// <param name="bufferOffset">The offset of the mix buffer.</param>
        /// <param name="nodeId">The node id associated to this command.</param>
        public void GenerateVolume(float volume, uint bufferOffset, int nodeId)
        {
            VolumeCommand command = new VolumeCommand(volume, bufferOffset, nodeId);

            command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);

            AddCommand(command);
        }
コード例 #2
0
        public void Create()
        {
            var log      = A.Fake <ILogger>();
            var radio    = A.Fake <IRadio>();
            var provider = A.Fake <IConfigurationProvider>();

            var command = new VolumeCommand(log, (s) => {}, provider, radio);

            Assert.NotNull(command);
        }
コード例 #3
0
        public uint Estimate(VolumeCommand command)
        {
            Debug.Assert(_sampleCount == 160 || _sampleCount == 240);

            if (_sampleCount == 160)
            {
                return((uint)1311.1f);
            }

            return((uint)1713.6f);
        }
コード例 #4
0
        public uint Estimate(VolumeCommand command)
        {
            Debug.Assert(_sampleCount == 160 || _sampleCount == 240);

            if (_sampleCount == 160)
            {
                return((uint)1280.3f);
            }

            return((uint)1737.8f);
        }
コード例 #5
0
 private void SerializeIf(VolumeCommand cmd)
 {
     if (cmd.Master)
     {
         sb.AppendFormat("main_volume_if {0}\n", cmd.Volume);
     }
     else
     {
         sb.AppendFormat("volume_if {0}\n", cmd.Volume);
     }
 }
コード例 #6
0
        public void CheckName()
        {
            var log      = A.Fake <ILogger>();
            var radio    = A.Fake <IRadio>();
            var provider = A.Fake <IConfigurationProvider>();

            var command = new VolumeCommand(log, (s) => {}, provider, radio);

            Assert.Contains("-v", command.Name);
            Assert.Contains("--volume", command.Name);
            Assert.Contains("Set {VALUE}% volume directly", command.Description);
        }
コード例 #7
0
        public async Task ExecuteWithoutValue()
        {
            var log      = A.Fake <ILogger>();
            var radio    = A.Fake <IRadio>();
            var provider = A.Fake <IConfigurationProvider>();
            var output   = A.Fake <Action <string> >();

            var command = new VolumeCommand(log, output, provider, radio);

            var result = await command.Execute(new string[0]);

            A.CallTo(output).MustHaveHappened();
            Assert.Equal(CommandResult.OK, result);
        }
コード例 #8
0
        public async Task ExecuteWithValue()
        {
            var log      = A.Fake <ILogger>();
            var radio    = A.Fake <IRadio>();
            var provider = A.Fake <IConfigurationProvider>();
            var output   = A.Fake <Action <string> >();

            var command = new VolumeCommand(log, output, provider, radio);

            var result = await command.Execute(new string[] { "0" });

            A.CallTo(output).MustNotHaveHappened();
            A.CallTo(() => radio.Volume(A <int> .That.IsEqualTo(0))).MustHaveHappened();
            A.CallTo(() => provider.Upload(A <Configuration> ._)).MustHaveHappened();
            A.CallTo(() => provider.Load()).MustHaveHappened();
            Assert.Equal(CommandResult.OK, result);
        }
コード例 #9
0
 public uint Estimate(VolumeCommand command)
 {
     return((uint)(_sampleCount * 8.8f * 1.2f));
 }
コード例 #10
0
ファイル: Song.cs プロジェクト: Stich991/GBAMusicStudio
        public MLSSSong(int offset)
        {
            SetOffset(offset);
            VoiceTable = VoiceTable.LoadTable <MLSSVoiceTable>(0, true); // 0 won't be used in the Load method

            int amt = GetTrackAmount(ROM.Instance.Reader.ReadInt16(offset));

            Commands = new List <SongEvent> [amt];
            for (int i = 0; i < amt; i++)
            {
                Commands[i] = new List <SongEvent>();
                int track = offset + ROM.Instance.Reader.ReadInt16(offset + 2 + (i * 2));
                ROM.Instance.Reader.BaseStream.Position = track;

                byte cmd = 0;
                while (cmd != 0xFF && cmd != 0xF8)
                {
                    int      off     = (int)ROM.Instance.Reader.BaseStream.Position;
                    ICommand command = null;

                    cmd = ROM.Instance.Reader.ReadByte();
                    switch (cmd)
                    {
                    case 0: command = new FreeNoteCommand {
                            Note = ROM.Instance.Reader.ReadByte(), Duration = ROM.Instance.Reader.ReadByte()
                    }; break;

                    case 0xF0: command = new VoiceCommand {
                            Voice = ROM.Instance.Reader.ReadByte()
                    }; break;

                    case 0xF1: command = new VolumeCommand {
                            Volume = ROM.Instance.Reader.ReadByte()
                    }; break;

                    case 0xF2: command = new PanpotCommand {
                            Panpot = (sbyte)(ROM.Instance.Reader.ReadByte() - 0x80)
                    }; break;

                    case 0xF4: command = new BendRangeCommand {
                            Range = ROM.Instance.Reader.ReadByte()
                    }; break;

                    case 0xF5: command = new BendCommand {
                            Bend = ROM.Instance.Reader.ReadSByte()
                    }; break;

                    case 0xF6: command = new RestCommand {
                            Rest = ROM.Instance.Reader.ReadByte()
                    }; break;

                    case 0xF8:
                        short offsetFromEnd = ROM.Instance.Reader.ReadInt16();
                        command = new GoToCommand {
                            Offset = (int)(ROM.Instance.Reader.BaseStream.Position + offsetFromEnd)
                        };
                        break;

                    case 0xF9: command = new TempoCommand {
                            Tempo = ROM.Instance.Reader.ReadByte()
                    }; break;

                    case 0xFF: command = new FinishCommand(); break;

                    default: command = new MLSSNoteCommand {
                            Duration = cmd, Note = ROM.Instance.Reader.ReadSByte()
                    }; break;
                    }
                    Commands[i].Add(new SongEvent(off, command));
                }
            }
        }
コード例 #11
0
ファイル: Song.cs プロジェクト: Stich991/GBAMusicStudio
        protected void Load(byte[] binary, EndianBinaryReader reader, int headerOffset)
        {
            _binary = binary;
            Header  = reader.ReadObject <M4ASongHeader>(headerOffset);

            VoiceTable = VoiceTable.LoadTable <M4AVoiceTable>(Header.VoiceTable - ROM.Pak);

            Commands = new List <SongEvent> [Header.NumTracks];
            for (int i = 0; i < Header.NumTracks; i++)
            {
                Commands[i] = new List <SongEvent>();
            }

            if (Header.NumTracks > ROM.Instance.Game.Engine.TrackLimit)
            {
                throw new InvalidDataException($"La canzone ha troppe tracce ({Header.NumTracks}).");
            }

            for (int i = 0; i < NumTracks; i++)
            {
                reader.BaseStream.Position = Header.Tracks[i] - ROM.Pak;

                byte cmd = 0, runCmd = 0, prevNote = 0, prevVelocity = 0x7F;

                while (cmd != 0xB1 && cmd != 0xB6)
                {
                    int      off     = (int)reader.BaseStream.Position;
                    ICommand command = null;

                    cmd = reader.ReadByte();
                    if (cmd >= 0xBD) // Commands that work within running status
                    {
                        runCmd = cmd;
                    }

                    #region TIE & Notes

                    if (runCmd >= 0xCF && cmd < 0x80) // Within running status
                    {
                        var peek = reader.PeekBytes(2);
                        if (peek[0] >= 0x80)
                        {
                            command = AddNoteEvent(cmd, prevVelocity, 0, runCmd, out prevNote, out prevVelocity);
                        }
                        else if (peek[1] > 3 || peek[1] < 1)
                        {
                            command = AddNoteEvent(cmd, reader.ReadByte(), 0, runCmd, out prevNote, out prevVelocity);
                        }
                        else
                        {
                            command = AddNoteEvent(cmd, reader.ReadByte(), reader.ReadByte(), runCmd, out prevNote, out prevVelocity);
                        }
                    }
                    else if (cmd >= 0xCF)
                    {
                        var peek = reader.PeekBytes(3);
                        if (peek[0] >= 0x80)
                        {
                            command = AddNoteEvent(prevNote, prevVelocity, 0, runCmd, out prevNote, out prevVelocity);
                        }
                        else if (peek[1] >= 0x80)
                        {
                            command = AddNoteEvent(reader.ReadByte(), prevVelocity, 0, runCmd, out prevNote, out prevVelocity);
                        }
                        // TIE cannot have an added duration so it needs to stop here
                        else if (cmd == 0xCF || peek[2] > 3 || peek[2] < 1)
                        {
                            command = AddNoteEvent(reader.ReadByte(), reader.ReadByte(), 0, runCmd, out prevNote, out prevVelocity);
                        }
                        else
                        {
                            command = AddNoteEvent(reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), runCmd, out prevNote, out prevVelocity);
                        }
                    }

                    #endregion

                    #region Rests

                    else if (cmd >= 0x80 && cmd <= 0xB0)
                    {
                        command = new RestCommand {
                            Rest = SongEvent.RestFromCMD(0x80, cmd)
                        }
                    }
                    ;

                    #endregion

                    #region Commands

                    else if (runCmd < 0xCF && cmd < 0x80) // Commands within running status
                    {
                        switch (runCmd)
                        {
                        case 0xBD: command = new VoiceCommand {
                                Voice = cmd
                        }; break;

                        case 0xBE: command = new VolumeCommand {
                                Volume = cmd
                        }; break;

                        case 0xBF: command = new PanpotCommand {
                                Panpot = (sbyte)(cmd - 0x40)
                        }; break;

                        case 0xC0: command = new BendCommand {
                                Bend = (sbyte)(cmd - 0x40)
                        }; break;

                        case 0xC1: command = new BendRangeCommand {
                                Range = cmd
                        }; break;

                        case 0xC2: command = new LFOSpeedCommand {
                                Speed = cmd
                        }; break;

                        case 0xC3: command = new LFODelayCommand {
                                Delay = cmd
                        }; break;

                        case 0xC4: command = new ModDepthCommand {
                                Depth = cmd
                        }; break;

                        case 0xC5: command = new ModTypeCommand {
                                Type = cmd
                        }; break;

                        case 0xC8: command = new TuneCommand {
                                Tune = (sbyte)(cmd - 0x40)
                        }; break;

                        case 0xCD: command = new LibraryCommand {
                                Command = cmd, Argument = reader.ReadByte()
                        }; break;

                        case 0xCE: command = new EndOfTieCommand {
                                Note = (sbyte)cmd
                        }; prevNote = cmd; break;
                        }
                    }
                    else if (cmd > 0xB0 && cmd < 0xCF)
                    {
                        switch (cmd)
                        {
                        case 0xB1:     // FINE & PREV
                        case 0xB6: command = new M4AFinishCommand {
                                Type = cmd
                        }; break;

                        case 0xB2: command = new GoToCommand {
                                Offset = reader.ReadInt32() - ROM.Pak
                        }; break;

                        case 0xB3: command = new CallCommand {
                                Offset = reader.ReadInt32() - ROM.Pak
                        }; break;

                        case 0xB4: command = new ReturnCommand(); break;

                        case 0xB5: command = new RepeatCommand {
                                Times = reader.ReadByte(), Offset = reader.ReadInt32() - ROM.Pak
                        }; break;

                        case 0xB9: command = new MemoryAccessCommand {
                                Arg1 = reader.ReadByte(), Arg2 = reader.ReadByte(), Arg3 = reader.ReadByte()
                        }; break;

                        case 0xBA: command = new PriorityCommand {
                                Priority = reader.ReadByte()
                        }; break;

                        case 0xBB: command = new TempoCommand {
                                Tempo = (short)(reader.ReadByte() * 2)
                        }; break;

                        case 0xBC: command = new KeyShiftCommand {
                                Shift = reader.ReadSByte()
                        }; break;

                        // Commands that work within running status:
                        case 0xBD: command = new VoiceCommand {
                                Voice = reader.ReadByte()
                        }; break;

                        case 0xBE: command = new VolumeCommand {
                                Volume = reader.ReadByte()
                        }; break;

                        case 0xBF: command = new PanpotCommand {
                                Panpot = (sbyte)(reader.ReadByte() - 0x40)
                        }; break;

                        case 0xC0: command = new BendCommand {
                                Bend = (sbyte)(reader.ReadByte() - 0x40)
                        }; break;

                        case 0xC1: command = new BendRangeCommand {
                                Range = reader.ReadByte()
                        }; break;

                        case 0xC2: command = new LFOSpeedCommand {
                                Speed = reader.ReadByte()
                        }; break;

                        case 0xC3: command = new LFODelayCommand {
                                Delay = reader.ReadByte()
                        }; break;

                        case 0xC4: command = new ModDepthCommand {
                                Depth = reader.ReadByte()
                        }; break;

                        case 0xC5: command = new ModTypeCommand {
                                Type = reader.ReadByte()
                        }; break;

                        case 0xC8: command = new TuneCommand {
                                Tune = (sbyte)(reader.ReadByte() - 0x40)
                        }; break;

                        case 0xCD: command = new LibraryCommand {
                                Command = reader.ReadByte(), Argument = reader.ReadByte()
                        }; break;

                        case 0xCE:     // EOT
                            sbyte note;

                            if (reader.PeekByte() < 0x80)
                            {
                                note     = reader.ReadSByte();
                                prevNote = (byte)note;
                            }
                            else
                            {
                                note = -1;
                            }

                            command = new EndOfTieCommand {
                                Note = note
                            };
                            break;

                        default: Console.WriteLine("Comando invalido: 0x{0:X} = {1}", off, cmd); break;
                        }
                    }

                    #endregion

                    Commands[i].Add(new SongEvent(off, command));
                }
            }

            ICommand AddNoteEvent(byte note, byte velocity, byte addedDuration, byte runCmd, out byte prevNote, out byte prevVelocity)
            {
                return(new M4ANoteCommand
                {
                    Note = (sbyte)(prevNote = note),
                    Velocity = prevVelocity = velocity,
                    Duration = (short)(runCmd == 0xCF ? -1 : (SongEvent.RestFromCMD(0xCF, runCmd) + addedDuration))
                });
            }
        }
コード例 #12
0
        /// <summary>
        /// Handles commands for the Denon published to MQTT.
        /// </summary>
        /// <param name="e">Event args.</param>
        protected override async void Mqtt_MqttMsgPublishReceived(MqttApplicationMessageReceivedEventArgs e)
        {
            var message = e.ApplicationMessage.ConvertPayloadToString();

            _log.LogInformation("MQTT message received for topic " + e.ApplicationMessage.Topic + ": " + message);

            var commandType = e.ApplicationMessage.Topic.Replace(TopicRoot + "/controls/", string.Empty).Replace("/set", string.Empty);

            Command command = null;

            if (commandType == "power")
            {
                command = new PowerCommand {
                    Value = message
                }
            }
            ;

            if (commandType == "volume")
            {
                command = new VolumeCommand {
                    Value = message
                }
            }
            ;

            if (commandType == "mute")
            {
                command = new MuteCommand {
                    Value = message
                }
            }
            ;

            if (commandType == "input")
            {
                command = new InputCommand {
                    Value = message
                }
            }
            ;

            if (commandType == "surroundMode")
            {
                command = new SurroundModeCommand {
                    Value = message
                }
            }
            ;

            if (commandType == "tunerFrequency")
            {
                command = new TunerFrequencyCommand {
                    Value = message
                }
            }
            ;

            if (commandType == "tunerMode")
            {
                command = new TunerModeCommand {
                    Value = message
                }
            }
            ;

            if (commandType.StartsWith("zone"))
            {
                if (int.TryParse(commandType.Substring(4, 1), out int zoneId))
                {
                    if (commandType == $"zone{zoneId}Power")
                    {
                        command = new ZonePowerCommand {
                            Value = message, ZoneId = zoneId
                        }
                    }
                    ;

                    if (commandType == $"zone{zoneId}Volume")
                    {
                        command = new ZoneVolumeCommand {
                            Value = message, ZoneId = zoneId
                        }
                    }
                    ;

                    if (commandType == $"zone{zoneId}Mute")
                    {
                        command = new ZoneMuteCommand {
                            Value = message, ZoneId = zoneId
                        }
                    }
                    ;

                    if (commandType == $"zone{zoneId}Input")
                    {
                        command = new ZoneInputCommand {
                            Value = message, ZoneId = zoneId
                        }
                    }
                    ;
                }
            }

            if (command != null)
            {
                await _client.SendCommandAsync(command)
                .ConfigureAwait(false);
            }
        }
コード例 #13
0
ファイル: Song.cs プロジェクト: Lafolie/GBAMusicStudio
        protected void Load(byte[] binary, M4ASongHeader head)
        {
            _binary = binary;
            Header  = head;
            Array.Resize(ref Header.Tracks, Header.NumTracks); // Not really necessary yet
            Commands = new List <SongEvent> [Header.NumTracks];
            for (int i = 0; i < Header.NumTracks; i++)
            {
                Commands[i] = new List <SongEvent>();
            }

            VoiceTable = VoiceTable.LoadTable <M4AVoiceTable>(Header.VoiceTable);

            if (NumTracks == 0 || NumTracks > 16)
            {
                return;
            }

            var reader = new ROMReader();

            reader.InitReader(_binary);

            for (int i = 0; i < NumTracks; i++)
            {
                reader.SetOffset(Header.Tracks[i]);

                byte cmd = 0, runCmd = 0, prevNote = 0, prevVelocity = 127;

                while (cmd != 0xB1 && cmd != 0xB6)
                {
                    uint     off     = reader.Position;
                    ICommand command = null;

                    cmd = reader.ReadByte();
                    if (cmd >= 0xBD) // Commands that work within running status
                    {
                        runCmd = cmd;
                    }

                    #region TIE & Notes

                    if (runCmd >= 0xCF && cmd < 0x80) // Within running status
                    {
                        var  o     = reader.Position;
                        byte peek1 = reader.ReadByte(),
                             peek2 = reader.ReadByte();
                        reader.SetOffset(o);
                        if (peek1 >= 128)
                        {
                            command = AddNoteEvent(cmd, prevVelocity, 0, runCmd, out prevNote, out prevVelocity);
                        }
                        else if (peek2 > 3 || peek2 < 1)
                        {
                            command = AddNoteEvent(cmd, reader.ReadByte(), 0, runCmd, out prevNote, out prevVelocity);
                        }
                        else
                        {
                            command = AddNoteEvent(cmd, reader.ReadByte(), reader.ReadByte(), runCmd, out prevNote, out prevVelocity);
                        }
                    }
                    else if (cmd >= 0xCF)
                    {
                        var  o     = reader.Position;
                        byte peek1 = reader.ReadByte(),
                             peek2 = reader.ReadByte(),
                             peek3 = reader.ReadByte();
                        reader.SetOffset(o);
                        if (peek1 >= 128)
                        {
                            command = AddNoteEvent(prevNote, prevVelocity, 0, runCmd, out prevNote, out prevVelocity);
                        }
                        else if (peek2 >= 128)
                        {
                            command = AddNoteEvent(reader.ReadByte(), prevVelocity, 0, runCmd, out prevNote, out prevVelocity);
                        }
                        // TIE cannot have an added duration so it needs to stop here
                        else if (cmd == 0xCF || peek3 > 3 || peek3 < 1)
                        {
                            command = AddNoteEvent(reader.ReadByte(), reader.ReadByte(), 0, runCmd, out prevNote, out prevVelocity);
                        }
                        else
                        {
                            command = AddNoteEvent(reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), runCmd, out prevNote, out prevVelocity);
                        }
                    }

                    #endregion

                    #region Rests

                    else if (cmd >= 0x80 && cmd <= 0xB0)
                    {
                        command = new RestCommand {
                            Rest = SongEvent.RestFromCMD(0x80, cmd)
                        }
                    }
                    ;

                    #endregion

                    #region Commands

                    else if (runCmd < 0xCF && cmd < 0x80) // Commands within running status
                    {
                        switch (runCmd)
                        {
                        case 0xBD: command = new VoiceCommand {
                                Voice = cmd
                        }; break;

                        case 0xBE: command = new VolumeCommand {
                                Volume = cmd
                        }; break;

                        case 0xBF: command = new PanpotCommand {
                                Panpot = (sbyte)(cmd - 0x40)
                        }; break;

                        case 0xC0: command = new BendCommand {
                                Bend = (sbyte)(cmd - 0x40)
                        }; break;

                        case 0xC1: command = new BendRangeCommand {
                                Range = cmd
                        }; break;

                        case 0xC2: command = new LFOSpeedCommand {
                                Speed = cmd
                        }; break;

                        case 0xC3: command = new LFODelayCommand {
                                Delay = cmd
                        }; break;

                        case 0xC4: command = new ModDepthCommand {
                                Depth = cmd
                        }; break;

                        case 0xC5: command = new ModTypeCommand {
                                Type = cmd
                        }; break;

                        case 0xC8: command = new TuneCommand {
                                Tune = (sbyte)(cmd - 0x40)
                        }; break;

                        case 0xCD: command = new LibraryCommand {
                                Command = cmd, Argument = reader.ReadByte()
                        }; break;

                        case 0xCE: command = new EndOfTieCommand {
                                Note = (sbyte)cmd
                        }; prevNote = cmd; break;
                        }
                    }
                    else if (cmd > 0xB0 && cmd < 0xCF)
                    {
                        switch (cmd)
                        {
                        case 0xB1:     // FINE & PREV
                        case 0xB6: command = new M4AFinishCommand {
                                Type = cmd
                        }; break;

                        case 0xB2: command = new GoToCommand {
                                Offset = reader.ReadPointer()
                        }; break;

                        case 0xB3: command = new CallCommand {
                                Offset = reader.ReadPointer()
                        }; break;

                        case 0xB4: command = new ReturnCommand(); break;

                        case 0xB5: command = new RepeatCommand {
                                Times = reader.ReadByte(), Offset = reader.ReadPointer()
                        }; break;

                        case 0xB9: command = new MemoryAccessCommand {
                                Arg1 = reader.ReadByte(), Arg2 = reader.ReadByte(), Arg3 = reader.ReadByte()
                        }; break;

                        case 0xBA: command = new PriorityCommand {
                                Priority = reader.ReadByte()
                        }; break;

                        case 0xBB: command = new TempoCommand {
                                Tempo = (ushort)(reader.ReadByte() * 2)
                        }; break;

                        case 0xBC: command = new KeyShiftCommand {
                                Shift = reader.ReadSByte()
                        }; break;

                        // Commands that work within running status:
                        case 0xBD: command = new VoiceCommand {
                                Voice = reader.ReadByte()
                        }; break;

                        case 0xBE: command = new VolumeCommand {
                                Volume = reader.ReadByte()
                        }; break;

                        case 0xBF: command = new PanpotCommand {
                                Panpot = (sbyte)(reader.ReadByte() - 0x40)
                        }; break;

                        case 0xC0: command = new BendCommand {
                                Bend = (sbyte)(reader.ReadByte() - 0x40)
                        }; break;

                        case 0xC1: command = new BendRangeCommand {
                                Range = reader.ReadByte()
                        }; break;

                        case 0xC2: command = new LFOSpeedCommand {
                                Speed = reader.ReadByte()
                        }; break;

                        case 0xC3: command = new LFODelayCommand {
                                Delay = reader.ReadByte()
                        }; break;

                        case 0xC4: command = new ModDepthCommand {
                                Depth = reader.ReadByte()
                        }; break;

                        case 0xC5: command = new ModTypeCommand {
                                Type = reader.ReadByte()
                        }; break;

                        case 0xC8: command = new TuneCommand {
                                Tune = (sbyte)(reader.ReadByte() - 0x40)
                        }; break;

                        case 0xCD: command = new LibraryCommand {
                                Command = reader.ReadByte(), Argument = reader.ReadByte()
                        }; break;

                        case 0xCE:     // EOT
                            sbyte note;

                            if (reader.PeekByte() < 128)
                            {
                                note     = reader.ReadSByte();
                                prevNote = (byte)note;
                            }
                            else
                            {
                                note = -1;
                            }

                            command = new EndOfTieCommand {
                                Note = note
                            };
                            break;

                        default: Console.WriteLine("Invalid command: 0x{0:X} = {1}", reader.Position, cmd); break;
                        }
                    }

                    #endregion

                    Commands[i].Add(new SongEvent(off, command));
                }
            }

            ICommand AddNoteEvent(byte note, byte velocity, byte addedDuration, byte runCmd, out byte prevNote, out byte prevVelocity)
            {
                return(new M4ANoteCommand
                {
                    Note = (sbyte)(prevNote = note),
                    Velocity = prevVelocity = velocity,
                    Duration = (short)(runCmd == 0xCF ? -1 : (SongEvent.RestFromCMD(0xCF, runCmd) + addedDuration))
                });
            }
        }