Der gute Ton: Stereo-Sampler für den TT

Rechner, die über einen Digital-Analog-Umsetzer verfügen, sind sehr gut geeignet, Schwingungen beliebiger Form auszugeben. Die wohl am meisten verbreitete Anwendung ist die Wiedergabe von Sounds in Spielen. Die neuen Atarirechner besitzen zwei DAU und sind so auch in der Lage, Stereo-Sound auszugeben. Wie man jedoch den Stereo-Sound in den Rechner bekommt, bleibt bei den meisten Rechnern noch dem Anwender überlassen.

Nachdem vor einigen Jahren noch das Thema Sampler-Bau in fast jeder Computerzeitschrift strapaziert wurde, soll nun wieder ein Sampler vorgestellt werden. Früher war es der erstmals im Überfluß vorhandene Speicherplatz, der solchen Projekten zu Auftrieb verhalf. Heute soll es die Fähigkeit des STE und TT sein, die im DMA-Mode Stereo-Sound ausgeben können. Die Soundausgabe benötigt keine Rechenzeit und kann demzufolge für jeden, der es erträgt, ständig im Hintergrund hörbar sein. Dabei werden vom Rechner bis zu 100000 Spannungswerte je Sekunde ausgegeben. Wie man 100000 (2*50000) und mehr Messungen je Sekunde bei vertretbarem finanziellen Aufwand (ca. 60,-DM) erreichen kann, beschreibt das folgende Projekt. Eine PD-Diskette mit Software für diesen Sampler erscheint auch, doch dazu später.

Um analoge Größen in digitale Daten zu wandeln, benötigt man einen Analog-Digital-Umsetzer (kurz ADU oder ADC). Dabei gibt es verschiedene Umsetzverfahren. Ein einfaches wird bei den meisten Spielrechnern angewendet. Hier gibt es ein Paddle, an dessen Drehknopf sich ein veränderlicher Widerstand befindet. In Verbindung mit einem Kondensator und einem Standardschaltkreis wird im Rechner ein elektronisches Schwingglied gebildet. Dieses schwingt mit einer Frequenz, die von dem Widerstands wert und damit von der Paddle-Position abhängt. Jetzt braucht man nur noch die Anzahl der Schwingungen in einer bestimmten Zeit zu zählen, und hat aus einer analogen Größe (hier der Widerstands wert oder die Paddle-Position) ein digitales Signal gewonnen. Seit einigen Jahren gibt es integrierte ADU-Schaltkreise, die nur noch wenig externe Beschaltung benötigen. Man hat hier einen Analogeingang, einen Digitalausgang und ein paar Steuerleitungen. Die digitalen Daten liegen in Form von Daten-Bits vor, die je nach Schaltkreistyp seriell oder parallel übertragen werden. Je höher die Anzahl der Daten-Bits ist, umso genauer läßt sich der Meßwert darstellen. Dies hat Auswirkungen auf die Dynamik und damit den Klang eines Sound-Samples.

Um nun aber einen Stereo-Sound in digitale Daten zu wandeln, benötigt man entweder zwei ADUs oder einen ADU mit vorgeschaltetem Analogmultiplexer. Ein Analogmultiplexer ist vergleichbar mit einfachen Schaltern, die nacheinander und zu einer bestimmten Zeit analoge Größen umschalten. Möchte man zwei Kanäle umsetzen, muß der ADU auch zwei AD-Umsetzungen nacheinander und in der gewünschten Meßzeit durchführen. Nimmt man aber zwei ADUs, kann man mit der AD-Umsetzung der beiden Kanäle gleichzeitig beginnen. Dies ist für Soundsampling von geringer Bedeutung, kann aber für die Meßtechnik entscheidend sein. Der hier vorgestellte 2-KanaI-ADU ist für die Meßtechnik wie für das Soundsampling geeignet.

Hardware

Kern des Samplers sind zwei ADU-Schaltkreise vom Typ AD7569. Beim AD7569 handelt es sich um ein komplettes Ein-/Ausgabesystem. So enthält er einen ADU und einen DAU. Der DAU wird bei dem Sampler nicht benötigt, läßt aber für Hobbybastler eine Erweiterung zu. Interessant sind die Daten des AD7569. So kann er eine AD-Umsetzung in 2us durchführen, verfügt über einen Track & Hold-Verstärker und ist busfähig. Um busfähig zu sein, müssen die Datenleitungen einen dritten Zustand kennen. Dieser ist neben High und Low der „hochohmige Zustand“. Möchte man zwei Ausgänge zusammenschalten, ist dieser dritte Zustand notwendig, um keinen Kurzschluß oder falsche Daten zu erhalten. Da der Sampler den Drucker-Port als Schnittstelle nutzt (welcher nur SBit breit ist), ist der hochohmige Zustand notwendig, um 2*8Bit übertragen zu können. Man muß jetzt nur noch beide Schaltkreise so ansteuern, daß mindestens ein Schaltkreis sich im hochohmigen Zustand befindet. Dafür ist eine Logik verantwortlich, die über das Strobe-Signal vom Rechner und über die Eigendynamik der ADUs die Steuerung übernimmt. Kritische Zeitregime müssen bei der Programmierung nicht beachtet werden, da jeder Zustand des Samplers als statisch angesehen werden kann. Die Logik ermöglicht auch den Betrieb als Mono-Sampler. Dazu muß man den Reset-Eingang des zweiten ADUs auf Low-Pegel legen. Der sich ergebende Mono-Sampler ist dann fast kompatibel zu anderen Mono-Samplern, die am Drucker-Port betrieben werden. Das Wörtchen „fast“ entsteht durch eine Eigenart des AD7569. Er legt die Daten negiert an den Ausgängen an. Dadurch ergibt sich ein stark verrauschter Sound, der erst nach einem Negieren der Sample-Daten anhörbar ist. Um den Aufwand beim Aufbau und die Bauelementezahl gering zu halten, wurde keine Negierung auf der Hardware-Ebene vorgenommen.

Zeit-Diagramm

Die beiden Kondensatoren am Eingang dienen der Gleichspannungsentkopplung der Analogeingänge. Da der Sampler mit einer Betriebsspannung von 5V arbeiten sollte und die ADUs damit Spannungen von 0... 1,28 V benötigen, wurde mit einem Spannungsteiler der Arbeitspunkt der Analogeingänge auf 640mV eingestellt. Für Wechselspannung ergibt sich die Eingangsspannung an den Analogeingängen aus 640mV plus der Spannung an den Cynch-Buchsen. Mit anderen Worten bedeutet es, daß bei Wechselspannungsspitzen von 640mV die ADUs voll ausgesteuert sind. Deshalb äußern sich beim Soundsampling Spannungen größer als 640mV mit einem starken Verzerren des Klangbildes. Es werden hier Klanginformationen abgeschnitten, so daß diese verlorengehen. Deshalb muß der Spannungspegel am Kopfhörerausgang genau eingestellt werden.

Die Betriebsspannung des AD7569 beträgt 5 V und kann aus der Joystick-Buchse gewonnen werden. Der Betrieb mit einer symmetrischen Betriebsspannung (+-5 V) ist auch möglich. Dabei kann der Spannungsteiler zur Arbeitspunkteinstellung entfallen.

Die Widerstände zwischen den Datenleitungen und dem Sub-D-Stecker haben die Aufgabe, bei falscher Programmierung des Drucker-Ports einen Kurzschluß zu verhindern. Der Strom wird so im Fall des Falles auf ca. 10mA begrenzt. Dabei wird zwar die Umsetzzeit (oder korrekter die Datenübertragungszeit > T=R*C, wobei C die Eingangskapazität des Drucker-Ports ist) etwas größer, doch ist es nicht einmal einem TT möglich, die noch bestehende Geschwindigkeit des Samplers zu erreichen. Das Strobe-Signal ist in der gleichen Weise geschützt, wobei dieser Widerstand bei einem richtigen Aufbau der Platine nicht notwendig ist.

Funktion

Der Sampler kann sich in vier Zuständen befinden. Die Steuerung der einzelnen Zustände erfolgt mit dem STROBE des Drucker-Ports. Das Zeit-Diagramm zeigt das Verhalten sehr anschaulich. Ausgehend von STROBE-HI, besitzen die Datenausgänge den „hochohmigen Zustand“. Der INT-Anschluß ist ein Interrupt-Ausgang und wird von den ADUs auf LOW gelegt, wenn die Messung beendet ist. So führen diese beiden Anschlüsse erst einmal HL Mit dem HI von STROBE liegt auch an den ST-Anschlüssen (durch die UND-Verknüpfung) ein HI an. Eine fallende Flanke an den ST-Anschlüssen bewirkt den Umsetzbeginn der ADUs. Diese fallende Flanke wird durch ein LOW von STROBE erreicht. Jetzt beginnen beide ADUs mit der Umsetzung. Nach ca. 2|is sind beide ADUs mit der Umsetzung fertig. Die Daten kann aber nur der ADU anlegen, der an CS und RD LOW führt. Da STROBE noch LOW und INT mit der Beendigung der Umsetzung LOW führt, legt der erste ADU seine Daten an. Jetzt heißt es Daten lesen. Ein folgendes HI von STROBE führt zu einem Rücksetzen des ersten ADUs. Damit werden die Datenleitungen hochohmig, und der INT-Ausgang geht auf HI. Der zweite ADU hat nun auch an den Anschlüssen CS und RD LOW, so daß dieser seine Daten anlegt. Jetzt heißt es wieder Daten lesen. Durch ein weiteres LOW von STROBE wird auch der zweite ADU zurückgesetzt, und die Datenausgänge werden hochohmig. Erst jetzt führt der INT-Ausgang des zweiten ADU HI, und die UND-Verknüpfung läßt nach dem nächsten HI von STROBE einen erneuten Start zu. Dieser beginnt, wie schon dargestellt, mit einer fallenden Flanke von STROBE.

Wie verhält sich der Sampler, wenn man den zweiten ADU in einen Dauer-Reset versetzt? Der zweite ADU ist nicht in der Lage, seinen INT-Ausgang auf LOW zu legen, so daß nach dem Zurücksetzen des ersten ADUs sofort die Freigabe für eine erneute Umsetzung gegeben wird. Das ist die typische Funktion eines Mono-Samplers. Man kann auch sehr schnell sehen, daß ein Mono-Sampler sehr leicht mit einem AD7569 und nur wenigen passiven Bauelementen aufgebaut werden kann.

Bestückungsplan

Aufbau

Die Schaltung wird auf einer zweiseitig beschichteten Leiterplatte der Größe 60*53 aufgebaut. Die Breite 53mm entsteht durch die Sub-D-Steckerleistenbreite. Der Schwierigkeitsgrad ist für den Handzeichner recht hoch, da einige Leitungen zwischen den Anschlüssen der Schaltkreise durchgeführt werden müssen. Deshalb sollte man sich eher an Fachleute halten, die den fotochemischen Weg durchführen können. Dabei wird eine mit Fotolack beschichtete Leiterplatte mit einer Maske belichtet und danach fixiert und geätzt. Die Maske kann eine Zeichnung auf Transparent sein, die man z.B. durch einen Plotter oder einem Tintenstrahldrucker erhält.

Beim Bestücken ist eine ruhige Hand von Vorteil. Als Schutzwiderstände wurden aus Platzgründen SMD-Widerstände eingesetzt. Diese können vor dem Löten auf der Leiteiplatte durch einen kleinen Klebepunkt fixiert werden. Wer sich seiner Sache sicher ist, kann diese Widerstände auch durch eine Brücke (Lötpunkt) ersetzen. Dabei ist zu beachten, daß die ADUs nach dem Einschalten des Rechners nicht unbedingt an ihren Ausgängen hochohmig sind (d.h. in keinem Fall den Rechner zum Drucken veranlassen). Neben dem Einstellregler befindet sich die einzige Durchkontaktierung, die nicht mit Bauelementeanschlüssen realisiert wurde. Da alle notwendigen Bauelemente auf der Leiterplatte Platz gefunden haben, muß man nach dem Bestücken nur noch drei Leitungen verdrahten. Das sind die zwei Leitungen von den Cynch-Buchsen zu den Kondensatoren und eine Leitung vom Plus-Anschluß der Leiterplatte zur Joystick-Buchse. Hat man diese Arbeiten beendet, sollte man zuerst die Leiterzüge zwischen dem Sub-D-Stecker und den Schutzwiderständen genau kontrollieren. Besteht hier ein Fehler, können auch Defekte am Rechner entstehen. Danach ist noch eine Kontrolle der restlichen Lötstellen und der Polung der Bauelemente durchzuführen. War alles in Ordnung, kann man den Sampler an den Rechner anschließen. Um die Musik sauber samplen zu können, muß man die besagten 640mV am Schleifer des Einstellreglers einstellen. Dabei darf am Analogeingang keine Spannung anliegen. Wer kein Meßgerät zu seiner Seite hat, kann auch das abgedruckte Programm OFFSET.GFA verwenden. Dieses Programm führt kontinuierlich Messungen durch und zeigt die gemessenen Spannungswerte an. Auch hier muß der Abgleich auf 640mV erfolgen.

In der Regel funktionieren solche Schaltungen nach einem sauberen Aufbau sofort. Sollte der Sampler nicht funktionieren, ist zuerst das Vorhandensein der Betriebsspannung zu prüfen. Liegt diese an, kann man nur noch den Strobe-Eingang mit der Hand takten und dabei die an Pin 10,20,16,17 anliegenden Pegel überwachen. Auf der Basis der Funktionsbeschreibung sollte sich hier sehr schnell das Fehlverhalten feststellen lassen.

Hat jemand kein Interesse für einen Monobetrieb des Samplers, kann er den Stereo/Mono-Schalter auch durch eine entsprechende Brücke ersetzen. Für die reinen Sampler-Anwender trifft dies auch für den AC/DC-Schalter zu. Hier kann man gleich die Bauelementeanschlüsse der Kondensatoren benutzen, um eine direkte Verbindung zu den Eingangsleitungen zu erhalten.

Bestückungsseite / Lötseite

Software

Die Einsatzgebiete für Analog-Digital-Umsetzer reichen vom einfachen Digital-Multimeter über Soundsampling bis hin zur Bildverarbeitung. Dabei dürfte für den Heimbereich das Soundsampling die wohl gebräuchlichste Anwendung sein. Das vorgestellte Programm (Listing 1) ist für viele Anwendungen im Heimbereich geeignet. Den Kern stellt ein Assemblerprogramm dar, welches wie eine Prozedur behandelt werden kann. Dazu wird das Assemblerprogramm von GFA-BASIC mit EXEC geladen, worauf man die Adresse der BASEPAGE erhält. Mit einem Offset auf dieser, lassen sich die Startadressen des Textsegmentes und Datensegmentes bestimmen. Im Datensegment werden vom Assembler-Programm die Startadresse des reservierten Speichers, die Anzahl der aufzuzeichnenden Messungen und die Timer-Voreinstellungen (Abtastfrequenz) benötigt. Nach der Übergabe dieser Parameter kann ein Aufruf des Programmes mittels CALL Textsegmentadresse erfolgen. Diese Methode ist zwar nicht die eleganteste, läßt aber sehr leicht nachträgliche Änderungen im Assembler-Programm zu. Das Ausgangsdatenformat des Assembler-Programmes ist mundgerecht für den PCM-Stereo-Sound eines STE oder TT.

Das Listing „Mini-Sampler“ (Listing 2) zeigt in GFA-BASIC, wie ein einfacher Stereo-Sampler mit einem STE oder TT aussehen kann. Um das Listing kurz zu halten, wurden alle Eingaben über Alert-Boxen bzw. die Fileselect-Box realisiert. Man kann mit 12.5KHz, 25KHz und 50KHz samplen. Auch das Anhören ist nur mit diesen drei Frequenzen möglich. Mit ‘Alles anhören’ ist das einmalige Anhören des gesamten Samples möglich. Die Länge des Sample wird durch den vorhandenen ST-Speicher vorgegeben und kann nicht geändert werden. Mit ‘Block anhö-ren’ kann ein gekennzeichneter Block einmalig oder endlos angehört werden. Der Blockstart wird bei ‘Alles anhören’ mit Drücken der linken Shift-Taste festgelegt und das Blockende durch Drücken der rechten Shift-Taste. Beim ‘Block sichern’ wird der so gekennzeichnete Block gespeichert. Hat man keinen Block gekennzeichnet, wird das gesamte Sample als Block aufgefaßt. Beim ‘Sample laden’ wird das Blockende auf das Sample-Ende gesetzt.

Möchte man die Abtastfrequenz in kleineren Stufen einstellen, muß man ein paar Grundlagen zum MFP kennen. Die Taktfrequenz der Timer ist 2,4576MHz. Alle Timer besitzen ein 8-Bit-Register (hier al), dessen Wert mit jedem Takt einer festen Frequenz dekrementiert wird, bis es den Wert Null hat. Die besagte Frequenz ist die Taktfrequenz des Timers geteilt durch den Wert des Vorteilers. Für die Anwendung im Programm gilt folgende Tabelle:

bl          1 2  3  4  5  6   7
Vorteiler   4 10 16 50 64 100 200

Möchte man z.B. 2*50000 Messungen je Sekunde durchführen, gilt:

al=INT(2457600/(Vorteiler*50000))

Für den Vorteiler setzt man zuerst 4 ein und prüft, wie groß al ist. Ist al größer als 255 muß man für den Vorteiler 10 einsetzen u.s.w.. So lassen sich Meßzeiten bis 20ms erreichen. Hat man den notwendigen Vorteiler gefunden, muß man aus der Tabelle den zugehörigen Wert von bl ablesen und kann den Timer mit al und bl setzen.

Die größte Abtastfrequenz hängt vom verwendeten Rechner ab. Auf einem STE(ST) sind die 50000Hz gerade erreichbar, wobei ein TT im ST-RAM mit eingeschaltetem Cache 68000Hz schafft. Schreibt man das Assembler-Programm für den Monobetrieb des Samplers um, sind fast doppelt so hohe Abtastfrequenzen möglich. Für das Samplen von Sound sind diese Frequenzen nicht mehr interessant. Speicheroszillographen hingegen können nicht genug Messungen je Sekunde durchführen. Eine Periode der Frequenz von fKHz läßt sich bei einer Meßfrequenz von 50000Hz durch 50 Messwerte darstellen. Man erkennt, daß ein solcher Speicheroszillograph eine sehr geringe Grenzfrequenz hat. Dafür kann man aber Analysen durchführen, von denen so mancher Elektroniker nur träumt. Sehr leicht läßt sich der Effektivwert berechnen und Spannungsspitzen feststellen. Aber auch einer Spektralzerlegung und damit der Berechnung des Klirrfaktors oder einer Filterfrequenz steht nichts mehr im Wege. Mit zwei Meßkanälen kann man auch Lissa-jous-Figuren darstellen und auswerten.

PD-535

Die PD-Diskette (ST-Computer-PD 535) enthält für die vorgestellte Hardware einen einfachen Stereo-Sampler für STE/TT bei Mid-Res ST oder höheren TT-Auflösungen. Für alle Bastler ist ein Speicheroszillograph enthalten. Er stellt seine größte Meßfrequenz in Abhängigkeit vom Rechner ein, verfügt über einen Generator (auf PCM-Sound-Basis) mit sechs Schwingungsformen, kann sowohl im Zweistrahlbetrieb als auch im „Lissajousbetrieb“ arbeiten und verfügt über einige andere Extras.

Schaltplan

Tips

Für all diejenigen, die nicht viel Erfahrung bei der Programmierung haben, und trotzdem eigene Programme schreiben wollen, sind folgende Tips gedacht:

Ach so! Falls jemand keinen Händler findet, der den AD7569 vertreibt, noch ein Tip. Bei „segor-electronic“ (Kaiserin-Augusta-Alle 94, 1000 Berlin 10) ist der AD7569 z.Z. für 21,-DM erhältlich. Auf Wunsch gibt es auch einen Abzug der Applikation des AD7569 von Analog Devices für 50Pf. je Blatt.

Literatur:

(1) Analog Devices. Applikation zum AD7569/AD7669

(2) M. Backschat, ST-Computer 8/9 88

(3) Jankowski/Rabich/Reschke, ATARI Profibuch ST-STE-TT (Sybex)

' Listing 1 : OFFSET 
' (c)1992 by MAXON-Computer 
' Autor: Torsten Thiel
' - ermöglicht das kontinuierliche Messen 
'   und Anzeigen der EingangsSpannung 
' - ohne EingangsSignal kann Offsetabgleich 
'   auf 640mV erfolgen
'
RESERVE 10000   ! Speicher für Variablen,
'               ! und Assemblerprogramm reservieren
a%=EXEC (3, "SAM_ASM.PRG", "", "") ! ausführbares Programm
'               ! in den Speicher laden
IF a%>0
    samtext%=LPEEK(a%+8)    ! Adresse des Textsegment
    samdata%=LPEEK(a%+16)   ! Adresse des Datensegment
    samstart%=samdata%
    samanzahl%=samdata%+4
    samzaehl%=samdata%+8
    samvorteil%=samdata%+9
    '
    puffer&=0
    puffer%=VARPTR(puffer&)
    '
    CLS
    PRINT AT(20,4);"Die Spannungen an den Analogeingangen sind"
    @mausaus
    REPEAT
        POKE samzaehl%, 20 ! Zählerstand des TimerD
        POKE samvorteil%,1 ! Vorteiler des TimerD
        LPOKE samstart%, puffer% ! Samplestartadresse 
        LPOKE samanzahl%, 2 ! Anzahl des Messungen (* 2)
        CALL samtext% 
        k1|=PEEK(puffer%) 
        k2|=PEEK(puffer%+1) 
        k1|=XOR(128,k1|) 
        k2|=XOR(128,k2|)
        PRINT AT(10,10);"Kanall = ";5*k1|;" mV "
        PRINT AT(50,10);"Kanal2 = ";5*k2|;" mV " 
        a|=PEEK(&HFFFFFC02)
    UNTIL a|=1 
    @mausein 
ELSE
    PRINT "Systemdatei konnte nicht nachgeladen werden" 
ENDIF 
RESERVE 
END
'
PROCEDURE mausaus 
    a|=18
    ~XBIOS(25,1,L:VARPTR(a|))
RETURN
PROCEDURE mausein 
    a|=8
    ~XBIOS(25,1,L:VARPTR(a|))
RETURN

Listing 1

' Listing 2: Mini-Stereo-Sampler 
' (c)1992 by MAXON-Computer
' Autor: Torsten Thiel
' erfordert das Assemblerprogramm: SAM_ASM.PRG
'
RESERVE 49152 ! Speicher für Variablen, Fileselectbox,
'             ! und Assemblerprogramm reservieren
speicher%=0
IF TT?        ! wenn TT, Speicher aus ST-Ram holen
    laenge%=GEMDOS(68,L:-1,0) ! länge des größten Speicherblocks
    laenge%=laenge%-10240     ! und kleine Reserve fürs Assemblerprg.
    speicher%=GEMDOS(68,L:laenge%,0) ! und diesen reservieren
ELSE        ! wenn STE, normal Speicher holen
    laenge%=MALLOC(-1)
    laenge%=laenge%-10240 
    speicher%=MALLOC(laenge%)
ENDIF
RESERVE 40960           ! nochmal Reserve; Warum> ???
speicherb%=speicher%    ! Blockstart ist Samplespeicherbeginn
laengeb%=laenge%        ! Blockende ist Samplespeicherende
'
a%=EXEC(3,"SAM_ASM.PRG","","")
'
IF a%>0 AND speicher%>0 AND STE?
    samtext%=LPEEK(a%+8)  ! Adresse des Textsegment
    samdata%=LPEEK(a%+16) ! Adresse des Datensegment
    samstart%=samdata%
    samanzahl%=samdata%+4
    samzaehl%=samdata%+8
    samvorteil%=samdata%+9
    '
    DMA SOUND speicher%,speicher%+2,3,0 ! DMA-Sound init.
    REPEAT
        ALERT 0," STEREO-Sampler (mini) | A - Sampeln| B - Anhören | C - Datei",0," A | B | C ",wahl%
        DMACONTROL 0        ! wird Grund-Menue angewählt > Sound aus
        '
        IF wahl%=1
            ALERT 2,“ Mit welcher Frequenz? | | Aufnahme beginnt nach | Anwahl des Button",3,"12.5k | 25k | 50k",wahl%
            IF wahl%=1
                @sample(50,1,speicher%,laenge%) ! Sample mit 12.5 kHz aufnehmen 
            ELSE IF wahl%=2
                @sample(25,1,speicher%,laenge%) ! Sample mit 25 kHz aufnehmen 
            ELSE
                @sample(12,1,speicher%,laenge%) ! Sample mit 50 kHz aufnehmen 
            ENDIF 
        ELSE IF wahl%=2
            ALERT 0," Hörenmenue | A - Alles anhören | B - Block anhören | C - Zurück",0,"A | B | Zurück",wahl%
            IF wahl%=1
                ALERT 2," Mit welcher Frequenz? | | Wiedergabe beginnt nach | Anwahl des Button",3,"12.5k | 25k | 50k",wahl%
                IF wahl%=1
                    DMASOUND speicher%,speicher%+laenge%,1 
                    t1%=200*laenget25000 ! t1% ist Laufzeit des gesamten Sample 
                ELSE IF wahl%=2         ! in 1/200 Sekunde
                    DMASOUND speicher%,speicher%+laenge%,2 
                    t1%=200*laenge%/50000 
                ELSE
                    DMASOUND speicher%,speicher%+laenge%,3
                    t1%=200*laenge%/100000 
                ENDIF
                l1%=laenge%/t1%     ! Länge/Laufzeit ist benötigter Speicher
                b|=1                ! je 1/200 Sekunde
                DMACONTROL 1        ! Sound einmal abspielen
                t%=TIMER            ! und in t% Startzeit merken 
                REPEAT
                    a|=BIOS(11,-1) ! Status der Umschalttasten lesen
                    IF a|=2 AND b| ! bei linker Shift-Taste > Blockstart 
                        speicherb%=speicher%+(TIMER-t%)*l1% 
                        laengeb%=laenge%-speicherb%+speicher%
                    ENDIF
                    IF a|=1         ! bei rechter Shifttaste > Blockende
                        laengeb%=(TIMER-t%)*l1%-speicherb%+speicher%
                        b|=0        ! ist Blockende gekennzeichnet, wird der 
                    ENDIF           ! Blockstart nicht mehr gekennzeichnet 
                UNTIL TIMER>=t%+t1% ! solange bis Laufzeit vorbei ist 
            ELSE IF wahl%=2
                ALERT 2," Der Block ist "+STR$(INT(laengeb%/1024))+" kByte | lang.| A - einmal anhören | B - endlos anhöhren",0," A | B ",a|
                ALERT 2," Mit welcher Freguenz? | | Wiedergabe beginnt nach | Anwahl des Button",3,"12.5k|25k|50k",wahl%
                IF wahl%=1
                    DMASOUND speicherb%,speicherb%+laengeb%,1 
                ELSE IF wahl%=2
                    DMASOUND speicherb%,speicherb%+laengeb%,2 
                ELSE
                    DMASOUND speicherb%,speicherb%+laengeb%,3 
                ENDIF 
                IF a|=1
                    DMACONTROL 1 ! Block einmal anhören
                ELSE
                    DMACONTROL 3 ! Block endlos anhören
                ENDIF 
            ENDIF 
        ELSE
            ALERT 0," Dateimenue | A - Sample laden | B -Block sichern | C - Programmende ",0,"A|B|Ende",wahl%
            IF wahl%=1
                FILESELECT #"Sample laden","\*.SMP","",file$
                IF file$<>""
                    OPEN “I",#1,file$ 
                    a%=LOF(#1)
                    IF a%>laenge% ! ist Sample länger als vorhandener
                        laengeb%=laenge% ! Speicher > Sample kürzen
                        BGET #1,speicher%,laenge%
                    ELSE ! sonst voll einladen und Blockende ist
                        laengeb%=a% ! Samplelänge
                        BGET #1,speicher%,a%
                    ENDIF 
                    CLOSE #1 
                ENDIF 
            ELSE IF wahl%=2
                FILESELECT #"Sampleblock sichern","\*.SMP",".SMP",file$
                IF file$<>""
                    a$=LEFT$(file$,1)
                    IF (a$>="A" OR a$<="P") AND MID$(file$,2,1)=":"
                        a%=DFREE(ASC(a$)-64) ! wieviel Speicher auf Disk X frei 
                    ELSE
                        a%=DFREE(0) ! wieviel Speicher auf Disk frei 
                    ENDIF
                    OPEN "O",#1,file$
                    IF a%>laengeb%
                        BPUT #1,speicherb%,laengeb%
                    ELSE
                        a$=STR$(INT((laengeb%-a%)/1024))
                        ALERT 3," | Sample mußte um | "+a$+" kB gekürzt werden. ", 2,"OK | Abbruch",wahl%
                        IF wahl%=1
                            BPUT #1,speicherb%,a%
                        ENDIF 
                    ENDIF 
                    CLOSE #1 
                ENDIF
            ELSE
                ALERT 3," | Schon abbrechen? ",2,"Ja,Ja|Nein ",ende| 
            ENDIF 
        ENDIF 
    UNTIL ende|=1 
ELSE IF a%=-33
    ALERT 1," Die Systemdatei | 'SAM_ASM.PRG'| konnte nicht nach- | geladen werden.",1,"Abbruch",dummy%
ELSE IF NOT (STE?)
    ALERT 1," Der Rechner verfügt | über keinen | DMA-Sound-Chip.",1,"Schade",dummy%
ENDIF
IF speicher>0
    ~MFREE(speicher%)
    RESERVE
ENDIF
END
'
'
'
PROCEDURE sample(a|,b|,VAR c%,d%)
    POKE samzaehl%,a|   ! Zählerstand des TimerD 
    POKE samvorteil%,b| ! Vorteiler des TimerD 
    LPOKE samstart%,c%  ! Samplestartadresse 
    LPOKE samanzahl%,d% ! Anzahl des Messungen (*2) 
    @taus
    CALL samtext%       ! es wird Interrupt gesperrt
    @tein 
RETURN
PROCEDURE taus 
    a|=18
    ~XBIOS(25,0,L:VARPTR(a|)) ! schaltet die Maus aus
    a|=19
    ~XBIOS(25,0,L:VARPTR(a|)) ! schaltet die Tastatur aus 
RETURN
PROCEDURE tein 
    a|=8
    ~XBIOS(25,0,L:VARPTR(a|)) ! schaltet die Maus ein 
    a|=17
    ~XBIOS(25,0,L:VARPTR(a|)) ! schaltet die Tastatur ein 
RETURN

Listing 2

* Listing 3: SAM_ASM
* (c)1992 by MAXON-Computer
* Autor: Torsten Thiel

* - Sampelt Stereo-Sound in STE/TT (ST)
*   wobei beim ST noch 2*50000
*   Messungen/Sekunde möglich sind

* - vor dem Aufruf müssen Datenelemente
*   gesetzt sein startadr > Startadresse
*   zum Ablegen der Sampledaten.

*   anzahl > Anzahl der Messungen
*   zaehler, vorteiler
*            > legen Abtastfreguenz fest
*   AFrequenz=2457600/(vorteiler*zaehler)

    movem.l d0-d7/a1-a6,-(sp)

    clr.l   -(sp)
    move.w  #$20,-(sp)
    trap    #1              in den Supervisormodus
    addq.l  #6,sp           schalten
    lea.l   oldsp(pc),a0
    move.l  d0,(a0)         alten Stack merken

    move.w  #$2600,sr       ab jetzt kein IRQ mehr

    movea.l startadr(pc),a1 Startadresse 
    movea.l a1,a2
    adda.l  anzahl(pc),a2   Endadresse 
    movea.l #$ffff8800,a5   SID-Basis 
    movea.l #$ffff8802,a4   SID-Basis+2 
    movea.l #$fffffa00,a6   MFP-Basis 
    movea.l #$fffffa0d,a3   MFP-Basis+13
    moveq.l #15,d1          SID-Register für Druckerport
    moveq.l #4,d2           für Bit 4 testen
    move.l  #$0e002f00,d3   Long für STROBE Hi
    move.l  #$0e000f00,d4   Long Fur STROBE Lo

    move.b  zaehler(pc),d0  Zählerstartwert holen 
    move.b  d0,$25(a6)      und setzen
    move.b  $1d(a6),d0      Vorteiler des Timer's C/D holen
    andi.b  #$f0,d0         und Timer D neu setzen
    move.b  vorteil(pc),d7
    or.b    d7,d0
    move.b  d0,$1d(a6)
    bset    #4,9(a6)        Timer D muß IRQ geben können

    move.b  #7,(a5)         Port B auf Eingabe
    move.b  (a5),d0         schalten
    andi.b  #$7f,d0
    move.b  d0,2(a5)

    move.l  d3,(a5)         STROBE Hi senden
    move.b  d1,(a5)         Port B selektieren
    move.b  (a5),d0         Port B testen
    beq.s   Takt1           wenn 'Ja' > Sampler bei Takt 4
    move.l  d4,(a5)         wenn 'Nein' > STROBE Lo und
    move.l  d3,(a5)         STROBE Hi senden
Takt1:
    move.l  d4,(a5)         STROBE Lo senden TAKT1(Start) 
    bclr    d2,(a3)
    move.b  (a3),d5         move ist schneller als bclr 
inplr:
    btst    d2,(a3)         warten bis Timerzeit
    beq.s   inplr           abgelaufen
    move.b  d5,(a3)         Timer zurucksetzen
    move.b  d1,(a5)         Port B selektieren
    move.b  (a5),(a1)+      Port B lesen
    move.l  d3,(a5)         STROBE Hi senden TAKT2
    move.b  d1,(a5)         Port B selektieren
    move.b  (a5),(a1)+      Port B lesen
    move.l  d4,(a5)         STROBE Lo senden TAKT3
    move.w  d3,(a4)         STROBE Hi senden TAKT4
    move.w  d4,(a4)         STROBE Lo senden TAKT1(Start)
    cmpa.l  a1,a2           ist Endadressen schon erreicht?
    bne.s   inplr           wenn 'Nein' noch ein Durchlauf

    move.b  $1d(a6),d0
    andi.b  #$f0,d0         Timer D stoppen
    move.b  d0,$1d(a6)
    bclr    #4,9(a6)

    move.l  d3,(a5)         STROBE Hi senden TAKT2
    move.l  d4,(a5)         STROBE Lo senden TAKT3

    move.w  #$2300,sr       IRQ's wieder erlauben

    move.l  oldsp(pc),-(sp)
    move.w  #$20,-(sp)
    trap    #1 in User-Modus zurück
    addq.l  #6,sp

    move.l  #%01111111011111110111111101111111,d0
    movea.l startadr(pc),a1 Startadresse
    movea.l a1,a2
    movea.l anzahl(pc),a3
    move.l  a3,d7
    andi.l  #%11111111111111111111111111100000,d7 
    beq.s   neg32end
    adda.l  d7,a2
neglr32:
    eor.l   d0,(a1)+        aus Geschwindigkeitsgrunden
    eor.l   d0,(a1)+        gleich 32 Byte
    eor.l   d0,(a1)+
    eor.l   d0,(a1)+
    eor.l   d0,(a1)+
    eor.l   d0,(a1)+ 
    eor.l   d0,(a1)+ 
    eor.l   d0,(a1)+
    cmp.l   a1,a2           ist Endadresse schon erreicht?
    bne.s   neglr32         wenn 'Nein' noch ein Durchlauf 
neg32end:
    move.l  a3,d7
    andi.l  #%00000000000000000000000000011111,d7
    beq.s   ende 
neglr1:
    eor.b   d0,(a1)+        die restlichen Bytes byteweise 
    dbf     d7,neglr1
ende:
    movem.l (sp)+,d0-d7/a1-a6 
    rts

DATA

startadr:   DC.l 0
anzahl:     DC.l 0
zaehler:    DC.l 20
vorteil:    DC.l 1
oldsp:      DC.l 0

Listing 3

' es wird das Assemblerprogramm SAM_ASM.PRG 
' aus Data-Zeilen generiert 
' - notwendig für den Mini-Stereo-Sampler 
' (c)1992 by MAXON-Computer 
' Autor: Torsten Thiel »

puffer$=SPACE$(318)
puffer%=VARPTR(puffer$) 
pruefsumme%=0 
FOR i%=0 TO 317
    READ a|
    POKE puffer%+i%,a|
    pruefsumme%=pruefsumme%+a| 
NEXT i%
IF pruefsumme%=24173
    BSAVE "sam_asm.prg",puffer%,318 
ELSE
    PRINT "Prüfsummenfehler !!!"
ENDIF
END
'
DATA 96,26,0,0,1,16,0,0,0,14
DATA 0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,72,231
DATA 255,126,66,167,63,60,0,32,78,65
DATA 92,143,65,250,1,10,32,128,70,252
DATA 38,0,34,122,0,246,36,73,213,250
DATA 0,244,42,124,255,255,136,0,40,124
DATA 255,255,136,2,44,124,255,255,250,0
DATA 38,124,255,255,250,13,114,15,116,4
DATA 38,60,14,0,47,0,40,60,14,0
DATA 15,0,16,58,0,204,29,64,0,37
DATA 16,46,0,29,2,0,0,240,30,58
DATA 0,189,128,7,29,64,0,29,8,238
DATA 0,4,0,9,26,188,0,7,16,21
DATA 2,0,0,127,27,64,0,2,42,131
DATA 26,129,16,21,103,4,42,132,42,131
DATA 42,132,5,147,26,19,5,19,103,252
DATA 22,133,26,129,18,213,42,131,26,129
DATA 18,213,42,132,56,131,56,132,181,201
DATA 102,230,16,46,0,29,2,0,0,240
DATA 29,64,0,29,8,174,0,4,0,9
DATA 42,131,42,132,70,252,35,0,47,58
DATA 0,90,63,60,0,32,78,55,92,143
DATA 32,60,127,127,127,127,34, 122,0,62
DATA 36,73,38,122,0,60,46,11,2,135
DATA 255,255,255,224,103,22,213,199,177,153
DATA 177,153,177,153,177,153,177,153,177,153
DATA 177,153,177,153,181,201,102,236,46,11
DATA 2,135,0,0,0,31,103,6,177,25
DATA 81,207,255,252,76,223,126,255,78,117
DATA 0,0,0,0,0,0,0,0,20,1
DATA 0,0,0,0,0,0,0,0,32,32

Listing 4


Torsten Thiel
Aus: ST-Computer 06 / 1992, Seite 117

Links

Copyright-Bestimmungen: siehe Über diese Seite