@Torsten2000: Das ist Unsinn mit dem `struct.pack_into()`. Du kopierst damit nur die Bytes in den Speicherbereich von einem `c_uint64`-Exemplar. Das kannst Du mit `c_uint64.from_buffer_copy()` einfacher haben. Da könntest Du auch gleich ein `c_uint64`-Array erstellen und das auf einen Schlag mit der `from_buffer_copy()`-Methode auf diesem Array befüllen. Umwandlung in Python-`int` gibt es dann über den Indexzugriff. Ansonsten bekommt man bei `ctypes`-Skalaren ein Python-Objekt über das `value`-Attribut.
Erwähnte ich schon `numpy`?
Entschlüsseln eines ganz komischen Datenformates
-
- User
- Beiträge: 40
- Registriert: Montag 27. Dezember 2010, 17:26
Hallo BlackJack,
numpy hast du noch nicht erwähnt klingt gut.
Aber das werde ich im Rahmen der Diplomarbeit wohl nicht mehr schaffen.
Bin froh, wenn ich noch das "Entschlüsseln" hin bekomme.
Ich habe jetzt folgendes Programmiert:
So scheint die Funktion zu funktionieren.
Wenn ich jetzt die Variante
aktiviere, bekomme ich eine Fehlermeldung
Ich habe .value gefunden.
er Zeigt mir allerdings immer dann noch ein "L" hinter den Ergebnissen...
Hat das ihrgend einen Einfluss? Ich nehme an, das hat was mit dem ctypes zu tun und mit dem Variablen-Typ
Wie bekomme ich denn das weg?
numpy hast du noch nicht erwähnt klingt gut.
Aber das werde ich im Rahmen der Diplomarbeit wohl nicht mehr schaffen.
Bin froh, wenn ich noch das "Entschlüsseln" hin bekomme.
Ich habe jetzt folgendes Programmiert:
Code: Alles auswählen
def _get_Frame(x):
global Wave
i=x*8
return = Wave[i+0]<<(0*8) | Wave[i+1]<<(1*8) | Wave[i+2]<<(2*8) | Wave[i+3]<<(3*8) | Wave[i+4]<<(4*8) | Wave[i+5]<<(5*8) | Wave[i+6]<<(6*8) | Wave[i+7]<<(7*8)
#return c_int64.from_buffer_copy(Wave, i)
def get_Sample_from_channel(Sample, Channel, Mode = -1):
#liefert das Ergebnis von der Abtastung der Kanal
global Wave
global _Mode
if Mode == -1:
Mode = _Mode
P1 = HARDWARE_MODE_TABELLE[Mode].P1
P2 = HARDWARE_MODE_TABELLE[Mode].P2
P3 = HARDWARE_MODE_TABELLE[Mode].P3
SamplesPerFrame = P2/P3
FrameX = Sample / SamplesPerFrame
SampleInFrame = Sample % SamplesPerFrame
Frame = _get_Frame(FrameX)
return Frame>>(SampleInFrame*P3 + Channel) & 1
Wenn ich jetzt die Variante
Code: Alles auswählen
return c_int64.from_buffer_copy(Wave, i)
Wie Wandel ich denn jetzt die c_int64 denn jetzt wieder in eine Python-Zahl um?return Frame>>(SampleInFrame*P3 + Channel) & 1
TypeError: unsupported operand type(s) for >>: 'c_longlong' and 'int'
Ich habe .value gefunden.
er Zeigt mir allerdings immer dann noch ein "L" hinter den Ergebnissen...
Hat das ihrgend einen Einfluss? Ich nehme an, das hat was mit dem ctypes zu tun und mit dem Variablen-Typ
Wie bekomme ich denn das weg?
-
- User
- Beiträge: 40
- Registriert: Montag 27. Dezember 2010, 17:26
ah mit "int( )"
Sorry für meinen blöden Fragen
Danke schön
Code: Alles auswählen
def _get_Frame(x):
global Wave
i=x*8
return int(c_int64.from_buffer_copy(Wave, i).value)
Danke schön
@Torsten2000: Das 'L' musst Du nicht wegbekommen, insbesondere kann es sein, dass Du es gar nicht weg bekommen kannst, dann liefert `int()` genau das selbe `long`-Objekt. Der Aufruf verbraucht einfach nur unnötig Zeit ohne wirklichen Vorteil.
``global`` solltest Du loswerden. Globale Daten machen Programme nur unflexibel und das neu binden von globalen Daten macht sie zusätzlich schwerer zu durchschauen und fehleranfälliger. Zumal Du keine der ``global``-Deklarationen i den gezeigten Quelltext-Abschnitten brauchst.
Stattdessen solltest Du `Wave` und die Funktionen die darauf operieren in einer Klasse verpacken. Da ein `Wave`-Wert ja wahrscheinlich auch nur Daten "in einem `Mode`" enthält, könnte man dann auch ein paar der Sachen, die Du immer wieder aufs neue berechnest, *einmal* für alle Samplezugriffe im Voraus berechnen. Und vielleicht Indexzugriffe auf einzelne Samples ermöglichen, eine `__len__()`-Methode implementieren und so weiter.
Und statt jeden Frame einzeln durch ein `c_int64` zu jagen, könntest Du das komplette `Wave`-Objekt über ein `c_uint64`-Array ansprechen.
``global`` solltest Du loswerden. Globale Daten machen Programme nur unflexibel und das neu binden von globalen Daten macht sie zusätzlich schwerer zu durchschauen und fehleranfälliger. Zumal Du keine der ``global``-Deklarationen i den gezeigten Quelltext-Abschnitten brauchst.
Stattdessen solltest Du `Wave` und die Funktionen die darauf operieren in einer Klasse verpacken. Da ein `Wave`-Wert ja wahrscheinlich auch nur Daten "in einem `Mode`" enthält, könnte man dann auch ein paar der Sachen, die Du immer wieder aufs neue berechnest, *einmal* für alle Samplezugriffe im Voraus berechnen. Und vielleicht Indexzugriffe auf einzelne Samples ermöglichen, eine `__len__()`-Methode implementieren und so weiter.
Und statt jeden Frame einzeln durch ein `c_int64` zu jagen, könntest Du das komplette `Wave`-Objekt über ein `c_uint64`-Array ansprechen.
-
- User
- Beiträge: 40
- Registriert: Montag 27. Dezember 2010, 17:26
Hallo BlackJack,
Wie geht denn das mit "c_uint64`-Array ansprechen"?
Danke nochmal für deine Wertvollen Tips
Die sind echt spizte.
Alle anderen Module habe ich schön mit einer Klasse eingebunden (Timer-Funktionen)
Da habe ich das erste mal mit Klassen gearbeitet und den riesen Vorteil gesehen, da man ganz oft Instanzen von denen anlegen kann und die sich nicht beeinflussen (globale Variablen). Das ist echt super.
Leider hatte ich bisher nicht den Sinn bei meinem Hauptmodul gesehen - fälschlicher weise..
Im Nachhinein ist man immer klüger.
ich werd jetzt erst mal die Diplomarbeit schreiben müssen und wenn ich noch Zeit habe, ändere ich das ja vielleicht noch ab (was wohl recht unwahrscheinlich ist )
Aber ich habe viel durch deine Hilfe gelernt und Python echt schätzen gelernt.
Ich bin dir dafür sehr dankbar - und sorry nochmal für die eine oder andere Frage, die ich gestellt habe.
Manchmal ist es eben schneller, wenn man einen Tipp bekommt (gerade wenn man unter Zeitdruck ist). Und mit den ctypes und den einbinden der DLLs war ja schon ein bisschen spezieller, glaube ich?
Viele Grüße
Torsten
PS: wenn ich nochmal was umsetzte, dann werden ich bestimmt nochmal die eine oder andere Frage haben.
Wie geht denn das mit "c_uint64`-Array ansprechen"?
Danke nochmal für deine Wertvollen Tips
Die sind echt spizte.
Alle anderen Module habe ich schön mit einer Klasse eingebunden (Timer-Funktionen)
Da habe ich das erste mal mit Klassen gearbeitet und den riesen Vorteil gesehen, da man ganz oft Instanzen von denen anlegen kann und die sich nicht beeinflussen (globale Variablen). Das ist echt super.
Leider hatte ich bisher nicht den Sinn bei meinem Hauptmodul gesehen - fälschlicher weise..
Im Nachhinein ist man immer klüger.
ich werd jetzt erst mal die Diplomarbeit schreiben müssen und wenn ich noch Zeit habe, ändere ich das ja vielleicht noch ab (was wohl recht unwahrscheinlich ist )
Aber ich habe viel durch deine Hilfe gelernt und Python echt schätzen gelernt.
Ich bin dir dafür sehr dankbar - und sorry nochmal für die eine oder andere Frage, die ich gestellt habe.
Manchmal ist es eben schneller, wenn man einen Tipp bekommt (gerade wenn man unter Zeitdruck ist). Und mit den ctypes und den einbinden der DLLs war ja schon ein bisschen spezieller, glaube ich?
Viele Grüße
Torsten
PS: wenn ich nochmal was umsetzte, dann werden ich bestimmt nochmal die eine oder andere Frage haben.
@Torsten2000: Na Du müsstest halt ein Array definieren was gross genug ist um die Daten aufzunehmen, davon dann die `from_buffer_copy()`-Methode benutzen um ein Array aus `Wave` zu machen, und kannst dann per Indexzugriff auf die einzelnen Werte zugreifen.
-
- User
- Beiträge: 40
- Registriert: Montag 27. Dezember 2010, 17:26
@BlackJack
Mmm...
Ich weiß nicht genau ob ich das richtig verstanden habe
Sowas in der Richtung?
Aber da ist doch kein Unterschied zu meiner vorigen Version - außer, dass ich das Array nur einmal anlege, oder?
Stimmt schon. mit meiner vorigen Version habe ich für jedes Sample unter Umständen immer das gleiche Frame geholt.
Schön wäre es jetzt - wie du schon gesagt hast - wenn das alles in einer Klasse wäre.
Mmm...
Und statt jeden Frame einzeln durch ein `c_int64` zu jagen, könntest Du das komplette `Wave`-Objekt über ein `c_uint64`-Array ansprechen.
@Torsten2000: Na Du müsstest halt ein Array definieren was gross genug ist um die Daten aufzunehmen, davon dann die `from_buffer_copy()`-Methode benutzen um ein Array aus `Wave` zu machen, und kannst dann per Indexzugriff auf die einzelnen Werte zugreifen.
Ich weiß nicht genau ob ich das richtig verstanden habe
Sowas in der Richtung?
Code: Alles auswählen
def transform_Wave_from_8_to_64():
global Wave
temp = (c_int64 * (len(Wave)/8)) ()
for i in range(len(w)):
temp[i] = c_int64.from_buffer_copy(Wave, i*8)
Wave = temp
Stimmt schon. mit meiner vorigen Version habe ich für jedes Sample unter Umständen immer das gleiche Frame geholt.
Schön wäre es jetzt - wie du schon gesagt hast - wenn das alles in einer Klasse wäre.
@Torsten2000: Du immer mit Deinem ``global``. Du weisst das man Funktionen Werte als Argumente ünbergeben kann und kennst die ``return``-Anweisung!?
Die `from_buffer_copy()`-Methode hat jeder `ctypes`-Datentyp, auch zusammengesetzte wie Arrays oder Strukturen. Du musst das nicht in einer Schleife machen sondern kannst ein Array mit einem Aufruf dieser Methode auf dem Array-Typ-Objekt erstellen. Ungetestet:
Die `from_buffer_copy()`-Methode hat jeder `ctypes`-Datentyp, auch zusammengesetzte wie Arrays oder Strukturen. Du musst das nicht in einer Schleife machen sondern kannst ein Array mit einem Aufruf dieser Methode auf dem Array-Typ-Objekt erstellen. Ungetestet:
Code: Alles auswählen
def frames2array(frames_data):
return (c_uint64 * (len(frames_data) // 8)).from_buffer_copy(frames_data)
-
- User
- Beiträge: 40
- Registriert: Montag 27. Dezember 2010, 17:26
@BlackJack
Ja ich weiß... kein guter Programmierstiel. Beim nächsten Projekt mache ich es besser (oder wie gesagt, wenn ich noch Zeit habe)
wie säh das denn aus wenn das in einer Klasse ist?
mit self.Wave ist das ja ähnlich wie global im Modul oder? Auch schlechte Programmierstiehl?
Auch innerhalb einer Klasse mit Parametern?
Ja ich weiß... kein guter Programmierstiel. Beim nächsten Projekt mache ich es besser (oder wie gesagt, wenn ich noch Zeit habe)
wie säh das denn aus wenn das in einer Klasse ist?
mit self.Wave ist das ja ähnlich wie global im Modul oder? Auch schlechte Programmierstiehl?
Auch innerhalb einer Klasse mit Parametern?
@Torsten2000: `self.wave` wäre ähnlich einem ``global`` aber nicht das selbe. Es ist nicht mehr automatisch für alle Funktionen im Modul sichtbar, man muss explizit über `self` darauf zugreifen. Man macht damit klar, dass hauptsächlich die Methoden darauf zugreifen. Ausserdem gibt es das nicht nur einmal, sondern man kann mehrere solcher Objekte mit verschiedenen Sampledaten erzeugen. Der Speicher kann auch automatisch wieder freigegeben werden, wenn das Objekt nicht mehr erreichbar ist.
-
- User
- Beiträge: 40
- Registriert: Montag 27. Dezember 2010, 17:26
Ja da hast du absolut recht.
eine Klasse wäre da sehr sinnvoll.
eine Klasse wäre da sehr sinnvoll.