Kazalo:

Laserski sintetizator harfe na plošči Zybo: 10 korakov (s slikami)
Laserski sintetizator harfe na plošči Zybo: 10 korakov (s slikami)

Video: Laserski sintetizator harfe na plošči Zybo: 10 korakov (s slikami)

Video: Laserski sintetizator harfe na plošči Zybo: 10 korakov (s slikami)
Video: Laser Harp Fully Functional 2024, Julij
Anonim
Laserski sintetizator harfe na plošči Zybo
Laserski sintetizator harfe na plošči Zybo

V tej vadnici bomo ustvarili popolnoma funkcionalno lasersko harfo z uporabo IR senzorjev s serijskim vmesnikom, ki bo uporabniku omogočil spreminjanje uglaševanja in tona instrumenta. Ta harfa bo predelava starodavnega inštrumenta v 21. stoletju. Sistem je bil ustvarjen z uporabo razvojne plošče Xilinx Zybo skupaj z Vivado Design Suites. Za dokončanje projekta boste potrebovali:

  • 12 IR senzorjev in oddajnikov (več ali manj se lahko uporablja glede na število nizov)
  • Razvojna plošča Zybo Zynq-7000
  • Brezplačen RTOS
  • Vivado Design Suite
  • Žica (za povezavo senzorjev s ploščo)
  • 3 kosi PVC cevi ((2) 18 palcev in (1) 8 palcev)
  • 2 PVC kolena

1. korak: Pridobite Digilentov Zybo DMA Audio Demo

FPGA stran tega projekta v veliki meri temelji na predstavljenem predstavitvenem projektu. Uporablja neposreden dostop do pomnilnika za pošiljanje podatkov neposredno iz pomnilnika, v katerega lahko procesor zapisuje prek AXI Stream v zvočni blok I2S. Naslednji koraki vam bodo pomagali pri zagonu predstavitvenega avdio projekta DMA:

  1. Morda bo potrebna nova različica datoteke plošče za ploščo Zybo. Sledite tem navodilom za pridobitev novih datotek plošče za Vivado.
  2. Sledite korakom 1 in 2 v navodilih na tej strani, da odprete predstavitveni projekt v Vivadu. Uporabite metodo Vivado in ne predaje strojne opreme SDK.
  3. Morda boste prejeli sporočilo, da je treba nekatere od vaših blokov IP posodobiti. Če je tako, izberite "Show IP Status" in nato na zavihku Status IP izberite vse zastarele IP in kliknite "Upgrade Selected". Ko se konča in se prikaže okno z vprašanjem, ali želite ustvariti izhodni izdelek, pojdite naprej in kliknite »Ustvari«. Če dobite kritično opozorilno sporočilo, ga prezrite.
  4. Preklopite z zasnove na zavihek viri v Vivadu in si oglejte izvorne datoteke. Z desno tipko miške kliknite zasnovo bloka "design_1" in izberite "Ustvari ovoj HDL". Ko ste pozvani, izberite "kopiraj ustvarjen ovoj, da dovoli uporabniška urejanja". Za projekt bo ustvarjena ovojna datoteka.
  5. Zdaj, ko so tisti kritični koraki, ki so bili v drugi vadnici nekako izpuščeni, končani, se lahko vrnete na vadnico, ki je bila že povezana, in nadaljujete od 4. koraka do konca ter se prepričate, da se predstavitveni projekt pravilno izvaja. Če nimate načina za vnos zvoka za snemanje, samo snemajte s slušalkami in poslušajte 5-10-sekundni mehki zvok, ko pritisnete gumb za predvajanje. Dokler ob pritisku na gumb za predvajanje nekaj izhaja iz priključka za slušalke, verjetno deluje pravilno.

2. korak: Naredite nekaj sprememb v Vivadu

Naredite nekaj sprememb v Vivadu
Naredite nekaj sprememb v Vivadu

