Nem egész frekvenciájú hang x86 ASM-ben
2010-12-30T21:03:50+01:00
2010-12-31T08:43:51+01:00
2022-08-03T08:50:30+02:00
Arrabo
Sziasztok!
Kezdő assemblys vagyok, és irtam egy programot, ami 440Hz-es kezdéssel a pc hangszóróját szólaltatja meg, és a jobb nyilra emeli, a balra csökkenti a frekvenciát:
;NGASM sd.asm FREK EQU 440 FREK_VALT EQU 1 PORT_BILL_OLVAS EQU 16h PORT_BILL_NYIL_BAL EQU 4Bh PORT_BILL_NYIL_JOB EQU 4Dh PORT_BILL_ESC EQU 1Bh PORT_HANG EQU 61h PORT_HANG_KI EQU 0FCh PORT_FREK_SET EQU 0B6h PORT_FREK_SET2 EQU 12h PORT_FREK_SET3 EQU 34DCh PORT_FREK_BE EQU 42h PORT_FREK EQU 43h PORT_KIKAPCS EQU 15h PORT_KIKAPCS_1 EQU 5301h PORT_KIKAPCS_2 EQU 0101h PORT_KIKAPCS_3 EQU 530Eh PORT_KIKAPCS_4 EQU 5307h PORT_KIKAPCS_5 EQU 0001 PORT_KIKAPCS_6 EQU 0003 start: MOV BX, FREK ; a frekvencia Hz-ben olvas: XOR AX,AX ; Billentyűzet figyelése INT PORT_BILL_OLVAS CMP AH,PORT_BILL_NYIL_BAL JZ csokkent CMP AH,PORT_BILL_NYIL_JOB JZ novel CMP AL,PORT_BILL_ESC JZ kilepes JMP olvas ; Ha egyik sem, akkor kezdi előről kilepes: XOR BX,BX ; ACPI kikapcsolás MOV AX,PORT_KIKAPCS_1 INT PORT_KIKAPCS XOR BX,BX MOV CX,PORT_KIKAPCS_2 MOV AX,PORT_KIKAPCS_3 INT PORT_KIKAPCS MOV BX,PORT_KIKAPCS_5 MOV CX,PORT_KIKAPCS_6 MOV AX,PORT_KIKAPCS_4 INT PORT_KIKAPCS RET hangki: IN AL,PORT_HANG AND AL,PORT_HANG_KI OUT PORT_HANG,AL JMP olvas hangbe: MOV AL,PORT_FREK_SET OUT PORT_FREK,AL MOV DX,PORT_FREK_SET2 MOV AX,PORT_FREK_SET3 div BX OUT PORT_FREK_BE,AL MOV AL,AH OUT PORT_FREK_BE,AL IN AL,PORT_HANG or AL,3 OUT PORT_HANG,AL JMP olvas csokkent: SUB BX,FREK_VALT CMP BX,FREK_VALT JZ novel JMP hangbe novel: ADD BX,FREK_VALT JMP hangbe
Ez rendesen működik is, de csak egész frekvenciával. Hogyan tudok nem egész számú frekvenciát hangoztatni?

köszi

Ui.:Boldog uj évet mindenkinek.
Mutasd a teljes hozzászólást!
Lehetséges törtszámú frekvenciát kiadni, csak érteni kell, hogy működik a kódod.

A PC speakert egy 1193180 Hz-es órajel hajtja. (Ez hexában 1234DC, ez van belekódolva a forrásodba a PORT_FREK_SET2 és PORT_FREK_SET3 konstansokba.) A speaker időzítőjének nem a frekvenciát kell megadni, hanem egy hullám hosszát órajelben mérve. A frekvenciából úgy kapsz hullámhosszt, hogy a másodpercenkénti órajelek számát elosztod a hang herzben vett frekvenciájával.

Na most az egyetlen dolog, ami visszatartja a kódodat a tört frekvenciáktól az az, hogy a DIV utasítás csak egészosztásra képes. Ezt kikerülheted azzal, hogy mondjuk az osztót és az osztandót is megszorzod tízzel, és egyből tized herz pontossággal fogod tudni megadni a frekvenciát. Másképpen, ha átírod a konstansokat:
PORT_FREK_SET2 EQU B6h PORT_FREK_SET3 EQU 1098h
és az összes használt frekvenciaértéket helyettesíted a tízszeresével, akkor már mennie kéne a tört frekvenciáknak.
Mutasd a teljes hozzászólást!

  • szerintem leginkább csak csalni tudsz: mondjuk 0,1 sec 50Hz 0,1 sec 51Hz majd újra felváltva ez a kettő. akkor az olyan mintha 50,5Hz szólna
    Mutasd a teljes hozzászólást!
  • Csak egész frekvenciájú hangot lehet tudtommal kiadni a speakerrel, de általában az elég szokott lenni.

    A speaker - Cikkek - Prog.Hu
    Mutasd a teljes hozzászólást!
  • akkor az olyan mintha 50,5Hz szólna

    Kipróbáltam, és sajnos nem

    attól tartok, hogy valóban nem lehet, de nekem fontos lenne

    Arrabo
    Mutasd a teljes hozzászólást!
  • Lehetséges törtszámú frekvenciát kiadni, csak érteni kell, hogy működik a kódod.

    A PC speakert egy 1193180 Hz-es órajel hajtja. (Ez hexában 1234DC, ez van belekódolva a forrásodba a PORT_FREK_SET2 és PORT_FREK_SET3 konstansokba.) A speaker időzítőjének nem a frekvenciát kell megadni, hanem egy hullám hosszát órajelben mérve. A frekvenciából úgy kapsz hullámhosszt, hogy a másodpercenkénti órajelek számát elosztod a hang herzben vett frekvenciájával.

    Na most az egyetlen dolog, ami visszatartja a kódodat a tört frekvenciáktól az az, hogy a DIV utasítás csak egészosztásra képes. Ezt kikerülheted azzal, hogy mondjuk az osztót és az osztandót is megszorzod tízzel, és egyből tized herz pontossággal fogod tudni megadni a frekvenciát. Másképpen, ha átírod a konstansokat:
    PORT_FREK_SET2 EQU B6h PORT_FREK_SET3 EQU 1098h
    és az összes használt frekvenciaértéket helyettesíted a tízszeresével, akkor már mennie kéne a tört frekvenciáknak.
    Mutasd a teljes hozzászólást!
  • Tényleg

    Köszönöm a válaszokat, és tied a pont!

    Arrabo
    Mutasd a teljes hozzászólást!
abcd