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

Quote from: dedndave on August 13, 2011, 02:45:58 AM
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


You are absolutely right - a hasty oversight on my part.  But it still doesn't work after correction.
Actually the difference would not show up at the invoke, but only after the return if I needed eax, ecx, or edx preserved, and in each case there was nothing to save.

Thanks, ral

dedndave

the one problem that i can see is that you use the same WndProc for all windows
then, at the beginning of WndProc....
WProc proc wp_hWnd,uMsg,wParam,lParam
        pushad
        mov     eax, [wp_hWnd]
        mov     [hwnd], eax

this overwrites the hwnd value every time a different window uses the proc

i am not sure this is a problem - lol - it just looks suspicious   :red
the functions you have inside the WndProc function make the code difficult to follow
it would be easier if the code was modularized
i can see the advantage in doing it that way - the WndProc parameters are local to everyone and need not be passed   :bg

raleeper

An interesting question regarding jj2997's program:

What happens if the OS (BeginPaint) tries to write 16d bytes to a 10d byte buffer - at the very end of the .DATA? segment?

dedndave

usually, nothing will happen
but, it's not good   :P

the sections are blocks of 512 bytes in the file
and i believe they are assigned blocks of 4096 bytes when loaded into memory

if it were a hard error, Dr Watson would come up

i am able to create the first window
but, when i try to create another, the program crashes silently
this is usually caused by a stack misalignment, but i can't find it

raleeper

Quote from: dedndave on August 13, 2011, 03:07:56 AM
the one problem that i can see is that you use the same WndProc for all windows
then, at the beginning of WndProc....
WProc proc wp_hWnd,uMsg,wParam,lParam
       pushad
       mov     eax, [wp_hWnd]
       mov     [hwnd], eax

this overwrites the hwnd value every time a different window uses the proc

i am not sure this is a problem - lol - it just looks suspicious   :red
the functions you have inside the WndProc function make the code difficult to follow
it would be easier if the code was modularized
i can see the advantage in doing it that way - the WndProc parameters are local to everyone and need not be passed   :bg

Well, my understanding of this stuff is pretty thin, but it seems to me that I have 2 windows, main with CProc, and child with CWProc.
But this makes me think of a possible danger of using global variables; suppose the OS calls WProc again while I am processing a previous call.  Could it do that?

Thanks, ral

dedndave

it can and does - lol

here is the cure for that
inside WProc, use the local variable named wp_hWnd in the function calls (like BeginPaint, etc) instead of hwnd

this one especially   :bg
invoke DefWindowProc,wp_hWnd,uMsg,wParam,lParam

then, you can remove these lines...
mov eax, [wp_hWnd]
mov [hwnd], eax

raleeper

Quote from: dedndave on August 13, 2011, 03:12:11 AM
usually, nothing will happen
but, it's not good   :P

the sections are blocks of 512 bytes in the file
and i believe they are assigned blocks of 4096 bytes when loaded into memory

if it were a hard error, Dr Watson would come up

i am able to create the first window
but, when i try to create another, the program crashes silently
this is usually caused by a stack misalignment, but i can't find it

Ah, a clue.

Mine crashes too, but not until I press a key in the child.
And I see why!  It is stack misalignment.  CWProc CALLS ckey, but then JMPs back.
Changing the call to a jmp fixes that problem!
Still no beep, though.

Thank you! ral
Quote from: dedndave on August 13, 2011, 03:35:03 AM
it can and does - lol

here is the cure for that
inside WProc, use the local variable named wp_hWnd in the function calls (like BeginPaint, etc) instead of hwnd

this one especially   :bg
invoke DefWindowProc,wp_hWnd,uMsg,wParam,lParam

then, you can remove these lines...
mov eax, [wp_hWnd]
mov [hwnd], eax


Another great suggestion.  I'll do it.

Thank you again!

raleeper

