News:

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

playing with the Beep API function...

Started by Jeff, May 29, 2005, 11:09:35 PM

Previous topic - Next topic

Jeff

...brings me to this, a "music" program.   :8)

anyone up for tetris?

Tetris.asm:
OPTION EXPR32
OPTION CASEMAP:NONE

.386
.MODEL FLAT

INCLUDE Tones.inc

ExitProcess PROTO STDCALL, :DWORD

.CODE
main PROC STDCALL
    XOR ebx,ebx
    @@:
    TEMPO 149
    METER 4,4
    PLAY <T_E5,T_N04>,<T_B4,T_N08>,<T_C5,T_N08>,<T_D5,T_N04>,<T_C5,T_N08>,<T_B4,T_N08>
    PLAY <T_A4,T_N04>,<T_A4,T_N08>,<T_C5,T_N08>,<T_E5,T_N04>,<T_D5,T_N08>,<T_C5,T_N08>
    PLAY <T_B4,T_N04+T_N08>,<T_C5,T_N08>,<T_D5,T_N04>,<T_E5,T_N04>
    PLAY <T_C5,T_N04>,<T_A4,T_N04>,<T_A4,T_N04>,<T_00,T_N04>

    PLAY <T_00,T_N08>,<T_D5,T_N04>,<T_F5,T_N08>,<T_A5,T_N04>,<T_G5,T_N08>,<T_F5,T_N08>
    PLAY <T_E5,T_N04+T_N08>,<T_C5,T_N08>,<T_E5,T_N04>,<T_D5,T_N08>,<T_C5,T_N08>
    PLAY <T_B4,T_N04>,<T_B4,T_N08>,<T_C5,T_N08>,<T_D5,T_N04>,<T_E5,T_N04>
    PLAY <T_C5,T_N04>,<T_A4,T_N04>,<T_A4,T_N04>,<T_00,T_N04>
    NOT ebx
    OR ebx,ebx
    JNZ @B                                                  ;first repeat
    PLAY <T_E4,T_N02>,<T_C4,T_N02>
    PLAY <T_D4,T_N02>,<T_B3,T_N02>
    PLAY <T_C4,T_N02>,<T_A3,T_N02>
    PLAY <T_Gs3,T_N02>,<T_00,T_N02>

    PLAY <T_E4,T_N02>,<T_C4,T_N02>
    PLAY <T_D4,T_N02>,<T_B3,T_N02>
    PLAY <T_C4,T_N04>,<T_E4,T_N04>,<T_A4,T_N02>
    PLAY <T_Gs4,T_N02>,<T_00,T_N02>
    ;NOT ebx                                                ;endless
    ;JMP @B
    INVOKE ExitProcess,0
main ENDP
END main


Tones.inc:
.NOLIST
IFNDEF TONES_INC
TONES_INC EQU

Beep PROTO STDCALL, :DWORD, :DWORD
Sleep PROTO STDCALL, :DWORD

T_00 EQU 0
T_000 EQU T_00

T_C3 EQU 131
T_Cn3 EQU T_C3
T_Cs3 EQU 139
T_Db3 EQU T_Cs3
T_D3 EQU 147
T_Dn3 EQU T_D3
T_Ds3 EQU 156
T_Eb3 EQU T_Ds3
T_E3 EQU 165
T_En3 EQU T_E3
T_F3 EQU 175
T_Fn3 EQU T_F3
T_Fs3 EQU 185
T_Gb3 EQU T_Fs3
T_G3 EQU 196
T_Gn3 EQU T_G3
T_Gs3 EQU 208
T_Ab3 EQU T_Gs3
T_A3 EQU 220
T_An3 EQU T_A3
T_As3 EQU 233
T_Bb3 EQU T_As3
T_B3 EQU 247
T_Bn3 EQU T_B3

T_C4 EQU 262
T_Cn4 EQU T_C4
T_Cs4 EQU 277
T_Db4 EQU T_Cs4
T_D4 EQU 294
T_Dn4 EQU T_D4
T_Ds4 EQU 311
T_Eb4 EQU T_Ds4
T_E4 EQU 330
T_En4 EQU T_E4
T_F4 EQU 349
T_Fn4 EQU T_F4
T_Fs4 EQU 370
T_Gb4 EQU T_Fs4
T_G4 EQU 392
T_Gn4 EQU T_G4
T_Gs4 EQU 415
T_Ab4 EQU T_Gs4
T_A4 EQU 440
T_An4 EQU T_A4
T_As4 EQU 466
T_Bb4 EQU T_As4
T_B4 EQU 494
T_Bn4 EQU T_B4

