How disabling sounds when calling a shell program?

M

Michel

Is there a way to stop the sound made through the soundcard when one
uses a Shell or Call in Excel?

I only want to hear a sound on the PC's internal speaker which I had
to make a assembler (fasm) *.com program for. It works perfect under
DOS without sounding the external speakers through win98, but now
Excel is making a sound!

call shell("c:\dos\inPCplay.com 1000 20",0)

witch calls:

; author (e-mail address removed)
; use: inPCplay hertz1 playtime1 [pausetime1 [hertz2 playtime2 ...]]
; time in 1/100 second
; use in Excel: call shell ("c:\inPCplay.com 1000 20 20 2000 20 20
3000 20")

;wait for a time-change of the 1/18sec ticks before starting
mov AH,0 ;function 0 for int 1Ah = read system timer
int 1Ah ;read bios timer (CX:DX = 1 / 18.206sec timeunits,
AL=midnightflag)
mov BX,DX ;save low word to compare later
_Loop:
mov AH,0 ;function 0 for int 1Ah = read system timer
int 1Ah ;read bios timer (CX:DX = 1 / 18.206sec timeunits,
AL=midnightflag)
cmp DX,BX
je _Loop ;if timer = saved time then wait

;initialize
mov AL, 0b6h ;Prepare the PC's internal speaker to sound a note
out 43h, AL ;set port 43h for channel 2
mov BX,0080h ;BX used to point to buffer (= first address -1)
mov DX,0 ;DX used for modes: 0=Hertz, 1=playtime,
2=pausetime

_NextVal:
mov CX,0 ;CX used to see if any value has been read
mov AX,0 ;AX used to hold value being read out of buffer
_ReadChar:
inc BX ;next character (bufferaddress+1)
cmp byte [BX],30h ;char from buffer[BX]
jb _ChkVal ;if character < "0" then stop read and check value
cmp byte [BX],39h ;char from buffer[BX]
ja _ChkVal ;if character > "9" then stop read and check value
mov CX,0Ah ;a numeric character has been found
push DX ;save DX
mul CX ;value*10 (DX:AX = AX * CX)
mov DX,0 ;(DX = 0)
mov DL,byte [BX] ;make word from byte (DX = BXpointedAddressValue)
add AX,DX ;value+char.ascII (DX:AX = AX + DX)
sub AX,30h ;value-48 ("0"=0, "1"=1, ...)
pop DX ;restore DX and delete overflow, value=max 65535
jmp _ReadChar ;get next char
_ChkVal:
cmp CX,0
jne _DoVal ;if CX <> 0 (some val given)
cmp byte [BX],0Dh
je _Exit ;if char = [enter] then stop
jmp _NextVal

_DoVal:
mov CX,AX ;CX=value (CX=AX)
cmp DX,2
je _PauseTime ;if DL=2
cmp DX,1
je _PlayTime ;if DL=1
_SetFrequence:
mov DX,14h ;high divider of frequency
mov AX,4F38h ;low divider of frequency
div CX ;CX = 1331000 / hertz (DX:AX= DX:AX / CX)
out 42h, AL ;Output low byte
mov AL,AH ;AL=AH
out 42h, AL ;Output high byte
mov DX,1 ;next val = Playtime
jmp _NextVal
_PlayTime:
in AL,61h ;read port 61h
or AL,3 ;set bits 1 & 0
out 61h, al ;send new value
mov DX,2 ;next val = Pausetime
jmp _Pause
_PauseTime:
in AL, 61h ;read port 61h
and AL, 252 ;clear bits 1 & 0
out 61h, al ;send new value
mov DL,0 ;next val = SetFrequence
jmp _Pause

_Pause:
push DX ;save mode
push BX ;save char-address
cmp CX,00FFh ;CX=delaytime in 1/100 second
jbe _TimeOk ;if time < 2,55sec then do pause
mov CX,00FFh ;lower val to maximum time (2,55 sec)
_TimeOk:
;change 1/100sec to 1/18.206 sec
mov AX,91 ;multiplier
mul CX ;time = time * 91 (DX:AX = CX * AX)
mov BX,500 ;divider
div BX ;time = time / 500 (DX:AX = DX:AX / BX)
mov BX,AX ;save result
mov AH,0 ;function 0 for int 1Ah = read system timer
int 1Ah ;read bios timer (CX:DX = 1 / 18.206sec timeunits,
AL=midnightflag)
add BX,DX ;add present time to delay time
_Loop1:
mov AH,0 ;function 0 for int 1Ah = read system timer
int 1Ah ;read bios timer (CX:DX = 1 / 18.206sec timeunits,
AL=midnightflag)
cmp DX,BX
ja _Loop1 ;if time > delay then wait on truncate low-word
_Loop2:
mov AH,0 ;function 0 for int 1Ah = read system timer
int 1Ah ;read bios timer (CX:DX = 1 / 18.206sec timeunits,
AL=midnightflag)
cmp DX,BX
jb _Loop2 ;if time < delay then wait
pop BX ;get saved char-address
pop DX ;get saved mode
jmp _NextVal

_Exit:
in AL, 61h ;read port 61h
and AL, 252 ;clear bits 1 & 0
out 61h, al ;send new value to stop any sound
mov AH,0
int 21h ;end
 
K

keepitcool

Michel, why the assembler?

Private Declare Function Beep Lib "kernel32" (ByVal dwFreq As Long,
ByVal dwDuration As Long) As Long

'Note beep parameters ignored in win95.
Sub Test()
beep 200, 500
End Sub

suc6!

keepITcool

< email : keepitcool chello nl (with @ and .) >
< homepage: http://members.chello.nl/keepitcool >
 
M

Michel

keepitcool wrote in message:
Michel, why the assembler?

Simple: This is the only way the internal speaker beeps in windows 98!
Otherwise the beep get's ridirected to the soundcard !!!!

Now the question still remains: How can I call a *.com program without
having a sound played on the soundcard when the external program
finishes?

Anyone?
 
M

Michel

!!!! there was a fault in the FASM code which could overload the
memory.

at the end change this:
jmp _NextVal

with:
cmp byte [BX],0Dh
jne _NextVal ;if char <> [enter] then read next char

So, the full inPCplay.com follows here:

; Play notes on PC internal speaker without any sounds through the
soundcard.
; This way you can audio notify the MS-Excel user without disturbing
the online streaming radio and so...
; author (e-mail address removed) ver:1.1
; use: inPCplay hertz1 playtime1 [pausetime1 [hertz2 playtime2 ...]]
; time in 1/100 second
; use Excel: call shell ("c:\inPCplay.com 1000 20 20 3000 20")

;wait for a time-change of the 1/18sec ticks before starting
mov AH,0 ;function 0 for int 1Ah = read system timer
int 1Ah ;read bios timer (CX:DX = 1/18.206sec,
AL=midnightflag)
mov BX,DX ;save low word to compare later
_Loop:
mov AH,0 ;function 0 for int 1Ah = read system timer
int 1Ah ;read bios timer (CX:DX = 1/18.206sec,
AL=midnightflag)
cmp DX,BX
je _Loop ;if timer = saved time then wait

;initialize
mov AL, 0b6h ;Prepare the PC's internal speaker to sound a note
out 43h, AL ;set port 43h for channel 2
mov BX,0080h ;BX used to point to buffer (= first address -1)
mov DX,0 ;DX used for modes: 0=Hertz, 1=playtime,
2=pausetime

_NextVal:
mov CX,0 ;CX used to see if any value has been read
mov AX,0 ;AX used to hold value being read out of buffer
_ReadChar:
inc BX ;next character (bufferaddress+1)
cmp byte [BX],30h ;char from buffer[BX]
jb _ChkVal ;if character < "0" then stop read and check value
cmp byte [BX],39h ;char from buffer[BX]
ja _ChkVal ;if character > "9" then stop read and check value
mov CX,0Ah ;a numeric character has been found
push DX ;save DX
mul CX ;value*10 (DX:AX = AX * CX)
mov DX,0 ;(DX = 0)
mov DL,byte [BX] ;make word from byte (DX = BXpointedAddressValue)
add AX,DX ;value+char.ascII (DX:AX = AX + DX)
sub AX,30h ;value-48 ("0"=0, "1"=1, ...)
pop DX ;restore DX and delete overflow, value=max 65535
jmp _ReadChar ;get next char
_ChkVal:
cmp CX,0
jne _DoVal ;if CX <> 0 (some val given)
cmp byte [BX],0Dh
je _Exit ;if char = [enter] then stop
jmp _NextVal

_DoVal:
mov CX,AX ;CX=value (CX=AX)
cmp DX,2
je _PauseTime ;if DL=2
cmp DX,1
je _PlayTime ;if DL=1
_SetFrequence:
mov DX,14h ;high divider of frequency
mov AX,4F38h ;low divider of frequency
div CX ;CX = 1331000 / hertz (DX:AX= DX:AX / CX)
out 42h, AL ;Output low byte
mov AL,AH ;AL=AH
out 42h, AL ;Output high byte
mov DX,1 ;next val = Playtime
jmp _NextVal
_PlayTime:
in AL,61h ;read port 61h
or AL,3 ;set bits 1 & 0
out 61h, al ;send new value
mov DX,2 ;next val = Pausetime
jmp _Pause
_PauseTime:
in AL, 61h ;read port 61h
and AL, 252 ;clear bits 1 & 0
out 61h, al ;send new value
mov DL,0 ;next val = SetFrequence
jmp _Pause

_Pause:
push DX ;save mode
push BX ;save char-address
cmp CX,00FFh ;CX=delaytime in 1/100 second
jbe _TimeOk ;if time < 2,55sec then do pause
mov CX,00FFh ;lower val to maximum time (2,55 sec)
_TimeOk:
;change 1/100sec to 1/18.206 sec
mov AX,91 ;multiplier
mul CX ;time = time * 91 (DX:AX = CX * AX)
mov BX,500 ;divider
div BX ;time = time / 500 (DX:AX = DX:AX / BX)
mov BX,AX ;save result
mov AH,0 ;function 0 for int 1Ah = read system timer
int 1Ah ;read bios timer (CX:DX = 1/18.206sec,
AL=midnightflag)
add BX,DX ;add present time to delay time
_Loop1:
mov AH,0 ;function 0 for int 1Ah = read system timer
int 1Ah ;read bios timer (CX:DX = 1/18.206sec,
AL=midnightflag)
cmp DX,BX
ja _Loop1 ;if time > delay then wait on truncate low-word
_Loop2:
mov AH,0 ;function 0 for int 1Ah = read system timer
int 1Ah ;read bios timer (CX:DX = 1/18.206sec,
AL=midnightflag)
cmp DX,BX
jb _Loop2 ;if time < delay then wait
pop BX ;get saved char-address
pop DX ;get saved mode
cmp byte [BX],0Dh
jne _NextVal ;if char <> [enter] then read next char

_Exit:
in AL, 61h ;read port 61h
and AL, 252 ;clear bits 1 & 0
out 61h, al ;send new value to stop any sound
mov AH,0
int 21h ;end
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top