コード例 #1
0
ファイル: EAccordeon.cs プロジェクト: waleyew/eAccordeon.cs
 public AccordeonState(int duration_ms, byte pressure, AccordeonRightKeys rightKeysState, UInt64 leftVoicesState)
 {
     PressureCode    = pressure;
     RightKeysState  = rightKeysState;
     LeftVoicesState = leftVoicesState;
     Duration_ms     = duration_ms;
 }
コード例 #2
0
ファイル: EAccordeon.cs プロジェクト: waleyew/eAccordeon.cs
        private void OnRightKeyStateChanged(AccordeonRightKeys noteKey, NoteState state)
        {
            var pureNote  = AccordeonRightKeyToNote(mRightHandOctaveShift, noteKey);
            var realNotes = SelectedRightRegister.GetNotes(pureNote);

            foreach (var n in realNotes)
            {
                mMidiHelper.Note(mChannelIdForRightSide, n, state, mKeystrokeForce);
            }
        }
コード例 #3
0
ファイル: EAccordeon.cs プロジェクト: waleyew/eAccordeon.cs
        private void ChangeActualRightKeysPressed(AccordeonRightKeys rightKeysState)
        {
            for (int i = 16; i < 64; i++)
            {
                UInt64 msk      = 1UL << i;
                bool   oldState = ((UInt64)mActualPightKeysState & msk) != 0;
                bool   newState = ((UInt64)rightKeysState & msk) != 0;

                if (newState != oldState)
                {
                    AccordeonRightKeys note = (AccordeonRightKeys)msk;
                    OnRightKeyStateChanged(note, newState ? NoteState.On : NoteState.Off);
                }
            }
            mActualPightKeysState = rightKeysState;
        }
コード例 #4
0
ファイル: EAccordeon.cs プロジェクト: waleyew/eAccordeon.cs
        /// <summary>
        /// Обрабатывает состояние нажатия клавиш и давления в мехах аккордеона. Вызывается при приеме новой команды из конроллера аккордеона.
        /// </summary>
        /// <param name="pressureCode">Давление в мехах аккордеона в кодах от 0 до 127.</param>
        /// <param name="rightKeysState">Состояние нажатия клавиш на левой клавиатуре.</param>
        /// <param name="leftVoicesState">Состояние открытия клапанов в правой части аккордеона.</param>
        public void HandleKeys(byte pressureCode, AccordeonRightKeys rightKeysState, UInt64 leftVoicesState)
        {
            //System.Diagnostics.Debug.Print($"{pressureCode}, {rightKeysState}, {leftVoicesState}");
            //return;

            ProccedPressude(pressureCode);

            if (rightKeysState != mActualPightKeysState)
            {
                ChangeActualRightKeysPressed(rightKeysState);
            }

            if (leftVoicesState != mActualLeftVoicesState)
            {
                ChangeActualLeftVoisesPressed(leftVoicesState);
            }
        }
コード例 #5
0
ファイル: EAccordeon.cs プロジェクト: waleyew/eAccordeon.cs
        /// <summary>
        /// Возвращает код ноты MIDI из кода левой клавиши на аккордеоне.
        /// </summary>
        /// <param name="octaveShift">Смещение октавы.</param>
        /// <param name="key">Клавиша.</param>
        /// <returns></returns>
        public int AccordeonRightKeyToNote(int octaveShift, AccordeonRightKeys key)
        {
            int baseOctave = 3 + octaveShift; // Малая октава имеет номер 3
            int tone       = -1;

            UInt64 tmp = (UInt64)key;

            //0xFFF0000000000000; // Октава 3
            //0x000FFF0000000000; // Октава 2
            //0x000000FFF0000000; // Октава 1
            //0x000000000FFF0000; // Октава малая

            tmp >>= 18; // Сдвигаем к малой октаве

            for (int o = 0; o <= 3; o++)
            {
                if (tone >= 0)
                {
                    break;
                }

                var tmpOctave = tmp & 0xFFF;
                if (tmpOctave != 0)
                {
                    for (var t = 0; t < 12; t++)
                    {
                        if ((tmpOctave & (1UL << t)) > 0)
                        {
                            tone = t;
                            break;
                        }
                    }
                }

                ++baseOctave;
                tmp >>= 12;
            }

            if (tone < 0)  // Какая клавиша нажата не определено
            {
                return(-1);
            }

            return(baseOctave * 12 + tone);
        }
コード例 #6
0
        private void ListenSerial()
        {
            const int packetSize = 1 + 2 + 8 + 8 + 1 + 1;

            byte[] packetData = new byte[packetSize];

            UInt16             pressure        = 0;
            AccordeonRightKeys rightKeysState  = AccordeonRightKeys.None;
            UInt64             leftVoicesState = 0;


            while (true)
            {
                // Если порт закрыт, то ждем когда откроется
                while (!mPort.IsOpen)
                {
                    Thread.Sleep(100);
                    DebugText = "Offline";
                }

                // Блокировка нужна, чтобы не возникало казусов при открытии и закрытии порта
                lock (mPort)
                {
                    try
                    {
                        var readed = 0;
                        packetData[0] = 0;
                        while (packetData[0] != 0x5B)
                        {
                            readed = mPort.Read(packetData, 0, 1);
                        }

                        while (readed < packetSize)
                        {
                            readed += mPort.Read(packetData, readed, packetSize - readed);
                        }
                    }
                    catch (TimeoutException)
                    {
                        mPort.DiscardInBuffer();
                        mPort.DiscardOutBuffer();
                        DebugText = "timeout";
                        continue;
                    }
                    catch
                    {
                        DebugText = "IO Error";
                        continue;
                    }

                    var startByte = packetData[0];
                    var endByte   = packetData[packetData.Length - 1];

                    // Проверка контрольных сумм
                    if (startByte != 0x5B || endByte != 0x5E)
                    {
                        EAccordeon.MidiHelper.ResetDevice();
                        mPort.DiscardInBuffer();
                        mPort.DiscardOutBuffer();

                        DebugText = "Checksum error";
                        continue;
                    }

                    int offset = 1;
                    pressure = BitConverter.ToUInt16(packetData, offset);
                    offset  += sizeof(UInt16);

                    rightKeysState = (AccordeonRightKeys)BitConverter.ToUInt64(packetData, offset);
                    offset        += sizeof(ulong);

                    leftVoicesState = BitConverter.ToUInt64(packetData, offset);
                    offset         += sizeof(ulong);

                    var pressedKey     = System.Text.Encoding.ASCII.GetChars(packetData, offset, 1)[0];
                    var pressedKeyCode = (int)pressedKey;

                    byte bPressure = EAccordeon.TransformPressure(pressure);
                    EAccordeon.HandleKeys(bPressure, rightKeysState, leftVoicesState);

                    DebugText = $"pressure={pressure}; rightKeysState={rightKeysState}; leftVoicesState={leftVoicesState}; pressedKey={pressedKey} ({pressedKeyCode})";
                }
            }
        }