Dragon 32 Homecomputer Kassetten in ASCII umwandeln...

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:


GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

So, mit https://github.com/jedie/PyDragon32/com ... 1c84c3b0a7 nutzte ich den "TextLeveMeter" vorgestellt hier: http://www.python-forum.de/viewtopic.php?f=11&t=32150

Damit kann man jetzt besser "sehen" was passiert. Dabei ist die Verkettung der Generatoren nun vom vorteil...

Sehen kann man dann sowas hier:

Code: Alles auswählen

|                                      |            *                         |
|                                      |             *                        |
|                                      |             *                        |
|                                      |             *                        |
|                                      |          *                           |
|                                      |       *                              |
|                                      |    *                                 |
|                                 *    |                                      |
|                              *       |                                      |
|                             *        |                                      |
|                             *        |                                      |
|                            *         |                                      |
|                               *      |                                      |
|                                *     |                                      |
|                                 *    |                                      |
|                                      |    *                                 |
|                                      |      *                               |
|                                      |       *                              |
|                                      |         *                            |
bit 1 at 1868 in 19Samples = 2321Hz
|                                      |          *                           |
|                                      |            *                         |
|                                      |             *                        |
|                                      |            *                         |
|                                      |             *                        |
|                                      |             *                        |
|                                      |            *                         |
|                                      |            *                         |
|                                      |          *                           |
|                                      |        *                             |
|                                      |       *                              |
|                                      |     *                                |
|                                      |    *                                 |
|                                 *    |                                      |
|                                 *    |                                      |
|                               *      |                                      |
|                             *        |                                      |
|                             *        |                                      |
|                            *         |                                      |
|                            *         |                                      |
|                            *         |                                      |
|                            *         |                                      |
|                             *        |                                      |
|                              *       |                                      |
|                               *      |                                      |
|                                *     |                                      |
|                                  *   |                                      |
|                                      |      *                               |
|                                      |        *                             |
bit 0 at 1897 in 29Samples = 1520Hz
|                                      |           *                          |
|                                      |            *                         |
|                                      |            *                         |
|                                      |            *                         |
|                                      |         *                            |
|                                      |      *                               |
|                                      |   *                                  |
|                                 *    |                                      |
|                              *       |                                      |
|                            *         |                                      |
|                            *         |                                      |
|                            *         |                                      |
|                               *      |                                      |
|                                *     |                                      |
|                                 *    |                                      |
|                                      |    *                                 |
|                                      |     *                                |
|                                      |      *                               |
|                                      |         *                            |
bit 1 at 1916 in 19Samples = 2321Hz
:D

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Komisch, bei manchen Dateien habe ich offensichtlich verkehre Vorzeichen aus den WAVE Daten. Das sieht dann z.B. so aus:

Code: Alles auswählen

 ==== go into positive sinus cycle ===============
bit 0 at 4432 in 33Samples = 1336Hz
|                                      |          *                           | value: 76 (3.0%)
|                                      |      *                               | value: 49 (5.0%)
|                                      |  *                                   | value: 21 (12.0%)
|                                      |*                                     | value: 6 (42.0%)
|                                      *                                      | value: 3 (85.0%)
|                                      | *                                    | value: 11 (23.0%)
|                                      |   *                                  | value: 29 (8.0%)
|                                      |       *                              | value: 57 (4.0%)
|                                      |            *                         | value: 85 (3.0%)
|                                      |            *                         | value: 85 (3.0%)
|                   *                  |                                      | value: -125 (3.0%)
|                     *                |                                      | value: -113 (3.0%)
|                        *             |                                      | value: -94 (3.0%)
|                           *          |                                      | value: -77 (4.0%)
|                             *        |                                      | value: -63 (5.0%)
|                               *      |                                      | value: -49 (6.0%)
|                                 *    |                                      | value: -36 (8.0%)
|                                   *  |                                      | value: -22 (12.0%)
|                                    * |                                      | value: -14 (19.0%)
|                                     *|                                      | value: -7 (37.0%)
|                                     *|                                      | value: -5 (51.0%)
|                                     *|                                      | value: -5 (51.0%)
|                                     *|                                      | value: -7 (37.0%)
|                                    * |                                      | value: -14 (19.0%)
|                                   *  |                                      | value: -21 (13.0%)
|                                 *    |                                      | value: -34 (8.0%)
|                               *      |                                      | value: -46 (6.0%)
|                             *        |                                      | value: -60 (5.0%)
|                           *          |                                      | value: -74 (4.0%)
|                         *            |                                      | value: -90 (3.0%)
|                      *               |                                      | value: -110 (3.0%)
|                                      |                  *                   | value: 126 (2.0%)
 ==== go into positive sinus cycle ===============