Zdaj imate na voljo Digilentov zvočni demo DMA, vendar to sploh ni končni cilj. Zato se moramo vrniti k Vivadu in narediti nekaj sprememb, tako da lahko naše senzorje priključimo v glave PMOD in njihovo vrednost uporabimo na strani programske opreme.

  1. Odprite blokovni diagram v Vivadu
  2. Ustvarite blok GPIO tako, da z desno tipko miške kliknete na prazen prostor v blokovnem diagramu in v meniju izberete »Dodaj IP«. Poiščite in izberite "AXI GPIO".
  3. Dvokliknite nov blok IP in v oknu za ponovno prilagoditev IP pojdite na zavihek Konfiguracija IP. Izberite vse vhode in nastavite širino na dvanajst, saj bomo na svoji harfi imeli 12 "nizov" in zato potrebujemo 12 senzorjev. Če želite uporabiti manj ali več senzorjev, ustrezno prilagodite to število. Nastavite tudi omogočeno prekinitev.
  4. Z desno miškino tipko kliknite nov blok IP GPIO in izberite "zaženi avtomatizacijo povezave". Potrdite polje AXI in pritisnite OK. To bi moralo samodejno povezati vmesnik AXI, vendar pustiti izhode bloka nepovezane.
  5. Če želite narediti prostor za dodatno prekinitev, dvokliknite blok IP xlconcat_0 in spremenite število vrat s 4 na 5. Nato lahko priključite zatič ip2intc_irpt iz novega bloka GPIO na nova neuporabljena vrata na bloku xlconcat.
  6. Z desno miškino tipko kliknite izhod "GPIO" novega bloka GPIO IP in izberite "naredi zunanje". Poiščite, kam vodi črta, in kliknite na mali stranski peterokotnik, na levi strani pa bi se moralo odpreti okno, kjer lahko spremenite ime. Spremenite ime v "SENSORS". Pomembno je, da uporabite isto ime, če želite, da datoteka omejitev, ki jo ponujamo, deluje, sicer boste morali spremeniti ime v datoteki omejitev.
  7. Nazaj na zavihek viri poiščite datoteko omejitev in jo zamenjajte s tisto, ki jo ponujamo. Izberete lahko, da datoteko zamenjate ali pa preprosto kopirate vsebino naše datoteke z omejitvami in jo prilepite nad vsebino stare. Ena od pomembnih stvari, ki jih naredi naša datoteka omejitev, je omogočiti izvlečne upore na glavi PMOD. To je potrebno za posamezne senzorje, ki smo jih uporabili, vendar niso vsi senzorji enaki. Če vaši senzorji zahtevajo spustne upore, lahko vsak primer "set_property PULLUP true" spremenite z "set_property PULLDOWN true". Če zahtevajo drugačno vrednost upora kot na plošči, lahko te vrstice odstranite in uporabite zunanje upore. Imena pin so v komentarjih v datoteki omejitev in ustrezajo oznakam v prvem diagramu v shemi Zybo stran, ki jo najdete tukaj. Če želite uporabiti različne zatiče pmod, le ujemajte imena v datoteki omejitev z oznakami v shemi. Uporabljamo glavo PMOD JE in JD in na vsakem uporabljamo šest podatkovnih zatičev, pri čemer izpustimo zatiča 1 in 7. Ti podatki so pomembni pri priključitvi senzorjev. Kot je prikazano na shemi, sta nožici 6 in 12 na PMODS VCC, nožici 5 in 11 pa ozemljeni.
  8. Ponovno ustvarite ovoj HDL kot prej, starega pa kopirajte in prepišite. Ko to storite, ustvarite bitni tok in izvozite strojno opremo kot prej in znova zaženite SDK. Če vas vprašajo, ali želite zamenjati staro datoteko strojne opreme, je odgovor pritrdilen. Ko izvozite strojno opremo, je najbolje, da SDK zaprete, da se ustrezno zamenja.
  9. Zaženite SDK.

3. korak: Zaženite FreeRTOS

