A DTMF sequence editor and player for HAM radio equipment command & control.

Dependencies:   mbed ExtTextLCD

Committer:
osmeest
Date:
Mon Mar 07 22:51:19 2011 +0000
Revision:
0:1324e7d9d471

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
osmeest 0:1324e7d9d471 1 #include "kbd_mgr/KeyboardState.h"
osmeest 0:1324e7d9d471 2
osmeest 0:1324e7d9d471 3 #include <algorithm>
osmeest 0:1324e7d9d471 4 #include <iomanip>
osmeest 0:1324e7d9d471 5
osmeest 0:1324e7d9d471 6 namespace kbd_mgr {
osmeest 0:1324e7d9d471 7
osmeest 0:1324e7d9d471 8 KeyboardState::KeyboardState() :
osmeest 0:1324e7d9d471 9 numRows(0), numKeysPerRow(0), rowMask(0), numRowsPerWord(0), numKeysPerWord(0), numWords(0), data(0)
osmeest 0:1324e7d9d471 10 { }
osmeest 0:1324e7d9d471 11
osmeest 0:1324e7d9d471 12 KeyboardState::KeyboardState(std::size_t numRows, std::size_t numKeysPerRow) :
osmeest 0:1324e7d9d471 13 numRows(numRows), numKeysPerRow(numKeysPerRow), rowMask((1 << numKeysPerRow) -1),
osmeest 0:1324e7d9d471 14 numRowsPerWord((sizeof(int) * 8) / numKeysPerRow), numKeysPerWord(numRowsPerWord * numKeysPerRow),
osmeest 0:1324e7d9d471 15 numWords((numRows + (numRowsPerWord-1)) / numRowsPerWord),
osmeest 0:1324e7d9d471 16 data(numWords, 0)
osmeest 0:1324e7d9d471 17 { }
osmeest 0:1324e7d9d471 18
osmeest 0:1324e7d9d471 19 void KeyboardState::clear() {
osmeest 0:1324e7d9d471 20 std::fill(this->data.begin(), this->data.end(), 0);
osmeest 0:1324e7d9d471 21 }
osmeest 0:1324e7d9d471 22
osmeest 0:1324e7d9d471 23 int KeyboardState::getRowInfo(std::size_t row, std::size_t &wordIndex, std::size_t &rowShift, int &rowMask) const
osmeest 0:1324e7d9d471 24 {
osmeest 0:1324e7d9d471 25 std::size_t rowInWord = row % numRowsPerWord;
osmeest 0:1324e7d9d471 26 wordIndex = row / numRowsPerWord;
osmeest 0:1324e7d9d471 27 rowShift = numKeysPerRow * rowInWord;
osmeest 0:1324e7d9d471 28 rowMask = this->rowMask << rowShift;
osmeest 0:1324e7d9d471 29
osmeest 0:1324e7d9d471 30 return this->data[wordIndex];
osmeest 0:1324e7d9d471 31 }
osmeest 0:1324e7d9d471 32
osmeest 0:1324e7d9d471 33 void KeyboardState::setRowState(std::size_t row, int rowState) {
osmeest 0:1324e7d9d471 34 std::size_t wordIndex;
osmeest 0:1324e7d9d471 35 std::size_t rowShift;
osmeest 0:1324e7d9d471 36 int rowMask;
osmeest 0:1324e7d9d471 37 int v = getRowInfo(row, wordIndex, rowShift, rowMask);
osmeest 0:1324e7d9d471 38 v = (v & ~rowMask) | ((rowState & this->rowMask) << rowShift);
osmeest 0:1324e7d9d471 39 this->data[wordIndex] = v;
osmeest 0:1324e7d9d471 40 }
osmeest 0:1324e7d9d471 41
osmeest 0:1324e7d9d471 42 int KeyboardState::getRowState(std::size_t row) const {
osmeest 0:1324e7d9d471 43 std::size_t wordIndex;
osmeest 0:1324e7d9d471 44 std::size_t rowShift;
osmeest 0:1324e7d9d471 45 int rowMask;
osmeest 0:1324e7d9d471 46 int v = getRowInfo(row, wordIndex, rowShift, rowMask);
osmeest 0:1324e7d9d471 47 return (v & rowMask) >> rowShift;
osmeest 0:1324e7d9d471 48 }
osmeest 0:1324e7d9d471 49
osmeest 0:1324e7d9d471 50 bool KeyboardState::getKeyState(std::size_t key) const {
osmeest 0:1324e7d9d471 51 std::size_t row = key / this->numKeysPerRow;
osmeest 0:1324e7d9d471 52 std::size_t keyInRow = key % this->numKeysPerRow;
osmeest 0:1324e7d9d471 53 int keyMask = 1 << keyInRow;
osmeest 0:1324e7d9d471 54
osmeest 0:1324e7d9d471 55 return (getRowState(row) & keyMask) != 0;
osmeest 0:1324e7d9d471 56 }
osmeest 0:1324e7d9d471 57
osmeest 0:1324e7d9d471 58 KeyboardState KeyboardState::operator&(const KeyboardState &other) const {
osmeest 0:1324e7d9d471 59 KeyboardState result(this->numRows, this->numKeysPerRow);
osmeest 0:1324e7d9d471 60
osmeest 0:1324e7d9d471 61 typedef Data::const_iterator SourceIterator;
osmeest 0:1324e7d9d471 62 typedef Data::iterator TargetIterator;
osmeest 0:1324e7d9d471 63
osmeest 0:1324e7d9d471 64 SourceIterator a = this->data.begin();
osmeest 0:1324e7d9d471 65 SourceIterator b = other.data.begin();
osmeest 0:1324e7d9d471 66 TargetIterator t = result.data.begin();
osmeest 0:1324e7d9d471 67 while (a != this->data.end() && b != other.data.end() && t != result.data.end())
osmeest 0:1324e7d9d471 68 {
osmeest 0:1324e7d9d471 69 *t = *a & *b;
osmeest 0:1324e7d9d471 70 ++a; ++b; ++t;
osmeest 0:1324e7d9d471 71 }
osmeest 0:1324e7d9d471 72
osmeest 0:1324e7d9d471 73 return result;
osmeest 0:1324e7d9d471 74 }
osmeest 0:1324e7d9d471 75
osmeest 0:1324e7d9d471 76 bool KeyboardState::operator==(const KeyboardState &other) const {
osmeest 0:1324e7d9d471 77 if (this == &other) {
osmeest 0:1324e7d9d471 78 return true;
osmeest 0:1324e7d9d471 79 }
osmeest 0:1324e7d9d471 80
osmeest 0:1324e7d9d471 81 if (this->numRows != other.numRows || this->numKeysPerRow != other.numKeysPerRow)
osmeest 0:1324e7d9d471 82 return false;
osmeest 0:1324e7d9d471 83
osmeest 0:1324e7d9d471 84 Data::const_iterator p = this->data.begin();
osmeest 0:1324e7d9d471 85 Data::const_iterator q = other.data.begin();
osmeest 0:1324e7d9d471 86 while (p != this->data.end() && q != other.data.end()) {
osmeest 0:1324e7d9d471 87 if (*p != *q) {
osmeest 0:1324e7d9d471 88 return false;
osmeest 0:1324e7d9d471 89 }
osmeest 0:1324e7d9d471 90 ++p; ++q;
osmeest 0:1324e7d9d471 91 }
osmeest 0:1324e7d9d471 92
osmeest 0:1324e7d9d471 93 return true;
osmeest 0:1324e7d9d471 94 }
osmeest 0:1324e7d9d471 95
osmeest 0:1324e7d9d471 96 bool KeyboardState::empty() const {
osmeest 0:1324e7d9d471 97 for(Data::const_iterator p = this->data.begin(); p != this->data.end(); ++p) {
osmeest 0:1324e7d9d471 98 if (*p != 0) {
osmeest 0:1324e7d9d471 99 return false;
osmeest 0:1324e7d9d471 100 }
osmeest 0:1324e7d9d471 101 }
osmeest 0:1324e7d9d471 102
osmeest 0:1324e7d9d471 103 return true;
osmeest 0:1324e7d9d471 104 }
osmeest 0:1324e7d9d471 105
osmeest 0:1324e7d9d471 106 namespace {
osmeest 0:1324e7d9d471 107 int getBitNumber(int v)
osmeest 0:1324e7d9d471 108 {
osmeest 0:1324e7d9d471 109 if (v == 0) {
osmeest 0:1324e7d9d471 110 return -1;
osmeest 0:1324e7d9d471 111 }
osmeest 0:1324e7d9d471 112
osmeest 0:1324e7d9d471 113 int key = 0;
osmeest 0:1324e7d9d471 114 while (v != 1) {
osmeest 0:1324e7d9d471 115 key++;
osmeest 0:1324e7d9d471 116 v >>= 1;
osmeest 0:1324e7d9d471 117 }
osmeest 0:1324e7d9d471 118
osmeest 0:1324e7d9d471 119 return key;
osmeest 0:1324e7d9d471 120 }
osmeest 0:1324e7d9d471 121 }
osmeest 0:1324e7d9d471 122
osmeest 0:1324e7d9d471 123 KeyboardState::KeyPressType KeyboardState::getKeyPressType(int *key) const
osmeest 0:1324e7d9d471 124 {
osmeest 0:1324e7d9d471 125 if (key) {
osmeest 0:1324e7d9d471 126 *key = -1;
osmeest 0:1324e7d9d471 127 }
osmeest 0:1324e7d9d471 128
osmeest 0:1324e7d9d471 129 Data::const_iterator p = this->data.begin();
osmeest 0:1324e7d9d471 130 std::size_t wordIndex = 0;
osmeest 0:1324e7d9d471 131 while (p != this->data.end() && *p == 0) {
osmeest 0:1324e7d9d471 132 ++p;
osmeest 0:1324e7d9d471 133 ++wordIndex;
osmeest 0:1324e7d9d471 134 }
osmeest 0:1324e7d9d471 135 if (p != this->data.end()) {
osmeest 0:1324e7d9d471 136 int v = *p;
osmeest 0:1324e7d9d471 137 if (v != (v & -v)) {
osmeest 0:1324e7d9d471 138 return MultiKeyPress;
osmeest 0:1324e7d9d471 139 }
osmeest 0:1324e7d9d471 140 int k = getBitNumber(v) + wordIndex * this->numKeysPerWord;
osmeest 0:1324e7d9d471 141 ++p;
osmeest 0:1324e7d9d471 142 while (p != this->data.end() && *p == 0) {
osmeest 0:1324e7d9d471 143 ++p;
osmeest 0:1324e7d9d471 144 }
osmeest 0:1324e7d9d471 145 if (p == this->data.end()) {
osmeest 0:1324e7d9d471 146 if (key) {
osmeest 0:1324e7d9d471 147 *key = k;
osmeest 0:1324e7d9d471 148 }
osmeest 0:1324e7d9d471 149 return SingleKeyPress;
osmeest 0:1324e7d9d471 150 }
osmeest 0:1324e7d9d471 151 else {
osmeest 0:1324e7d9d471 152 return MultiKeyPress;
osmeest 0:1324e7d9d471 153 }
osmeest 0:1324e7d9d471 154 }
osmeest 0:1324e7d9d471 155 else {
osmeest 0:1324e7d9d471 156 return Idle;
osmeest 0:1324e7d9d471 157 }
osmeest 0:1324e7d9d471 158 }
osmeest 0:1324e7d9d471 159
osmeest 0:1324e7d9d471 160 void KeyboardState::streamTo(std::ostream &out) const {
osmeest 0:1324e7d9d471 161 using namespace std;
osmeest 0:1324e7d9d471 162 std::size_t width = (this->numKeysPerWord + 3) / 4;
osmeest 0:1324e7d9d471 163 ios_base::fmtflags f = out.flags();
osmeest 0:1324e7d9d471 164 for(Data::const_reverse_iterator p = this->data.rbegin(); p != this->data.rend(); ++p) {
osmeest 0:1324e7d9d471 165 out << hex << setw(width) << setfill('0') << *p;
osmeest 0:1324e7d9d471 166 }
osmeest 0:1324e7d9d471 167 out.flags(f);
osmeest 0:1324e7d9d471 168 }
osmeest 0:1324e7d9d471 169
osmeest 0:1324e7d9d471 170 } // kbd_mgr