Sie sind auf Seite 1von 32

Die Soundkarte im Informatikunterricht

© 2001 Klaus J. Koch, Marburg


• Was ist eine Soundkarte?
• Verwendung als Analog-I/O in der Schule
• Vorbereitungen, Programmierung in Delphi
• Samplen und Darstellen
• Erfassen und Auswerten
• Erzeugen und Wiedergeben einer Datei
• Direkte Ausgabe
• Weitere Informationsquellen, Diskussion
Deutscher Verein zur Förderung des mathematischen und naturwissenschaftlichen Unterrichts
Landesverband Hessen, 30. Hessische Landestagung, 5. September 2001 in Marburg, 14:30 Uhr, HS 113
Didaktische Begründung

• Siehe entsprechende Beiträge aus den 80er Jahren


• Hohe Motivation bei Schülern (und Lehrern)
• überzeugende Demonstration des EVA-Prinzips

E V A
Was ist eine Soundkarte? (1)
• Die erste Sound Blaster für IBM-PCs wurde von
Creative Labs bereits 1989 eingeführt.
http://scitsc.wlv.ac.uk/~e9567075/CP2014/Scards.htm
DOS-Treiber verfügbar.
• Ursprünglich häufigster Einsatzbereich:
Aufpeppen von PC-Spielen durch Sound-Effekte.
Daher der Game-Port auf jeder Soundkarte.
• Außerdem Wiedergabe von Audio-CDs. Daher
früher oft Anschluß für diverse CD-ROM-
Laufwerke vorhanden.
Selten benutzt, aber Standard: Eingänge
Was ist eine Soundkarte? (2)
Analoge Eingänge: Analoge Ausgänge
• Line • [Line]
• Mikrofon • Kopfhörer
• Audio-CD • [Lautsprecher]

Zusätzliche Optionen wie


digitale Ein-/Ausgänge,
Wavetable, MIDI etc.
werden hier nicht
behandelt.
Was ist eine Soundkarte? (3)
Einige zusätzliche technische Angaben:
• der Mikrofon-Eingang unterstützt i.a. nur ein Mono-
Mikrofon. Auf dem für den zweiten Kanal vorgesehenen
Stift liegt oft eine Hilfsspannung (1,5 - 5 V) für
Mikrofonvorverstärker. Der ist meist auch erforderlich!
• Falls kein Lautsprecher-Anschluß vorhanden ist, können
an den Line- oder Kopfhörer-Ausgang auch
Kleinlautsprecher mit 25 - 50 W angeschlossen werden.
• An dem GAME-Anschluß liegt u.a. eine Spannung von
5 V. Achtung: Dieser Anschluß ist i.a. nicht abgesichert!
Verwendung als Analog-I/O in der Schule
Vorteile: Nachteile:
• durch Treiber ins • nur für
Betriebssystem Wechselspannungen ab
eingebunden, keine ca. 20 Hertz
Peeks und Pokes • für manche Zwecke zu
• hohe Auflösung: 16 Bit langsam
• hohe Geschwindigkeit: • Eingangsempfindlichkeit
44100 Samples/s (modellabhängig) oft zu
• 2 Kanäle niedrig
• Oft ohne Aufpreis
enthalten (Notebook)
Vorbereitungen, Programmierung in Delphi

• Einbau und Installation einer


Soundkarte
(falls noch nicht erfolgt.
Gedenket der Interrupts und DMAs!)
• Beschaffen einer geeigneten
Delphi-Komponente
(Empfohlen: AudioIO.ZIP* von John Mertus,
weil mit Sourcen, verwendbar ab Delphi 2!)
und Installation
*) zu finden auf:
http://homepages.borland.com/efg2lab/Library/Delphi/Graphics/Multimedia.htm
Alternativen zur eigenen Programmierung

Verwendung separater Programme


• zur Kommunikation mit der Soundkarte
(Schreiben der erfassten Daten in eine
Datei bzw. Ausgabe einer Datei an die
Soundkarte), z.B. Cooledit, Goldwave, etc.
• zur Datenmanipulation, Auswertung,
Aufbereitung und Darstellung mit
Tabellenkalkulationsprogramm, z.B. Excel
Start
Konventionelle
(time ist die
Programmierung T=time Systemzeit)
ohne
V=input
Ereignissteuerung
V speichern,
Die Meßwerte sind in anzeigen,
konstanten Zeitabständen zu verarbeiten
erfassen. Daher muß
sichergestellt werden, daß T=T+dt
die Anweisungen in der
Schleife innerhalb des
Zeitintervalls dt time<T? ja
abgearbeitet werden
können.
(Abfrage für Stop fehlt noch) Stop
Samplen und Darstellen (1)
• Vergessen Sie Peeks
und Pokes
• Unter Windows
werden Ressourcen
bereitgestellt
Die Puffergröße unterliegt den
üblichen Systembegrenzungen.
Mono, 16 Bit, 22050 Samples/s,
Size=1MByte ergibt 22,67 Sekunden.

• und Botschaften
versandt
Samplen und Darstellen (2)
function TForm1.AudioIn1BufferFilled(Buffer: PChar;
var Size: Integer): Boolean;
var SP : ^SmallInt;
i, N, v, xMin, xMax : Integer;
begin
N := Size div 2; // sizeof(smallint) = 2
SP := Pointer(Buffer);
xMin := SP^; (aus dem Beispiel des Autors)
xMax := xMin;
for i := 0 to N-1 do Diese Methode ermittelt
begin jedesmal, wenn der Puffer
v := SP^; Inc(SP); gefüllt wurde, den
if xMin > v then xMin := v;
if xMax < v then xMax := v; Maximalwert, der in dieser
end; Zeitspanne auftrat.
if Min > xMin then Min := xMin;
if Max < xMax then Max := xMax;
TempMax := xMax;
if Abs(xMin) > xMax then TempMax := Abs(xMin);
Result := TRUE;
end;
Samplen und Darstellen (3)
Allein durch Ereignissteuerung wird die Hardware
natürlich nicht schneller. (Eher im Gegenteil!)
Aber:
• Das Übertragen der Meßwerte vom Eingabeport
in den Puffer erfolgt jetzt durch DMA (Direct
Memory Access) ohne Beanspruchung der CPU.
• Die Bedingung
„Verarbeitungszeit < Meßintervall“ gilt jetzt
nicht für einen Meßwert, sondern gemittelt für N
Meßwerte, wobei N die Puffergröße ist.
Samplen und Darstellen (4)
function TForm1.AudioIn1BufferFilled(Buffer: PChar;
var Size: Integer): Boolean;
type puffer = array[0..1023] of SmallInt;
var zeiger : ^puffer;
i, x, N : Integer;
begin
N := Size Div 2;
zeiger := Pointer(Buffer);
i := 0; // zeigt in den Puffer
x := 0; // zeigt auf den Oszi-Schirm
PaintBox1.Canvas.MoveTo(x,128+zeiger^[i] div 256);
while i < N do
begin
PaintBox1.Canvas.LineTo(x,128+zeiger^[i] div 256);
inc(i);
inc(x);
Hier haben wir bereits einen vollständigen
end; Oszillographen.
Result := TRUE; Es fehlen lediglich noch Anweisungen zum
end;
Löschen des vorhergehenden Bildschirms und
Algorithmen zur Triggerung.
Samplen und Darstellen (5)
function TForm1.AudioIn1BufferFilled(Buffer: PChar; var Size: Integer): Boolean;
var SP : ^Byte; i, N, v : Integer;
const f = 5;
begin
N := Size;
SP := Pointer(Buffer);
with Canvas do FillRect(ClientRect);
Canvas.Pen.Color := clLime; // zeichne links das Ende von letztem Puffer
Canvas.MoveTo(0,128+f*(rechts[0]-128));
for i := 0 to 255 do Vertrauen Sie fremden Puffern?
Canvas.LineTo(i,128+f*(rechts[i]-128));
Canvas.Pen.Color := clRed; // zeichne rechts den Anfang von neuem Puffer
v := SP^; Inc(SP);
for i := 0 to 255 do Visuelle Prüfung, ob das Ende des
begin vorausgehenden Puffers mit dem
v := SP^; Inc(SP);
Canvas.LineTo(256+i,128+f*(v-128));
Anfang des folgenden Puffers „stetig“
end; fortgesetzt wird.
SP := Pointer(Buffer); // kopiere das Ende von neuem Puffer
Inc(SP,N-256); // in ein temporäres Array
for i := 0 to 255 do //
begin
rechts[i] := SP^; Inc(SP);
end;
Result := TRUE;
end;
Samplen und Darstellen (6)
function TMiniOszi.AudioIn1BufferFilled(Buffer: PChar;
var Size: Integer): Boolean;
var i, N, v : integer;
SP : ^SmallInt;
begin
Chart1.Series[0].Clear;
N := Size div 2; SP := Pointer(Buffer);
for i := 0 to N-1 dDo
begin
v := SP^; Inc(SP);
Chart1.Series[0].AddXY(i, v, '', clBlack)
end;
result := true;
end;

Wer sich die Arbeit mit dem Canvas sparen will, kann einfach
die in Delphi enthaltene TChart-Komponente benutzen.
Samplen und Darstellen (7)
Beispiel für einen „Freihandversuch“ mit der Soundkarte:
Zur Zeit der altmodischen (nichtelektronischen) Telefonapparate gab es
Induktionsspulen mit Saugfuß, um eigene Telefongespräche auf dem
Cassettenrecorder mitzuschneiden. Diese haben bereits den für die
Soundkarte benötigten 3,5mm-Stecker.
Falls kein Telefonadapter
zur Hand, genügt auch eine
3000-Wdg-Spule aus der
Physik-Sammlung mit
einem entsprechenden
Übergangskabel.
Wenn man einen kleinen
Magneten an dieser
Induktionsspule
vorbeiführt, ergibt sich
das nebenstehende Bild.
Erfassen und Auswerten (1)
Aufgabenbeispiel:
Es sollen Ereignisse gezählt werden, die durch
folgende Eigenschaften spezifiziert sind:
• Ein Ereignis hat eine bestimmte
Mindestamplitude
• Zwei Ereignisse werden durch eine Pause
von einer bestimmten Mindestdauer
unterbrochen, in der die Mindestamplitude
nicht erreicht wird.
Erfassen und Auswerten (1a)
Impulse sehen in der Realität meist
Zur Definition
eines Impulses nicht so aus wie einem die
Literatur es weismachen will.

Abstand

Schwelle

Die Festlegungen von Schwelle und Abstand


sind mehr oder weniger willkürlich.
Erfassen und Auswerten (2)
function TForm1.AudioIn1BufferFilled(Buffer: PChar;
procedure WarteAufEreignis;
var Size: Integer): Boolean;
var SP : ^SmallInt; begin
i, N, v : Integer; if abs(v) > MindestAmpl then
begin begin
N := Size div 2; zustand := WarteAufPause;
SP := Pointer(Buffer); Shape1.Brush.Color := clRed;
for i := 0 to N-1 do inc(zaehler);
begin Label1.Caption := IntToStr(zaehler);
v := SP^; Inc(SP); tEvent := t;
t := pz*N+i; end;
case zustand of end;
BinInPause : WarteAufEreignis;
WarteAufPause : WarteAufEreignisEnde;
end; procedure WarteAufEreignisEnde;
end; begin
inc(pz); if abs(v) > MindestAmpl then tEvent := t;
Result := TRUE; if t - tEvent > PausenDauer then
end; begin
zustand := BinInPause;
Shape1.Brush.Color := clGreen;
end;
end;
Erfassen und Auswerten (3)
Viele akustische Signale, z.B. Musikinstrumente,
werden sinnvollerweise in der Frequenzverteilung
analysiert.
Um dies während der Erfassung durchzuführen,
ist die konventionelle diskrete Fourieranalyse zu
langsam.
Erst mit der Fast-Fourier-Analyse kann in
Echtzeit ausgewertet werden.
Die zugrundeliegenden Algorithmen sind jedoch
i.a. für die Behandlung in der Schule zu komplex.
Erzeugen und Wiedergeben einer Datei
Für das programmgesteuerte Abspielen einer
Sound-Datei gibt es mehrere Möglichkeiten:
• Unit MMSystem:
SndPlaySound('Clock.wav',0)

• Unit Classes: TMemoryStream


• Komponente TMediaPlayer:
MediaPlayer1.Filename := 'Clock.wav';
MediaPlayer1. Open;
MediaPlayer1. Play;
Aufbau von Dateien im WAV-Format
Alle bisherigen Versuche zum effektiven und verlustfreien Komprimieren von Audio-Dateien müssen
als gescheitert betrachtet werden. (MP3 ist hochkompliziert und nicht verlustfrei!)
Nur so ist es zu erklären, daß das unkomprimierte Windows-Format *.WAV (genauso wie das
entsprechenden Graphik-Format *.BMP) nach wie vor so weit verbreitet ist. Die Analyse des Aufbaus
gelingt durch Vergleich einiger Audio-Dateien:
Direkte Ausgabe (1)
• Vergessen Sie Peeks
und Pokes
• Unter Windows
werden Ressourcen
bereitgestellt

• und Botschaften
versandt
Direkte Ausgabe (2)
function TForm1.AudioOut1FillBuffer(Buffer: PChar;
var Size: Integer): Boolean;
var P : ^SmallInt;
I, tp, N : Integer;
const Freq = 440;
begin
Ton mit konstanter Frequenz 440 Hz
N := Size div 2;
P := Pointer(Buffer);
for i := 0 to N-1 do
begin
tp := N*AudioOut1.FilledBuffers+i;
P^ := Round(MaxShort*Sin(2*pi*tp*Freq/AudioOut1.FrameRate));
Inc(p);
end;
Result := TRUE;
end; Beim Start werden zunächst alle 4 Puffer mit
Daten gefüllt. Erst dann wird mit der Ausgabe
begonnen. Sobald ein Puffer abgearbeitet ist,
fordert er neue Daten an. In der Zwischenzeit
wird erst mal der nächste Puffer abgearbeitet.
Direkte Ausgabe (2a)
Je nach Qualität von Sound-
karte, Endstufe und
Belastung

SINUS

DREIECK
sind die
Resultate mehr SÄGEZAHN
oder weniger zufrieden- RECHTECK
stellend.
Direkte Ausgabe (3)
function TForm1.AudioOut1FillBuffer(Buffer: PChar;
var Size: Integer): Boolean;
var P : ^SmallInt;
I, tp, N : Integer;
begin
Label1.Caption := Format('Frequenz: %8.1f Hz',[freq]);
N := Size div 2;
P := Pointer(Buffer); Anfangsfrequenz muß vorher
for i := 0 to N-1 do
begin
festgelegt worden sein.
tp := N*AudioOut1.FilledBuffers+i;
P^ := Round(MaxShort*Sin(2*pi*tp*freq/AudioOut1.FrameRate));
Inc(p);
freq := freq*1.000001; Ton mit ansteigender Frequenz
end;
Result := freq < 20000.0; // stop, wenn 20 kHz erreicht
end;

Diese Methode sollte einen gleichmäßig


ansteigenden Ton erzeugen.
Klingt aber merkwürdig ...
Direkte Ausgabe (4)
function TForm1.AudioOut1FillBuffer(Buffer: PChar;
var Size: Integer): Boolean;
var P : ^SmallInt;
I, tp, N : Integer;
fneu : extended;
begin
Label1.Caption := Format('Frequenz: %8.1f Hz',[freq]);
N := Size div 2;
P := Pointer(Buffer);
for i := 0 to N-1 do
Erst mit einer Phasenkorrektur ergibt
begin sich das gewünschte Ergebnis.
inc(sample);
tp := N*AudioOut1.FilledBuffers+i;
P^ := Round(MaxShort*Sin(2*pi*tp*freq/AudioOut1.FrameRate+phase));
Inc(p);
fneu := freq*1.000001;
phase := 2*pi*tp/AudioOut1.FrameRate*(freq-fneu)+phase;
freq := fneu;
end;
Result := freq < 20000.0; // stop, wenn 20 kHz erreicht
end;
Direkte Ausgabe (5)
Beispiel für akustische Täuschungen:

Ein Klang, der aus drei Teiltönen besteht; deren Tonhöhe


fortlaufend ansteigt. Erreicht ein Ton die obere Frequenzgrenze,
so wird sie auf die unter Frequenzgrenze zurückgesetzt, um
erneut anzusteigen. Damit dieser Vorgang unkenntlich gemacht
wird, wird die Amplitude der Teiltöne an den Frequenzgrenzen
auf Null abgesenkt. (nach R. Shepard)
Weitere Informationsquellen (1)
• W. Stein: Versuche mit der Soundkarte.
Aus der Klett-Buchreihe Impulse Physik. ISBN 3127725752
• F. Bönsel (Ober-Ramstadt):
Schallwellen mit der PC-Soundkarte vermessen.
Vortrag auf der 26. MNU-Landestagung am 17.9.97 in Darmstadt
• S. Schaal, G. Braune: Physik lernen am Fahrrad.
Http://www.ipn.uni-kiel.de/aktuell/ipnblatt/ip499/ip499r05.htm
• Gert Braune (Humboldt-Schule Kiel/IPN):
Fachübergreifende Unterrichtsprojekte mit der Soundkarte.
Vortrag auf der 47. MNU-Tagung in Bremerhaven am 20.11.2000
• Versuchsanleitungen der TU München. http://www.phprakt.mw.tu-
muenchen.de/mw/mw_v01.html
Weitere Informationsquellen (2)
• Using a sound card in QBasic.
http://www.fys.nl/~bergmann/soundblaster.html
• FreeVIEW sound
http://www.ines.de/sound.htm
Gymnasium Korschenbroich:
• Messung der Schallgeschwindigkeit mit einer Soundkarte.
http://users.aol.com/gykophys/vschall.htm
• Messungen zum freien Fall mit der Soundkarte.
http://users.aol.com/gykophys/ffall.htm
• Eine Messung zum Dopplereffekt.
http://users.aol.com/gykophys/doppler.htm
• Akustische Täuschungen
http://users.aol.com/gykophys/shep.htm
Diskussion
Das vorgestellte Material ist abrufbar unter:

http://www.physik.uni-marburg.de/didact/mnu/mr2001.html

Fortführung der Diskussion in Form einer öffentlichen


Mailingliste.
e-mail an:

soundkarte%klaushilf@mailings.gmx.de