Naslednji korak je zagon delovanja FreeRTOS na plošči Zybo.

  1. Če še nimate kopije, prenesite FreeRTOS tukaj in izvlecite datoteke.
  2. Uvozite predstavitev FreeRTOS Zynq na naslovu FreeRTOSv9.0.0 / FreeRTOS / Demo / CORTEX_A9_Zynq_ZC702 / RTOSDemo. Postopek uvoza je skoraj enak kot pri drugem predstavitvenem projektu, vendar ker demo FreeRTOS Zynq temelji na drugih datotekah v mapi FreeRTOS, datotek ne smete kopirati v svoj delovni prostor. Namesto tega postavite celotno mapo FreeRTOS v mapo projekta.
  3. Ustvarite nov paket podpore za ploščo, tako da odprete "file" -> "new" -> "package support package". Prepričajte se, da je izbrano samostojno, in kliknite Dokončaj. Čez nekaj časa se prikaže okno, potrdite polje zraven lwip141 (to ustavi eno od predstavitev FreeRTOS -a, da ne bi uspelo prevesti) in pritisnite V redu. Ko končate, z desno miškino tipko kliknite projekt RTOSdemo in pojdite na "lastnosti", pojdite na zavihek "reference projekta" in potrdite polje poleg novega bsp, ki ste ga ustvarili. Upajmo, da bo prepoznan, včasih pa je lahko Xilinx SDK čuden glede takšnih stvari. Če po tem koraku še vedno dobite napako, da xparameters.h manjka ali kaj podobnega, poskusite ponoviti ta korak in morda zapustiti in znova zagnati SDK.

4. korak: Dodajte kodo laserske harfe

Zdaj, ko je FreeRTOS uvožen, lahko datoteke iz projekta laserske harfe prenesete v predstavitev FreeRTOS

  1. Ustvarite novo mapo pod mapo src v predstavitvi programa FreeRTOS in v to mapo kopirajte in prilepite vse priložene datoteke c, razen main.c.
  2. Zamenjajte RTOSDemo main.c s priloženim main.c.
  3. Če je vse narejeno pravilno, bi morali na tem mestu zagnati kodo laserske harfe. Za namene testiranja se vnos gumbov, ki je bil uporabljen v predstavitvenem projektu DMA, zdaj uporablja za predvajanje zvokov brez priključenih senzorjev (kateri koli od štirih glavnih gumbov bo deloval). Vsakič, ko pritisnete nanjo, bo zaigral niz in med več pritiski premikal po vseh nizih v sistemu. Priključite nekaj slušalk ali zvočnikov v priključek za slušalke na plošči Zybo in se prepričajte, da slišite zvoke strun, ki prihajajo skozi, ko pritisnete gumb.

5. korak: O kodi

Mnogi od vas, ki berete to vadnico, se boste verjetno naučili, kako nastaviti zvok ali uporabiti DMA za nekaj drugačnega ali ustvariti drugačen glasbeni instrument. Zato je naslednjih nekaj razdelkov namenjenih opisu delovanja priložene kode v povezavi s predhodno opisano strojno opremo za pridobivanje delujočega avdio izhoda z uporabo DMA. Če razumete, zakaj so kodi, jih morate prilagoditi glede na to, kar želite ustvariti.

Prekine

Najprej bom omenil, kako v tem projektu nastajajo prekinitve. Tako smo naredili tako, da smo najprej ustvarili strukturo vektorske tabele prekinitev, ki spremlja ID, upravljalnik prekinitev in sklic na napravo za vsak prekinitev. ID -ji prekinitev prihajajo iz xparameters.h. Upravljavec prekinitev je funkcija, ki smo jo napisali za DMA in GPIO, prekinitev I2C pa izvira iz gonilnika Xlic I2C. Referenca naprave kaže na primerke vsake naprave, ki jih inicializiramo drugje. Proti koncu funkcije _init_audio zanka preide skozi vsak element v vektorski tabeli prekinitev in pokliče dve funkciji, XScuGic_Connect () in XScuGic_Enable () za povezavo in omogočanje prekinitev. Sklicujejo se na xInterruptController, ki je krmilnik prekinitev, ki je privzeto ustvarjen v datoteki main.c FreeRTOS. Tako v bistvu vsak naš prekinitev povežemo s tem krmilnikom prekinitev, ki nam ga je že ustvaril FreeRTOS.

DMA