bit 0 at 4464 in 32Samples = 1378Hz
|                                      |                *                     | value: 112 (2.0%)
|                                      |             *                        | value: 93 (2.0%)
|                                      |          *                           | value: 76 (3.0%)
|                                      |        *                             | value: 62 (4.0%)
|                                      |      *                               | value: 49 (5.0%)
|                                      |    *                                 | value: 35 (7.0%)
|                                      |  *                                   | value: 21 (12.0%)
|                                      | *                                    | value: 13 (19.0%)
|                                      |*                                     | value: 6 (42.0%)
|                                      *                                      | value: 3 (85.0%)
|                                      *                                      | value: 3 (85.0%)
|                                      |*                                     | value: 4 (63.0%)
|                                      | *                                    | value: 11 (23.0%)
|                                      |  *                                   | value: 18 (14.0%)
|                                      |   *                                  | value: 29 (8.0%)
|                                      |     *                                | value: 43 (5.0%)
|                                      |       *                              | value: 57 (4.0%)
|                                      |          *                           | value: 71 (3.0%)
|                                      |            *                         | value: 85 (3.0%)
|                                      |               *                      | value: 105 (2.0%)
|                                      |               *                      | value: 105 (2.0%)
|                   *                  |                                      | value: -125 (3.0%)
|                        *             |                                      | value: -94 (3.0%)
|                             *        |                                      | value: -63 (5.0%)
|                                 *    |                                      | value: -36 (8.0%)
|                                    * |                                      | value: -14 (19.0%)
|                                     *|                                      | value: -5 (51.0%)
|                                     *|                                      | value: -7 (37.0%)
|                                   *  |                                      | value: -21 (13.0%)
|                               *      |                                      | value: -46 (6.0%)
|                           *          |                                      | value: -74 (4.0%)
|                      *               |                                      | value: -110 (3.0%)
|                                      |                *                     | value: 112 (2.0%)
 ==== go into positive sinus cycle ===============
bit 0 at 4497 in 33Samples = 1336Hz

:shock:

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Neben 8, 16, 32bit gibt es eben noch signed und unsigned-Datentypen in WAVE-Files.
BlackJack

@jens: Das war ja genau der Grund warum Deine original aufgenommene WAV bei einem ersten Versuch funktioniert hat, die von xroar aber nicht. Ich habe mir dann mit der `audioop.bias()`-Funktion beholfen um das zu korrigieren. Sollte irgendwo in diesem mittlerweile ziemlich langen Thema stehen. :-)
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Sirius3 hat geschrieben:Neben 8, 16, 32bit gibt es eben noch signed und unsigned-Datentypen in WAVE-Files.
Die Information bekommt man allerdings aus dem WAVE modul nicht raus, oder? Zumindest finde ich nichts dazu bei http://docs.python.org/2/library/wave.html

Ich mein wäre ja ein leichtes, das Vorzeichen umzudrehen, wenn man wüßte ob das nötig ist.
BlackJack hat geschrieben:Ich habe mir dann mit der `audioop.bias()`-Funktion beholfen um das zu korrigieren.
Stimmt. Allerdings würde ich gern auf audioop verzichten, wenn's geht.

audioop ist ein binär modul, oder?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