T_C5 EQU 523
T_Cn5 EQU T_C5
T_Cs5 EQU 554
T_Db5 EQU T_Cs5
T_D5 EQU 587
T_Dn5 EQU T_D5
T_Ds5 EQU 622
T_Eb5 EQU T_Ds5
T_E5 EQU 659
T_En5 EQU T_E5
T_F5 EQU 698
T_Fn5 EQU T_F5
T_Fs5 EQU 740
T_Gb5 EQU T_Fs5
T_G5 EQU 784
T_Gn5 EQU T_G5
T_Gs5 EQU 831
T_Ab5 EQU T_Gs5
T_A5 EQU 880
T_An5 EQU T_A5
T_As5 EQU 932
T_Bb5 EQU T_As5
T_B5 EQU 988
T_Bn5 EQU T_B5

T_C6 EQU 1047
T_Cn6 EQU T_C6
T_Cs6 EQU 1109
T_Db6 EQU T_Cs6
T_D6 EQU 1175
T_Dn6 EQU T_D6
T_Ds6 EQU 1245
T_Eb6 EQU T_Ds6
T_E6 EQU 1319
T_En6 EQU T_E6
T_F6 EQU 1397
T_Fn6 EQU T_F6
T_Fs6 EQU 1480
T_Gb6 EQU T_Fs6
T_G6 EQU 1568
T_Gn6 EQU T_G6
T_Gs6 EQU 1661
T_Ab6 EQU T_Gs6
T_A6 EQU 1760
T_An6 EQU T_A6
T_As6 EQU 1865
T_Bb6 EQU T_As6
T_B6 EQU 1976
T_Bn6 EQU T_B6

T_C7 EQU 2093
T_Cn7 EQU T_C7
T_Cs7 EQU 2217
T_Db7 EQU T_Cs7
T_D7 EQU 2349
T_Dn7 EQU T_D7
T_Ds7 EQU 2489
T_Eb7 EQU T_Ds7
T_E7 EQU 2637
T_En7 EQU T_E7
T_F7 EQU 2794
T_Fn7 EQU T_F7
T_Fs7 EQU 2960
T_Gb7 EQU T_Fs7
T_G7 EQU 3136
T_Gn7 EQU T_G7
T_Gs7 EQU 3322
T_Ab7 EQU T_Gs7
T_A7 EQU 3520
T_An7 EQU T_A7
T_As7 EQU 3729
T_Bb7 EQU T_As7
T_B7 EQU 3951
T_Bn7 EQU T_B7

DIVR MACRO \
    num:REQ,
    denom:REQ
    IF (num MOD denom) GE (denom/2)
        EXITM <(num/denom)+1>
    ENDIF
    EXITM <num/denom>
ENDM

TEMPO MACRO \
    bpm:=<120>
    T_BPM = bpm
ENDM

METER MACRO \
    num:=<4>,
    den:=<4>
    IF (den NE 2) AND (den NE 4) AND (den NE 8)
        .ERR <invalid macro operand (den)>
    ELSE
        IFNDEF T_BPM
            T_BPM = 120
        ENDIF
        IF den EQ 2
            T_N02 = DIVR(60000,T_BPM)
            T_N01 = T_N02 SHL 1
            T_N04 = T_N02 SHR 1
            T_N08 = T_N02 SHR 2
            T_N16 = T_N02 SHR 3
            T_Measure = num*T_N02
        ELSEIF den EQ 4
            T_N04 = DIVR(60000,T_BPM)
            T_N01 = T_N04 SHL 2
            T_N02 = T_N04 SHL 1
            T_N08 = T_N04 SHR 1
            T_N16 = T_N04 SHR 2
            T_Measure = num*T_N04
        ELSE
            T_N08 = DIVR(60000,T_BPM)
            T_N01 = T_N08 SHL 3
            T_N02 = T_N08 SHL 2
            T_N04 = T_N08 SHL 1
            T_N16 = T_N08 SHR 1
            T_Measure = num*T_N08
        ENDIF
    ENDIF
ENDM

PLAYNOTE MACRO \
    nPitch:REQ,
    nLength:REQ
    IF nPitch
        INVOKE Beep, nPitch, nLength
    ELSE
        INVOKE Sleep, nLength
    ENDIF
ENDM