Inicializacijska koda DMA se začne v lh_main.c. Najprej se razglasi statični primerek strukture XAxiDma. Nato se v funkciji _init_audio () konfigurira. Najprej se pokliče konfiguracijska funkcija iz predstavitvenega projekta, ki je v dma.c. To je precej dobro dokumentirano in prihaja neposredno iz predstavitve. Nato se prekinitev poveže in omogoči. Za ta projekt je potreben samo prekinitev master-to-slave, ker DMA pošlje vse podatke krmilniku I2S. Če želite snemati zvok, boste potrebovali tudi prekinitev slave-to-master. Prekinitev master-to-slave se pokliče, ko DMA konča s pošiljanjem podatkov, ki ste mu jih naročili. Ta prekinitev je za naš projekt izjemno pomembna, saj mora vsakič, ko DMA pošlje en vmesnik zvočnih vzorcev, takoj začeti pošiljati naslednji vmesnik, sicer bo med pošiljanji prišlo do zvočne zamude. Znotraj funkcije dma_mm2s_ISR () si lahko ogledate, kako ravnamo s prekinitvijo. Pomemben del je pred koncem, kjer uporabljamo xSemaphoreGiveFromISR () in portYIELD_FROM_ISR () za obvestilo _audio_task (), da lahko sproži naslednji prenos DMA. Način, na katerega pošiljamo stalne zvočne podatke, je izmenično med dvema vmesnikoma. Ko se en vmesni pomnilnik prenaša v blok I2C, se v drugem vmesnem pomnilniku izračunajo in shranijo njegove vrednosti. Potem, ko prekinitev prihaja iz DMA, se aktivni vmesni pomnilnik preklopi in nedavno zapisani medpomnilnik se začne prenašati, medtem ko se prej preneseni vmesni pomnilnik začne prepisovati z novimi podatki. Ključni del funkcije _audio_task je kraj, kjer se pokliče fnAudioPlay (). fnAudioPlay () vzame primerek DMA, dolžino medpomnilnika in kazalec na vmesnik, iz katerega se bodo podatki prenesli. Nekaj vrednosti je poslanih v registre I2S, da sporočijo, da prihaja več vzorcev. Nato se pokliče XAxiDma_SimpleTransfer () za začetek prenosa.

I2S zvok

audio.c in audio.h sta kraj inicializacije I2S. Iniciacijska koda I2S je precej pogost kos kode, ki lebdi na številnih mestih, morda boste našli majhne razlike od drugih virov, vendar bi ta morala delovati. To je precej dobro dokumentirano in ga za projekt harfe ni treba veliko spreminjati. Zvočni demo DMA, iz katerega je prišel, ima funkcije za preklop na mikrofonske ali linijske vhode, tako da jih lahko uporabite, če potrebujete to funkcijo.

Sinteza zvoka

Da opišem, kako deluje sinteza zvoka, bom navedel vsak zvočni model, uporabljen pri razvoju, ki je pripeljal do končne metode, saj vam bo dal občutek, zakaj se to počne tako, kot je narejeno.

1. metoda: Za vsako struno se izračuna eno obdobje sinusnih vrednosti na ustrezni frekvenci za glasbeno noto te godbe in shrani v niz. Na primer, dolžina matrike bo obdobje sinusnega vala v vzorcih, kar je enako # vzorcev / cikel. Če je hitrost vzorčenja 48 kHz in notna frekvenca 100Hz, potem obstaja 48.000 vzorcev na sekundo in 100 ciklov na sekundo, kar vodi do 4800 vzorcev na cikel, dolžina matrike pa bo 4800 vzorcev in bo vsebovala vrednosti enega celotnega sinusno obdobje. Ko se niz predvaja, se medpomnilnik zvočnega vzorca napolni tako, da vzame vrednost iz matrike sinusnih valov in jo vstavi v zvočni vmesnik kot vzorec, nato pa indeks poveča v niz sinusnih valov, tako da z uporabo našega prejšnjega primera tečaj od 4800 vzorcev se en cikel sinusnega valovanja vstavi v zvočni vmesnik. Modularna operacija se uporablja za indeks matrike, tako da vedno pade med 0 in dolžino, in ko indeks matrike preseže določen prag (na primer vzorce v vrednosti 2 sekund), se niz izklopi. Za predvajanje več nizov hkrati spremljajte indeks nizov vsakega niza ločeno in dodajte vrednost iz sinusnega vala vsakega niza skupaj, da dobite vsak vzorec.