@jens: Wenn es kein Binärmodul wäre, dann wäre es wohl zu langsam. Zumindest in CPython.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hab bei http://docs.python.org/2/library/audioo ... op.lin2lin was interessantes gefunden:
In some audio formats, such as .WAV files, 16 and 32 bit samples are signed, but 8 bit samples are unsigned. So when converting to 8 bit wide samples for these formats, you need to also add 128 to the result:

new_frames = audioop.lin2lin(frames, old_width, 1)
new_frames = audioop.bias(new_frames, 1, 128)

The same, in reverse, has to be applied when converting from 8 to 16 or 32 bit width samples.
Das heißt doch aber auch, das ich einfach pauschal bei 8-bit waves 128 addieren kann.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

@jens: Genau das habe ich in meine Code der hier irgendwo im Thema steht gemacht. Wenn Samplebreite 1 Byte dann mit `bias()` drauf addieren.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

done: https://github.com/jedie/PyDragon32/com ... b3c4ee065f

ohne:

Code: Alles auswählen

|                                      |         *                            | value: 64 (3.0%)
|                                      |         *                            | value: 65 (3.0%)
|                                      |         *                            | value: 64 (3.0%)
|                                      |         *                            | value: 65 (3.0%)
|                                      |         *                            | value: 64 (3.0%)
|                                      |         *                            | value: 64 (3.0%)
|                                      |         *                            | value: 65 (3.0%)
|                                      |         *                            | value: 65 (3.0%)
|                                      |         *                            | value: 65 (3.0%)
|                   *                  |                                      | value: -128 (2.0%)
|                        *             |                                      | value: -92 (3.0%)
|                            *         |                                      | value: -69 (4.0%)
|                           *          |                                      | value: -76 (4.0%)
|                        *             |                                      | value: -92 (3.0%)
|                                      |                 *                    | value: 124 (2.0%)
 ==== go into positive sinus cycle ===============
|                                      |            *                         | value: 88 (2.0%)
|                                      |         *                            | value: 64 (3.0%)
|                                      |         *                            | value: 65 (3.0%)
|                                      |            *                         | value: 88 (2.0%)
|                                      |              *                       | value: 104 (2.0%)
|                    *                 |                                      | value: -120 (3.0%)
|                       *              |                                      | value: -100 (3.0%)
|                         *            |                                      | value: -84 (4.0%)
|                           *          |                                      | value: -77 (4.0%)
|                            *         |                                      | value: -68 (4.0%)
|                            *         |                                      | value: -69 (4.0%)
|                           *          |                                      | value: -76 (4.0%)
|                        *             |                                      | value: -92 (3.0%)
|                      *               |                                      | value: -108 (3.0%)
|                    *                 |                                      | value: -121 (3.0%)
|                                      |                *                     | value: 116 (2.0%)
und mit:

Code: Alles auswählen

|                            *         |                                      | value: -64 (4.0%)
|                             *        |                                      | value: -63 (5.0%)
|                            *         |                                      | value: -64 (4.0%)
|                             *        |                                      | value: -63 (5.0%)
|                            *         |                                      | value: -64 (4.0%)
|                            *         |                                      | value: -64 (4.0%)
|                             *        |                                      | value: -63 (5.0%)
|                             *        |                                      | value: -63 (5.0%)
|                             *        |                                      | value: -63 (5.0%)
 *** Have 1 samples skipped, because to lower amplitude.
|                                      |    *                                 | value: 36 (7.0%)
 ==== go into positive sinus cycle ===============
|                                      |        *                             | value: 59 (4.0%)
|                                      |       *                              | value: 52 (4.0%)
|                                      |    *                                 | value: 36 (7.0%)
|                                     *|                                      | value: -4 (64.0%)
|                                *     |                                      | value: -40 (7.0%)
|                            *         |                                      | value: -64 (4.0%)
|                             *        |                                      | value: -63 (5.0%)
|                                *     |                                      | value: -40 (7.0%)
|                                  *   |                                      | value: -24 (11.0%)
|                                      |*                                     | value: 8 (31.0%)
|                                      |   *                                  | value: 28 (9.0%)
 ==== go into positive sinus cycle ===============
bit 1 at 21 in 11Samples = 2004Hz
First bit is at: 21
enable half sinus scan
|                                      |      *                               | value: 44 (5.0%)
|                                      |       *                              | value: 51 (5.0%)
|                                      |        *                             | value: 60 (4.0%)
|                                      |        *                             | value: 59 (4.0%)
|                                      |       *                              | value: 52 (4.0%)
|                                      |    *                                 | value: 36 (7.0%)
|                                      |  *                                   | value: 20 (12.0%)
|                                      |*                                     | value: 7 (36.0%)
|                                    * |                                      | value: -12 (22.0%)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Dumme Frage: Was macht genau ein frames = audioop.bias(frames, 1, 128) ?
Also wie korrigiert es die Werte?

Frage deshalb: Vielleicht kann man zur Not das auch direkt im Skript machen.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

@jens: Also *ganz* genau steht es hier: http://hg.python.org/cpython/file/48259 ... oop.c#l957 :-)

Im Fall von 8-Bit-Werten sollte es auf ``new_value = (old_value + 128) & 0xff`` hinaus laufen. Wobei `new_value` und `old_value` als ``unsigned`` betrachtet werden. Erst danach darf man `new_value` als ``signed`` interpretieren.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

BlackJack hat geschrieben:new_value = (old_value + 128) & 0xff
Das liefert nicht die erwarteten Werte. Das folgende allerdings schon:

Code: Alles auswählen

value = value % 0xff - 128

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

@jens: Ich habe ja extra geschrieben, dass man das auf als *unsigned* interpretierte Bytewerte anwenden muss. Da würde Deine Formel ja schon mal keinen Sinn ergeben, weil das ``value % 256`` bei unsigned Bytewerten eine Nullopration ist — egal was man für `value` einsetzt, es käme immer wieder `value` dabei heraus:

Code: Alles auswählen

In [7]: all(v % 256 == v for v in xrange(256))
Out[7]: True
Wenn man es in reinem Python lösen wollte, ist es wahrscheinlich am einfachsten den Typ-Code für `array` oder `struct` zu ``unsigned byte`` zu ändern und dann einfach 127 von jedem Wert abzuziehen.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Heute viel zu viel Zeit damit verbracht. Aber ich will es endlich mal benutzbar haben...

Aktueller Stand: https://github.com/jedie/PyDragon32/com ... 8f4dd87bac

Damit das Debuggen einfacher wird, hab ich nur schon Code da um aus einem ASCII BASIC Datei einen bitstream zu generieren. Wenn nun noch bitstream2wave da ist, dann wäre das auch schon fertig.

Eigentlich klappt das ganze schon ganz gut. Allerdings z.Z. nur richtig mit "HelloWorld1 xroar.wav"
Die anderen WAVES, funktionieren nur halb. Der Filename-Block ist ok, aber die eigentlichen Daten sind verfälscht.

Denke aber das liegt am WAVE2bitstream Teil und nicht später beim verwerten des Bitstreams.

Nun ist alles stark auf Generatoren ausgelegt. d.h. die WAVE Datei wird ausgelesen und alles komplett bis zum erzeugen der eigentlichen Python-Daten-Objekten geschieht "gleichzeitig"...

Ich hab mal eine separate "Config Klasse" angelegt: https://github.com/jedie/PyDragon32/blo ... configs.py

Theoretisch sollte man damit einfach auch andere Formate, wie halt C64 Datasette, unterstützten können.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Schade, ich dachte der Datenmüll würde zustande kommen, weil ich nur einmal, am Anfang, einen Bit-Sync mache. Mit https://github.com/jedie/PyDragon32/com ... 0c39cbf656 mache ich jeweils vor einem neuen Block ein neuen Bit-Sync.