dedndave: I'm going to give up on the beep problem.  I don't really need tha beeps.
I'll go back to the real problems:
1 Getting the child to show properly, and
2. Getting the main window to redisplay after the child does invoke SetFocus,hwnd (in light of your earlier suggestion, I guess I should put CWProc inside WProc and use invoke SetFocus,wp_hWnd)

But can windows procedures be nested?  Will the OS be able to find a proc declared locally?
If I do that I might as well put erbeep inside too.  Maybe that will fix the erbeep problem,

Thanks, ral

dedndave

well - the beep thing is interesting, also
but, i understand what you are saying

i have looked at the documentation for using winmm to play a midi file, as well as the docs for creating a midi in memory
it is more than i want to dive into at the moment   :bg
i remember creating midi files for a morse code beeper many years ago - it didn't seem that hard
i will come back to it later
there is a need for a good beep routine because newer OS's don't support the Beep API function
the MIDI file format is ideal for this

raleeper

Assembler Error 02144 cannot nest procedures.

So much for that.

Thanks, ral

raleeper

Quote from: raleeper on August 13, 2011, 04:23:10 AM
Assembler Error 02144 cannot nest procedures.

So much for that.

But I see the answer - in CWProc use the handle passed passed in.

Thanks, ral

I'm getting groggy.  I must have hit Quote rather than Modify.

Sorry, ral

raleeper

That works.

And the child shows properly, given that it's very undeveloped.

But I have to destoy it to get the main to redisplay.

Thanks, ral

dedndave

 :U

in the mean time, i have been playing with Beep   :lol
here is my new TstBeep.inc
i will make it a midi player some day
TstBeep PROTO   :DWORD

        .CODE

TstBeep PROC    nNote:DWORD

;plays musical notes from 37 to 4435 Hz
;higher notes are played for shorter durations
;(duration = 6 to 600 mS)

;Call With: EAX = 1 to 84 (84 plays 4435 Hz for 6 mS)
;
;All registers and flags are preserved.

        pushfd
        push    eax
        push    ecx
        push    edx
        test byte ptr [esp+13],4  ;DF
        jz      TBeep0

        cld

TBeep0: mov     eax,nNote
        mov     ecx,84
        or      eax,eax
        jnz     TBeep1

        inc     eax

TBeep1: cmp     eax,ecx
        mov     edx,0AAAAAAABh
        jbe     TBeep2

        xchg    eax,ecx

TBeep2: dec     eax
        mov     ecx,eax
        mul     edx
        shr     edx,3
        imul    eax,edx,12
        sub     ecx,eax
        movzx   eax,word ptr __Tones[2*ecx]
        mov     ecx,6
        sub     ecx,edx
        xor     edx,edx
        shr     eax,cl
        adc     eax,edx
        xchg    eax,ecx
        mov     eax,22175
        div     ecx
        shl     edx,1
        cmp     edx,ecx
        cmc
        adc     eax,1
        INVOKE  Beep,ecx,eax
        pop     edx
        pop     ecx
        pop     eax
        popfd
        ret

        ALIGN   2

__Tones dw      2349,2489,2637,2794,2960,3136,3322,3520,3729,3951,4186,4435

TstBeep ENDP

Geryon

Quote from: dedndave on August 12, 2011, 09:10:58 PM
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
I'm glad you liked it and you are right. It's a overkill. Actually, I've wrote this code in C++ a long time ago for using my sound card as a signal synthesizer.
I don't remember MIDI format but I will work on it
"Some people have got a mental horizon of radius zero and call it their point of view." --D.Hilbert

jj2007

Quote from: raleeper on August 13, 2011, 03:09:11 AM
An interesting question regarding jj2997's program:

What happens if the OS (BeginPaint) tries to write 16d bytes to a 10d byte buffer - at the very end of the .DATA? segment?

Nothing happens, as the .data? section has 4096, pardon:1000h bytes. But of course that's an error, and at the same time it shows the problems of idiosyncratic programming styles. Using .radix 16 looks cool but it does not really help teamwork :bg