2. način: Če želimo ustvariti bolj glasbeni ton, začnemo s prejšnjim modelom in vsaki osnovni frekvenci dodamo harmonike. Harmonične frekvence so frekvence, ki so celobrojni večkratniki osnovne frekvence. V nasprotju s tem, ko se dve nepovezani frekvenci seštejeta, kar ima za posledico istočasno predvajanje dveh različnih zvokov, pri seštevanju harmonikov pa še naprej zveni kot samo en zvok, vendar z drugačnim tonom. Da bi to dosegli, vsakič, ko v zvočni vzorec dodamo vrednost sinusnega vala na lokaciji (indeks matrike % dolžina niza), dodamo tudi (2 * indeks matrike % dolžina niza) in (3 * indeks matrike % dolžina niza) itd., čeprav je zaželenih veliko harmonikov. Ti pomnoženi indeksi bodo prečkali sinusni val pri frekvencah, ki so celobrojni večkratniki prvotne frekvence. Da bi omogočili večji nadzor nad tonom, se vrednosti vsakega harmonika pomnožijo s spremenljivko, ki predstavlja količino tega harmonika v celotnem zvoku. Na primer, osnovni sinusni val ima lahko vse svoje vrednosti pomnožene s 6, da bi bil bolj pomemben dejavnik v celotnem zvoku, medtem ko ima peti harmonik multiplikator 1, kar pomeni, da njegove vrednosti veliko manj prispevajo k celotnemu zvoku.

Metoda 3: V redu, zdaj imamo zelo lep ton pri notah, vendar je še vedno precej pomemben problem: igrajo pri določeni glasnosti za določen čas. Da bi sploh zvenelo kot pravi instrument, bi morala glasnost godal, ki se igrajo, sčasoma počasi upadati. Da bi to dosegli, je matrika napolnjena z vrednostmi eksponentno razpadajoče funkcije. Zdaj, ko se ustvarjajo zvočni vzorci, se zvok, ki prihaja iz vsakega niza, izračuna tako kot v prejšnji metodi, vendar se pred dodajanjem zvočnemu vzorcu pomnoži z vrednostjo v indeksu matrike teh nizov v nizu funkcij eksponentnega razpada. Zaradi tega se zvok sčasoma gladko razprši. Ko indeks matrike doseže konec matrike razpada, se niz ustavi.

Metoda 4: Ta zadnji korak je tisto, kar daje zvokom godov njihov realističen zvok. Preden so zveneli prijetno, a jasno sintetizirano. Da bi poskušali bolje posnemati niz harfe v resničnem svetu, je vsakemu harmoniku dodeljena drugačna stopnja razpada. V pravih strunah, ko je struna prvič udarjena, je visoka vsebnost visokofrekvenčnih harmonikov, ki ustvarjajo takšen zvok, ki ga pričakujemo od strune. Ti visokofrekvenčni harmoniki so zelo kratek glavni del zvoka, zvok strune je udarjen, vendar zelo hitro propadejo, ko počasnejši harmoniki prevzamejo oblast. Za vsako harmonično število, ki se uporablja pri sintezi zvoka, se ustvari niz razpadanja, vsak s svojo stopnjo upadanja. Zdaj je mogoče vsak harmonik neodvisno pomnožiti z vrednostjo njegove ustrezne matrike razpada pri indeksu niza niza in dodati zvoku.

Na splošno je sinteza zvoka intuitivna, vendar je izračun težak. Shranjevanje celotnega zvoka niza v pomnilnik naenkrat bi vzelo preveč pomnilnika, vendar bi izračunavanje sinusnega vala in eksponentne funkcije med vsakim kadrom trajalo predolgo, da bi sledili hitrosti predvajanja zvoka. Za pospešitev izračuna se v kodi uporabljajo številni triki. Vsa matematika, razen pri začetnem ustvarjanju sinusnih in eksponentno razpadnih tabel, se izvede v celoštevilskem formatu, kar zahteva razširitev razpoložljivega številskega prostora v 24 -bitnem avdio izhodu. Na primer, tabela sinusov ima amplitudo 150, tako da je gladka, vendar ne tako velika, da bi lahko številne strune, ki se igrajo skupaj, dodale več kot 24 bitov. Podobno se vrednosti eksponentne tabele pomnožijo z 80, preden se zaokrožijo na cela števila in shranijo. Harmonične uteži lahko dobijo diskretne vrednosti med 0 in 10. Prav tako se vsi vzorci dejansko podvojijo, sinusni valovi pa so indeksirani z 2, kar učinkovito prepolovi stopnjo vzorčenja. To omejuje največjo frekvenco, ki jo je mogoče predvajati, vendar je bilo potrebno, da se trenutno število nizov in harmonikov izračuna dovolj hitro.

