News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Beep

Started by raleeper, August 12, 2011, 12:24:46 PM

Previous topic - Next topic

raleeper

I have taken to heart the comments of qword and others.

I am not rewriting my whole program;  what I am doing is writing a small program (testp), using better programming style, designed just to debug the specific problem described in Topic "Child Window Makes Parent Inactive - Another try"

But I have run into an unrelated problem: Beep doesn't work.

erbeep:
mov eax,0B0 ; duration of the sound, in milliseconds
mov ebx, eax ; trial & error

shl eax, 4 ; freq in hertz  0B0 shl 4 = 0B00

invoke Beep,eax,ebx

retn


The identical code works in my big program, but not in the new small one.
The includes are identical.  Debugging lfw.exe, I hear the beep when I execute the invoke.  Not in testp.exe.

Any idea what could be wrong?

I would also be grateful for any suggestions as to what else I might do to improve programming style.

Thanks, ral

qWord

; 2KHz, 50ms
invoke Beep,2000,50

This sounds are really irritating - you may better use the default sounds coming with Windows: MessageBeep
FPU in a trice: SmplMath
It's that simple!

raleeper

Quote from: qWord on August 12, 2011, 12:53:20 PM
; 2KHz, 50ms
invoke Beep,2000,50

This sounds are really irritating - you may better use the default sounds coming with Windows: MessageBeep

I prefer my frequency and duration.  But your code made me realize how silly it was to use the registers.

Thanks, ral

dedndave

i sometimes use different tones so i can test more than one thing at a time

for things that are going to occur frequently, i use a higher pitch with a shorter duration
for not-so-frequent events, lower tones with longer duration

ToutEnMasm


There is a best soluce (I find)

http://www.soundjay.com/beep-sounds-1.html

Quote
;in ressource file ,     530 WAVE DISCARDABLE "nom.wav"
;include  winmm.lib et winmm.inc
;       invoke SonWav,530
;les macros chr$ et FUNC font parties de MASM32
;################################################################
SonWav PROC  IDwave:DWORD
         Local  retour:DWORD
         Local   hResInfo:DWORD,hRes,lpRes,bRtn
         mov retour,0
    ; Find the resource
    mov hResInfo,FUNC(FindResource,hInstance, IDwave,chr$("WAVE"))
   .if eax == 0   
      wavechec:   
      jmp FindeSonWav
   .endif

    ;--------------------

    mov hRes,FUNC(LoadResource,hInstance, hResInfo)
    .if hRes == NULL
   jmp wavechec
    .endif

    mov lpRes,FUNC(LockResource,hRes)
    .if lpRes != NULL
        mov bRtn,FUNC(sndPlaySound,lpRes, SND_MEMORY + SND_SYNC + SND_NODEFAULT)
        ;invoke UnlockResource,hRes ;obsolete pas necessaire en 32 bits
   mov retour,eax
    .endif
    ;------------------------

    invoke FreeResource,hRes
FindeSonWav:
         mov eax,retour
         ret
SonWav endp



raleeper

ToutEnMasm and dedndave:

Excellent suggestions, but of limited immediate use, since Beep doesn't work at all in testp.

In the meantime I am learning dialog boxes so I can enter and test different values without repeated reassemblies.

Thanks, ral

Geryon

Well there is also more compatable way.
You can also adjust freq. in this example
Just call SuperBeep, Freq.

.686
.xmm
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
include winmm.inc
includelib user32.lib
includelib kernel32.lib
includelib winmm.lib

AUDIO_STREAM_LEN    equ     1
PCM_DATA_SIZE       equ     (44100 * 2 * AUDIO_STREAM_LEN)
PCM_RAW_SIZE        equ     (PCM_DATA_SIZE + 44)

.data
    fTwoPi          dq  6.28
    fNormFactor     dq  44100.0
    fAmpFactor      dq  32767.5
   
    pPcmHeader  db  "RIFF"
                dd  PCM_DATA_SIZE + 36
                db  "WAVE"
                db  "fmt "
                db  16, 0, 0, 0, 1, 0, 1, 0
                dw  44100
                db  0, 0
                dw  44100
                db  0, 0, 2, 0, 16, 0
                db  "data"
                dd  PCM_DATA_SIZE
.data?
    pPcmRaw     dd  ?
   
.code
SuperBeep PROC uses edi ecx nFreq:DWORD
LOCAL dwTmp:DWORD
    finit
    mov edi, pPcmRaw
    add edi, 44
    mov ecx, PCM_DATA_SIZE / 2
    @@:
    mov eax, PCM_DATA_SIZE / 2
    sub eax, ecx
    mov dwTmp, eax
    fild nFreq
    fld fNormFactor
    fdiv
    fld fTwoPi
    fild dwTmp
    fmul
    fmul
    fsin
    fld fAmpFactor
    fmul
    fistp dwTmp
    mov eax, dwTmp
    stosw
    loop @B
    invoke PlaySound, NULL, 0, SND_PURGE
    invoke PlaySound, pPcmRaw, 0, SND_SYNC or SND_MEMORY
    ret
SuperBeep Endp

start:
    finit
    invoke GetProcessHeap
    invoke HeapAlloc, eax, HEAP_ZERO_MEMORY, PCM_RAW_SIZE
    mov pPcmRaw, eax
    push esi
    push edi
    mov edi, pPcmRaw
    mov esi, offset pPcmHeader
    mov ecx, 11
    rep movsd
    pop edi
    pop esi

    invoke SuperBeep, 400   
    invoke GetProcessHeap
    invoke HeapFree, eax, NULL, pPcmRaw
    invoke ExitProcess, -1
   