PLAY MACRO \
    notes:VARARG
    T_TempCounter = 0
    T_TempBeats = 0
    FOR note,<notes>
        IF T_TempCounter MOD 2
            PLAYNOTE T_TempPitch,note
            T_TempBeats = T_TempBeats+note
        ELSE
            T_TempPitch = note
        ENDIF
        T_TempCounter = T_TempCounter+1
    ENDM
    IF (T_TempBeats LT T_Measure-16) OR (T_TempBeats GT T_Measure+16)
        .ERR <measure worth of beats required>
    ENDIF
ENDM

ENDIF
.LIST

[attachment deleted by admin]

MichaelW

Good stuff Jeff :U

I don't know enough about music to understand your system of equates and multiple other details, but I can recognize clean, compact code, and it clearly does work.
eschew obfuscation

hutch--

Jeff,

Works GREAT ! This played through the computer speaker, I wonder if there is a way to get it to play through a sound card ?
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

MichaelW

Per MSDN, under Windows ME/98/95 the Beep function ignores the frequency and duration parameters, and on system with a sound card it plays the default sound event. I tested the program under Windows XP HE on a system with a functional sound card (a Sound Blaster AWE64), and it used the computer speaker. My quick search for a user-accessible device setting that would change this behavior turned up nothing.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/beep.asp
eschew obfuscation

Jeff

heres some info on the usage.

i tried to name each pitch with its appropriate frequency. T_A3 for example is A on the 3rd octave, T_Bb5 B flat on the 5th, T_Gn4 G natural on the 4th.  i added naturals just so the code can look uniform when lined up and other aliases to remain flexible.  T_00 (and T_000) were rests.  i only added equates for the tones that were pleasing to the ear (or at least tolerable).

the TEMPO macro helps with the note length equates.  the METER macro sets up the note lengths for whole notes down to 16ths.  so T_N01 is a whole note, T_N02 is a half note, T_N04 quarter and so on.  i guess you would need to be somewhat familiar with musical notation to understand the numbers and naming.

then, the PLAYNOTE macro will play a specified pitch of a certain length.  so if i wanted to play a quarter note worth of middle C on a piano: PLAYNOTE T_C4, T_N04
the PLAY macro on the other hand can play a measure worth of notes (and rests) as defined by the METER macro.  i couldnt really figure out how to take 2 lines from a FOR macro so i improvised.


i have a couple more ideas to make it look a lot better like macros for repeats and maybe even tricking the speaker to play 2 tones at the "same time" (may or may not be possible).  ill try to come up with more and more samples when i get the chance or perhaps other the musicians in the house could make something.  :)

ideally, i would want to eventually get the sounds to the sound card but im still learning.  in due time i hope.  :)

GregL


Jeff

ooh thanks for that link.  i will definitely try something with that in the future.

in the mean time, i will play more with this.  so far, i created macros to handle repeats (standard, capo, segno, coda) and currently working on endings.

AeroASM

Quote from: MichaelW on May 30, 2005, 01:38:23 AM
Good stuff Jeff :U

I don't know enough about music to understand your system of equates and multiple other details.

The most basic interval in music is the octave, which is two notes where one has double the frequency of the other e.g. 440Hz and 880Hz.
The second most basic interval is the fifth, where the multiplying constant is 1.5 rather than 2 e.g. 440Hz and 660Hz. To combine these two into a usabel scale, we need to find an integral solution of 2^m=1.5^n but unfortunately there are none. The 12-note scale that we use is based on the approximation 2^7 roughly equals 1.5^12. Because of this approximation, the intervals between octaves of the scale are perfect, but the fifths are not. For example, piano and keyboard players are taught that the interval between A and E is a perfect fifth. However, A5 = 440Hz but E5=659Hz, which is slightly off a perfect fifth.

However violin players do not have to worry, because they are fretless and can play any note that they want.

hutch--

Aero,

I am glad to see you are a perfect scale man.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Farabi

Hi it must be good, but I cannot test it on this computer. It use linux.
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"

Jeff

