Logitech G hub lua script, trying to turn integer to string - lua

function OnEvent(event, arg)
--OutputLogMessage("Event: "..event.." Arg: "..arg.."\n")
-- MP value: 34390, 31219
-- CC: 43405, 15670
-- OK: 36029, 36017
--if IsMouseButtonPressed(2) then
-- x, y = GetMousePosition()
-- OutputLogMessage("Mouse is at %d, %d\n", x, y)
--end
i = 61
while IsMouseButtonPressed(5) do
MoveMouseTo(34390, 31219)
Sleep(100)
PressAndReleaseMouseButton(1)
Sleep(100)
PressAndReleaseKey("%d", i)
i = i + 1
OutputLogMessage(i)
Sleep(100)
PressAndReleaseKey(28)
Sleep(100)
MoveMouseTo(43405, 15670)
PressAndReleaseMouseButton(1)
Sleep(300)
end
I'm trying to convert an integer to a string. I've tried
PressAndReleaseKey(tostring(i))
But that didn't work.
I also tried
PressAndReleaseKey(i)
But that just turns it into a scancode which is "F3" btw.
What I'm trying to do is get it to click on something, type out "61", then increase the number by 1 each time it runs through the cycle.

Try
i = 0x61; -- hexadecimal!!!
PressAndReleaseKey(string.char(i))
That should probably do what you want.
Another approach is using function PressAndReleaseHidKey() - it has more consistent codes for keyboard keys: 4-29 are for letters a-z, 30-39 are for digits 1234567890
For example, PressAndReleaseHidKey(4) is the same as PressAndReleaseKey("a").
The complete list of arguments accepted by PressAndReleaseHidKey, PressHidKey, ReleaseHidKey:
hidcode
description
0x00
Reserved (no event indicated) (not a physical key)
0x01
Keyboard ErrorRollOver (not a physical key)
0x02
Keyboard POSTFail (not a physical key)
0x03
Keyboard ErrorUndefined (not a physical key)
0x04
Keyboard a and A
0x05
Keyboard b and B
0x06
Keyboard c and C
0x07
Keyboard d and D
0x08
Keyboard e and E
0x09
Keyboard f and F
0x0A
Keyboard g and G
0x0B
Keyboard h and H
0x0C
Keyboard i and I
0x0D
Keyboard j and J
0x0E
Keyboard k and K
0x0F
Keyboard l and L
0x10
Keyboard m and M
0x11
Keyboard n and N
0x12
Keyboard o and O
0x13
Keyboard p and P
0x14
Keyboard q and Q
0x15
Keyboard r and R
0x16
Keyboard s and S
0x17
Keyboard t and T
0x18
Keyboard u and U
0x19
Keyboard v and V
0x1A
Keyboard w and W
0x1B
Keyboard x and X
0x1C
Keyboard y and Y
0x1D
Keyboard z and Z
0x1E
Keyboard 1 and !
0x1F
Keyboard 2 and #
0x20
Keyboard 3 and #
0x21
Keyboard 4 and $
0x22
Keyboard 5 and %
0x23
Keyboard 6 and ^
0x24
Keyboard 7 and &
0x25
Keyboard 8 and *
0x26
Keyboard 9 and (
0x27
Keyboard 0 and )
0x28
Keyboard Return (ENTER)
0x29
Keyboard ESCAPE
0x2A
Keyboard Backspace
0x2B
Keyboard Tab
0x2C
Keyboard Spacebar
0x2D
Keyboard - and _
0x2E
Keyboard = and +
0x2F
Keyboard [ and {
0x30
Keyboard ] and }
0x31
Keyboard \ and
0x32
Keyboard Non-US # and ~
0x33
Keyboard ; and :
0x34
Keyboard ' and "
0x35
Keyboard Grave Accent and Tilde
0x36
Keyboard , and <
0x37
Keyboard . and >
0x38
Keyboard / and ?
0x39
Keyboard Caps Lock
0x3A
Keyboard F1
0x3B
Keyboard F2
0x3C
Keyboard F3
0x3D
Keyboard F4
0x3E
Keyboard F5
0x3F
Keyboard F6
0x40
Keyboard F7
0x41
Keyboard F8
0x42
Keyboard F9
0x43
Keyboard F10
0x44
Keyboard F11
0x45
Keyboard F12
0x46
Keyboard PrintScreen
0x47
Keyboard Scroll Lock
0x48
Keyboard Pause
0x49
Keyboard Insert
0x4A
Keyboard Home
0x4B
Keyboard PageUp
0x4C
Keyboard Delete
0x4D
Keyboard End
0x4E
Keyboard PageDown
0x4F
Keyboard RightArrow
0x50
Keyboard LeftArrow
0x51
Keyboard DownArrow
0x52
Keyboard UpArrow
0x53
Keypad Num Lock and Clear
0x54
Keypad /
0x55
Keypad *
0x56
Keypad -
0x57
Keypad +
0x58
Keypad ENTER
0x59
Keypad 1 and End
0x5A
Keypad 2 and Down Arrow
0x5B
Keypad 3 and PageDn
0x5C
Keypad 4 and Left Arrow
0x5D
Keypad 5
0x5E
Keypad 6 and Right Arrow
0x5F
Keypad 7 and Home
0x60
Keypad 8 and Up Arrow
0x61
Keypad 9 and PageUp
0x62
Keypad 0 and Insert
0x63
Keypad . and Delete
0x64
Keyboard Non-US \ and |
0x65
Keyboard Application (context menu key)
0x66
Keyboard Power (not a physical key)
0x67
Keypad =
0x68
Keyboard F13
0x69
Keyboard F14
0x6A
Keyboard F15
0x6B
Keyboard F16
0x6C
Keyboard F17
0x6D
Keyboard F18
0x6E
Keyboard F19
0x6F
Keyboard F20
0x70
Keyboard F21
0x71
Keyboard F22
0x72
Keyboard F23
0x73
Keyboard F24
0x74
Keyboard Execute
0x75
Keyboard Help
0x76
Keyboard Menu
0x77
Keyboard Select
0x78
Keyboard Stop
0x79
Keyboard Again
0x7A
Keyboard Undo
0x7B
Keyboard Cut
0x7C
Keyboard Copy
0x7D
Keyboard Paste
0x7E
Keyboard Find
0x7F
Keyboard Mute
0x80
Keyboard Volume Up
0x81
Keyboard Volume Down
0x82
Keyboard Locking Caps Lock
0x83
Keyboard Locking Num Lock
0x84
Keyboard Locking Scroll Lock
0x85
Keypad Comma (Brazilian ".")
0x86
Keypad Equal Sign (on AS/400 keyboard)
0x87
Keyboard International1 (Brazilian "/" and "?", Kanji)
0x88
Keyboard International2
0x89
Keyboard International3
0x8A
Keyboard International4
0x8B
Keyboard International5
0x8C
Keyboard International6
0x8D
Keyboard International7 (Double-byte/Single-byte)
0x8E
Keyboard International8
0x8F
Keyboard International9
0x90
Keyboard LANG1 (Hangul/English, Korean)
0x91
Keyboard LANG2 (Hanja, Korean)
0x92
Keyboard LANG3 (Katakana, Japanese)
0x93
Keyboard LANG4 (Hiragana, Japanese)
0x94
Keyboard LANG5 (Zenkaku/Hankaku, Japanese)
0x95
Keyboard LANG6
0x96
Keyboard LANG7
0x97
Keyboard LANG8
0x98
Keyboard LANG9
0x99
Keyboard Alternate Erase
0x9A
Keyboard SysReq/Attention
0x9B
Keyboard Cancel
0x9C
Keyboard Clear
0x9D
Keyboard Prior
0x9E
Keyboard Return
0x9F
Keyboard Separator
0xA0
Keyboard Out
0xA1
Keyboard Oper
0xA2
Keyboard Clear/Again
0xA3
Keyboard CrSel/Props
0xA4
Keyboard ExSel
0xA5
(Reserved)
0xA6
(Reserved)
0xA7
(Reserved)
0xA8
(Reserved)
0xA9
(Reserved)
0xAA
(Reserved)
0xAB
(Reserved)
0xAC
(Reserved)
0xAD
(Reserved)
0xAE
(Reserved)
0xAF
(Reserved)
0xB0
Keypad 00
0xB1
Keypad 000
0xB2
Thousands separator (locale-dependent symbol)
0xB3
Decimal Separator (locale-dependent symbol)
0xB4
Currency Unit (locale-dependent symbol)
0xB5
Currency Sub-unit (locale-dependent symbol)
0xB6
Keypad (
0xB7
Keypad )
0xB8
Keypad {
0xB9
Keypad }
0xBA
Keypad Tab
0xBB
Keypad Backspace
0xBC
Keypad A
0xBD
Keypad B
0xBE
Keypad C
0xBF
Keypad D
0xC0
Keypad E
0xC1
Keypad F
0xC2
Keypad XOR
0xC3
Keypad ^
0xC4
Keypad %
0xC5
Keypad <
0xC6
Keypad >
0xC7
Keypad &
0xC8
Keypad &&
0xC9
Keypad
0xCA
Keypad
0xCB
Keypad :
0xCC
Keypad #
0xCD
Keypad Space
0xCE
Keypad #
0xCF
Keypad !
0xD0
Keypad Memory Store
0xD1
Keypad Memory Recall
0xD2
Keypad Memory Clear
0xD3
Keypad Memory Add
0xD4
Keypad Memory Subtract
0xD5
Keypad Memory Multiply
0xD6
Keypad Memory Divide
0xD7
Keypad +/-
0xD8
Keypad Clear
0xD9
Keypad Clear Entry
0xDA
Keypad Binary
0xDB
Keypad Octal
0xDC
Keypad Decimal
0xDD
Keypad Dexadecimal
0xDE
(Reserved)
0xDF
(Reserved)
0xE0
Keyboard LeftControl
0xE1
Keyboard LeftShift
0xE2
Keyboard LeftAlt
0xE3
Keyboard Left GUI (Left Win)
0xE4
Keyboard RightControl
0xE5
Keyboard RightShift
0xE6
Keyboard RightAlt
0xE7
Keyboard Right GUI (Right Win)
If you want to type "61":
i = 61
for key in tostring(i):gmatch"%d" do
PressAndReleaseKey(key)
Sleep(100)
end

