Obsah:
- Krok 1: Teorie
- Krok 2: Ingredience a nástroje
- Krok 3: Zapojení a nastavení hardwaru
- Krok 4: Nastavení VHDL (Vivado)
- Krok 5: Stažení kódu
Video: Digitální zvukový syntetizér Basys3 FPGA: 5 kroků
2024 Autor: John Day | [email protected]. Naposledy změněno: 2024-01-30 08:24
Tento digitální syntezátor klávesnice se sinusovými vlnami převezme uživatelské vstupy prostřednictvím řady momentálních přepínačů rozložených jako klávesnice a prostřednictvím reproduktoru bude vysílat zvukovou vlnu. Na základě uživatelských vstupů bude zařízení generovat sinusové vlny různých frekvencí od C4 do C6. Uživatel může zadávat noty od C4 až po C6 (celkem 25 not) a až čtyři klávesy současně - pokud stisknete více než čtyři klávesy, zazní čtyři nejnižší tóny.
Tento projekt provedli Ryan Morris a Mavis Tsoi pro naši třídu digitálního designu Cal Poly CPE 133:)
Krok 1: Teorie
Deska FPGA může vydávat pouze digitální signály. Jinými slovy, může produkovat pouze vysoké (3,3 V) napětí nebo nízké (0 V) napětí. Zvukové signály jsou však analogové a mohou mít nekonečně mnoho přírůstků napětí. Abychom to zvládli, použijeme k emulaci analogové vlny signál PWM (pulse width modulation). Pokud nevíte, co je PWM, podívejte se na toto:
Krok 2: Ingredience a nástroje
- Počítač s nainstalovaným Vivado
- Budeme používat Vivado verze 2017.2
- Deska FPGA Basys3
- 25 koncových spínačů SPDT (použili jsme je)
- 30 propojovacích vodičů (jeden konec samec, druhý konec nezáleží), 12 palců
- Nůžky na drát
- Odstraňovače drátů
- Náhradní drát pro pájení
- Pájka s pryskyřičným jádrem
- Páječka
- Audio”samice audio konektor
- Zesilovač/reproduktor
- Něco, na co lze namontovat spínače (použili jsme protoboard + dřevěnou krabici)
Krok 3: Zapojení a nastavení hardwaru
architektura systému
Viz obrázek 1: 25 dostupných vstupů → Deska Basys3 → zesilovač a reproduktor.
Výstup
Viz obrázek 2: Deska Basys3 → 1/2palcový zvukový konektor pro ženy → reproduktor (se zesilovačem)
Vstup
Připojení pmod na desce Basys3 musí být připojeno k zemi, aby bylo vidět nízký vstup, a nebude správně fungovat, pokud zůstane ponecháno jako otevřený obvod. Z tohoto důvodu musíme používat přepínače SPDT pro všechny naše notové klíče. Přepínač SPDT v podstatě umožňuje uživateli přepínat mezi obvody po stisknutí, takže je použijeme jako „tlačítka“pro vstup nízkých (0 V) nebo vysokých (3,3 V) signálů na desku Basys3.
Každý přepínač bude mít svorku NO (normálně otevřený) připojenou k 3,3 V, NC (normálně zavřenou) svorku připojenou k GND a COM (společnou) svorku připojenou ke vstupu FPGA. Viz obrázek 3.
Protože máme 25 koncových spínačů, budou všechny sdílet společnou linku 3,3 V a společnou linku GND. Poté bude signální vedení z každého koncového spínače seskupeno do skupin po 8 a připojeno k pmod spojům na desce Basys3 pomocí propojovacích propojovacích kabelů, které lze zapnout, aby se minimalizoval monumentální nepořádek, který uděláme. Viz obrázek 4 nebo příklad prvních osmi kláves.
Krok 4: Nastavení VHDL (Vivado)
Generátor sinusových vln a generátor PWM byly nejprve testovány, aby se ujistil, že náš koncept funguje, poté byl integrován omezovač vstupu a sčítač/řadič amplitudy. Podrobnosti o funkci a I/O každého procesního bloku jsou uvedeny na obrázku. Kód je zobrazen níže, ale je také připojen jako soubory VHD a txt. Pokud existují nesrovnalosti, přejděte k souborům VHD.
BTW: Pravděpodobně jsme měli zkrátit naše řádky, ale vkládání kódu do Instructables se také ukázalo jako docela otravné, takže mezery nejsou největší a není zvýrazněno syntaxe. Pokud máte Vivado a rádi byste se řídili kódem, důrazně vám doporučujeme soubor si stáhnout.
Nejprve se podívejme na modul generátoru sinusových vln.
knihovna IEEE; použijte IEEE. STD_LOGIC_1164. ALL; použijte IEEE. NUMERIC_STD. ALL; entity Wave_Generator is Port (Trigger: in STD_LOGIC; - Key press Freq_Cnt: in STD_LOGIC_VECTOR (15 downto 0); - Counter value = 100MHz / (Note Frequency*64 Divitions of Sine Wave) (round to nearest num) - renamed z Freq wavegenCLK: v STD_LOGIC; - Basys3 100MHz CLK WaveOut: out STD_LOGIC_VECTOR (9 až 0)); - Podepsaná amplituda konce vlny Wave_Generator; architektura Behavioral of Wave_Generator is signal i: integer range 0 to 64: = 0; -index typu banky paměti amplitudy typ paměťový_typ je pole (0 až 63) s celočíselným rozsahem -64 až 63; - vytvořit paměťovou banku (ROM) pro uchování hodnot amplitudy- zajímá se tato RAM nebo ROM … amplituda signálu: typ_paměti: = (0, 7, 13, 19, 25, 30, 35, 40, 45, 49, 52, 55, 58, 60, 62, 63, 63, 63, 62, 60, 58, 55, 52, 49, 45, 40, 35, 30, 25, 19, 13, 7, 0, -7, -13, -19, -25, -30, -35, -40, -45, -49, -52, -55, -58, -60, -62, -63, -63, -63, -62, - 60, -58, -55, -52, -49, -45, -40, -35, -30, -25, -19, -13, -7); - banka amplitudové paměti pro proces zahájení sinusové vlny (wavegenCLK, Trigger) variabilní čítač: bez znaménka (15 dolů až 0): = to_unsigned (0, 16); - čítač děliče hodin, přejmenovaný z count1 begin if (rise_edge (wavegenCLK)) then if (Trigger = '1') then- key isPress counter counter: = counter + 1; if (counter = unsigned (Freq_Cnt)) then - Freq_Cnt = 100Mhz / (note freq * 64 divitions of the sine wave) - reset counter and assign amplitude data to output counter: = to_unsigned (0, 16); WaveOut <= STD_LOGIC_VECTOR (to_signed (amplitude (i), 10)); - přírůstek i pro další čtení i <= i + 1; - resetujte i, pokud byla dokončena jedna sinusová vlna, pokud (i = 63) pak i <= 0; konec pokud; konec pokud; - (čítač = bez znaménka (Freq_Cnt)) else- klávesa není stisknuta- reset výstupu, index amplitudy a čítač WaveOut <= "0000000000"; i <= 0; čítač: = to_unsigned (0, 16); --výstupní amplituda = -64, když se nehraje žádná nota, konec pokud; - (Trigger = '1') end if; - (rise_edge (CLK)) koncový proces; konec Behaviorální;
V Basys3 vygenerujeme digitální sinusovou vlnu pomocí vnitřních hodin a ROM. Tato ROM bude ukládat 64 hodnot, které představují 64 amplitud na sinusové vlně. Viz obrázek 1. 64 hodnot, které používáme, emuluje sinusovou vlnu s docela dobrým rozlišením.
Pomocí interních hodin počítáme do hodnoty, která představuje rychlost hodin dělenou frekvencí vlny, kterou chceme a 64: Clk div = 100MHz / (Freq * 64) Pokaždé, když náš čítač dosáhne této hodnoty, zavoláme na číslo z ROM a odešlete ji z našeho modulu generátoru vln. Frekvence naší vlny bude záviset na tom, jak rychle tyto amplitudy nazýváme.
Budeme mít 25 dílčích modulů, každý spojený s jednou frekvencí/poznámkou.
Zde je zbývající část kódu, který volá moduly generátoru sinusových vln:
knihovna IEEE; použijte IEEE. STD_LOGIC_1164. ALL; použijte IEEE. NUMERIC_STD. ALL; entita Two_Octave_Synth je Port (CLK: v STD_LOGIC; O4: v STD_LOGIC_VECTOR (11 až 0); O5: ve STD_LOGIC_VECTOR (12 až 0); výstup: mimo STD_LOGIC); konec Two_Octave_Synth; architektura Behavioral of Two_Octave_Synth is component Wave_Generator is Port (Trigger: in STD_LOGIC; Freq_Cnt: in STD_LOGIC_VECTOR (15 downto 0); wavegenCLK: in STD_LOGIC; WaveOut: out STD_LOGIC_VECTOR (9 downto 0)); koncová složka; --------------------------- výstupní signály z generátoru vln ------------------ ----- signál WaveC4, WaveCs4, WaveD4, WaveDs4, WaveE4, WaveF4, WaveFs4, WaveG4, WaveGs4, WaveA4, WaveAs4, WaveB4, WaveC5, WaveCs5, WaveD5, WaveDs5, WaveE5, WaveE5, WaveE5, WaveE5, WaveE5 WaveAs5, WaveB5, WaveC6: podepsáno (9 až 0); -------------------------------- pro logiku výběru not -------------- ------ signál C4, Cs4, D4, Ds4, E4, F4, Fs4, G4, Gs4, A4, As4, B4, C5, Cs5, D5, Ds5, E5, F5, Fs5, G5, Gs5, A5, As5, B5, C6: bez znaménka (4 až 0); signál cntC4, cntCs4, cntD4, cntDs4, cntA5, cntA5: bez znaménka (4 až 0); chyba signálu: STD_LOGIC; ----------------------------------- pro přidání sinusových vln ----------- --------------- signál Wave0, Wave1, Wave2, Wave3: podepsáno (9 až 0); --signály z výstupního signálu modulu generátoru vln WaveSum: STD_LOGIC_VECTOR (9 až 0); -signál pro součet sinusových vln (kompliment 2 -512 až 511) signál positiveWaveSum: STD_LOGIC_VECTOR (9 až 0); -nepodepsáno 0 až 1023, pro použití v generátoru PWM ----------------------------------- pro generování PWM ------------------------------- signál ping_length: unsigned (9 downto 0): = unsigned (positiveWaveSum); --signal off_length: unsigned (6 downto 0): = to_unsigned (127, 7) -unsigned (WAVE); signál PWM: bez znaménka (9 až 0): = to_unsigned (0, 10); začít Note_C4: Mapa portu Wave_Generator (Trigger => O4 (0), Freq_Cnt => X "1755", wavegenCLK => CLK, podepsáno (WaveOut) => WaveC4); --5973, 261,63 Hz Note_Cs4: Mapa portu Wave_Generator (Trigger => O4 (1), Freq_Cnt => X "1606", wavegenCLK => CLK, signováno (WaveOut) => WaveCs4);-5638, 277,18 Hz Poznámka_D4: Mapa portu Wave_Generator (Trigger => O4 (2), Freq_Cnt => X "14C9", wavegenCLK => CLK, signováno (WaveOut) => WaveD4); --5321, 293,66 Hz Note_Ds4: Mapa portu Wave_Generator (Trigger => O4 (3), Freq_Cnt => X "139F", wavegenCLK => CLK, signováno (WaveOut) => WaveDs4);-5023, 311,13 Hz Note_E4: Mapa portu Wave_Generator (Trigger => O4 (4), Freq_Cnt => X "1285", wavegenCLK => CLK, signováno (WaveOut) => WaveE4); --4741, 329,63 Hz Poznámka_F4: Mapa portu Wave_Generator (Trigger => O4 (5), Freq_Cnt => X "117B", wavegenCLK => CLK, signováno (WaveOut) => WaveF4); --4475, 349,23 Hz Note_Fs4: Mapa portu Wave_Generator (Trigger => O4 (6), Freq_Cnt => X "1080", wavegenCLK => CLK, signováno (WaveOut) => WaveFs4);-4224, 369,99 Hz Note_G4: Mapa portu Wave_Generator (Trigger => O4 (7), Freq_Cnt => X "0F92", wavegenCLK => CLK, signováno (WaveOut) => WaveG4); --3986, 392,00 Hz Note_Gs4: Mapa portu Wave_Generator (Trigger => O4 (8), Freq_Cnt => X "0EB3", wavegenCLK => CLK, signováno (WaveOut) => WaveGs4);-3763, 415,30 Hz Note_A4: Mapa portu Wave_Generator (Trigger => O4 (9), Freq_Cnt => X "0DE0", wavegenCLK => CLK, podepsáno (WaveOut) => WaveA4); --3552, 440,00 Hz Poznámka_As4: Mapa portu Wave_Generator (Trigger => O4 (10), Freq_Cnt => X "0D18", wavegenCLK => CLK, signováno (WaveOut) => WaveAs4);-3352, 466,16 Hz Poznámka_B4: Mapa portu Wave_Generator (Trigger => O4 (11), Freq_Cnt => X "0C5C", wavegenCLK => CLK, signováno (WaveOut) => WaveB4); --3164, 493,88 Hz -------------------------------------------- ---------------------------------------------------------- --------------------------- Note_C5: Mapa portu Wave_Generator (Trigger => O5 (0), Freq_Cnt => X "0BAB", wavegenCLK => CLK, podepsáno (WaveOut) => WaveC5); --2987, 523,25 Hz Note_Cs5: Mapa portu Wave_Generator (Trigger => O5 (1), Freq_Cnt => X "0B03", wavegenCLK => CLK, signováno (WaveOut) => WaveCs5);-2819, 554,37 Hz Poznámka_D5: Mapa portu Wave_Generator (Trigger => O5 (2), Freq_Cnt => X "0A65", wavegenCLK => CLK, signováno (WaveOut) => WaveD5); --2661, 587,33 Hz Note_Ds5: Mapa portu Wave_Generator (Trigger => O5 (3), Freq_Cnt => X "09D0", wavegenCLK => CLK, signováno (WaveOut) => WaveDs5);-2512, 622,25 Hz Note_E5: Mapa portu Wave_Generator (Trigger => O5 (4), Freq_Cnt => X "0943", wavegenCLK => CLK, signováno (WaveOut) => WaveE5); --2371, 659,25 Hz Poznámka_F5: Mapa portu Wave_Generator (Trigger => O5 (5), Freq_Cnt => X "08Be", wavegenCLK => CLK, signováno (WaveOut) => WaveF5); --2238, 698,46 Hz Note_Fs5: Mapa portu Wave_Generator (Trigger => O5 (6), Freq_Cnt => X "0840", wavegenCLK => CLK, signováno (WaveOut) => WaveFs5);-2112, 739,99 Hz Note_G5: Mapa portu Wave_Generator (Trigger => O5 (7), Freq_Cnt => X "07CA", wavegenCLK => CLK, signováno (WaveOut) => WaveG5); --1994, 783,99 Hz Note_Gs5: Mapa portu Wave_Generator (Trigger => O5 (8), Freq_Cnt => X "075A", wavegenCLK => CLK, signováno (WaveOut) => WaveGs5);-1882, 830,61 Hz Note_A5: Mapa portu Wave_Generator (Trigger => O5 (9), Freq_Cnt => X "06F0", wavegenCLK => CLK, signováno (WaveOut) => WaveA5); --1776, 880,00 Hz Note_As5: Mapa portu Wave_Generator (Trigger => O5 (10), Freq_Cnt => X "068C", wavegenCLK => CLK, signováno (WaveOut) => WaveAs5);-1676, 932,33 Hz Note_B5: Mapa portu Wave_Generator (Trigger => O5 (11), Freq_Cnt => X "062E", wavegenCLK => CLK, signováno (WaveOut) => WaveB5); --1582, 987,77 Hz Poznámka_C6: Mapa portu Wave_Generator (Trigger => O5 (12), Freq_Cnt => X "05D6", wavegenCLK => CLK, signováno (WaveOut) => WaveC6); --1494, 1046,5 Hz ------------ logika výběru not ------------ C4 <= "0000" & O4 (0); Cs4 <= "0000" & O4 (1); D4 <= "0000" & O4 (2); Ds4 <= "0000" & O4 (3); E4 <= "0000" & O4 (4); F4 <= "0000" & O4 (5); Fs4 <= "0000" & O4 (6); G4 <= "0000" & O4 (7); Gs4 <= "0000" & O4 (8); A4 <= "0000" & O4 (9); As4 <= "0000" & O4 (10); B4 <= "0000" & O4 (11); C5 <= "0000" & O5 (0); Cs5 <= "0000" & O5 (1); D5 <= "0000" & O5 (2); Ds5 <= "0000" & O5 (3); E5 <= "0000" & O5 (4); F5 <= "0000" & O5 (5); Fs5 <= "0000" & O5 (6); G5 <= "0000" & O5 (7); Gs5 <= "0000" & O5 (8); A5 <= "0000" & O5 (9); As5 <= "0000" & O5 (10); B5 <= "0000" & O5 (11); C6 <= "0000" & O5 (12); cntC4 <= C4; cntCs4 <= C4 + Cs4; cntD4 <= C4 + Cs4 + D4; cntDs4 <= C4 + Cs4 + D4 + Ds4; cntE4 <= C4 + Cs4 + D4 + Ds4 + E4; cntF4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4; cntFs4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4; cntG4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4; cntGs4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4; cntA4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4; cntAs4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4; cntB4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4; cntC5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5; cntCs5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5; cntD5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5; cntDs5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5; cntE5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5; cntF5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5; cntFs5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5; cntG5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5 + G5; cntGs5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5 + G5 + Gs5; cntA5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5 + G5 + Gs5 + A5; cntAs5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5 + G5 + Gs5 + A5 + As5; cntB5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5 + G5 + Gs5 + A5 + As5 + B5; cntC6 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5 + G5 + Gs5 + A5 + As5 + B5 + C6; Výběr: WaveC4, WaveCs4, WaveD4, WaveDs4, WaveE4, WaveF4, WaveFs4, WaveG4, WaveGs4, WaveA4, WaveAs4, WaveB4, WaveC5, WaveCs5, WaveD5, WaveDs5, WaveE5 WaveB5, WaveC6) begin if (cntC6 = "00000") then --------------- pokud nejsou generovány žádné signály Wave0 <= "0000000000"; Wave1 <= "0000000000"; Wave2 <= "0000000000"; Wave3 <= "0000000000"; else if (O4 (0) = '1') then ------------------- note C4 playing Wave0 Wave0 Wave1 error Wave0 Wave1 Wave2 error Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave2 error Wave0 Wave1 Wave2 wave3 Wave2 Wave3 error Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave2 error Wave0 Wave1 Wave2 error3 = WaveC6; Wave1 <= "0000000000"; Wave2 <= "0000000000"; Wave3 Wave1 <= WaveC6; Wave2 <= "0000000000"; Wave3 Wave2 <= WaveC6; Wave3 Wave3 error Wave1 <= "0000000000"; Wave2 <= "0000000000"; Wave3 Wave2 <= "0000000000"; Wave3 Chyba Wave3 <= '1'; koncový případ; konec pokud; konec pokud; konečný proces; ------------- sinusový sčítač -------------------- WaveSum <= STD_LOGIC_VECTOR (Wave0 + Wave1 + Wave2 + Wave3); --------- aby byla sinusová vlna pozitivní pro pwm --------------------- positiveWaveSum <= ne WaveSum (9) & WaveSum (8 až 0); ------------- PWM generátor --------------------- proces (CLK)-variabilní počet: bez znaménka (1 až 0): = to_unsigned (0, 2); begin if (rise_edge (CLK)) then --count: = count + 1; --if (count = to_unsigned (4, 2)) then --count: = to_unsigned (0, 2); --if (PWM = to_ if (PWM <délka ping) pak výstup <= '1'; jinak výstup <= '0'; konec pokud; PWM <= PWM + 1; délka ping <= bez znaménka (positiveWaveSum); --end if; end if; end process; end Behavioral;
4 Selector Selector Nejsložitější částí tohoto projektu je výběr pouze čtyř frekvencí. Udělali jsme to s IF příkazy Lotta a místo proměnných jsme použili signály, aby bylo možné proces simulovat a ladit. Zkoušeli jsme jiné metody pomocí proměnných a FOR smyček, ale narazili jsme na chyby za běhu. Nakonec jsme se tedy rozhodli, že pokud to bude fungovat, necháme to na pokoji. Neopravovat, co není rozbitý amirit?
Čtyři výstupní vlny jsou označeny Wave0, Wave1, Wave2, Wave3 - to je to, co se sečte a vytvoří konečný výstup.
Při pohledu na kód uvidíte spoustu signálů označených C4, Cs4, D4, Ds4 atd. Jedná se o 5bitové signály, které vezmou odpovídající spoušť z O4 (oktáva 4) nebo O5 (oktáva 5) a vytvoří je. 5bitové pro přidání.
Dále proměnné cntC4, cntCs4 atd. Představují, kolik not nižších než cílová nota bylo odehráno, včetně cílové noty. Pokud se například hraje na C4, E4, G4, A#4 a D5 (akord C9), cntC4 bude 1, cntE4 bude 2, cntG4 bude 3 atd.
Poté, kdykoli zazní nota, bude zkontrolován počet pro cílovou notu, aby se zjistilo, kam se má signál noty připojit. Pokud se například hraje nota D5 (což znamená, že O5 (2) je vysoká) a cntD5 je 3, pak se aktuálně hrají 3 noty, přičemž 2 tóny jsou nižší než D5, takže připojíme waveD5 k Wave2 (třetí vlna) počítání signálu z Wave0). Alternativně, pokud je cntD5 5, pak se aktuálně hraje 5 not, přičemž 4 noty jsou nižší než D5, takže waveD5 necháme viset a nic s tím neuděláme.
Příkazy IF se poté opakují, aby pokryly případy pro všech 25 poznámek.
Sčítač amplitudy
Poté, co jsou vybrány nejnižší 4 vlny, musíme je sečíst. Důvod, proč přidáme pouze čtyři poznámky dohromady, je ten, že myšlenka PWM, kterou používáme pro náš výstup, může mít pouze určité rozlišení, dokud PWM běží příliš pomalu a reproduktor nezačne přijímat čtvercovou vlnu PWM. Pokud bychom například použili rozlišení 8192 (13 bitů), každý z těchto 8192 bodů musí odpovídat stoupající hraně palubních hodin. Takže 100MHz / 8192 = 12,2kHz, což je dobře v dosahu lidského sluchu.
Vlastní přidání amplitud je velmi jednoduché, jen se musíte ujistit, že může běžet opravdu rychle.
PWM výstup
Pracovní cyklus PWM bude v tomto okamžiku představovat amplitudu naší výstupní vlny. Pokud například máme rozsah amplitudy 0 až 128, 0 by byl 0%pracovní cyklus, 64 by bylo 50%, 128 by bylo 100%atd. Tento PWM poběží extrémně rychle (náš je 97,6 kHz), tak rychle, že reproduktor nerozpozná jednotlivé čtvercové vlny a místo toho se podívá na průměrné napětí a vytvoří náš „analogový“signál.
Soubor omezení
Možná jste připojili svůj hardware jinak, takže se ujistěte, že soubor omezení odpovídá.
Krok 5: Stažení kódu
Níže je kód, a to ve formátu.txt i.vhd pro Vivado. Wave_Generator je submodul generátoru vln a Two_Octave_Synth je nejlepší modul se vším ostatním.
Doporučuje:
Domácí zvukový systém: 6 kroků (s obrázky)
Domácí zvukový systém: Tento zvukový systém se snadno vyrábí a je levný (méně než 5 $ plus některé získané materiály nalezené v mé dílně). Umožňuje dostatečně silný konkurz do velké místnosti. Jako zdroje signálu lze použít: -Bluetooth z jakéhokoli mobilního telefonu telefon. -MP3 z paměti
Jak si vyrobit 32pásmový LED zvukový hudební spektrální analyzátor pomocí Arduino Nano doma #arduinoproject: 8 kroků
How to DIY 32 Band LED Audio Music Spectrum Analyzer using Arduino Nano at home #arduinoproject: Today we will make a 32 band LED Audio Music Spectrum Analyzer at Home using Arduino, it can show frequency range and play muisc at the same time. musí být připojen před odpor 100k, jinak hluk spea
Zvukový přehrávač ESP32: 6 kroků (s obrázky)
ESP32 Audio Player: Kvůli epidemii jsem za posledních šest měsíců strávil více času doma než obvykle. Je nevyhnutelné, že by se člověk doma nudil, a tak jsem udělal zvukový přehrávač s ESP32, abych věnoval čas. ESP32 lze použít jako nezávislý systém pro spouštění aplikací
DIY VR běžecký pás- Basys3 FPGA-Digilent soutěž: 3 kroky
DIY VR běžecký pás- Basys3 FPGA-Digilent Contest: Chcete postavit běžecký pás VR, na kterém můžete spouštět desktopové aplikace a hry? Pak jste na správném místě! V konvenčních hrách používáte myš a klávesnici k interakci s prostředím. Proto musíme poslat
Jak strhnout digitální posuvné měřítko a jak funguje digitální posuvné měřítko: 4 kroky
Jak strhnout digitální posuvné měřítko a jak funguje digitální posuvné měřítko: Mnoho lidí ví, jak používat třmeny k měření. Tento tutoriál vás naučí strhávat digitální posuvné měřítko a vysvětlí, jak digitální posuvné měřítko funguje