ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/docs/poster.sdf
Revision: 1.1
Committed: Sat Feb 3 23:05:01 2001 UTC (25 years, 7 months ago) by root
Branch: MAIN
CVS Tags: HEAD
Log Message:
*** empty log message ***

File Contents

# Content
1 !init OPT_STYLE="paper"
2
3 !define DOC_NAME "Was Marc Zuhause macht, wenn ihm langweilig ist!"
4 !define DOC_AUTHOR "Marc Lehmann <pcg@goof.com>"
5 !build_title
6
7 H1: Marc langweilt sich...
8
9 immer dann, wenn er wenig Abwechslung hat. Wenn er vor einem (nicht
10 sonderlich lebensbedrohlichem und eigentlich völlig unwichtigem) Problem
11 steht, passiert es bisweilen, daß er versucht, es zu lösen. Allerdings
12 nicht sehr ernsthaft, weshalb die "Lösung" meist ein ganz anderes Problem
13 "löst". Manchmal kommt dabei ein Perl-Modul heraus, und einige davon
14 werden sogar veröffentlicht. Oder auf dem Perl-Workshop 2001 in einer
15 POSTER-Session vorgeführt...
16
17 H2: PDL::Audio - Tonkrachklang mit Perl!
18
19 Das Problem.. was war das Problem denn gleich noch.. Ach ja, ich wollte
20 die gesprochenen Texte für meinen Anrufbeantworter nachbearbeiten (damit
21 nicht jeder sofort erkennt, wen er anruft, ist ja schließlich nicht
22 die Aufgabe des Telefons... ;).
23
24 Zuerst habe ich das mit dem freien Sound-Editor "snd" (tolles Ding!)
25 gemacht, teilweise in Scheme (Marc schüttelt sich). "Warum kann man
26 das nicht in Perl???" schrie ich verzweifelt (ich hätte auch ein
27 Kommandozeilentool genommen, so verzweifelt war ich). Jetzt kann man es,
28 und jede Menge zusätzliches Schnickschnack gibt es auch.
29
30 H3: Code-Beispiele
31
32 "The Basics". Audiodateien einlesen, ein Klacks:
33
34 !block perl
35 use PDL;
36 use PDL::Audio;
37
38 $wav = raudio "kongas.wav"; # Laden
39 $wav->scale2short->playaudio; # Abspielen
40 $wav->scale2short->playaudio(rate => 1000); # Grausam!
41 waudio $wav, "kongas.au"; # Und wieder Speichern!
42 !endblock
43
44 Da Audiodaten sehr umfangreich sein können, kommt eine Speicherung als
45 normales Perl-Array nicht in Frage. Zum Glück gibt es {{die}} Lösung zur
46 Speicherung und Verarbeitung großer Datenmengen (Vektoren und Matrizen!)
47 in Perl, die {{Perl Data Language}} (PDL). Damit kann man nicht nur Daten
48 kompakt speichern, sondern auch damit rechnen, z.B. eine Wellenform
49 "normalisieren":
50
51 !block perl
52 $wav -= min($wav);
53 $wav /= max($wav);
54 $wav = ($wav - 0.5) * 2
55 !endblock
56
57 Oder eine Sinus-Schwingung erzeugen:
58
59 !block perl
60 $sine = sin (zeroes(10000)->xlinvals(0,6.282));
61 !endblock
62
63 C<PDL::Audio> hat viele solcher Generatoren für Wellenformen.
64
65 Und nun: "The Worx". Ok, ich übertreibe, aber es ist nur ein Beispiel:
66
67 !block perl
68 $snd = raudio "kongas.iff";
69 $snd *= gen_oscil $snd, 9/$snd->rate; # AM-Modulation "flirren"
70 $snd->scale2short->playaudio;
71 !endblock
72
73 Oder ein bißchen Audio-Synthese (langweiliger Sinuston):
74
75 !block perl
76 $envelope = gen_env (22500*2, pdl(0,1,2,15,16), pdl(0,1,0.9,0.7,0));
77 $snd = $envelope * gen_oscil $envelope, 900/22500;
78 $snd->scale2short->playaudio(rate => 22500);
79 !endblock
80
81 Raumschift Enterprise läßt grüßen (FM-Synthese):
82
83 !block perl
84 $env = gen_env (22050*2, pdl(0,1,2,15,16), pdl(0,1,0.9,0.7,0));
85 my $fm = gen_triangle $env, 16/22500;
86 $fm *= $fm->xlinvals(0,0.1);
87 $snd = $env * gen_oscil $env, 900/22500, 0, $fm;
88 $snd->scale2short->playaudio(rate => 22500);
89 !endblock
90
91 Oder die original-Strong-Synthese, zum ersten Mal mit PDL!
92
93 !block perl
94 my $pdl = zeroes 22500*5; # der "Ton"
95 my $freq = int (22500/220); # Grundfrequenz der Saite
96 my $x = $pdl->slice("0:".($freq-1)); $x .= gen_rand $x, 1;
97 # Am Anfang stehen nun Zufallszahlen, es folgt ein
98 # einfacher Filter:
99 $pdl = $pdl->filter_lir(0,1,pdl($freq,$freq+1),pdl(0.5,0.5));
100 $pdl->scale2short->playuaiod(rate => 22500);
101 !endblock
102
103 Wer das (und mehr) hören will, braucht entweder PDL::Audio oder den
104 Perl-Workshop ;)
105
106 H2: RCU - Mein Wecker: "Aus!"
107
108 Irgendjemand hatte die dumme Idee, sich von seinem Anrufbeantworter
109 wecken zu lassen (der Anrufbeantworter versteht natürlich Perl). Nur
110 wie stellt man das Ding (es steht ziemlich weit weg) wieder ab, ohne
111 aufzustehen? Natürlich per Infrarot-Fernbedienung. Klar, dafür gibt es
112 auch ein Perl-Interface, genannt C<RCU> (für Remote-Control-Unit). Damit
113 kann man sein Programm per Linux-Lircd oder mittels Irman (ein sehr
114 populäres Empfangsgerät für Infrarot-Fernbedienungen) fernsteuern.
115
116 H3: Beispiel, primitive Variante
117
118 !block perl
119 use RCU;
120
121 $rcu = new RCU "RCU:Irman";
122
123 while (($keycode, $repeat) = $rcu->get) {
124 print "Taste $keycode wurde empfangen\n";
125 }
126 !endblock
127
128 Gibt z.B.:
129
130 !block verbatim
131 Taste 575000000000 wurde empfangen
132 Taste 55d000000000 wurde empfangen
133 Taste 558000000000 wurde empfangen
134 Taste 558000000000 wurde empfangen
135 !endblock
136
137 Langweilig. Schlechtes Interface. Aber für Hacks ganz o.k.
138
139 H3: Beispiel, korrekte Variante
140
141 Fernbedienungen senden ihre Wiederholungssignale (z.B. wenn man die
142 "Lauter"-Taste lange gedrückt hält) in 0.2s, 0.02, 0.1s oder anderen
143 Intervallen, einen Standard gibt es nicht. Die meisten Programme ändern
144 die Lautstärke jedesmal in festen Schritten, d.h. beim Programmautor
145 klappt's toll, woanders aber weniger, weil es entweder zu langsam oder zu
146 schnell geht.
147
148 Deshalb gilt: nur Taste-drücken-/Taste-loslassen-Ereignisse sind von
149 Belang, bzw. die Zeit dazwischen. Mit dem C<Event>-Modul ist es einfach:
150
151 !block perl
152 use Event;
153 use RCU::Event;
154
155 # ein Timer, der fünfmal pro Sekunde feuert
156 $forward = Event->timer(interval => 0.2, hard => 1, parked => 1, cb => sub {
157 print "Vorwärts, auf, auf!\n";
158 });
159
160 # der "Kontext", in dem die Tasten interpretiert werden
161 my $ctx = new RCU::Context;
162 $ctx->bind(
163 "sony-cd-(\d+)" => sub { print "Taste ($_[0])\n" },
164 "sony-cd-fwd" => sub { $forward->at($_[1]); $forward->start },
165 "~sony-cd-fwd" => sub { $forward->stop },
166 "sony-cd-stop" => sub { Event::unloop },
167 );
168
169 # Fernbedienung öffnen
170 $rcu = new RCU::Event "RCU:Irman";
171 # Startkontext setzen
172 $rcu->set_context($ctx);
173
174 # und los!
175 Event::loop;
176 !endblock
177
178 H2: Compress::LZF, wenns mal schnell gehen soll
179
180 Was macht man, wenn man sehr viele "Datenpäckchen" speichern muss, die
181 alle unabhängig sind, Platz wegnehmen und ziemlich gut komprimierbar sind
182 (bei mir z.B. viele Hashes, die mit C<Storable> behandelt wurden). Klar,
183 man komprimiert sie. Aber irgendwie war da nichts richtig freies ("blöde
184 GPL, ich will das kommerziell ausbeuten!"), nichts richtig schnelles (LZO,
185 na gut, aber das ist so umständlich) und irgendwie alles so groß und
186 kompliziert.
187
188 C<Compress::LZF> ist da anders, es ist klein:
189
190 !block perl
191 -rwxr-xr-x 8236 Jan 13 19:36 LZF.so
192 !endblock
193
194 verglichen mit anderen "Monstern":
195
196 !block perl
197 -rwxr-xr-x 33417 Oct 18 21:56 Zlib.so
198 -rwxr-xr-x 60926 Nov 5 06:48 libz.so.1.1.3
199 !endblock
200
201 Ausserdem ist es schnell (ja, echt!), frei (BSD-Lizenz), einfach zu
202 installieren (keine Library, kein autoconfig-Zeugs), klein, resistent
203 gegen Bitfehler in seinen Datenstrukturen (naja, wers braucht) und
204 komprimiert durchschnittlich halb so gut wie C<gzip -9> (Bei kleinen
205 Blöcken ist es allerdings viel besser ;), man kann nicht alles haben.
206
207 Und die Bedienung ist nicht der Rede wert:
208
209 !block perl
210 use Compress::LZF;
211
212 $meist_kleiner = compress $data;
213 $original = decompress $meist_kleiner;
214 !endblock
215
216 C<$meist_kleiner> ist auch in Extremfällen maximal ein Byte größer als
217 das Original.
218
219 H2: Modem-VBox - Habe ich schon von meinem Anrufbeantworter erzählt?
220
221 Ja, er spricht Perl, und damit auch C<Modem::VBox>, ein Modulchen,
222 mit dem man Anrufbeantworter, Voiceboxen oder anderes programmieren kann
223 (hey, es ist Perl!). Leider wurde es bisher nur mit Linux-ISDN eingesetzt,
224 aber die benutzten AT-Befehle sind eigentlich universell verbreitet.
225
226 H3: Meine kleine Voicebox
227
228 Das mitgelieferte Beispielskript ist etwas zu lang (unter anderem
229 verschickt es aufgenommene Gespräche per e-mail) um es ganz abzudrucken,
230 aber in aller Kürze sieht es so aus:
231
232 !block perl
233 use Modem::VBox;
234
235 # Wir VBoxen uns durch
236 $v = new Modem::VBox
237 line => $ARGV[0] || "/dev/ttyI1",
238 modeminit => 'ATZ&D2&B512&E9377358S13.4=0S13.2=1S13.6=0+FCLASS=8',
239 rings => 5, # connect after 5 rings
240 connect_cb => \&main_menu;
241 $v->loop;
242
243 # Das Hauptmenü
244 sub main_menu {
245 my $context = $v->context->set(
246 # Beispiele für die Menüführung
247 "1\$" => [\&record_menu], # Taste "1": Nachricht hinterlassen
248 "2\$" => [\&music_menu], # Taste "2": Musik spielen
249 "[^12]+\$" => \&not_valid,# alles andere ist ganz, ganz falsch
250 );
251
252 # Wir sagen "Hallo" und vielleicht noch mehr:
253 $v->play_file("$MSG/welcome"); $v->play_pause(0.2);
254
255 # Aus dieser Schleife lassen wir sie nicht entkommen!
256 while (my $ev = $v->event) {
257 if ($ev->isbreak) {
258 $v->play_flush;
259 $v->play_pause(0.5);
260 $ev->data->[0]->();
261 return unless $v->connected;
262 }
263
264 # Wenn nur noch ein Soundfile in der Warteschlange
265 # steht, füge den Hilfetext ("das Menü") an:
266 if ($v->play_count <= 1) {
267 $v->play_file("$MSG/help");
268 $v->play_pause(1);
269 }
270 }
271 }
272
273 sub not_valid {
274 my $context = $v->context->set(".*" => sub {});
275 $v->play_flush;
276 # Das beliebte
277 # AT&T-Multilingual-The-number-you-have-dialed-is-not-valid
278 $v->play_file ("$MSG/number_not_valid");
279 $v->play_pause (0.4);
280 $v->play_drain;
281 }
282
283 # usw...
284 !endblock
285
286 H2: Audio::Play::MPG123 - ich liebe Terminals
287
288 Es gibt ja sooo tolle mp3-Player. Aber alle machen diese häßlichen
289 "meine-Knöpfe-sind-noch-kleiner"-, "mein-Skin-ist-länger-als-deiner"-
290 und "ich-nehme-gerne-Platz-weg"-Fenster auf. Das mag' ich nicht: Wenn ich
291 Fenster will, mache ich Fenster, wenn ich beim Arbeiten mp3s hören will,
292 muss das per Skript gehen.
293
294 Das war das Problem...
295
296 H3: Wie sage ichs mpg123?
297
298 Das Modul spielt natürlich selbst keine mp3s ab, sondern startet nur (das
299 eigene, gefixte) C<mpg123> nach und bedient es bzw. verarbeitet Ereignisse
300 wie "Lied zu Ende, was nun?".
301
302 Ein einfaches Abspielprogramm wäre z.B.:
303
304 !block perl
305 use Audio::Play::MPG123;
306
307 $player = new Audio::Play::MPG123;
308 $player->load("/root/mp2/Misc/kult.mp3");
309 print $player->artist,"\n";
310 $player->poll(1) until $player->state == 0;
311 !endblock
312
313 Diese bestechende Simplizität, diese Eleganz, mit der es wirklich nur
314 mp3s abspielt, keine Playlists, keine Buttons, nichts. Schließlich muß
315 man ja irgendwie seiner Creativität Ausdruck geben können. (Ich höre
316 lieber auf bevor es allzu peinlich wird).
317
318 Dieses Modul hat sogar schon ein Problem gelöst (oder bei der Lösung
319 geholfen), bevor es ein Problem war (ganz untypisch für mich): Der
320 Sound-Treiber meines Notebooks mag es gar nicht, wenn er beim Suspend noch
321 geladen ist. Deshalb gibt mein Abspielprogramm das Audio-Device bei einem
322 SIGPWR frei. Außerdem ist es ganz gut, wenn man sein Notebook Zuhause
323 zuklappt, beim Workshop-Vortrag auf und er spielt {{nicht}} automatisch
324 weiter...
325
326 Und in der Praxis? Wie mir zugetragen wurde, gibt es für die
327 Mitarbeiter von mp3.com einen Service, bei dem man per Web Musiktitel
328 bestellen kann, mit denen dann die Arbeitsräume beschallt werden. Mit
329 C<Audio::Play::MPG123> und C<mpg123> natürlich.
330
331 H2: Video Capturing mit Video4linux
332
333 Hier war das Problem, daß ich eine regelmäßige Serie im Fernsehen
334 aufnehmen wollte, die keinen festen Sendetermin hatte. Der Sender hatte
335 auch eine merkwürdige Vorstellung von VPS, also entschloss ich mich, den
336 Anfang der Sendung aufzunehmen und mit einem Skript täglich auf diese
337 Sequenz zu warten. Als es endlich fehlerlos lief, hatte ich alle Folgen
338 gesehen, aber dafür kann man mit Perl jetzt auch Fernsehbilder (oder
339 Digitalkameras) benutzen, zumindest unter Linux.
340
341 Doch dann entdeckte ich die vertikale Austastlücke. Intercast, Internet,
342 Videotext, PDC, EPG, sogar MP3s... Toll! Genau beschrieben habe ich das
343 in einem längeren Artikel im Perl-Journal bzw. auf meiner Homepage
344 (http://home.plan9.de/). Vorführen werde ich das nicht können, aber wer
345 mich besucht kann sicherlich einiges darüber erfahren...
346
347
348
349
350
351
352
353
354