Das bringt allerdings keine Besserung.

Denke ich werde nochmal anders heran gehen und wirklich den Null-Durchgang der Sinus-Kurve Triggern. Ist eh besser, weil Lautstärke unabhängig.

Doch wie machen?

Einfach sahen, Null-Durchgang ist immer dann, wenn sich das Vorzeichen ändert wäre IMHO zu Störanfällig.
Ich denke über folgendes nach (pseudocode):

Code: Alles auswählen

end_count = 3
mid_count = 2

previous_values = frame_values[:end_count] # e.g.: 123-----
mid_values = frame_values[end_count:end_count] # e.g.: ---45---
next_values = frame_values[-end_count:] # e.g.: -----678

if previous_values > 0 and next_values <0:
    yield mid_time(mid_values)
Mit anderen Worten: Nulldurchgang ist dann, wenn einige Werte Negativ waren, einige Werte egal (neg. oder pos.) und einige nächsten Werte Positiv sind.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@jens:
Wenn Du die Rohdaten vorverarbeitest, kannst Du jeden Vorzeichenwechsel als Nulldurchgang werten. Z.B. mit einem simplen Glättfilter als moving average der letzten 2 oder 3 Werte. Grössere Störungen lassen sich damit nicht bügeln, da helfen nur noch schwerere Geschütze.
Weiter oben hattest Du etwas zum Schmitttrigger geschrieben. Hattest Du das auch implementiert? Mit Kenntnis der Zielfrequenzen kannst Du doch eine simple Triggerfunktion schreiben.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

jerch hat geschrieben:Z.B. mit einem simplen Glättfilter als moving average der letzten 2 oder 3 Werte.
Das habe ich mir auch überlegt.

Die Idee von vorhin war doch recht schnell implementiert: https://github.com/jedie/PyDragon32/com ... 9ef#L1R272

Siehe da, nun kommt auch was vernünftiges raus!

EDIT: Schmittriger mit Hysterese hatte ich auch mal, war aber nicht so richtig effektiv.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hab es mal eingebaut: https://github.com/jedie/PyDragon32/com ... e2f#L1R323

Aber es ist besser das aus zu lassen. Also Witzlos. Oder ich hab was falsch gemacht.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Endlich ein cli mit https://github.com/jedie/PyDragon32/com ... 14c28e036f

Code: Alles auswählen

usage: PyDC_cli.py [-h] [-v] [--verbosity {0,10,20,30,40,50}]
                   [--logfile {0,10,20,30,40,50}]
                   [--hz_variation HZ_VARIATION]
                   [--min_volume_ratio MIN_VOLUME_RATIO]
                   [--avg_count AVG_COUNT] [--end_count END_COUNT]
                   [--mid_count MID_COUNT]
                   src dst

Python dragon 32 converter

positional arguments:
  src                   Source filename (.wav/.bas)
  dst                   Destination filename (.wav/.bas)

optional arguments:
  -h, --help            show this help message and exit
  -v, --version         show program's version number and exit
  --verbosity {0,10,20,30,40,50}
                        verbosity level to stdout (lower == more output!)
                        (default: 30)
  --logfile {0,10,20,30,40,50}
                        verbosity level to log file (lower == more output!)
                        (default: 20)
  --hz_variation HZ_VARIATION
                        How much Hz can signal scatter to match 1 or 0 bit ?
                        (default: 450)
  --min_volume_ratio MIN_VOLUME_RATIO
                        percent volume to ignore sample (default: 5)
  --avg_count AVG_COUNT
                        How many samples should be merged into a average
                        value? (default: 0)
  --end_count END_COUNT
                        Sample count that must be pos/neg at once (default: 2)
  --mid_count MID_COUNT
                        Sample count that can be around null (default: 1)
Bsp.:

Code: Alles auswählen

~$ python PyDC_cli.py FooBar.wav FooBar.bas

EDIT: Siehe auch: http://www.python-forum.de/viewtopic.php?f=1&t=32170

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten