Fórumok
4MHz-es Z80-nal szeretnék egyszerű 1 bites hanghatásokat generálni, hasonlóan a következő kódhoz:
LD DE, 0
LD BC, 0
LOOP:
INC BC
INC DE
LD A, C
AND D
AND %11111100
JR Z, PLAY_BIT_0
JR PLAY_BIT_1
PLAY_BIT_0:
; ... gépfüggő kód, ami kikapcsolja a hangszórót
JR LOOP
PLAY_BIT_1:
; ... gépfüggő kód, ami bekapcsolja a hangszórót
JR LOOP
A generált hang itt hallható.
Ilyen típusú dallamok a kód kisebb módosításával még készíthetőek, de a fentitől lényegében eltérő hatásokat keresek.
A legnagyobb szükségem valamiféle fehér-zajra generálására lenne, de a ROM tartalom olvasásával csak másodperces nagyságrendben tudok értékelhető zajt generálni, a rövidebb lejátszások inkább hasonlítanak kalapácsütéshez, mint zajhoz.
Tehát, ha van valakinek érdemi ötlete, örömmel fogadnám.
A válaszok alapján a következő Z80 kódok születtek:
Zaj generálása:
LFSR_TAP_H: EQU %01000001
LFSR_TAP_L: EQU %10100111
LFSR_CURRENT_DATA16: DW 15 ; uint32_t in <> 0
LFSR:
LD A, (LFSR_CURRENT_DATA16)
BIT 0, A
JR Z, LFSR_CURRENT_DATA_EVEN
LD HL, (LFSR_CURRENT_DATA16)
LD A, H
XOR LFSR_TAP_H
LD H, A
LD A, L
XOR LFSR_TAP_L
LD L, A
RR H
RR L
LD DE, %1000000000000000
LD A, D
OR H
LD A, E
OR L
LD (LFSR_CURRENT_DATA16), HL
RET
LFSR_CURRENT_DATA_EVEN:
LD HL, (LFSR_CURRENT_DATA16)
RR H
RR L
LD (LFSR_CURRENT_DATA16), HL
RET
A CALL LFSR minden hívása után 16 bit használható az (LFSR_CURRENT_DATA16) címről. A végtelen ciklussal generált hang itt hallható.
Hozzászólások
Muszáj random 1-bites zajnak lennie? Mármint, használhatnál akár saját több bites hangmintát is, ami zajnak hangzik, és akkor véletlenül sem lenne kalapácsütés. A PICO-8 és a TIC-80 például 32 darab 4 bites mintát tárol. Az a plusz 16 bájt nem tűnik soknak, cserébe készen kapsz egy valag hangmintát, ami közül válogathatsz. Vagy akár előre le is generálhatod magadnak.
Minta adatsorokat is tudok adni ehhez:
Elvileg jók, hacsak el nem basztam :-D Mindenesetre a generáló forrása is mellékelve vagyon, valamint a TIC-80 SFX-el is készíthetsz ilyen mintákat (amit aztán a lementett .tic fájlból kell kibányászni, ami nem túl vészes, de ha nincs kedved hozzá, akkor a cart2prj sima szöveges bájtsorrá alakítja, ilyenné)
A random nem követelmény, az 1 bit sajnos a hardver korlátja, azt nem tudom átlépni. Bár trükközni lehet, ha az ember csak nagyon rövid ideig kapcsolja be a hangszórót, akkor nem tud teljes mértékben kitérni, és így talán 2-3 bitesre fel lehet növelni a felbontást, de ezek így már nagyon tárigényes hangminták lesznek. Én inkább kis tárigényű hanghatásokat keresek, mint előre digitalizált adatot.
Kizárt dolognak tartom, hogy a hanggenerátor frekvenciatartománya 1 bites legyen. Szerintem benézel valamit.
Pont ezért írtam, amit írtam, a 16 bájt rohadtul nem "tárigényes". De használhatnál 8 darab egyenként egy bájtos mintát is, ezt csak azért írtam, mert rengeteg pont ilyen mintát találsz a neten a PICO-8-nak és a TIC-80-nak hála.
Egyébként ilyen alacsony számú (32) és kis felbontású (16 lehetséges értékű) minta esetén nem beszélhetünk digitalizált adatról, erre a "chiptune" a szakkifejezés.
Valószínűleg nagyon mást értettünk 1 bites hang alatt. Amivel én eddig találkoztam, ott a bitszám a különböző amplitúdó értékeket jelentette, de már felfogtam, hogy nem erre gondoltál.
Ha 4 biten frekvenciákat tárolok, akkor nekem hiányzik még egy paraméter, hogy a megadott frekvenciák mennyi ideig szóljanak. De köszönöm utánanézek a PICO-8-nak és TIC-80-nak.
Rossz válasz.
A hangszóró induktivitása és a mechanikus tehetetlensége másodfokú aluláteresztő szűrőt képez, ami pont jól jön egy DAC kimenetére.
Az 1 bit nem ritkaság, hiszen a SACD (Szuper Audio CD) is 1 bitet használ a nagyfelbontású multicsatornás felvételek tárolásához. A technológia a szigma-delta ADC/DAC,
A frekvenciataromány pedig a mintavételi frekvencia/2/bitszám lehet. Tehát a fő kérdés az, hogy milyen szaporán lehet kiadni azt az 1 bitet.
Az SACD-n úgy emlékszem MASH jel van rögzítve, ami tulajdonképpen egy nagy frekvenciás PWM. De ezt csak emlékezetből mondom.
A szigma-delta ADC egy visszacsatolt struktúra, ami a kvantálási zajt feltranszformálja a már nem hallható tartományba, ami aztán levágásra kerül --> e miatt az effektív bitszám sokkal jobban növekszik, mint a sima túlmintavételezésnél.
Just for the records.
SACD:
A 0 es 1 nem be- vagy kikapcsolja a hangszorot.
Az 1 bites hanggenrator eseten a valtasok frekvenciajaval operalsz leginkabb, illetve a PWM kitoltesi tenytezojevel is.
Ezt a valtozo frekvenciaju es kitoltesu negyszogjelet (ami mar alapesetben is jo sok szinusz linearkombinacioja) rakuldod egy savszurore (mondjuk 20Hz-20kHz), majd azt a kimenetet hallod.
Hangmernok kell, vagy jo matematikus, aki visszafejti a csatornat, es atlatja, hogy milyen bemeneti jelnek mi a hatasa.
Egyszeru feherzaj-generator:
Elinditod barmilyen nem-nulla ertekrol, es 2^32-1 lepes mulva kezdi el ismetelni magat, mikozben folyamatosan jon egy 32bites stream (szoval mint bitstream, a periodusa egesz pontosan 137438953440 lesz... egy darabig talaln eleg :)).
Ez ugyan C kod, de az effele bit-csamcsogasos algoritmusoknak pont az a szepsege hogy assemblybol jobb kodot tudsz csinalni mint C-bol ;) (es ez marcsak izombol-hardverbol, pl Verilogban lenne meg egyszerubb).
Köszönöm, valami effélét keresek, bár úgy látom, azért a hatványozással valós időben meg fog izzadni a CPU...
Nincs itt semmi hatvanyozas :) Ez a kizaro vagy (XOR) muvelet (lasd itten: https://en.wikipedia.org/wiki/Exclusive_or#Alternative_symbols, alulrol a masodik).
az ott egy xor, nem hatványozás. a bit-shift meg csak menni fog (ha esetleg arra gondoltál, mint hatványozás)
Ezzel inkább az a bökkenő, hogy a Z80-nak csak két 8 bites regisztere van operandusként a műveletekre, szóval nem tud 32 biten dolgozni, csak max. 16 biten. Viszont maga az ötlet szerintem nagyon jó, egy kis átalakítással
Akár még Z80-on is működhet. (Megjegyzés, a 16807 nemcsak egy hasraütésszerű szám, hanem ebből az 1988-as véletlenszámokkal foglalkozó, kiváló tanulmányból ered.)
Jaja, kevesebb bites LFSR is jo lehet ha azert eleg hosszu a periodusa. Ez itten legjobb esetben is 131070-es bitperiodust ad, ez mondjuk 10-20 masodpercre mar eleg lehet.
Mondjuk igen, itt annyi a konnyebbseg hogy a kolleganak spektralisan feherzaj kell es nem valodi(bb) (al)veletlen sorozat, ez azert sokat konnyit a dolgon...
Jól gondolom, hogy az első hívás visszatérő értékét kell a következő hívásban paraméterként megadni, és az out érték valamelyik (0.?) bitje jelzi majd, hogy mikor kell be- vagy kikapcsolnom a hangszórót?
Jól gondolom, hogy az első hívás visszatérő értékét kell a következő hívásban paraméterként megadni?
Igen!
és az out érték valamelyik (0.?) bitje jelzi majd, hogy mikor kell be- vagy kikapcsolnom a hangszórót?
Ebben az a jo hogy a teljes bitsorozatot tudod hasznalni.
Egyelőre csak a 0. bitet használom, de már így is sokkal zajosabb, mint a ROM olvasása! Köszönöm.
Ezek szerint minden hívás után mind a 16 bitet is felhasználhatnám?
Feltöltöd hogy hogy szól?
A témanyitót kiegészítettem a forráskóddal és a hangzásával is.
Egyebkent assemblyben ugy tudsz trukkozni az effele LFSR jellegu bitcsamcsogasokkal (meg a rokon muveleteknel, pl Galois algebras cuccoknal, CRC-knel, stb), hogy:
ez eleg sok architekturan siman mukodik igy, beleertve azt is hogy X bites architekturan N*X bites regisztered van. Ugyanis, a jobb shiftnek van olyan opcioja (altalaban) hogy a carry bitet behozza balrol. De nyugodtan forgathatsz balra is, akkor az add + add-with-carry a baratod a ror-jellegu utasitasok helyett. Csak altalaban a jobbra tolas a megszokott a gyakorlatban, az algebras dolgoknal az a "logikusabb". De ha ez nem fontos (pl itt nalad, zajgeneralasnal) akkor az ADD + ADC is fasza (csak akkor a tap erteket meg kell forditani bit reverse modon).
Ez egy eleg speci mintazat, es a C forditok altalaban nem ismerik fel. Szoval itt erdemes assemblyt hasznalni valoban.
Közben én is keresgélek még, és tényleg sok verziója van. Pseudorandom generátor néven jókat hoz a google, de nem mindegyik generál fehér zajnak tűnő hangot.
Találtam még egy blum blum shub módszert is, ami rotálás helyett maradékosztályokkal variál, de sajnos szorzás van benne (pontosabban négyzetreemelés), így nekem túl lassú.
Irtam is fentebb hogy ide erre a probemara nem pszeudorandom-generator kell hanem feherzaj-generator :) Ezutobbi joval egyszerubb, eleg hozza az XOR muvelet (plusz persze a szukseges
rosszakegyebek: bitshift, carry-fuggo elagazasok, stb). Pszudorandomnal mar nem uszod meg az osszetettebb dolgokat, amik tenyleg mar szamitasigenyesebbek.Ha erdekel a tema, olvasgass utana pl a Gold code reszleteinek meg hogy hogy is mukodik a GPS.
https://www.hobbielektronika.hu/forum/dallamcsengo-z80-al-es-27c256
https://elektrotanya.com/content/z80-alapu-dalllamcsengo-dallam-generat…
https://tkiraaly.hu/arduino/dallamcsengo/dallamcsengo.html
"Normális ember már nem kommentel sehol." (c) Poli
Szerintem ez a Z80 alapú dallamcsengő pontosan az, amit a kolléga keres!
na. szereztél egy zx-spectrumot ?
*ja nem, ott csak 3.5Mhz a cpu.
HUP te Zsiga !