Ustvarjanje tega zvočnega modela in njegovo delo je zahtevalo precejšnje napore na strani procesorja, zato bi bilo v časovnem okviru tega projekta izredno težko delati na strani fpga iz nič (zamislite si, da morate vsako bitko znova ustvariti čas preverjanja zvoka). Vendar pa bi bilo to lahko boljši način za fpga, kar bi morda odpravilo težavo, da ne bi mogli dovolj hitro izračunati vzorcev in omogočiti izvajanje več nizov, harmonikov in celo zvočnih učinkov ali drugih nalog procesorska stran.

6. korak: Priključite senzorje

Ožičenje senzorjev
Ožičenje senzorjev

Za ustvarjanje nizov smo uporabili senzorje IR prekinitvenega snopa, ki bodo zaznali, ko se godba igra. Naše senzorje smo naročili na naslednji povezavi. Tipala imajo napajalno, ozemljitveno in podatkovno žico, oddajniki pa samo napajalno in ozemljitveno žico. Za napajanje oddajnikov in senzorjev smo uporabili 3,3 V in ozemljitvene zatiče iz glavo PMOD. Za napajanje vseh senzorjev in oddajnikov je potrebno vse senzorje in oddajnik povezati vzporedno. Podatkovne žice iz senzorjev bodo morale iti na svoj pmod pin.

7. korak: Konstrukcija okostja

Konstrukcija okostja
Konstrukcija okostja

Za ustvarjanje oblike harfe se trije deli uporabljajo kot okostje za namestitev senzorjev in oddajnikov. Na enem od dveh 18 -palčnih kosov PVC cevi položite senzorje in oddajnike v izmeničnem vrstnem redu 1,5 cm drug od drugega in jih nato prilepite na cev. Na drugi 18 -palčni PVC cevi senzorje in oddajnike poravnajte v izmeničnem vrstnem redu, vendar pazite, da izravnate vrstni red (tj. Če je prva cev imela senzor prva, bi morala druga imeti najprej oddajnik in obratno). Na podatkovne, napajalne in ozemljitvene žice boste morali spajkati daljše žice, da zagotovite, da bodo lahko dosegli ploščo.

8. korak: Gradnja lesene zunanjosti

Gradnja lesene zunanjosti
Gradnja lesene zunanjosti

Ta korak ni obvezen, vendar je zelo priporočljiv. Zunanjost lesa ne le naredi harfo lep videz, ampak tudi zaščiti senzorje in žice pred poškodbami. Leseni okvir je lahko izdelan iz votlega pravokotnega obroča iz lesa. Notranjost pravokotnika mora imeti odprtino vsaj 1-1/2 palca, da se prilega okostju cevi in senzorja. Ko je okvir izdelan, izvrtajte dve luknji, ki bosta omogočili žice iz senzorja in oddajnikov, da ju povežete s ploščo.

*Opomba: Priporočljivo je, da dodate dostopne točke, da lahko odstranite in vstavite ogrodje cevi, če je potrebno popraviti ali narediti manjše prilagoditve.

9. korak: Združite vse kose

Združevanje vseh kosov
Združevanje vseh kosov

Ko so vsi prejšnji koraki končani, je čas za izgradnjo harfe. Okvir cevi najprej postavite v leseno zunanjost. Nato priključite žice za senzorje in oddajnike na pravo mesto na plošči. Nato odprite SDK in kliknite gumb za odpravljanje napak, da programirate ploščo. Ko je plošča programirana, priključite slušalke ali zvočnik. Odvisno od tega, kateri senzor se konča, v katerih vratih pmod bodo strune vaše harfe za začetek verjetno neuporabne. Ker je težko ugotoviti, katera žica gre do katerega senzorja, ko je vpletenih toliko žic, smo vključili način preslikave številk nizov za prekinitev položajev bitov v programski opremi. Poiščite "static int sensor_map [NUM_STRINGS]" in prilagodite vrednosti v matriki, dokler se nizi ne predvajajo od najnižjega do najvišjega po vrstnem redu.

Meni lahko uporabite tako, da odprete serijski terminal (npr. RealTerm) in nastavite hitrost prenosa na 115200, zaslon pa na ANSI. Po meniju se lahko premikate s tipkama w in s za premikanje gor in dol ter s tipkama a in d za spreminjanje vrednosti.

10. korak: ROCK OUT

Ko je harfa popolnoma funkcionalna. Obvladajte harfo in poslušajte sladek zvok lastne glasbe!

Priporočena: