| 
| Autor | Beitrag |  
| Dunkel 
          Beiträge: 682
 
 Mac OS X Snow Leopard
 Xcode 3.1
 
 | 
Verfasst: Mo 29.12.08 19:35 
 
Hallo zusammen!
 Ja, interessanter Thread-Titel, nicht wahr?     Was verbirgt sich hinter dem TPCMDrawer? Und wie, zum Belzebub, kann man Bilder hören?
 Ein wenig zur Vorgeschichte:
 Der werte User   delfiphan  hat vor ziemlich genau 2 Jahren ein Rätsel  gepostet. Vor 2 Tagen habe ich, beim Stöbern im Forum, genau diese MP3-Datei entdeckt, runtergeladen, mir angehört - und ich war baff, als ich die Auflösung des Rätsels von ihm gesehen habe.
 Nach dem dann die Faszination ein wenig nachgelassen hat und ich wieder klar denken konnte     habe ich mich mit der BASS.dll dran gemacht, ähnliche Töne zu kreieren. Das hat auch irgendwann (nach studieren der RIFF WAVE-Spezifikationen, aufarbeiten der theoretischen Hintergründe, ziemlich viel Verzweiflung, ein Schubs in die richtige Richtung von   delfiphan  [vielen Dank nochmal dafür!] und einer Nacht drüber schlafen) recht gut geklappt. Dann habe ich aus dem Projekt, welches die BASS.dll benötigt eine 190-Zeilen-Klasse ohne irgendwelche externen Abhängigkeiten (DLLs, Units, etc.) gebastelt.
 Und genau diese PCMDrawer.pas, mit der man ohne großen Aufwand recht nett anzuhörende/anzusehende Audio-Dateien erstellen kann, stelle ich der OpenSource-Gemeinde, unter der "Creative Commons Attribution-ShareAlike (CC by-sa)"-Lizenz zur Verfügung. Kurz gesagt: Ihr könnt alles damit machen, solange Ihr meine Wenigkeit in Euren Resultaten erwähnt und die Projekte in ähnlicher Form verbereitet werden.
 Im Anhang befindet sich die PCMDrawerDemo.zip, in der sich der komplette Sourcecode inklusive einer Demo-Echse und einem Kompilat der Demo befindet. In der Beispiel.zip befindet sich eine Bitmap-Datei und das (zu einer MP3 komprimierte) Ergebnis der Demo.
 Zum Ansehen der Töne empfehle ich, wie auch   delfiphan  im zitierten Thread, www.tyberis.com/download/SAnalyze.exe .
 Viel Spaß damit!
 Grüße
 Michael
Einloggen, um Attachments anzusehen!
 
_________________Ich streite einsam mich mit dieser Oberflächenwelt Gutes sei ein löblich Brot von dem ich zehre - bis zum Tod       [Das Ich - Im Ich]
 
 Zuletzt bearbeitet von Dunkel am Fr 23.01.09 22:22, insgesamt 3-mal bearbeitet
 |  |  |  
| JayEff 
          Beiträge: 2971
 
 Windows Vista Ultimate
 D7 Enterprise
 
 | 
Verfasst: Mo 29.12.08 20:40 
 
