public AccordeonState(int duration_ms, byte pressure, AccordeonRightKeys rightKeysState, UInt64 leftVoicesState) { PressureCode = pressure; RightKeysState = rightKeysState; LeftVoicesState = leftVoicesState; Duration_ms = duration_ms; }
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); } }
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; }
/// <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); } }
/// <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); }
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})"; } } }