Related

How to implement ESP8266 5 kHz PWM?

I need to realise a PWM output with 5 kHz +/- 5%. (Presumably due to a filter circuit into which this feeds over which I have no control.)
Is this realisable with a ESP8266 (ideally with NodeMCU)?
I realise that the software PWM of the ESP8266 has a maximum frequency of 1 kHz while the sigma-delta can be used to implement a PWM with a fixed frequency of about 300 kHz.
So is there a reliable way to achieve 5 kHz? I know some people experimented with the I2S peripheral for waveform output but I am unsure whether it can be used for 5kHz output.
Has anybody looked at into a similar problem before?
The essential code is:
#define qap 2 // Quick As Possible ... Duty cycle only 0, 50, 100%
#define HFreq 5150
#define pPulse D2 // a NodeMCU/ESP8266 GPIO PWM pin
analogWriteRange(qap); analogWriteFreq( HFreq ); analogWrite(pPulse, 1); // start PWM
TL;DR
Just did some crude benchamrks
// had HFreq=126400 with 75 KHz pulse at 80 MHz ESP clock, every 1 sec but proof of evidence lost
nominally with 80 MHz clock got
// 72.24 KHz 361178 2015061929
// 72.23 KHz 361163 2415062390
// 72.23 KHz 361133 2815062824
and
// 141.52 KHz 353809 2009395076
// 141.54 KHz 353846 2409395627
// 141.52 KHz 353806 2809395946
with 160 MHz clock
CAVEATS!!!
1. The duty cycle range is 2!
2. As well the system had no other conditioning, so other timing artifacts were still present from Serial IO etc. In particular instability due to the WDT and WiFi penultimately appeared. (Anyhow, presumably this is an issue only when the ESP8266 is under stress and duress.)
// 141.50 KHz 353754 619466806
// 141.52 KHz 353810 1019467038
// ...
// ad infinitum cum tempore finitum, infinitus est ad nauseum?
// ...
// 141.54 KHz 353857 735996888
//
// ets Jan 8 2013,rst cause:4, boot mode:(1,7)
//
//wdt reset
When using the following code to generate a 5 KHz square wave signal, the considerations above are not an issue and do not occur.
// ------------ test results for 80 MHz clock --------------
//
//
// PWM pulse test
//
// F_CPU: 80000000L
// ESP8266_CLOCK: 80000000UL
// PWM "freq.": 5150
//
//
// connect D1 to D2
//
//
// raw MPU
// frequency count cycle
// 0.00 KHz 1 407976267
// 4.74 KHz 9482 567976702
// 5.00 KHz 10007 727977137
// 5.00 KHz 10006 887977572
// 5.00 KHz 10006 1047978007
// 5.00 KHz 10007 1207978442
// 5.00 KHz 10006 1367978877
// 5.00 KHz 10006 1527979312
// 5.00 KHz 10007 1687979747
// 5.00 KHz 10006 1847980182
// 5.00 KHz 10006 2007980617
// 5.00 KHz 10007 2167981052
// 5.00 KHz 10006 2327981487
// 5.00 KHz 10006 2487981922
// 5.00 KHz 10007 2647982357 ...
//
// crude testing for 5KHz signal
// extracted from:
// highest frequency / shortest period pin pulse generate / detect test
//
// uses raw ESP8266 / NodeMCU V1.0 hardware primitive interface of Arduino IDE (no included libraries)
//
// timing dependencies: WDT, WiFi, I2S, I2C, one wire, UART, SPI, ...
//
// Arduino GPIO 16 5 4 0 2 14 12 13 15 3 1 0 1 2 3 4 5 ... 12 13 14 15 16
// NodeMCU D pin 0 1 2 3 4 5 6 7 8 9 10 3 10 4 9 2 1 ... 6 7 5 8 0
// | | | | | | | | | | |
// a WAKE | | F Tx1 | | Rx2 Tx2 Rx0 Tx0
// k (NO PWM or | | L blue | | | |
// a' interrupt) | S A * H | H | H | | * led's
// s red S D S S M S H
// * C A H C I I C
// L T L S M S
// K A K O O
// └ - - - - └----UART's----┘
// └--I2C--┘ └-----SPI------┘
//
// rules of engagement are obscure and vague for effects of argument values for the paramters of these functions:
// analogWriteRange(qap); analogWriteFreq( HFreq ); analogWrite(pPulse, 1);
//
// http://stackoverflow.com/questions/42112357/how-to-implement-esp8266-5-khz-pwm
//
// system #defines: F_CPU ESP8266_CLOCK
#define pInt D1 // HWI pin: NOT D0 ie. GPIO16 is not hardwared interrupt or PWM pin
#define pPulse D2 // PWM pulsed frequency source ... ditto D0 (note: D4 = blue LED)
#define countFor 160000000UL
#define gmv(p) #p // get macro value
#define em(p) gmv(p) // evaluate macro
#define qap 2 // minimal number of duty cycle levels (0, 50, 100% ) Quick As Possible ...
#define HFreq 5150 //((long int) F_CPU==80000000L ? 125000 : 250000) // ... to minimize time of a cycle period
// max values ^ and ^ found empirically
// had HFreq=126400 with 75 KHz pulse at 80 MHz ESP clock, every 1 sec but proof of evidence lost
#define infoTxt (String) \
"\n\n\t PWM pulse test " \
"\n F_CPU: " em(F_CPU) \
"\n ESP8266_CLOCK: " em(ESP8266_CLOCK) \
"\n PWM \"freq.\": " + HFreq + "\n" \
"\n\n connect " em(pInt) " to " em(pPulse) "\n" \
"\n\n raw MPU " \
" \n frequency count cycle "
long int oc=1, cntr=1;
unsigned long int tc=0;
void hwISR(){ cntr++; } // can count pulses if pInt <---> to pPulse
void anISR(){ tc=ESP.getCycleCount(); timer0_write( countFor + tc ); oc=cntr; cntr=1; }
void setup() { // need to still confirm duty cycle=50% (scope it or ...)
noInterrupts();
Serial.begin(115200); Serial.println(infoTxt); delay(10); // Serial.flush(); Serial.end(); // Serial timing?
analogWriteRange(qap); analogWriteFreq( HFreq ); analogWrite(pPulse, 1); // start PWM
pinMode( pInt, INPUT ); attachInterrupt(pInt, hwISR, RISING); // count pulses
timer0_isr_init(); timer0_attachInterrupt( anISR ); anISR(); //
interrupts();
}
void loop() { delay(10); if (oc==0) return;
Serial.println((String)" "+(oc/1000.0*F_CPU/countFor)+" KHz "+oc+" "+tc); oc=0; }
//
You can also use the hardware SPI interface which has an adjustable clock speed.
By writing continuous data, the output waveform appears on SCLK.
I've figured out the abovementioned while creating a knight rider effect with IC 74hc595 on ESP8266, using MicroPython (which is indeed slow, as being a script language).
It worked for me up to 4MHz SPI clock speed.
The disadvantage is, for permanent waveform, you need to write data to MOSI forever (as when SPI data buffer goes empty, there is no signal on SCLK anymore).

Delphi XE7 TBitBtn Image wrong Displayed at run time

I have a project developed with Delphi 7 and VCL, that compiles and works with the new Delphi XE7 without any modification, the only issue that I'm experiencing is that the Glyph image of the TBitBtn is wrong displayed(as you can see the color and the position are not the same) at run time despite is well displayed at design time .
Design Time :
RunTime :
What can cause the problem ?
NOTE
With the old Delphi 7 I don't have this issue : the image is correctly displayed both at design and run time .
Following the first 3 lines of the Glyph data in the dfm :
Glyph.Data = {
36050000424D3605000000000000360400002800000010000000100000000100
080000000000000100000000000000000000000100000000000000164900001C
4D0000275700003C7100003D6E00004483000046760000467B0000548C00005B
...
that it is the same in Delphi 7 and Delphi XE7.
If I click on the Glyph property of TBitBtn I can see the image(the wrong one) in the dialog and if I confirm with OK, the IDE changes the Glyph property in the DFM files in this way(diff output) :
Glyph.Data = {
- 36340000424D3638000000000000360800002800000040000000400000000100
- 1800000000000030000000000000000000000001000000000000724242007B47
- 47007D4849007E4C4B00804C4C0081524F008155500083535200845754008458
- 56008459590085525200855B5700875D58008B6260008B6361008B6362008C65
- 63008C6664008D615C008D6665008D6766008E5A5A008F696800906B6A00916C
- 6B00935F5F00936F6E0094616100946F6F00957170009773730097747400986A
- 6600997777009C7B7B009E7D7D009F6B6B00A06C6C00A1818100A26E6E00A37B
- 7400A3817600A4707000A6727200A67C7600A6867A00A7737300A7877B00A983
- 7B00AA8E8E00AB8C7F00AC8A7F00AC8F8F00AE918300AE939300AF959500B190
- 8400B1958700B2999900B37F7F00B49B9B00B79F9F00B8848400B89FA000BA86
- 8600BB878700BBA5A500BC888800BE8A8A00C08B8B00C18D8D00C1A89700C2AD
- AD00C38F8F00C4A69800C5919100C7929200C8939300C9949400CA959500CB95
- 9600CB969600CCA79D00CDA49D00CF999A00CFBBA700D09D9C00D0BCA700D0BC
- A800D0BDA900D19C9C00D1BDA900D29F9E00D39E9E00D3AAA300D49F9F00D4B2
- A700D4C1AC00D4C1AD00D4C2AD00D4C5C500D6ABA500D6C8C800D7ADA700D7C5
- B000D8AFA800D8C7B000D8C7B100D8CACB00D9B1A900D9BEAE00DAB2AA00DAB3
- AA00DAB3AB00DACAB300DACECE00DBA6A600DBB4AB00DBB4AC00DBB5AC00DBB6
- AC00DBC1B000DBCBB400DBCCB400DCB6AC00DCB6AD00DCCCB400DDB7AE00DDB8
- AE00DDCDB600DEADAB00DEBAAF00DEBBB000DED4D400DFBCB100DFBDB100DFBD
- B200DFBEB200DFD0B900E0ADAC00E0B4AE00E0BDB200E0BEB200E0BFB300E0D2
- BA00E1ADAD00E1C0B400E1C1B400E1D1BA00E2BAB200E2C3B500E3C4B600E3C5
- B700E3C7B700E4C5B700E4C7B700E4C7B800E4C8B800E4C9B900E5C9B900E5CA
- B900E5CABA00E5CBBA00E6CCBC00E6DDDD00E7CEBD00E7D7C000E8B8B500E8B9
- B600E8BAB600E8C3B900E8CFBD00E8CFBE00E8D0BE00E8D0BF00E8D1BF00E9C7
- BB00E9D1BF00E9D2BF00E9D2C000E9D3C000EAC7BC00EBD5C200ECB9B800ECCE
- BF00ECD4C200ECD7C300ECD8C300ECD8C400ECD9C400ECE6E600EDD9C400EDD9
- C500EDDAC500EDDBC500EED3C300EEDBC700EEDCC700EEDDC800EFCCC100EFDD
- C800F0BEBC00F0DFC900F0E0CA00F0E1CA00F0E1CB00F1E1CB00F1E2CB00F1E2
- CC00F1E3CC00F1EDED00F2C4C100F2C9C200F2DDCA00F2E3CC00F2E4CC00F2E4
- CD00F2E5CD00F2EDEE00F3E5CD00F3E5CE00F3E6CE00F3EFEF00F4F0F000F4F0
- F100F5E5CF00F5F2F200F6EBD200F6ECD300F6F3F400F7ECD300F7EDD300F7ED
- D400F7EED400F8EDD400F8EED400F8EED500F8EFD500F8F0D500F8F6F600F9EF
- D500F9F0D600F9F1D600F9F1D700F9F7F700FAF2D700FAF8F800FAF9F900FBF4
- D900FBF9F900FBFAFA00FCFBFB00FDFDFD00FEFEFE00FFFFFF00FFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFCFCD3C5C5C7B5B5D7CBCBE4DC
- DCEFEAEAF7F5F5FDFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ 36300000424D3634000000000000360400002800000040000000400000000100
+ 1800000000000030000000000000000000000001000000000000FFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
## -469,7 +403,43 ## object Form1: TForm1
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF}
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000}
At this link there is the complete DFM file that present the problem .
It appears to be a mismatch between NumGlyphs property and actual number of Glyphs in the image.
I can not explain why you don't have the problem in Delphi 7, but I can create the same effect in XE7 with e.g. a 64x64 TBitBtn, a 256 pixel wide image, that has four glyphs (64 pixels wide each), if I set NumGlyphs := 3.
In design time, the first glyph is shown. The calculation of pixels per glyph (256 div 3) would give a width of 85 pixels. But that doesn't matter since we are seeing the first glyph, beginning from first pixel.
In runtime it seems the button is in disabled (Enabled=false) state, and thus it shows the second glyph, but because of wrong value in NumGlyphs it shows the pixels starting with left 85 forward, thus cutting 21 pixels from left and bleeding those 21 pixels from the third glyph into view.
You can compare the beginning of the Glyph.Data in the .dfm files (in D7 and XE7) with the following break up
Glyph.Data = {
36C00000424D36C0000000000000360000002800000000010000400000000100
18000000000000C00000C40E0000C40E00000000000000000000F0F0F0F0F0F0
F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0
...
interpreted as
offs 36C00000 file size = 0x0000C036 = 49206
0000 424D 'BM' signature
0002 36C00000 file size
0006 0000 reserved 2 bytes
0008 0000 reserved 2 bytes
000A 36000000 pixel array offset = 0x36 = 54
000E 28000000 BITMAPINFOHEADER size 0x28 = 40
0012 00010000 bitmap width 0x0100 = 256
0016 40000000 bitmap height 0x0040 = 64
001A 0100 num of color planes = 1
001C 1800 num of bits per pixel = 24
001E 00000000 compression method (0 = none)
0022 00C00000 raw bitmap data size 49152 = 256 x 64 x 3 bytes
0026 C40E0000 horizontal resolution (pix per meter) 3780/m
002A C40E0000 vertical resolution (pix per meter) 3780/m
002E 00000000 num of colors in color palette or 0 for default 2^n
0032 00000000 num of important colors used, or 0 for every color is important
pixel array follows
0036 F0F0F0F0F0F0
003C F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0
Delphi adds its own size in front of the actual .bmp file. Offset is from the 'BM' signature
Edit after additional data
The three lines that are the same in D7 and XE7 interpreted:
Glyph.Data = {
36050000 File size 1334
424D 'BM'
36050000 file size 1334
0000
0000
36040000 1078 pix arr offset
28000000 40 header size
10000000 16 bmp width
10000000 16 bmp height
0100 1 color planes
0800 8 bits per pix
00000000 no compression
00010000 256 raw bitmap data size
00000000 0 horiz pix per meter
00000000 0 vert ppm
00010000 256 colors in palette
00000000 all colors important
00164900001C ....
Doesn't really fit the image you posted, which is 64 x 64 within the thin gray border and has 1628 unique colors.
But what really puzzles me is the change when you click the Glyph property. According the diff listing the three first replaced (-) lines don't match the above three lines at all. Break up follows:
{
36340000 13366
424D 'BM'
36380000 14390
0000
0000
36080000 2102 pix arr offset
28000000 40 header size
40000000 64 width
40000000 64 height
0100
1800
00000000
00300000 12288 raw bmp data size
00000000
00000000
00010000 256 colors in palette
00000000
724242007B47 ...}
Now, this matches the size (64 x 64) but not number of colors. Anyway the rest is corrupt and useless data. Go figure. The only solution I can think of is to replace the image.
Since I already had your posted image in my editor, I made a triple image (normal, disabled, pressed) 192 x 64 and tested in D7 as well as in XE7 and works fine for me.
Here, since your original is lost, as a friendly seasons gift :-)
I decided to enter another answer instead of editing the previous, because the first answer was given by the information available at that time, and although not the correct one, may serve a purpose. In the following is an answer I believe is the correct one.
The short answer
Most of the images had partly corrupt headers. The reason might be in the original images, conversion from other image formats or in Delphi7, but I couldn't set aside enough time to debug the code. If I had the time I would look at TBitmap.ReadDIB and TBitmap.Changed. The error surfaces in Delphi XE7 (possibly also in earlier version) because some changes have been made in above mentioned methods.
The cure is to redraw the images in a decent image editor.
The longer answer
I came to the corrupt images conclusion by investigating Glyph.Data of a couple of TBitBtn controls in the .dfm file. Those that seem to be wrong have similar errors in the bitmap headers. Let's look at one of them:
ToolButton1: TBitBtn
Glyph.Data = {
36340000424D3638000000000000360800002800000040000000400000000100
1800000000000030000000000000000000000001000000000000724242007B47
...}
Glyph.BitmapSize = 13366
bmfh.bfType = BM
bmfh.bfSize = 14390
bmfh.bfReserved1 = 0
bmfh.bfReserved2 = 0
bmfh.bfOffBits = 2102
bmih.biSize = 40
bmih.biWidth = 64
bmih.biHeight = 64
bmih.biPlanes = 1
bmih.biBitCount = 24
bmih.biCompression = 0
bmih.biSizeImage = 12288
bmih.biXPelsPerMeter = 0
bmih.biYPelsPerMeter = 0
bmih.biClrUsed = 256
bmih.biClrImportant = 0
The structure of the whole Glyph.Data is
Glyph.BitmapSize (size 4 bytes), managed by Delphi
BITMAPFILEHEADER (size 14 bytes)
BITMAPINFOHEADER (size 40 bytes)
bmiColors array (size, when used, should be biClrUsed * SizeOf(TRGBQuad) or 1024 in this case)
bmBits (pixel values, either indexes to bmiColors or direct RGB(A) color values)
The problems are:
Glypf.BitmapSize is 13366 but bmpfh.bfSize reports it to be 14390, a difference of 1024 bytes.
Offset of pixel array is reported to be 2102. Subtracting size of bmfh (14) and bmih (40) leaves 2048 bytes for the colortable, bmiColors. Should be 1024.
The actual image data in the .dfm is 1024 bytes for the color table, bmiColors. When the image is read in XE7 the erroneous bfOffBits offsets the beginning of the pixel data and thus we see the shift in the image and its colors.
When the image is 'reloaded' by opening the image editor the error is repeted with already erroneous data and the image and color shifts are exaggerated.
As said above, the cure is to redraw the images. One could of course also attempt to change the .dfm files directly.

How CUDA constant memory allocation works?

I'd like to get some insight about how constant memory is allocated (using CUDA 4.2). I know that the total available constant memory is 64KB. But when is this memory actually allocated on the device? Is this limit apply to each kernel, cuda context or for the whole application?
Let's say there are several kernels in a .cu file, each using less than 64K constant memory. But the total constant memory usage is more than 64K. Is it possible to call these kernels sequentially? What happens if they are called concurrently using different streams?
What happens if there is a large CUDA dynamic library with lots of kernels each using different amounts of constant memory?
What happens if there are two applications each requiring more than half of the available constant memory? The first application runs fine, but when will the second app fail? At app start, at cudaMemcpyToSymbol() calls or at kernel execution?
Parallel Thread Execution ISA Version 3.1 section 5.1.3 discusses constant banks.
Constant memory is restricted in size, currently limited to 64KB which
can be used to hold statically-sized constant variables. There is an
additional 640KB of constant memory, organized as ten independent 64KB
regions. The driver may allocate and initialize constant buffers in
these regions and pass pointers to the buffers as kernel function
parameters. Since the ten regions are not contiguous, the driver
must ensure that constant buffers are allocated so that each buffer
fits entirely within a 64KB region and does not span a region
boundary.
A simple program can be used to illustrate the use of constant memory.
__constant__ int kd_p1;
__constant__ short kd_p2;
__constant__ char kd_p3;
__constant__ double kd_p4;
__constant__ float kd_floats[8];
__global__ void parameters(int p1, short p2, char p3, double p4, int* pp1, short* pp2, char* pp3, double* pp4)
{
*pp1 = p1;
*pp2 = p2;
*pp3 = p3;
*pp4 = p4;
return;
}
__global__ void constants(int* pp1, short* pp2, char* pp3, double* pp4)
{
*pp1 = kd_p1;
*pp2 = kd_p2;
*pp3 = kd_p3;
*pp4 = kd_p4;
return;
}
Compile this for compute_30, sm_30 and execute cuobjdump -sass <executable or obj> to disassemble you should see
Fatbin elf code:
================
arch = sm_30
code version = [1,6]
producer = cuda
host = windows
compile_size = 32bit
identifier = c:/dev/constant_banks/kernel.cu
code for sm_30
Function : _Z10parametersiscdPiPsPcPd
/*0008*/ /*0x10005de428004001*/ MOV R1, c [0x0] [0x44]; // stack pointer
/*0010*/ /*0x40001de428004005*/ MOV R0, c [0x0] [0x150]; // pp1
/*0018*/ /*0x50009de428004005*/ MOV R2, c [0x0] [0x154]; // pp2
/*0020*/ /*0x0001dde428004005*/ MOV R7, c [0x0] [0x140]; // p1
/*0028*/ /*0x13f0dc4614000005*/ LDC.U16 R3, c [0x0] [0x144]; // p2
/*0030*/ /*0x60011de428004005*/ MOV R4, c [0x0] [0x158]; // pp3
/*0038*/ /*0x70019de428004005*/ MOV R6, c [0x0] [0x15c]; // pp4
/*0048*/ /*0x20021de428004005*/ MOV R8, c [0x0] [0x148]; // p4
/*0050*/ /*0x30025de428004005*/ MOV R9, c [0x0] [0x14c]; // p4
/*0058*/ /*0x1bf15c0614000005*/ LDC.U8 R5, c [0x0] [0x146]; // p3
/*0060*/ /*0x0001dc8590000000*/ ST [R0], R7; // *pp1 = p1
/*0068*/ /*0x0020dc4590000000*/ ST.U16 [R2], R3; // *pp2 = p2
/*0070*/ /*0x00415c0590000000*/ ST.U8 [R4], R5; // *pp3 = p3
/*0078*/ /*0x00621ca590000000*/ ST.64 [R6], R8; // *pp4 = p4
/*0088*/ /*0x00001de780000000*/ EXIT;
/*0090*/ /*0xe0001de74003ffff*/ BRA 0x90;
/*0098*/ /*0x00001de440000000*/ NOP CC.T;
/*00a0*/ /*0x00001de440000000*/ NOP CC.T;
/*00a8*/ /*0x00001de440000000*/ NOP CC.T;
/*00b0*/ /*0x00001de440000000*/ NOP CC.T;
/*00b8*/ /*0x00001de440000000*/ NOP CC.T;
...........................................
Function : _Z9constantsPiPsPcPd
/*0008*/ /*0x10005de428004001*/ MOV R1, c [0x0] [0x44]; // stack pointer
/*0010*/ /*0x00001de428004005*/ MOV R0, c [0x0] [0x140]; // p1
/*0018*/ /*0x10009de428004005*/ MOV R2, c [0x0] [0x144]; // p2
/*0020*/ /*0x0001dde428004c00*/ MOV R7, c [0x3] [0x0]; // kd_p1
/*0028*/ /*0x13f0dc4614000c00*/ LDC.U16 R3, c [0x3] [0x4]; // kd_p2
/*0030*/ /*0x20011de428004005*/ MOV R4, c [0x0] [0x148]; // p3
/*0038*/ /*0x30019de428004005*/ MOV R6, c [0x0] [0x14c]; // p4
/*0048*/ /*0x20021de428004c00*/ MOV R8, c [0x3] [0x8]; // kd_p4
/*0050*/ /*0x30025de428004c00*/ MOV R9, c [0x3] [0xc]; // kd_p4
/*0058*/ /*0x1bf15c0614000c00*/ LDC.U8 R5, c [0x3] [0x6]; // kd_p3
/*0060*/ /*0x0001dc8590000000*/ ST [R0], R7;
/*0068*/ /*0x0020dc4590000000*/ ST.U16 [R2], R3;
/*0070*/ /*0x00415c0590000000*/ ST.U8 [R4], R5;
/*0078*/ /*0x00621ca590000000*/ ST.64 [R6], R8;
/*0088*/ /*0x00001de780000000*/ EXIT;
/*0090*/ /*0xe0001de74003ffff*/ BRA 0x90;
/*0098*/ /*0x00001de440000000*/ NOP CC.T;
/*00a0*/ /*0x00001de440000000*/ NOP CC.T;
/*00a8*/ /*0x00001de440000000*/ NOP CC.T;
/*00b0*/ /*0x00001de440000000*/ NOP CC.T;
/*00b8*/ /*0x00001de440000000*/ NOP CC.T;
.....................................
I annotated to the right of the SASS.
On sm30 you can see that parameters are passed in constant bank 0 starting at offset 0x140.
User defined __constant__ variables are defined in constant bank 3.
If you execute cuobjdump --dump-elf <executable or obj> you can find other interesting constant information.
32bit elf: abi=6, sm=30, flags = 0x1e011e
Sections:
Index Offset Size ES Align Type Flags Link Info Name
1 34 142 0 1 STRTAB 0 0 0 .shstrtab
2 176 19b 0 1 STRTAB 0 0 0 .strtab
3 314 d0 10 4 SYMTAB 0 2 a .symtab
4 3e4 50 0 4 CUDA_INFO 0 3 b .nv.info._Z9constantsPiPsPcPd
5 434 30 0 4 CUDA_INFO 0 3 0 .nv.info
6 464 90 0 4 CUDA_INFO 0 3 a .nv.info._Z10parametersiscdPiPsPcPd
7 4f4 160 0 4 PROGBITS 2 0 a .nv.constant0._Z10parametersiscdPiPsPcPd
8 654 150 0 4 PROGBITS 2 0 b .nv.constant0._Z9constantsPiPsPcPd
9 7a8 30 0 8 PROGBITS 2 0 0 .nv.constant3
a 7d8 c0 0 4 PROGBITS 6 3 a00000b .text._Z10parametersiscdPiPsPcPd
b 898 c0 0 4 PROGBITS 6 3 a00000c .text._Z9constantsPiPsPcPd
.section .strtab
.section .shstrtab
.section .symtab
index value size info other shndx name
0 0 0 0 0 0 (null)
1 0 0 3 0 a .text._Z10parametersiscdPiPsPcPd
2 0 0 3 0 7 .nv.constant0._Z10parametersiscdPiPsPcPd
3 0 0 3 0 b .text._Z9constantsPiPsPcPd
4 0 0 3 0 8 .nv.constant0._Z9constantsPiPsPcPd
5 0 0 3 0 9 .nv.constant3
6 0 4 1 0 9 kd_p1
7 4 2 1 0 9 kd_p2
8 6 1 1 0 9 kd_p3
9 8 8 1 0 9 kd_p4
10 16 32 1 0 9 kd_floats
11 0 192 12 10 a _Z10parametersiscdPiPsPcPd
12 0 192 12 10 b _Z9constantsPiPsPcPd
The kernel parameter constant bank is versioned per launch so that concurrent kernels can be executed. The compiler and user constants are per CUmodule. It is the responsibility of the developer to manage coherency of this data. For example, the developer has to ensure that a cudaMemcpyToSymbol is update in a safe manner.

Cannot parse Width/Height in AVC SPS

Here is the information which I have parsed out of an avcC atom in an mp4 container
The avc extradata Conforms with ISO/IEC 14496-15:2004(E) 5.2.4.1.1
> 0x01 0x42 0x00 0x1E 0xFF 0xE1 0x00 0x0E
Configuration Version: 1 u(8)<br>
AVCProfileIndication: 66 u(8)<br>
profile_compatability: 0 u(8)<br>
AVCLevelIndication: 30 u(8)<br>
bit(6) reserved = '111111' b <br>
unsigned int (2) lengthSizeMinusOne = '11' <br>
bit(3) reseved = '111' <br>
unsigned int (5) numOfSequenceParameterSets = 1 <br>
unsigned int (16) sequenceParameterSetLength = 14 <br>
SPS
> 0x67 0x42 0x00 0x1E 0x8D 0x68 0x6E 0x03 0xDA 0x6A 0x0C 0x02 0x0C 0x04 <br>
avC data Continued
> 0x01 0x00 0x04 <br>
unsigned int (8) numOfPictureParameterSets: 1 <br>
unsigned int (16) pictureParameterSetLength: 4 <br>
PPS <br>
>0x68 0xCE 0x74 0xC8
The contents of the SPS appears to give incorrect results regarding pic_width_in_mbs_minus1 (5) and I do not believe there are any emulation_3_byte preventions. Am I missing something obvious? I am parsing the SPS according to ISO/IEC 14496-10:2004(E) which is the same SPS parsing information found here.
Image is 96x16 (why?)
Sequence Parameter Set
profile_idc 66
constraint_set0_flag 0
constraint_set1_flag 0
constraint_set2_flag 0
constraint_set3_flag 0
level_idc 30
seq_parameter_set_id 0
// ...
num_ref_frames 1
gaps_in_frame_num_value_allowed_flag 0
pic_width_in_mbs_minus1 5
pic_height_in_map_units_minus1 0
frame_mbs_only_flag 1
direct_8x8_inference_flag 1
frame_cropping_flag 0
vui_parameters_present_flag 0
// ...
Picture Parameter Set
pic_parameter_set_id 0
seq_parameter_set_id 0
entropy_coding_mode_flag 0
num_slice_groups_minus1 0
// ...

SSE2: How to reduce a _m128 to a word

What's the best way ( sse2 ) to reduce a _m128 ( 4 words a b c d) to one word?
I want the low part of each _m128 components:
int result = ( _m128.a & 0x000000ff ) << 24
| ( _m128.b & 0x000000ff ) << 16
| ( _m128.c & 0x000000ff ) << 8
| ( _m128.d & 0x000000ff ) << 0
Is there an intrinsics for that ? thanks !
FYI, the sse3 intrinsics _mm_shuffle_epi8 do the job: (with the mask 0x0004080c in this case )
The SSE2 answer takes more than one instructions:
unsigned benoit(__m128i x)
{
__m128i zero = _mm_setzero_si128(), mask = _mm_set1_epi32(255);
return _mm_cvtsi128_si32(
_mm_packus_epi16(
_mm_packus_epi16(
_mm_and_si128(x, mask), zero), zero));
}
The above amounts to 5 machine ops, given the input in %xmm1 and output in %rax:
pxor %xmm0, %xmm0
pand MASK, %xmm1
packuswb %xmm0, %xmm1
packuswb %xmm0, %xmm1
movd %xmm1, %rax
If you want to see some unusual uses of SSE2, including high-speed bit-matrix transpose, string search and bitonic (GPGPU-style) sort, you might want to check my blog, Coding on the edges.
Anyway, hope that helps.

Resources