Außerordentlich cool.    Kleinigkeit: ich frage mich, ob es möglich ist, eine Callback-Prozedure einzubauen, die man dann als Progress benutzen kann. Soll heißen, ich geb der Komponente einen Prozedurenzeiger und sie führt ihn beim konvertieren aus, wobei natürlich ein Wert für z.b. Progressbar.min / max interessant wäre.
 Ah, da das eine Komponente ist, wieso nicht gleich ein onProgress ereigniss! 
 Auf jedenfall ist das eine witzige Idee - funktioniert halt am besten bei Schwarzweiß-bildern einer bestimmten größe, zumindest wenn man das Analysetool von delphifan benutzt, aber trotzdem..!_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
 [>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
 |  |  |  
| Dunkel  
          Beiträge: 682
 
 Mac OS X Snow Leopard
 Xcode 3.1
 
 | 
Verfasst: Mo 29.12.08 21:20 
 
	  |  JayEff hat folgendes geschrieben  : |  	  | Außerordentlich cool.  | 
 Vielen Dank!
 	  |  JayEff hat folgendes geschrieben  : |  	  | Kleinigkeit: ich frage mich, ob es möglich ist, eine Callback-Prozedure einzubauen, die man dann als Progress benutzen kann. Soll heißen, ich geb der Komponente einen Prozedurenzeiger und sie führt ihn beim konvertieren aus, wobei natürlich ein Wert für z.b. Progressbar.min / max interessant wäre.
 | 
 Hör' mal, das ist erst Version 0.1 dieser kleinen (aber feinen     ) Klasse. Aber daran habe ich auch schon gedacht; ein Thread würde sich auch anbieten, finde ich. Ich bastle nach wie vor daran.
 	  |  JayEff hat folgendes geschrieben  : |  	  | Auf jedenfall ist das eine witzige Idee - funktioniert halt am besten bei Schwarzweiß-bildern einer bestimmten größe, zumindest wenn man das Analysetool von delphifan benutzt, aber trotzdem..!
 | 
 v0.1 hat nur die schwarzen Pixel [RGB(0,0,0)] hörbar gemacht, lokal werden nun auch "Graustufen" abgebildet.
 Edith flüstert: Ach ja, bis jetzt werden nur Bitmaps mit einer maximalen Höhe von 250 Pixeln komplett dargestellt, in der Breite sind selbstverfreilich keine Grenzen gesetzt.
 btw. mein Player AudioDB kann auch solch ein Sonagramm darstellen, sogar in Farbe und bunt; probier es mal damit (wobei ich sagen muss, dass AudioDB die Grafik mehr in die Länge zieht, damals wusste ich halt noch nicht, dass ich so einen Unsinn mit Tönen veranstallten werde...     )_________________Ich streite einsam mich mit dieser Oberflächenwelt Gutes sei ein löblich Brot von dem ich zehre - bis zum Tod       [Das Ich - Im Ich]
 |  |  |  
| Dunkel  
          Beiträge: 682
 
 Mac OS X Snow Leopard
 Xcode 3.1
 
 | 
Verfasst: Di 30.12.08 01:29 
 
Direkt mal eine neue Version inklusive Bugfix, da der Header der Wave-Datei nicht WMP-konform geschrieben wurde.
 TPCMDrawer kann jetzt auch "Graustufen" darstellen, vorher wurden nur alle schwarzen [RGB(0,0,0)] Pixel hörbar gemacht. Alle Änderungen vom omata  wurden übernommen. Die Klasse ist jetzt von TThread abgeleitet, ob es auch so funktioniert wie es funktionieren soll - keine Ahnung, ich hab jetzt auch kein Bock mehr das ausgiebig zu testen     .
 Der Download im ersten Beitrag wurde entsprechend aktualisiert._________________Ich streite einsam mich mit dieser Oberflächenwelt Gutes sei ein löblich Brot von dem ich zehre - bis zum Tod       [Das Ich - Im Ich]
 |  |  |  
| delfiphan 
          Beiträge: 2684
 Erhaltene Danke: 32
 
 
 
 
 | 
Verfasst: Di 30.12.08 14:20 
 
Sehr schön    Satt schwarz-weiss könnte man jetzt noch Graustufenbilder zulassen    Oder geht das schon? 
 Da die Energie (die in den meisten Programmen angezeigt wird) quadratisch zur Amplitude ist müsstest du ganz einfach die Wurzel der Helligkeit als Amplitude nehmen und schon würde das klappen   |  |  |  
| JayEff 
          Beiträge: 2971
 
 Windows Vista Ultimate
 D7 Enterprise
 
 | 
Verfasst: Di 30.12.08 18:33 
 
	  |  delfiphan hat folgendes geschrieben  : |  	  | Sehr schön  Satt schwarz-weiss könnte man jetzt noch Graustufenbilder zulassen  Oder geht das schon? | 
 	  |  Dunkel hat folgendes geschrieben  : |  	  | TPCMDrawer kann jetzt auch "Graustufen" darstellen, vorher wurden nur alle schwarzen [RGB(0,0,0)] Pixel hörbar gemacht. | 
   Ich finde die erzeuge WAV etwas zu leise, wäre gut, wenn das lauter ginge, ausserdem hat deine neue Version von der Demo nicht die ganze Datei ausgewertet, sondern nur die obere Hälfte - dafür war die "Auflösung" des erzeugten "Bildes" in der Frequenzanalyse viel höher, nicht übel!
 Dein Demoprojekt friert beim konvertieren immernoch ein, bist du dir sicher, dass du es in einem abgespaltenen Thread rechnen lässt?    Wie auch immer, ich find's klasse - Wie wär's jetzt noch, wenn du ein farbiges Bild erstmal in Graustufen umrechnen lässt (ist ja nicht schwer, ich hab einen Libraryeintrag dazu, moment... www.delphi-library.d...iewtopic.php?t=70493  Diese Prozedur mit den Parametern StepsCount = Step = 1 und darkness = 0 müsste das gewünschte Ergebnis erzielen.)?_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
 [>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
 |  |  |  
| delfiphan 
          Beiträge: 2684
 Erhaltene Danke: 32
 
 
 
 
 | 
Verfasst: Di 30.12.08 18:55 
 
@JayEff:     hatte nicht den ganzen Thread gelesen, nur das Beispiel angeschaut    	  |  Dunkel hat folgendes geschrieben  : |  	  | AudioDB die Grafik mehr in die Länge zieht | 
 Die Umkehrrechnung von Wav zu einzelnen Frequenzen ist leider nicht eindeutig    Da hier mit Wellen gearbeitet wird gibt's genau wie in der Quantenphysik eine Unschärferelation. Beim Zurückrechnen der ursprünglichen Daten hat man entweder eine bessere Auflösung in der Zeit und eine schlechtere Frequenzauflösung oder umgekehrt. Eine exakte Rekonstruktion ist im allgemeinen Fall nicht möglich.    Es gibt auch Programme, die zeigen das ganze auf einer logarithmischen Skala an. Das kann das Bild dann nochmals etwas verzerren. |  |  |  
| Dunkel  
          Beiträge: 682
 
 Mac OS X Snow Leopard
 Xcode 3.1
 
 | 
Verfasst: Di 30.12.08 20:38 
 
	  |  JayEff hat folgendes geschrieben  : |  	  | Ich finde die erzeuge WAV etwas zu leise, wäre gut, wenn das lauter ginge, | 
 Hmmm... bei manchen Bildern kann man's lauter machen, bei manchen übersteuert die Ausgabe da zu sehr, so dass keine klaren Geräusche/Bilder mehr generiert werden. Ich bastle momentan an einem GUI um diverse Einstellungen komfortabel vornehemn zu können.
 	  |  JayEff hat folgendes geschrieben  : |  	  | ausserdem hat deine neue Version von der Demo nicht die ganze Datei ausgewertet, sondern nur die obere Hälfte - dafür war die "Auflösung" des erzeugten "Bildes" in der Frequenzanalyse viel höher, nicht übel! | 
 Nur die obere Hälfte? OK....
 	  |  JayEff hat folgendes geschrieben  : |  	  | Dein Demoprojekt friert beim konvertieren immernoch ein, bist du dir sicher, dass du es in einem abgespaltenen Thread rechnen lässt?
  | 
 Die Klasse TPCMDrawer ist nur von TTHread abgeleitet, das Demoprojekt nutzt diese Möglichkeit aber noch nicht. Der Quellcode ist für alle da, viel Spaß beim Umschreiben auf eine gethreadete Version.     	  |  JayEff hat folgendes geschrieben  : |  	  | Wie auch immer, ich find's klasse - Wie wär's jetzt noch, wenn du ein farbiges Bild erstmal in Graustufen umrechnen lässt (ist ja nicht schwer, ich hab einen Libraryeintrag dazu, moment... www.delphi-library.d...iewtopic.php?t=70493 Diese Prozedur mit den Parametern StepsCount = Step = 1 und darkness = 0 müsste das gewünschte Ergebnis erzielen.)?
 | 
 Ja, hab ich auch schon drüber nachgedacht. Da Ergebnis von bunten Bildern ist nicht wirklich pralle. Mal schaun'.
 Edith flüstert: hab ich gerade testweise implementiert; kein Unterschied zu meiner Methode
 		                       Delphi-Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 
 |   color:= fBitmap.Canvas.Pixels[fBitmapPosCounter, fBitmap.Height - i];r:= GetRValue(color);
 g:= GetGValue(color);
 b:= GetBValue(color);
 if fRevertColor then
 c:= 255 - ((r+b+g) div 3)
 else
 c:= ((r+b+g) div 3);
 |  Farben in "Pseudo-Graustufen" zu verwandeln. Ich lasse es trotzdem mal als Option drin. Danke!_________________Ich streite einsam mich mit dieser Oberflächenwelt Gutes sei ein löblich Brot von dem ich zehre - bis zum Tod       [Das Ich - Im Ich]
 |  |  |  
| Dunkel  
          Beiträge: 682
 
 Mac OS X Snow Leopard
 Xcode 3.1
 
 | 
Verfasst: Do 01.01.09 18:10 
 
Ich hab' mal ein wenig dran weitergebastelt.
 Das Demoprojekt ist jetzt auch endlich erwachsen, Laden von Bitmaps und JPEGs funktioniert via Drag&Drop aus dem Explorer, die Bilder können verkleinert/vergrößert werden, an diversen Einstellungen kann nach Lust und Laune herumgespielt werden, Threading ist endlich implementiert.
 
 ToDos: Geschwindigkeit! Mal gucken, ob man Multithreading implementieren kann.
 
 Viel Spaß damit!
 _________________Ich streite einsam mich mit dieser Oberflächenwelt Gutes sei ein löblich Brot von dem ich zehre - bis zum Tod       [Das Ich - Im Ich]
 |  |  |  
| JayEff 
          Beiträge: 2971
 
 Windows Vista Ultimate
 D7 Enterprise
 
 | 
Verfasst: Do 01.01.09 20:13 
 
	  |  Dunkel hat folgendes geschrieben  : |  	  | ToDos: Geschwindigkeit! Mal gucken, ob man Multithreading implementieren kann. | 
 Bevor du mit multithreading anfängst, konvertiere mal dashier: 		                       Delphi-Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 11:
 12:
 13:
 14:
 15:
 16:
 17:
 18:
 19:
 20:
 21:
 22:
 23:
 24:
 
 | procedure TPCMDrawer.ReadPictureData;var
 i: integer;
 r, g, b, c: byte;
 color: integer;
 begin
 for i := 0 to fBitmap.Height - 1 do
 begin
 color := fBitmap.Canvas.Pixels[fBitmapPosCounter, fBitmap.Height - i];
 r := GetRValue(color);
 g := GetGValue(color);
 b := GetBValue(color);
 if fReverseColors then
 c := 255 - ((r+b+g) div 3)
 else
 c := ((r+b+g) div 3);
 
 if c >= cIgnoreColorLower then
 fPixelData[i].Amplitude := Trunc(c / 255 * fAmplitude)
 else
 fPixelData[i].Amplitude := 0;
 end;
 Inc(fBitmapPosCounter);
 end;
 |   in Scanline Code... Es kann sein, dass du die bitmap erstmal kippen musst, da du ja spaltenweise konvertieren musst und es scheinbar kein Scanline für Spalten gibt. Scanline ist schneller als pixels. SEHR viel schneller:
 												| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 11:
 12:
 13:
 14:
 15:
 16:
 17:
 18:
 19:
 20:
 21:
 22:
 23:
 24:
 25:
 26:
 27:
 28:
 29:
 30:
 31:
 32:
 33:
 34:
 35:
 36:
 37:
 38:
 39:
 40:
 41:
 42:
 43:
 44:
 45:
 46:
 
 | procedure TForm1.Button2Click(Sender: TObject);type
 pixel = array[0..2] of byte;
 var
 p : ^pixel;
 x, y : Integer;
 ticks : Cardinal;
 begin
 ticks := GetTickCount;
 for y := 0 to Image1.ClientHeight - 1 do
 begin
 p := Image1.Picture.Bitmap.ScanLine[y];
 for x := 0 to Image1.ClientWidth do
 begin
 p^[0] := Byte(p^[0] + 100);
 p^[1] := Byte(p^[1] + 100);
 p^[2] := Byte(p^[2] + 100);
 inc(p);
 end;
 end;
 Label1.Caption := IntToStr(GetTickCount - ticks);
 Image1.Refresh;
 end;
 
 procedure TForm1.Button3Click(Sender: TObject);
 var
 x, y : Integer;
 c : TColor;
 r, g, b : Byte;
 ticks : Cardinal;
 begin
 ticks := GetTickCount;
 for x := 0 to Image1.ClientWidth do
 for y := 0 to Image1.ClientHeight do
 begin
 c := Image1.Canvas.Pixels[x, y];
 r := GetRValue(c);
 g := GetGValue(c);
 b := GetBValue(c);
 r := Byte(r + 100);
 g := Byte(g + 100);
 b := Byte(b + 100);
 Image1.Canvas.Pixels[x, y] := RGB(r, g, b);
 end;
 Label1.Caption := IntToStr(GetTickCount - ticks);
 end;
 |  Das Image ist 937x449px groß. Button3 braucht 2600 ms. Button2 braucht unter 1 ms. Nur so zum Vergleich.  _________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
 [>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
 |  |  |  
| Dunkel  
          Beiträge: 682
 
 Mac OS X Snow Leopard
 Xcode 3.1
 
 | 
Verfasst: Do 01.01.09 21:39 
 
Danke für den Vorschlag, werde ich auf jeden Fall implementieren.     Mit Multithreading habe ich angefangen, die ersten Versuche mit 2 Threads (ich habe ein DualCore, deswegen bietet sich das an) bringen in etwa 40% Geschwindigkeitszuwachs. Mit Scanline ist da wahrscheinlich noch wesentlich mehr rauszuholen. I'll try..._________________Ich streite einsam mich mit dieser Oberflächenwelt Gutes sei ein löblich Brot von dem ich zehre - bis zum Tod       [Das Ich - Im Ich]
 |  |  |  
| Dunkel  
          Beiträge: 682
 
 Mac OS X Snow Leopard
 Xcode 3.1
 
 | 
Verfasst: Fr 23.01.09 22:22 
 
Lange nicht mehr dran weitergebastelt und doch ist zwischenzeitlich das Projekt gewachsen.     Ich hab mal ein neues ZIP-Archiv an den ersten Beitrag gepinnt. In ihr befindet sich ein etwas ausgereifter Editor, um Geräusche aus Bildern zu kreieren. Mit integriert ist auch eine Sonagramm-Visualisierung.
 Den Quelltext der TPCMDrawer-Klasse muss ich noch ein wenig "schönschreiben", dann werde ich ihn auch im ersten Beitrag aktualisieren._________________Ich streite einsam mich mit dieser Oberflächenwelt Gutes sei ein löblich Brot von dem ich zehre - bis zum Tod       [Das Ich - Im Ich]
 |  |  |  |