Dr.Godfried-Willem RAES
Kursus Experimentele Muziek: Boekdeel 1: Algoritmische Kompositie
Hogeschool Gent : Departement Muziek & Drama
| <Terug naar inhoudstafel kursus> |
Het weergeven van WAV bestanden vanuit Basic
via een Soundblaster kaart
Het hiernavolgend voorbeeldprogramma (twee versies) toont hoe je een wave-bestand binnen basic programmas kan weergeven. De voorbeeld kode spreekt rechtstreeks de hardware aan van de soundblaster kaart en maakt geen gebruik van externe libraries zoals beschikbaar voor Soundblaster kaarten. Om deze reden kunnen we kompatibiliteit met latere klankkaarten van Soundblaster, en zeker met andere klonen, niet garanderen.
Sedert 2000 is deze aanpak achterhaald en kunnen we de studenten beter verwijzen naar de door ons ontwikkelde kode zoals die deel uitmaakt van onze GMT programmeertaal voor kompositie.
' ***********************************
' * Voorbeeldprogramma 'QBWAVE.BAS' *
' ***********************************
'Original found at http://www.fys.ruu.nl/~bergmann/basic.html 'converted to PowerBASIC by Dave Navarro, Jr. 'additional work by unknown author on CompuServe, and by Godfried-Willem Raes
' this version runs on the Microsoft BC7 PDS platform.
' This SHOULD work on everything that is higher than an XT. An 386-16 won't
' keep up with this in the environment but runs most 8 bit waves fine from
' the compiled program. I also added the environ string stuff to detect a
' non-standard SB port, if BLASTER= is set.
DECLARE SUB SetVoice (OnOff%)
DEFINT A-Z
MaxTicks& = 1193180
SHARED WritePort%, MaxTicks&
'-Div.Init (maybe you get the filename from command line?
CLS
FILES ("*.WAV")
INPUT "Select Wave File"; VocFile$
VocFile% = FREEFILE
'-open the voc-file
OPEN VocFile$ FOR BINARY AS #VocFile%
TestPort$ = ENVIRON$("BLASTER")
IF TestPort$ > "" THEN
PortAddress$ = "&H" + MID$(TestPort$, 2, 3)
PortAddress = VAL(PortAddress$)
WritePort = PortAddress + 12
ELSE
WritePort = &H22C
END IF
'-parameters for copy-to-soundblaster
Bytes& = LOF(VocFile%) 'number of bytes
X$ = SPACE$(40) 'riff file header stuff
GET #VocFile, , X$
Speed = ASC(MID$(X$, 26, 1)) * 256 OR ASC(MID$(X$, 25, 1))
'Playrate in Bytes per second.
'We are assuming an 8 bit *.Wav File Here
' And my 386-16 will hang in there at 11025 BPS under DOS
Clocks = MaxTicks& \ Speed 'using an integer divide. Close enough
'and doesn't pull in floating point math pack
'Maxticks are for the "normal" PC Clock at
'18.206 + ticks per second.
'We'll use this to time the play rate.
Bytes& = Bytes& - 40
BytesRemaining& = Bytes& 'number of remaining bytes
BufferMax% = &H3F00 'largest buffer
Buffer$ = SPACE$(BufferMax%) 'create buffer
SetVoice 1 'Soundblaster on
'-read {BufferMax%} bytes from disc, output on SB
DO
BytesRemaining& = BytesRemaining& - BufferLen%
IF BytesRemaining& = 0 THEN EXIT DO 'nothing left over?
IF BytesRemaining& > BufferMax% THEN 'how many bytes?
BufferLen% = BufferMax%
ELSE
BufferLen% = BytesRemaining& 'remaining (<BufferMax%)..
Buffer$ = SPACE$(BufferLen%) '..throw it into SB :-)
END IF
GET #VocFile%, , Buffer$ 'read buffeer
T = 0
DEF SEG = STRSEG(Buffer$)
K = STRPTR(Buffer$)
OUT &H43, &H34 'PIT Timer select one shot then we can let the
OUT &H40, 0 'clock keep up.
OUT &H40, 0 ' set the clock to 0 and start the count down
Rate& = 65536 - Clocks 'First count down stopping value
' "zero" - Rate
DO 'output od {bufferlen%}
Char = PEEK(K + T)
WAIT WritePort, &H80, &HFF 'wait for data-ready
OUT WritePort, &H10
WAIT WritePort, &H80, &HFF
OUT WritePort, Char 'Direct DAC method
T = T + 1
DO
C& = (INP(&H40) + INP(&H40) * 256&) 'check the ticker
LOOP UNTIL C& <= Rate& 'end if it's at or below the ticks we alloted
Rate& = Rate& - Clocks
IF Rate& < 0 THEN
OUT &H40, 0 'reset the ticker to 0
OUT &H40, 0 'both bytes
Rate& = 65536 - Clocks 'Reset the Rate& value
END IF
LOOP UNTIL T = BufferLen 'This is faster than a for next loop
OUT &H43, 4
LOOP UNTIL Forever
SetVoice 0 'SB off
CLOSE #VocFile% 'close file
END '.. good bye :-)
' Turns Speaker on and off
SUB SetVoice (OnOff%)
IF OnOff% THEN
WAIT WritePort%, &H80, &HFF 'wait for data-ready on SB
OUT WritePort%, &HD1 'ON
ELSE
WAIT WritePort%, &H80, &HFF
OUT WritePort%, &HD3 'OFF
END IF
END SUB
'***********************************************
'* PB-WAVE.BAS PowerBasic Version *
'***********************************************
'Original found at http://www.fys.ruu.nl/~bergmann/basic.html
'converted to PowerBASIC by Dave Navarro, Jr.
'-Div.Init (maybe you get the filename from commandline?
VocFile$ = "MAKEITSO.WAV" 'input-file
VocFile% = FREEFILE '.
xDelay% = 120 'value for delay
'-open the voc-file
OPEN VocFile$ FOR BINARY AS #VocFile%
'-parameters for copy-to-soundblaster
Bytes& = LOF( VocFile% ) 'number of bytes
BytesRemaining& = Bytes& 'number of remaining bytes
BufferMax% = &H7F00 'largest buffer
Buffer$ = SPACE$( BufferMax% ) 'create buffer
SetVoice 1 'Soundblaster on
'-read {BufferMax%} bytes from disc, output on SB
DO
BytesRemaining& = BytesRemaining& - BufferLen%
IF BytesRemaining& = 0 THEN EXIT DO 'nothing left over?
IF BytesRemaining& > BufferMax% THEN 'how many bytes?
BufferLen% = BufferMax%
ELSE
BufferLen% = BytesRemaining& 'remaining (<BufferMax%)..
Buffer$ = SPACE$( BufferLen% ) '..throw it into SB :-)
END IF
GET #VocFile%,, Buffer$ 'read buffer
DEF SEG = STRSEG( Buffer$ ) 'get address of buffer
VOff% = STRPTR( Buffer$ ) '.
FOR t% = 1 TO BufferLen% 'output od {bufferlen%}
FOR qq% = 1 TO xDelay: NEXT qq% ' delay
WAIT &H22C, &H80, &HFF 'wait for data-ready
OUT &H22C, &H10
WAIT &H22C, &H80, &HFF
OUT &H22C, PEEK( VOff% )
VOff% = VOff% + 1
NEXT t%
LOOP WHILE INKEY$ = ""
SetVoice 0 'SB off
CLOSE #VocFile% 'close file
END '.. good bye :-)
SUB SetVoice( OnOff% )
IF OnOff% THEN
WAIT &H22C, &H80, &HFF 'wait for data-ready on SB
OUT &H22C, &HD1 'ON
ELSE
WAIT &H22C, &H80, &HFF
OUT &H22C, &HD3 'OFF
END IF
END SUB
Enkele extra links naar bronnen voor het werken met geluid in BASIC:
Filedate: 98-09-07
| Terug naar inhoudstafel kursus: <Index Kursus> | Naar homepage dr.Godfried-Willem RAES |