end start

"Some people have got a mental horizon of radius zero and call it their point of view." --D.Hilbert

raleeper

Quote from: Geryon on August 12, 2011, 08:13:26 PM
Well there is also more compatable way.
You can also adjust freq. in this example
Just call SuperBeep, Freq.
[

Thank you.

I'm sorry I have not made myself clear.
I am not looking for a better beep; I am looking for one that works.
I am not trying to compose a string quartet, I want a debugging tool that will let me know whether keyboard input is being processed.
I am quite happy with what I get from


invoke beep,0b00,0b0


But I get it only in one program and not (nothing) in another.

I attached the program in which it doesnt work in the initial post in this topic.
I suspect that there is some sort of environmental difference, since qword said my beeps were irritating, whereas I get no beeps at all with either his values (2000,50) or mine (0b00,0b0).

Thanks, ral

[later]   I don't find anything about a "superbeep" function in the SDK docunentation or on the msdn site.



dedndave

Ral,
if you do not hear the sound, the program is probably not getting to that point in the code
that is, assuming it is a valid audible tone frequency and duration
you can use this fact to help troubleshoot your code
copy/paste the Beep call earlier into the code until you can hear it   :U

Geryon,
that is very interesting code
although, using WAVE format seems like overkill
wouldn't it be better to generate a MIDI sound, instead ?
it's not like we are trying to play a symphony - lol

do you have a similar example of how to make sounds with an in-memory MIDI format ?

actually - the format looks pretty simple
maybe i can figure it out   :P

raleeper

Quote from: dedndave on August 12, 2011, 09:10:58 PM
Ral,
if you do not hear the sound, the program is probably not getting to that point in the code
that is, assuming it is a valid audible tone frequency and duration


Well, the first thing I tried was to set a breakpoint at invoke Beep,0b00,0b0 and, with a different assembly, invoke Beep,2000,50 in my debugger (WinDbg - yes I know I should probably be using OllyDbg).
Debugging lfw.exe the code works fine, but debugging testp.exe, nothing  (as I think I said in a previous post).

ps to qword: is the 2000, 2000h = 8192d 0r 2000d = 7d0h?
All my code and comments unless otherwise noted are radix 16.

Thanks, ral

[later] correction: the first version I tried, and what I posted had

erbeep:
   pushad
   mov   eax,0B0      ;[in] Duration of the sound, in milliseconds
   push   eax
   shl   eax, 4          ;0b0 shl 4 = 0b00 [and later 200 shl 4 = 2000]
   push   eax
   call   Beep
   popad
       retn

But this doesn't seem to make any difference except in style and efficiency.

jj2007

Quote from: dedndave on August 12, 2011, 09:10:58 PM
Ral,
if you do not hear the sound, the program is probably not getting to that point in the code

Exactly. Here is a primitive macro that might help you...

nclude \masm32\include\masm32rt.inc

MyBeep MACRO arg
  ifndef continueBoxes
.data
continueBoxes dd IDOK
.code
  endif
  .if continueBoxes==IDOK
MsgBox 0, "&arg", "Hi", MB_OKCANCEL
mov continueBoxes, eax
  .endif
ENDM

.code
AppName db "Masm32:", 0

start:
MyBeep A
nop
MyBeep B
nop
MyBeep C
nop
MyBeep D
nop
exit

end start

raleeper

Well, I tried something else.
I put a call erbeep in the initialization part of the program, leaving the call in the key routine in WProc.

Both reach erbeep, but from initailization it works.  From key it doesn't.  Both reach invoke Beep,0b00,0b0.  One beeps the other not.

What could be going on?

Thanks, ral

[later] There is also a jz erbeep in newwin if CreateWindow fails.  If I set a breakpoint there and manually set zf. again the invoke Beep is reached, but doesn't beep.

jj2007

This one works fine, it beeps like hell. But I had to convert the radix16 stuff... ::)

raleeper

Quote from: jj2007 on August 12, 2011, 11:18:04 PM
This one works fine, it beeps like hell. But I had to convert the radix16 stuff... ::)

Well, as I said, the erbeep called from initialization works for me.  The erbeep called from key on key "w', hex 57 doesn't work in my program and your program didn't change the hex 57 to 85d.  To key in 57d = 39h I pressed "9" in your program and that crashed.  I added your include \masm32\include\masm32rt.inc to my program and it didn't help.

I don't think this helps, but I really appreciate your effort.

Thanks, ral

Also
You changed my

scrbf DB 50*25 DUP (" ") ;screen buffer, 25 rows, 50 columns

to

scrbf DB 50h*25 DUP (" ") ;screen buffer, 25 rows, 50 columns
.
Shouldn't that have been "50h*25h"?  That's probably why there is garbage on lines 19h = 25d through 24h = 36d in your program.

You also didn't change
cmdl DB 40 DUP (?) ;not used -
ps LABEL DWORD ;PAINTSTRUCT
DD 10 DUP (?)

The first wouldn't matter; I'm not sure about the second.

What was your reason for removing the "Radix 16" and adding the "h"es anyway.  I don't understand.

Thanks, ral

dedndave

Ral,
one thing i might suggest......

as we mentioned before, the EBX, EBP, ESI, and EDI registers should be preserved
and the EAX, ECX, and EDX registers may be altered

well, windows functions follow these same rules
that includes Beep   :P

in order that you may insert the erbeep routine almost anywhere (anywhere flags need not be preserved).....
erbeep:
        push    eax
        push    ecx
        push    edx
        invoke  Beep,0B00h,0B0h
        pop     edx
        pop     ecx
        pop     eax
        retn