ok, ive made a few adjustments to some macros as you can see in the zip.  what's the maximum amount of arguments a FOR macro can take?  it's really messing up things with my PLAY macros.  :(

heres another one i did.  it's all by ear (and memory) so it may not sound right.  anyone know what this is?  :)

i still need to work out the kinks in the other macros.  documentation will come much later.  :D

sorry Farabi for it not working for ya on linux, not exactly my "target audience" (same for 98 and below users).

OPTION EXPR32
OPTION CASEMAP:NONE

.386
.MODEL FLAT

INCLUDE Tones.inc

ExitProcess PROTO STDCALL, :DWORD

.CODE
main PROC STDCALL
    TEMPO 178
    METER 2,2
    PLAY N(T_B4,T_N02+T_N04)
    PLAY S(T_B4,T_N08),S(T_B4,T_N08)
    PLAY N(T_B4,T_N02+T_N04)
    PLAY S(T_B4,T_N08),S(T_B4,T_N08)
    PLAY S(T_B4,T_N04),S(T_Gs4,T_N04)
    PLAY S(T_E4,T_N04),S(T_Gs4,T_N04)
    PLAY S(T_B4,T_N04),S(T_Gs4,T_N04)
    PLAY S(T_B4,T_N04),S(T_E5,T_N04)

    PLAY S(T_B4,T_N04),S(T_Gs4,T_N04)
    PLAY S(T_E4,T_N04),S(T_Gs4,T_N04)
    PLAY S(T_B4,T_N04),S(T_Gs4,T_N04)
    PLAY S(T_B4,T_N04),S(T_E5,T_N04)
    PLAY N(T_B4,T_N02+T_N04)
    PLAY S(T_B4,T_N08),S(T_B4,T_N08)
    PLAY N(T_B4,T_N02+T_N04)
    PLAY S(T_B4,T_N08),S(T_B4,T_N08)

    PLAY N(T_B4,T_N02+T_N04)
    PLAY S(T_B4,T_N08),S(T_B4,T_N08)
    PLAY N(T_B4,T_N02+T_N04)
    PLAY S(T_B4,T_N08),S(T_B4,T_N08)

    PLAY S(T_B4,T_N04),S(T_B4,T_N04),S(T_B4,T_N04)
    PLAY S(T_B4,T_N08),S(T_B4,T_N08)
    PLAY S(T_B4,T_N04),S(T_B4,T_N04),S(T_B4,T_N04)
    PLAY S(T_B4,T_N08),S(T_B4,T_N08)
    PLAY N(T_B4,T_N01)
    PLAY REST(T_N01)
MarkerA:
    PLAY S(T_B3,T_N08),S(T_B3,T_N08),S(T_B3,T_N04)
    PLAY S(T_B3,T_N08),S(T_B3,T_N08),S(T_B3,T_N04)
    PLAY S(T_B3,T_N08),S(T_B3,T_N08)
    PLAY S(T_E4,T_N04),S(T_Fs4,T_N04),S(T_Gs4,T_N04)

    PLAY S(T_B3,T_N08),S(T_B3,T_N08),S(T_B3,T_N04)
    PLAY S(T_B3,T_N08),S(T_B3,T_N08),S(T_E4,T_N04)
    PLAY S(T_Gs4,T_N08),S(T_Gs4,T_N08)
    PLAY S(T_Fs4,T_N04),S(T_Ds4,T_N04),S(T_B3,T_N04)

    PLAY S(T_B3,T_N08),S(T_B3,T_N08),S(T_B3,T_N04)
    PLAY S(T_B3,T_N08),S(T_B3,T_N08),S(T_B3,T_N04)
    PLAY S(T_B3,T_N08),S(T_B3,T_N08)
    PLAY S(T_E4,T_N04),S(T_Fs4,T_N04),S(T_Gs4,T_N04)

    PLAY S(T_E4,T_N08),S(T_Gs4,T_N08)
    PLAY N(T_B4,T_N02+T_N08),S(T_A4,T_N08)
    PLAY S(T_Gs4,T_N08),S(T_Fs4,T_N08)
    PLAY S(T_E4,T_N04),S(T_Gs4,T_N04),S(T_E4,T_N04)
MarkerB:
    PLAY S(T_B4,T_N08),S(T_B4,T_N08),S(T_B4,T_N04)
    PLAY S(T_B4,T_N08),S(T_B4,T_N08),S(T_B4,T_N04)
    PLAY S(T_B4,T_N08),S(T_B4,T_N08)
    PLAY S(T_E5,T_N04),S(T_Fs5,T_N04),S(T_Gs5,T_N04)

    PLAY S(T_B4,T_N08),S(T_B4,T_N08),S(T_B4,T_N04)
    PLAY S(T_B4,T_N08),S(T_B4,T_N08),S(T_E5,T_N04)
    PLAY S(T_Gs5,T_N08),S(T_Gs5,T_N08)
    PLAY S(T_Fs5,T_N04),S(T_Ds5,T_N04),S(T_B4,T_N04)

    PLAY S(T_B4,T_N08),S(T_B4,T_N08),S(T_B4,T_N04)
    PLAY S(T_B4,T_N08),S(T_B4,T_N08),S(T_B4,T_N04)
    PLAY S(T_B4,T_N08),S(T_B4,T_N08)
    PLAY S(T_E5,T_N04),S(T_Fs5,T_N04),S(T_Gs5,T_N04)

    PLAY S(T_E5,T_N08),S(T_Gs5,T_N08)
    PLAY N(T_B5,T_N02+T_N08),S(T_A5,T_N08)
    PLAY S(T_Gs5,T_N08),S(T_Fs5,T_N08)
    PLAY S(T_E5,T_N04),S(T_Gs5,T_N04),S(T_E5,T_N04)
MarkerC:
    PLAY S(T_Gs5,T_N08),S(T_Gs5,T_N08),S(T_Gs5,T_N04)
    PLAY S(T_Gs5,T_N08),S(T_Gs5,T_N08),S(T_Gs5,T_N04)
    PLAY S(T_Gs5,T_N08),S(T_Gs5,T_N08)
    PLAY S(T_Gs5,T_N04),S(T_Cs6,T_N04),S(T_Gs5,T_N04)

    PLAY S(T_Cs6,T_N04),S(T_Gs5,T_N04)
    PLAY S(T_Cs6,T_N04),S(T_Gs5,T_N04)
    PLAY S(T_Fs5,T_N04),S(T_E5,T_N04)
    PLAY S(T_Ds5,T_N04),S(T_Cs5,T_N04)

    PLAY S(T_Gs5,T_N08),S(T_Gs5,T_N08),S(T_Gs5,T_N04)
    PLAY S(T_Gs5,T_N08),S(T_Gs5,T_N08),S(T_Gs5,T_N04)
    PLAY S(T_Gs5,T_N08),S(T_Gs5,T_N08)
    PLAY S(T_Gs5,T_N04),S(T_Cs6,T_N04),S(T_Gs5,T_N04)

    PLAY S(T_Cs6,T_N04),S(T_Gs5,T_N04)
    PLAY S(T_Cs6,T_N04),S(T_B5,T_N04)
    PLAY S(T_As5,T_N04),S(T_B5,T_N04)
    PLAY S(T_As5,T_N04),S(T_B5,T_N04)

    PLAY S(T_Gs5,T_N08),S(T_Gs5,T_N08),S(T_Gs5,T_N04)
    PLAY S(T_Gs5,T_N08),S(T_Gs5,T_N08),S(T_Gs5,T_N04)
    PLAY S(T_Gs5,T_N08),S(T_Gs5,T_N08)
    PLAY S(T_Gs5,T_N04),S(T_Cs6,T_N04),S(T_Gs5,T_N04)

    PLAY S(T_Cs6,T_N04),S(T_Gs5,T_N04)
    PLAY S(T_Cs6,T_N04),S(T_Gs5,T_N04)
    PLAY S(T_Fs5,T_N04),S(T_E5,T_N04)
    PLAY S(T_Ds5,T_N04),S(T_Cs5,T_N04)

    PLAY S(T_Gs5,T_N08),S(T_Gs5,T_N08),S(T_Gs5,T_N04)
    PLAY S(T_Gs5,T_N08),S(T_Gs5,T_N08),S(T_Gs5,T_N04)
    PLAY S(T_Gs5,T_N08),S(T_Gs5,T_N08)
    PLAY S(T_Gs5,T_N04),S(T_Cs6,T_N04),S(T_Gs5,T_N04)

    PLAY S(T_Cs6,T_N04),S(T_Gs5,T_N04)
    PLAY S(T_Cs6,T_N04),S(T_B5,T_N04)
    PLAY S(T_As5,T_N04),S(T_B5,T_N04)
    PLAY REST(T_N01)
    INVOKE ExitProcess,0
main ENDP
END main

[attachment deleted by admin]

skywalker

Quote from: Jeff on May 29, 2005, 11:09:35 PM
...brings me to this, a "music" program.   :8)

anyone up for tetris?

Tetris.asm:

.LIST
[/quote]

Good code and it sounds great.

When I try to compile it, I get:
unresolved symbol _Beep@8,_Sleep@4, and _ExitProcess@4.

Thanks.

Mincho Georgiev