Java ByteBuffer w Qt5.

1. Współdzielenie danych między Javą a Qt5 chyba mam opanowane:

ByteArrayW Javie to wygląda np. tak:

public ByteBuffer bbuf = ByteBuffer.allocateDirect(10);
public byte b[] = new byte [] {1, 1, 2, 3, 5, 8, 13, 21, 34, 55};
public static native void sendBufAddr(ByteBuffer buf);
// natywna funkcja w C++ do której przekazujemy adres bufora
// dane z bufora pakujemy do ByteBuffera w ten sposób:
bbuf.put(b);
// i wysyłamy adres do funkcji w C++
sendBufAddr(bbuf);

A funkcja w C++ w wersji minimalistycznej w QT5 wygląda tak:

extern "C" {
   JNIEXPORT void JNICALL
   Java_net_greblus_MyActivity_sendBufAddr(JNIEnv *env,
   jobject, jobject buf)
   {
   jbyte *bbuf = (jbyte *)env->GetDirectBufferAddress(buf);
   // i możemy robić z danymi w bbuf[] co chcemy
   }
}

2. Pakiet jar ze sterownikiem do FTDI działa w Qt5 w MainActivity, więc wszystkie elementy układanki zaczynają do siebie pasować ;).

Java ByteBuffer w Qt5.

D2XX + Sio2PC-USB.

Niestety chyba na chwilę odpuszczę próby odpalenia Sio2PC-USB na Androidzie bez roota z opensource-owego libftdi. Nauczyłem się obsługiwać JNI w QT5, wszystko niby działa, ale moje zmodyfikowane libusb coś niedomaga. libftdi zwraca error -4 przy próbie otwarcia pliku z wykorzystaniem wydłubanego w Javie (po nadaniu uprawnień) deskrypytora pliku… Może to być wina konfiguracji Antka, a tego bez modyfikacji obrazu systemu nie przeskoczę. Muszę spróbować czegoś innego:20150605_011113Wracam do sterownika D2XX od FTDI. Ten działa z poziomu Javy na Androidzie zawijając ftdi i libusb w JNI w ładny pakiet Javowy (więc będziemy to zawijać dwa razy ;)), ale przynajmniej da się w nim otworzyć urządzenie. To był mój pierwszy pomysł jak to zrobić: Wywołać API Javowe sterownika przez JNI, wszystko z urządzeniem robić w MainActivity w Javie, a dane współdzielić z QT przez ByteBuffer. Teraz już wiem, że jest to do zrobienia i nie jest to trudne.

D2XX + Sio2PC-USB.

Małe kroczki…

Cieszą najbardziej ;)

sio2usb_fd

Cały widz polegał na tym, że aby uzyskać uprawnienia, trzeba to robić w  wątku UI Androida. Dzięki Bogdanowi Vatrze i jego prezentacji „Crash course…” wiem jak to zrobić ładnie w BroadcastReceiverze przez runOnUiThread(). A żeby coś zwrócić do QT, trzeba to zakolejkować jako funkcję do wykonania w wątku UI QT, bo to dwa osobne wątki… Piękny design i superowa zabawa :). Mam nadzieję, że teraz już będzie z górki.

Małe kroczki…

QAndroidJniObject. To naprawdę działa!

Jakby ktoś się zastanawiał, to walczę dalej z portem aspeqt na Androida, a dokładniej z obsługą czipu FTDI na Androidzie. Sterownik ftd2xx od FTDI to totalna porażka (segfault goni segfault) i z tego co widzę nie ma szans na obsługę FTDI za pomocą tego sterownika bezpośrednio z C++, bez roota i modyfikacji obrazu systemu.

Na szczęście jest jeszcze libftdi.

Ale i tutaj nie jest tak różowo. W pierwszej kolejności musiałem skompilować libusb na Antka, potem samo libftdi, a to wszystko, żeby się przekonać, że standardowe libusb nie potrafi otworzyć urządzenia bo nie ma do tego uprawnień. I choćby nie wiem jak kombinować z uprawnieniami w Manifest.xml, nic  to nie da.

Jest alternatywne podejście: najpierw z poziomu Javy należy otworzyć urządzenie i uzyskać uprawnienia do usb. Potem przekazać deskryptor pliku urządzenia do libusb. To ponoć działa na delikatnie zmodyfikowanej wersji libusb (mam już ją skompilowaną na Antka).

Mój plan był prosty: z poziomu QT wywołuje klasę Javovą, która otworzy urządzenie i poprosi o uprawnienia, a potem zwróci do QT deskryptor pliku. Plan planem, ale JNI w QAndroidJniObject nie chciało mi działać. Teraz już wiem dlaczego :). Przykład Bogdana Vetry zawierał rozwiązanie problemu w pierwszym komentarzu: plik źródłowy w Javie, umieszczamy w katalogach odpowiadających strukturze pakietu, ale w android/src. Jak pakiet utworzę w android to nie zadziała ;).

Czyli:
1. Tworzymy nowy projekt QT Android.
2. W pliku .pro dodajemy:

QT += core gui androidextras
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android/

W katalogu projektu dodajemy katalog android/src/net/greblus/MyJavaClass.java:

package net.greblus;

public class MyJavaClass {
     public static int fibonacci(int n)
    {
        if (n < 2)
            return n;
        return fibonacci(n-1) + fibonacci(n-2);
    }
}

i wywołujemy w C++ z QAndroidJniObject w ten sposób:

ret = QAndroidJniObject::callStaticMethod<jint>("net/greblus/MyJavaClass", "fibonacci", "(I)I", n);

Dwa wieczory spędziłem nad tym brakującym src, ale dzięki temu sporo się nauczyłem ;). QT5 to dla mnie w tym momencie toolkit nr 1.

libusb mam już skompilowane, teraz tylko mała modyfikacja libftdi i można próbować z otwieraniem urządzenia z Javy ;).

QAndroidJniObject. To naprawdę działa!

Aspeqt na github.

Aktualny deweloper Aspeqt pokłócił się z paroma osobami na forum Atari Age i dostał tam bana. W odwecie usunął wszystkie wprowadzone przez niego zmiany od wersji 0.6 do 1.0 i postanowił rozwijać to dalej w zaciszu swojego forum, udostępniając za opłatą. Szkoda.

Wrzuciłem ostatnie udostępione na AAge źródła 1.0.0 preview 6 do repo na Github.

https://github.com/greblus/aspeqt

Nie mam jakichś wielkich planów, chciałbym kompilować od czasu do czasu aby działało na aktualnych wersjach bibliotek. Fajnie by było też zrobić nowe gui, bo aktualne jest beznadziejne, zwłaszcza na małych ekranach, ale to w wolnych chwilach.

Pierwszy pomysł jest taki: minimalna geometria okna i dynamiczne dodawanie slotów:

mini_aspeqtUpdate:

Tak sobie niezobowiązująco myślę… Jest port QT5 na Androida: http://doc.qt.io/qt-5/android-support.html muszę się więc zaznajomić z Android NDK. Nawet gdyby trzeba było Gui zrobić od nowa, zdecydowanie jest to do zrobienia.

FTDI też działa: http://www.ftdichip.com/Android.htm (sprawdzałem na tablecie z 4.2.2 i faktycznie, wygląda że to działa out-of-the-box).

Myślę, że przy odrobinie wolnego czasu można by to ze sobą pożenić. Jest w TME nawet FTDI w wersji zintegrowanej z kablem. SIO2PC zmieści się we wtyczce SIO. Dałoby się z tego zrobić coś fajnego ;).

 

Aspeqt na github.

Yamaha DTX-400 i Krigg Triggera.

Postanowiłem wymienić KU-100 (silent kick pedal) Yamahy na mechaniczny pedał stopy z triggerem piezoelektrycznym. Wybór padł na Krigg Triggera + tani pedał stopy Basix PD-600 V3. Pedał bardzo fajny z napędem łańcuszkowym, a co najważniejsze – oddzielnym uchwytem bijaka. Po zdemontowaniu, jak widać na zdjęciach poniżej, zostaje tylko uchwyt łańcuszka. Wygląda na niezniszczalny.

Działa świetnie ;). Tylko trochę ciężko się samemu nagrać.

Do pełni szczęścia trzeba ustawić w DTX-400 charakterystykę prędkości na 3 (Song + Kit potem 5 i 1, kick i wpisać wartość 3) żeby było głośno i wyraźnie nawet przy lekkim graniu. Odstęp między mocowaniem łańcuszka a przetwornikiem ustawiłem na 4-5mm, a punkt styku mocowania łańcuszka z gumą przetwornika podkleiłem taśmą izolacyjną (zostają ślady po uderzaniu metalu o gumę).

Yamaha DTX-400 i Krigg Triggera.