Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Syntezator MIDI, SID 8580 [8051][Asembler]

Jimi Hendrix 11 Gru 2011 02:12 12298 48
  • #1 11 Gru 2011 02:12
    Jimi Hendrix
    Poziom 19  

    otóż buduję syntezator midi oparty o układ 8580 z commodore. Programuje w asm. Komunikacja z układem ok, przez zatrzaski na linii adresu i danych, zegar generator kwarcowy 4 MHz dzielony przez 4 do 1 MHz dla SIDA, chip select dla sida z P1.0 mikrokontrolera.
    Mikrokontroler na płytce AVT2550, konkretniej DS89C430 z własnym bootloaderem obsúgującym dodatkowe przerwania, pod złącze klawiatury/displeja podłączony SID pod IO1, przez zatrzaski 74HCT573 i dekoder adresu 74HCT27. Pod 7 bit zatrzasku adresu (4000h w mapie movx procka, data 4001h) podłączona dioda do debugowania, pod 6 bit pin RESET układu SID. Na tej samej płytce znajduje się też transoptor 6N138 do MIDI IN i diody do MIDI OUT oraz analogowa część SIDa - kondensatory filtra oraz wyjściowy wtórnik emiterowy, a także zasilanie +9V dla części analogowej SIDA i wcześniej wspomnianego wtórnika.
    Z tym nie ma problemu. Wszystko działa ok, mogę wydawać dźwięki jakie chcę i tak samo programować rejestry SIDA. Odpowiada za to ten kod:

    Code:

    write_sid:          ;write to sid data and address latches,
                 ;also control chip enable line
    mov dptr,#sid_addr ;sid address latch
    mov A,reg          ;sid register
    movx @dptr,A       ;latch sid register address
    inc dptr          ;sid data latch
    mov A,dta          ;sid data
    movx @dptr,A       ;latch sid data
    clr sid_cs          ;enable sid
    mov R0,#cs_delay  ;\those lines determine the
    djnz R0,$          ;/length of chip select pulse low
    setb sid_cs       ;disable sid
    mov R0,#cs_delay ;\those lines determine the
    djnz R0,$          ;/length of chip select pulse high
    ret

    cs_delay equ 10h


    No i to działa pięknie, programuje sobie adres rejestru, jego wartość i już.
    Problem leży w czym innym. Port szeregowy w postaci konwertera USB<->RS232 TTL (MCP2200) jest podpięty pod UART0, natomiast MIDI pod UART1. Po uruchomieniu programu zmieniam taktowanie timera na 31250, co nie jest problemem, gdyż przy programie korzystam tylko z drugiego portu szeregowego, jakieś debugowe informacje wysyłami MIDI OUTem. Po resecie procesora UARTY wracają do taktowania 4800, tego zgodnego z USB i z kompem, do przesyłania hexów. Przerwanie portu od midi wygląda tak:

    Code:

    serial1:
    jnb TI_1,s1_rx      ;exit if int triggered by transmitter
    reti                 ;

    s1_rx:
    push acc
    push psw




    mov A,sbuf1      ;move char to acc
    jnb Acc.7,s1_data   ;jump if data was recieved (rx=0-127)
    s1_status:              ;proceed if status was recieved (rx=128-255)
    anl A,#01100000b   ;check if status was different then note on/off
    jnz s1_exit              ;and exit if it was
    mov A,sbuf1      ;move char to acc
    setb allow_note      ;next byte would be a note number
    jb Acc.4,s1_note_on   ;check for note on
    s1_note_off:      ;oherwise note off
    clr note_on
    jmp s1_exit
    s1_note_on:
    setb note_on
    jmp s1_exit

    s1_data:                      ;data byte recieved
    jnb allow_note,s1_exit   ;exit if data recieved is not suspected to be a note
    mov midi_note,sbuf1           ;save recieved note
    push 00h
    push 01h                      ;save R0 and R1
    jb note_on,buffer_add           ;add to buffer on note on
    jnb note_on,buffer_remove   ;remove from buffer on note off
    s1_data_complete:
    clr allow_note
    pop 01h
    pop 00h                   ;restore R0 and R1
    s1_exit:
    clr ri_1
    pop psw
    pop acc
    reti


    Jak widać procedura odbiera tylko sygnały NOTE ON i NOTE OFF ze wszystkich kanałów. Po odeberaniu NOTE ON wywoływane jest to:

    Code:
     
    
    buffer_add:              ;add note to buffer on note on
    mov R0,#buffer_head   ;
    mov R1,#buffer_size   ;R0=buffer location in memory, R1=size
    ba_loop:
    mov A,@R0      ;load buffer item to accumulator
    jnz ba_next      ;try next one if this isn't empty
    mov @R0,midi_note   ;save note to buffer
    jmp ba_exit      ;and exit
    ba_next:
    inc R0         ;increase memory pointer
    djnz R1,ba_loop      ;decrease counter, if buffer is full exit
    ba_exit:
    jmp s1_data_complete


    A NOTE OFF to:

    Code:
     
    
    buffer_remove:      ;remove note from buffer at note off
    mov R0,#buffer_head   ;
    mov R1,#buffer_size   ;R0=buffer location,R1=size
    br_loop:
    mov A,@R0      ;load buffer item to accumulator
    cjne A,midi_note,br_next;compare item to recieved note off and jump if not equal
    mov @R0,#0      ;otherwise fill item with zero
    jmp br_exit      ;and exit
    br_next:
    inc R0         ;increase memory pointer
    djnz R1,br_loop      ;decrease counter, exit if item wasn't found
    br_exit:
    jmp s1_data_complete


    Czyli mamy 5-elementową tablicę w pamięci, po naduszeniu klawisza(note on) pojawia się w niej jego wartość, po puszczeniu jest ona zastępowana zerem. Oczywiście wcześniej tablica jest wyczyszczona itd. Wszystko pracuje bez zarzutu.


    I TERAZ NAJWAŻNIEJSZE: W CZYM PROBLEM?
    Zacznijmy po co ta tablica: instrument jest monofoniczny i ma grać jeden dźwięk - najwyższy jeśli naciśnięto kilka, jeśli zagramy akord C-E-G ma grać G, puścimy G ma grać E, puścimy E to C, kumacie? Czyli tablica przytrzymuje naciśnięte dźwięki, a instrument wyszukuje najwyższy i go gra. Portamento itd zajmę się później.
    Z programisycznego punktu widzenia wydawało mi się, że wystarczy w pętli przeszukać największą liczbę i ustawić ją po prostu jako dźwięk do grania:

    Code:

    buffer_highest:      ;find highest note in buffer and put in A
    mov R0,#buffer_head
    mov R1,#buffer_size   ;load buffer location and size
    mov A,#0         ;clear B - max value counter
    bh_loop:
    mov B,@R0      ;load value
    subb A,B              ;A=A-B, if current value>max value then C set
    jnc bh_next      ;if not try next value
    mov A,B         ;if it does set it as new highest value
    bh_next:
    inc R0         ;next value
    djnz R1,bh_loop      ;loop until whole table is checked
    ret



    tak to wygląda. Tylko jeśli nacisnę na przykład C-D-E to z niższej do wyższej ładnie przechodzi, ale jeśli puszczę E albo D to na wyjściu pojawia się jakieś niskie 05 albo 0D! do tego gdy bezpośrednio wysyłam akumulator z tej funkcji na MIDI OUT to zamiast naciśniętego dźwięku np. 65 pojawia się zawsze o 1 mniejszy!

    Co się dzieje do jasnej kurki wodnej? caly dzień siedzę nad tym programem i nie mogę tego rozwiązać

    pozdrawiam

    0 29
  • #2 20 Gru 2011 22:48
    Jimi Hendrix
    Poziom 19  

    znalazłem rozwiązanie:

    Code:

    buffer_highest:      ;find highest note in buffer and put in A
    mov R0,#buffer_head           ;load buffer pointer to R0
    mov R1,#4                  ;numbers to compare
    mov B,@R0      ;assume first value is the highest
    inc R0
    bh_loop:
    mov A,@R0      ;move next value to A
    subb A,B          ;A=A-B
    jc bh_next        ;next value if current value was smaller then B
    mov B,@R0      ;otherwise copy it to A
    bh_next:      
    inc R0         ;increase table pointer
    djnz R1,bh_loop      ;loop until all values are checked
    mov A,B         ;copy highest value to A
    ret

    0
  • #3 25 Gru 2011 18:33
    Madman07
    Poziom 19  

    Witam.
    Zabawnie się składa, że obecnie programuję ten sam chip (tylko z użyciem PIC18F4450).

    Ja problem odpowienich częstotliwoście rozwiązałem w tem sposób:
    - numer nuty dziele przez 12, dzielenie oznacza numer oktawy, reszta to nuta w oktawie
    - w programie zadeklarowałem tablice czestotliwości jednej najwyższej oktawy - niższe można uzyskać przez zwykłe przesunięcie bitowe

    Tak z ciekawości - dlaczego zegar SID'a wydzielasz z zegara systemowego a nie np. z PWM? Ja swojego pica taktuje na 48MHz, sygnał fi2 biorę z PWM. Jednoczesnie w kodzie moge sprawdzić, czy ten sygnał miał opadający czy narastające zbocze (wczesniej na 20MHz też działało, tylko przesiadłem się z 16F na 18F ze względu na ilość pamięci w procku).

    I druga rzecz - pamiętaj, że NOTE ON i NOTE OFF może być zastąpione przez NOTE ON oraz NOTE ON z Velocity = 0 dla wyłączonej nuty w przypadku nowszych keyboardów.

    Jakie funkcje planujesz dodać w przyszłości? Ja w zamyśle mam tryb polifoniczny, monofoniczny, SYNC(np. osc1 z osc2 itp.) oraz jakiś arpeggio :)

    0
  • #4 03 Sty 2012 19:41
    Jimi Hendrix
    Poziom 19  

    Wywaliłem generator 1MHz i tak jak Ty napędzam zegar sida z mikrokontrolera (DS ma funkcję clock out na timerze 2, w przeciwieństwie do 8051, można to wykorzystać jako dodatkowy kanał do dźwięku, jednak tylko z falą prostokątną, już kiedyś tak kombinowałem). Dzięki za radę, zawsze prostszy układ. Muszę tylko podłączyć 2 piny ze sobą by na wolnym porcie badać czy mam narastające czy opadające zbocze. Zawsze lepiej niż przez pętle opóźniające. Do wgrywania programu mam przejściówkę usb-uart na MCP2200 podłączoną pod serial0, pod serial1 MIDI przez 6N138. Oprócz procka eprom z bootloaderem i ram z programem. Docelowo zostanie tylko zewnętrzny RAM (z bateryjką, do zapamiętywania ustawień, 16Kb 15ns z starej płyty głównej), program we flashu (max 16 kb są też wersje z 64). SID zmapowany jest jako 2 komórki pamięci zewnętrznej, podłączony do zatrzasków 74HCT573 (1 jako adres, reset i dioda led, 2 jako szyna danych. Zrobiłem tak bo szyna danych 6501 jest wolniejsza niż ta, dodatkowo uniezależniam zapisy do SIDa od taktowania procka (teraz 16MHZ, docelowo 32, wtedy procek osiąga 32MIPSy, większość instrukcji w 1 cyklu zegarowym) Tak samo mam tabelę z najwyższą oktawą i dzielę przez 2 (16 bitowe przesunięcie w prawo), do odbierania MIDI tak samo z dzieleniem - dzielenie oktawa, reszta nuta.
    Do odbierania danych mam 5-elementowy bufor (5 palców, wystarczająco na monofoniczny syntezator), note on dodaje wartość do buforu, note off usuwa. Każde następne note on powyżej 5 wartości jest ignorowane po prostu. Dalej procek wybiera najwyższy dźwięk z buforu i przelicza na wartość do wysłania SIDowi. O tym note on z velocity 0 to wiem, dobrze że mi przypomniałeś, muszę to dopisać.
    Załączam mój kod - chwilowo pierwszy oscylator gra odebrany dźwięk, drugi i trzeci odpowiednio oktawę i dwie oktawy niżej.
    Co do przyszłości to mam 6 tych SIDów, myślałem o polifonii i o jakimś trybie unisono, żeby wszystkie naraz ten sam dźwięk grały, fajnie by to musiało brzmieć. Mam też gotowy filtr na drabince diodowej (bardzo ciekawe brzmienie, polecam) + ADSR analogowe na 555 do sterowania go, muszę tylko podpiąć przetwornik D/A by mieć 1V/oct, brzmienie jest ciekawsze gdy cutoff filtra rośnie im wyższa nuta, z samym ADSR troche nudno. Do tego jeszcze będzie panel przedni z ustawieniami dla oscylatorów i filtra oraz klawiatura w jednej obudowie, coś na wzór minimooga - wybór kształtu fali dla każdego oscylatora, wybór 0,1,2 oktawy w dół, odstrojenie, z ADSR do końca jeszcze nie wiem. Do tego sterowanie analogowego filtra. Gdy zdecyduje się na polifonię to wybór trybu - mono/poli/unisono.
    Nie mam tylko pomysłu jak zrealizować odstrojenie każdego z oscylatorów, myślałem by dorzucić drugą tabelę z wartościami jakie trzeba odjąć lub dodać do wzorcowej wartości by odstroić oscylator o 1 cent w dół/górę. Potem oczywiście dzielenie przez 2 do odpowiedniej oktawy. To chyba najprostsze rozwiązanie by zaimplementować pitch bend/odstrojenie/portamento.
    Ty jakie masz plany? Polifonia na jednym (do 3 dźwięków) czy kilka SIDów? Jak podłączyłeś SIDa? Bezpośrednio do procka czy jakieś 74HC595 jak w MIDIBOX SID?

    0
  • #5 04 Sty 2012 18:55
    Madman07
    Poziom 19  

    Na razie mam jeden SID, za kilka dni dojdzie drugi (tylko nie jestem pewien czy ten sam model). SIDa łącze bezpośrednio do procka. Na jednym porcie mam szynę danych SIDa i wyświetlacza LCD. Wygodne rozwiązanie - nigdy nie będę wysyłał danych do 2 rzeczy naraz a i mniej pinów wykorzystam.
    Obecnie pracuje nad LCD i klawiaturą matrycową. Jako że projekt powstaje z rzeczy "które są w domu" także będą przyciski i jeden enkoder - naciskam A, D, S, R, Cutoff etc a enkoderem reguluje wartość. Właśnie niedawno skończyłem pisań fragmenty kodu do czytania literek prosto z pamięci programu (ah te wygodne mnemoniki TBLRD) :)
    Co do trybów to planuje tradycyjny RINGMOD, Tryb POLI1 (6 niezależnych dźwięków), POLI2 (2 lub 3 niezależne dźwięki), MONO (prawdopodobnie zastąpiony trybem POLI2), SYNTH. Zastanawiam się nad LFO. Generować to bezpośrednio w procesorze, czy np. wykorzystać oscylator nr. 3?
    Dobry pomysł z tak dużym buforem, ja obecnie mam tylko potrójny (komenda, nuta, natężenie). Czy w tych buforach przechowujesz też komendy? Zamierzasz dodać możliwość grania kanałami? Np. powiedzmy ustawiam sobie 2 niezależne kanały (1 i 3 - w moim keyboardzie w sam raz dla Leadu i Basu), każdy z 2-3 niezależnymi nutami (w zależności od użycia Oscylatora nr. 3).
    Hmm, też się zastanawiałem nad modulatorem Pitch. Może wziąć różnicę pomiędzy dwoma dźwiękami i w jakiś sposób ją dzielić?

    0
  • #6 04 Sty 2012 22:01
    Jimi Hendrix
    Poziom 19  

    wygląda to tak dla każdego dźwięku w stroju równomiernie temperowanym: A to 440Hz, A# to 466,16Hz czyli pierwiastek 12 stopnia z 2 wyższa częstotliwość. 1 cent wyżej to częstotliwość wyższa o pierwiastek 1200 stopnia z 2. Wartość, którą należy wpisać do SIDa, określająca częstotliwość oscylatora to: częstotliwość dźwięku * 0,0596. Także jak widzisz wymaga to obliczeń zmiennoprzecinkowych, które zabierają sporo cykli procesora. Problem z nutami wynika z tego, że zależność między dźwiękami nie jest liniowa, tylko wykładnicza.
    Do odstrojenia rozwiązanie które wcześniej podałem z tabelą będzie chyba najlepsze.

    Ja ringmod wywalę na przedni panel, tak samo sync i kształt fali.
    LFO generuj w procesorze, wykorzystując oscylator nr 3 musisz się paprać z odczytami z sida (u mnie jest to i tak niemożliwe, bo zatrzaskuje dane), nie widziałem projektu syntezatora, który by wykorzystywał 3 oscylator. Tylko programy na C64. Lepiej programowo, robisz jak chcesz, prosto jest to oprogramować wykorzystując timery (zależy od fali jaką chcesz modulować, w sumie dopiero do sinusa musisz robić jakieś odczyty z tabeli, dla prostokąta, trójkąta czy piły wystarczy jak będziesz zmieniał wartość z 255 na 0, zwiększał od 0-255 albo zwiększał od 0-255 i potem zmiejszał w drugą stronę. Dopiero do sinusa musi być tabela i dds), , nawet ten którym taktujesz MIDI. Pozatym wykorzystując oscylator 3 masz tylko 8-bitową rozdzielczość, no i niejako poświęcasz na ten cel jeden kanał sida. Naprawdę podaruj sobie.
    Bufor mam tylko do przechowywania numeru dźwięku, nie ma sensu przechowywać komendy, lepiej ustawić w przerwaniu jakąś flagę i potem w programie to implementować. Bufor do numeru dźwięku jest konieczny gdy zakładasz więcej niż 1 klawisz naciśnięty, by potem w programie wybrać ten najwyższy lub najniższy by go zagrać albo do polifonii. Nawet w monofonicznym syntezatorze są momenty gdy masz 2 note on, jak grasz legato na przykład. Przerabiałem to, tabela i podprogram wybierający największą wartość są konieczne.
    Do tego konieczne są jeszcze zmienne, w których będziesz przechowywał aktualne ustawienia SIDa, przy odczycie klawiszy sterujących sprawdzasz czy otrzymane dane różnią się z tymi zapisanymi, jeśli tak to wysyłasz nowe dane do SIDa i uaktualniasz zmienne. Przez to unikasz niepotrzebnego wpisywania danych.
    Nie zamierzam dodawać możliwości grania kanałami, bo tak jak mówiłem instrument ma być razem z klawiaturą. MIDI podłączyłem tylko tak do testów, ale pewno zostanie bo fajnie mieć możliwość edytowania ustawień przez MIDI, no i chciałbym jeszcze wysyłać note on/off z wbudowanej klawiatury, do sterowania czymś innym.
    Pitch tak jak mówiłem - masz 16-bitową wartość odebraną przez MIDI, sensownie by było pitchem przestrajać powiedzmy oktawę w górę/dół - czyli 1200 centów, powiedzmy że o 1024 bo ładnie potęga 2. Cholera nie pamiętam czy pitch bend jest wysyłany w postaci ze znakiem czy bez. No ale wywalasz 6 bitów z tej wartości (przesunięcie w prawo, zachowując wcześniej 16 bit znaku by wiedzieć czy bend jest w górę czy w dół), mnożysz tyle razy przez wartość odczytaną z tabeli dla danego dźwięku (jak to nazwałem "przesunięcie centowe" :) ) i otrzymaną wartość dodajesz do częstotliwości danego dźwięku najwyższej oktawy i potem tradycyjnie dzielisz przez 2 tyle razy ile oktaw w dół. Dla pitch bend w dół odejmujesz. Podobnie chcę zaimplementować portamento.
    Pytaj jak chcesz coś jeszcze wiedzieć, ja się do tego tematu przez 4 lata przygotowywałem, zrobiłem midibox sid, teraz wreszcie coś sensownego na tym 8051 klecę. Kombinowałem z tym sidem coś nawet na C64, no ale assemblera 6501 nie lubię strasznie i C64 trochę niewygodne.
    pozdrawiam

    Dodano po 2 [minuty]:

    Właśnie, bym zapomniał - wykorzystujesz jakoś velocity z komunikatu midi on? ja nie mam dynamicznej klawiatury to i tak mam 64 cały czas, ale myślałem by to użyć na przykład do regulacji cutoff albo wziąć 4 bity z tego i bezpośrednio wysłać do rejestru SIDa odpowiadającego za głośność. Byłby jakiś zalążek dynamiki, a tego w syntezatorach na tym układzie nie widziałem :)

    0
  • #7 05 Sty 2012 20:00
    Madman07
    Poziom 19  

    Ja się około miesiąca przygotowywałem. Podstawowy koncept jest, zostało mi wszystko oprogramować. Miałem lecieć w C, ale jak zobaczyłem jaki kompilator czasami daje kod to się wystraszyłem :) W każdym razie ja na panel daje wszystko jako przyciski.
    Raczej nie planuję wykorzystania velocity. No chyba, że do ustawiania parametru Sustain, musiałbym spróbować, jak by to brzmiało. Może i nawet przyzwoicie, chociaż problemem było by tu to, że na początku dźwięk i tak narasta do wartości max.
    Nie wiem czy to tylko ja mam taki problem, z bitem GATE. Gdy go ustawiam to oscylator się włącza, obwiednia ADSR jest wywołana. W momencie gdy go zeruję, dźwięk gra dalej. Tak mam w ok 75% przypadków. Czasami po wyczyszczeniu bitu obwiednia ADSR jest wykonana do końca i dźwięk prawidłowo milknie...
    Pisałeś, że wykorzystasz zew. pamięć RAM + bateryjka. Nie lepiej jakiś zewnętrzny EEPROM? Albo, jak w moim pierwotnym zamyśle karta pamięci? Była by od razu możliwość modyfikacji ustawień spod komputera. Albo USB + jakieś oprogramowanie na PC. Chociaż dla mnie to tak średnio przydatne, syntezator planuje wykorzystać do grania realtime samemu bądź z zespołem muzycznym :)

    0
  • #8 05 Sty 2012 21:31
    Jimi Hendrix
    Poziom 19  

    Spróbuj ustawić parametr sustain w ADSR na 0, to on odpowiada za "potrzymanie" dźwięku po wyzerowaniu gate. Ciekaw jestem czy u Ciebie w tym tkwi problem.
    Zastosowałem RAM bo w procku jest do niego dedykowany kontroler, łatwiej to można i szybciej oprogramować niż kartę czy eeprom. Nie zapomnij że w 8051 nie ma sprzętowego SPI czy I2C, więc by trzeba było ręcznie wystawiać po kolej wszystkie bity, co by niepotrzebnie wydłużyło czas ładowania patcha. No i jeszcze konieczne do tego opóźnienia.
    Też planuję wykorzystać do grania realtime, stąd jak najbardziej przyjazny interfejs, z możliwością regulowania wszystkich parametrów w czasie grania.
    No C czasem straszne głupoty wytwarza.
    USB mam do ładowania oprogramowania.
    Do sustain? jak?

    pozdrawiam

    0
  • #9 06 Sty 2012 14:01
    Madman07
    Poziom 19  

    Nie nie, to nie pomaga. W tych większości przypadków SID nawet nie reaguje na obwiednię ADSR, nie mam pojęcia dla czego. Mało tego, czasami też nie reaguje na ustawienie bitu GATE :) Zasilanie dobrze odfiltrowane jest, komunikacja musi być ok , bo wyświetlacz pracuje bez problemów a ma wspólną szynę danych.

    A no tak, że velocity odpowiada za wartość Sustain. Chociaż jak mówię, trzeba by to wpierw przetestować.

    0
  • #10 06 Sty 2012 17:07
    Jimi Hendrix
    Poziom 19  

    Ja nigdy nie miałem z tym problemu. Spróbuj wydłużyć czas trwania chip select.

    0
  • #11 06 Sty 2012 17:25
    Madman07
    Poziom 19  

    Nic nie zrobiłem a układ zaczął cudownie działać. Może po prostu są zakłócenia gdzieś? Wiadomo, jak to wszystko wygląda na płytkach stykowych...
    Tak z ciekawości, jak u Ciebie będzie wyglądał panel główny? Potencjometry? Enkodery jak w midiboxie? Tradycyjny LCD 2x16 znaków?

    0
  • #12 07 Sty 2012 22:01
    Jimi Hendrix
    Poziom 19  

    Potencjometry i przełączniki typu "rocker". Nie będzie wyświetlacza.
    Dzisiaj wreszcie odnalazłem śmieszny błąd, otóż gdy oscylator grał oktawę niżej nie stroił. Okazało się, że przy odejmowaniu numeru dźwięku o 12 zapomniałem wyczyścić znak przeniesienia, teraz wszystko jest ok. Tylko muszę zainstalować D/A, panel przedni i zbliżamy się do końca.
    Pozdrawiam

    Dodano po 1 [godziny] 24 [minuty]:

    załączam fotografię:
    Syntezator MIDI, SID 8580 [8051][Asembler]

    mała żółta płytka to konwerter usb-uart (na MCP2200, polecam ten układzik, rewelacja i w przyjemnej obudowie), jasnozielona płytka to zasilacz stabilizowany 5 i 9V, zasilany transformatorem TS25/11 (w końcowej wersji zamówię toroid z napięciami 7V,12V i 2x15V do filtra i analogowego ADSR), płytka po lewej to AVT2250, z epromem 2716 zawierającym bootloader, prockiem DS89C430, SRAMem DS1230 z bateryjką wewnątrz, MAX232 jest wyjęty i zamiast niego jest konwerter, płytka uniwersalna zawiera dwa 74HCT573 (drugi jest po SIDem) i samego SIDa 8580 wraz z częścią analogową i kondensatorami do filtrów (polecam podłączenia wyjścia sida, tego za wtórnikiem emiterowym do jego wejścia przez potencjometr, można dzięki temu go przesterować i uzyskać ciekawy efekt dźwiękowy), 74HCT27 - bramkami użytymi do dekodowania adresu i interfejsem MIDI na 6N138 (widać na zdjęciu złącza din). Płytki są połączone 14-żyłowym kablem, prowadzącym zasilanie części cyfrowej, szynę danych i wybieranie adresu. Oryginalnie w tej płytce prototypowej do tego złącza podłączona jest klawiatura z wyświetlaczem led. Wolne kabelki zielony i biały prowadzą do SIDa zegar i chip select.
    Planuję później zaprojektować i wykonać płytkę z procesorem wraz z otoczeniem i przetwornikami d/a i a/d. SID raczej będzie na osobnej płytce, nie zdecydowałem się jeszcze ile ich w końcu ma być. Zegar mikrokontrolera zwiększę chyba do 24MHz jak dołożę te sidy, żeby się wyrobił z obliczeniami jak zaimplementuję odstrajanie poszczególnych oscylatorów i panel przedni.

    Używasz SIDa 8580 czy 6582? Planujesz też dodać zewnętrzny filtr?
    pozdrawiam

    0
  • #13 07 Sty 2012 22:37
    Madman07
    Poziom 19  

    Jeżeli zamierzasz robić to w taki sposób, że np. dany potencjometr reguluje np. parametr A obwiedni, a przełącznikiem zamierzasz przełączać który z oscylatorów ma podlegać regulacji to ostrzegam - jest to nieco problematyczne. Swojego czasu zrobiłem prosty kontroler midi z regulacją głośności, balansu itp. oraz z przełącznikiem shift dla zwiększenia liczby obsługiwanych kanałów. W momencie przełączenia nigdy nie wiedziałem, jak były ustawione kanały i pojawiał się problem :)

    Obecnie mam jedną kość 8580. Mam nadzieje że druga (której jeszcze nie widziałem) to też ta sama. Nie, nie planuje żadnych filtrów na chwilę obecną. Chociaż mam pomysł - dostać jakąś prostą kość opóźniającą i wtedy dodać sprzężenie zwrotne. Ciekawy efekt by mógł powstać :) A bezpośrednie połączenie wejścia i wyjścia przywodzi mi na myśl jakiś efekt pogłosu jeśli się nie mylę :)

    0
  • #14 07 Sty 2012 23:12
    Jimi Hendrix
    Poziom 19  

    Co do linii opóźniającej to polecam zaopatrzenie się w 3, zrobienie układu do przesuwania fazy o 0,120 i 240st i taktowanie układów sprzężoną wolną i szybką częstotliwością. Powstanie wtedy efekt typu "ensemble" stosowany w wintydżowym instrumencie Solina String Ensemble. Brzmienie jest wtedy kapitalne.

    No, 8580 są znacznie cichsze niż 6582 i nie mają problemu z włączaniem kilku fal naraz. Oczywiście włączenie którejkolwiek z fal razem z sygnałem noise powoduje zablokowanie oscylatora. Niemniej jednak spróbuj na przykład włączyć jednocześnie piłę i trójkąt, co produkuje ciekawe efekty brzmieniowe, zastanawiam się czy nie wywalić tego na przedni panel.

    Nad regulacją ADSR się zastanawiam, na pewno 4 potencjometry dam do analogowego ADSR którym będę sterować zewnętrzny filtr. W SIDach jest to tylko 4-bitowe także nie wiem czy nie zastosuję po prostu obrotowego przełącznika.

    Panel przedni ma wyglądać tak: dla każdego oscylatora dokładna regulacja strojenia, zgrubny przełącznik oktawy (oktawę, 2 oktawy w dół albo 0)i obrotowy przełącznik kształtu fali (szum, trójkąt, prostokąt, piła, wyłaczony). Czyli razem 6 potencjometrów i 3 przełączniki. Do tego ADSR dla zewnętrznego filtra, resonance i cutoff zewnętrznego filtra. To daje dodatkowe 6 potencjometrów. 1 potencjometr glide, przełącznik trybu (mono, poli, unisono) no i regulacja głośności oraz wybór trybu filtru (dolnoprzepustowy, środkowoprzepustowy, pasmowy). Razem 15 gałek i 4 przełączniki + jeszcze nie wiem co z ADSR SIDa.
    Chcę jeszcze może LFO do modulacji PWM oscylatorów, bardzo ciekawy efekt. Do tego pitch bend po lewej stronie + modulacja LFO.

    Filtr mam taki:
    Link
    Polecam budowę, naprawdę prosta konstrukcja, a rezultat ciekawy. Nie używałem CA3046 (UL1111), mam dobrane w parę tranzystory. Zobaczę jaki będzie efekt końcowy, narazie próby wypadły pomyślnie, nie wiem jak po dołączeniu sterowania z klawiatury, może zdecyduje się na filtr mooga na drabince tranzystorów.

    Ty ile będziesz mieć kontrolek? Nie będzie Cię męczyć regulacja wszystkiego enkoderem? Polegasz tylko na zaprogramowanych ustawieniach, będziesz mieć możliwość szybkiej regulacji "w locie"? Naprawdę polecam potencjometry, zwłaszcza że masz przetwornik AD w procku. Ja muszę dorzucić przetworniki A/D i D/A do kontroli filtra i odczytu położenia potencjometrów, zapewne z dwoma 4051...

    0
  • #15 07 Sty 2012 23:29
    Madman07
    Poziom 19  

    Ja ten projekt traktuję jako taki mniejszy, także nie przesadzam z ilością bajerów. Następnie mam ochotę zabrać się za dsPIC i na tym 16 bitowym sygnałowym procku zrobić syntezator z prawdziwego zdarzenia. Wtedy wszelka pomoc będzie mile widziana jako że będę musiał pisać wszystko od podstaw. I wszystko będzie robione programowo. Wg zamysłu część sprzętowa to tylko enkodery, LCD, DAC...

    A tak, próbowałem włączać 2 oscylatory jednocześnie. Ładnie to brzmi. Akurat testowałem Trójkąt i piłę. Próbowałem też prostego LF0 (piła) do modulacj PWM - bardzo ładnie to brzmiało. Podejrzewam że docelowe LFO dla modulacji PWM, parametrów filtra Resonans i Cut Off wyjdzie nieźle. Zastanawiam się też, czy takie LFO można podpiąć pod parametr Sustain oraz Pitch - naprawdę niezłe efekty mogły by wyjść z tego.

    Około 16 przycisków i enkoder z przyciskiem. Rozważałem potencjometry (co by było bardzo wygodnym rozwiązaniem) ale ostatecznie odrzuciłem je właśnie ze względu na efekt "przełączania kanałów" - tzn. ustawiając parametry jednego oscylatora i przechodząc do kolejnego, po powrocie nie wiadomo jak potencjometry były ustawione. Może w następnym projekcie je wykorzystam. U mnie będzie to działać na zasadzie "wciśnij przycisk i kręć enkoderem". Czyli jak najbardziej edycja "jedną ręką" (druga naciska klawisze żeby przetestować dźwięk) w locie z dodatkową możliwością zapisu/odczytu wcześniejszych ustawień. Oczywiście jeszcze dłuuga droga przede mną, wiele godzin programowania.

    Raczej zrezygnuję z filtra, wolę czysty dźwięk SID'a. Tak ogólnie ja zamierzam polegać głównie na samym SID'zie (w przeciwieństwie do Ciebie :). Chociaż skłaniam się ku kostce AN7322 znalezionej w jakiś biurkowych głośniczkach. Na jej wejściu daje się sygnał mono, na wyjściu jest stereo. W dodatku są do wyboru trzy konfiguracje oraz łatwo można to sterować z procesora. Musze tylko przetestować, jakie efekty są dostępne. Ewentualnie ustawiłbym jeden na gotowo bez możliwości zmiany.

    Ciekawostką jest fakt, że obecnie jestem na granicy wolnych pinów w procesorze. Jeszcze kilka pomysłów mi podrzucisz, i będę musiał używać rejestrów przesuwnych :P

    0
  • #16 07 Sty 2012 23:48
    Jimi Hendrix
    Poziom 19  

    Ano z tymi enkoderami bardzo fajny kompromis. Ja daję te potencjometry do regulowania wszystkiego w locie, bo ma ta konstrukcja mieć jak najwygodniejszą regulację. Przeraża mnie tylko perspektywa dodawania przetwornika A/D i multipleksera na szynę danych i potem lutowanie całego okablowania do przedniego panelu, szycia wiązek z kablami :). Z klawiszy mam tylko starego Hammonda, brakuje mi syntezatora.
    dsPIC widzę bardzo fajna maszyna, możesz sobie wszystko programowo, filtry, dds do syntezy, midi programowo zaimplementować. Jak dla mnie tylko strasznie dużo pisania kodu, a ja noga z matematyki i przetwarzania sygnałów jestem.
    Jak używasz procka z sprzętowym SPI to zrób sobie "sid module" z strony ucapps.de, możesz sobie kilka sidów dać i tylko linią CS je aktywować :).
    Ten AN7322 z tego co znalazłem w Internecie to oferuje jakieś live stereo czy coś. Na czym to polega?

    Dodano po 2 [minuty]:

    SID naprawdę super jest, ma brzmienie bardziej jak syntezator, a nie jak jakaś komputerowa popierdółka. I to jak analogowy, Z tego co testowałem z klawiszem to soczyste, mięsiste brzmienie, zwłaszcza w zakresie średnich i niskich częstotliwości.

    0
  • #17 08 Sty 2012 17:25
    Madman07
    Poziom 19  

    Jeżeli zamierzasz dać potencjometr do wszystkiego, bez żadnych przycisków "shift" to to jest najlepsze rozwiązanie. Ale wolę nie myśleć, ile to może miejsca zająć. Ja mam małą obudowę 10x15cm, od 1 do 5 cm wysokości. A może łatwiej było by nawet porysować pisakiem panel przedni (płytkę) i to wytrawić a potem puścić tylko taśmę do głównej płytki? albo nawet na tym panelu umieścić przetworniki A/D ?

    Tak nie za bardzo, nie mam wolnych procesorów pod ręką, a konstrukcja ma być zrobiona z części znalezionych w domu. Z tego też powodu męczę się z badziewnym enkoderem. Zwykłe enkodery przy każdym "cyknięciu" zmieniają swój stan wg kodu graya. Mój odpala całą sekwencję przy tym cyknięciu (tzn 00 01 11 10) także mam lekkie problemy z implementacją tego. Chyba będzie trzeba wykorzystać 2 zew. przerywania z detekcją zbocza.

    Nie miałem czasu jeszcze odpalić tej kostki, ale pochodzi z biurkowych głośniczków. Podejrzewam że w jakiś sposób może przesuwać fazę sygnałów aby zrobić "pseudo stereo".

    Ja osobiście jeszcze filtrów nie testowałem, a jestem ciekaw jak to z nimi wyjdzie :)

    0
  • #18 08 Sty 2012 20:44
    Jimi Hendrix
    Poziom 19  

    Myślę, że wystarczy mi 8 potencjometrów, które będę musiał odczytywać cyfrowo (6 do odstrojenia, regulacja resonance i cutoff filtra wewnetrznego). Reszta analogowo, to nie potrzeba 2 multiplekserów, wystarczy mi 1 przetwornik i 1 cd4051. Panel przedni zrobię chyba z laminatu A4. Warstwę miedzi użyję jako masę, wtedy do potencjometru pójdzie tylko +5V i wyjście ze ślizgacza. Można nawet wytrawić i zrobić miejsce na ten multiplekser w SMD. Nie wiem jeszcze, najpierw kupię potencjometry 10kA i jakoś prowizorycznie to podłącze. Przetwornik myślę zmieści się na płytce z SIDem, będzie łatwo szynę danych pociągnąć.
    Nie wiem tylko ile bitów potrzebuję do przetwornika tym razem cyfrowo-analogowego, by uzyskać 1V/oct. Wiesz może? W midiboxie stosują 8 bit, mam ten przetwornik co tam jest, tylko bym musiał programowe SPI zaimplementować. Chyba naprawdę czas się tymi PICkami zająć co mają wszystko wbudowane, mam zresztą 18F452, 18F4620, 18F4550, a nawet zrobiłem kiedyś programator brenner8. Ten assembler picowy jest tylko obrzydliwy, nie lubię asma na procesory RISC. A C się nie chce uczyć. x86 też w asmie programowałem, od tego zaczynałem.
    Cały instrument będzie prawdopodobnie nie większy niż kartka papieru. Nawet bez dedykowanych płytek i z takim syfem jak jest teraz by się zmieściło.
    Daj sobie spokój z tą kostką, wątpie czy rzeczywiście będzie jakiś wymierny efekt. Zrób lepiej filtr mooga czy ten na drabince diodowej steinera albo z ems synthi, bądź jakiś phaser. To są efekty które fajnie brzmią z syntkami.
    Sam filtr, po sztywnym wpisaniu do niego wartości obcina wysokie częstotliwości, tak jakbyś kondensator do wyjścia podłączył. Operowany dynamicznie to zupełnie inna bajka. Musisz mieć parę rzeczy do filtra:
    -wartość cutoff musi rosnąć logarytmicznie z numerem kolejnego klawisza. Czyli być mniej więcej proporcjonalna do częstotliwości dźwięku
    -po drugie musisz mieć ADSR osobny do filtra by miało to ręce i nogi. To on w połączeniu z filtrem odpowiada za klasyczne brzmienie syntezatorowego basu. Przy użyciu timera nie powinieneś mieć kłopotu z programowym ADSR. Tak jak mówiłem nie polecam używania trzeciego oscylatora, marnujesz wtedy jeden kanał, ma to tylko sens w gównianym C64 (z całym szacunkiem dla tej maszyny) gdzie masz mało mocy obliczeniowej. Serio, wystarczy tylko zapisywanie do SIDa. Przetwornik do odczytywania położenia potencjometrów w SIDzie jest gówniany, polega na pomiarze czasu rozładowywania kondensatora.
    -regulacja resonance, czyli sprzężenia zwrotnego filtru na przednim panelu - przesuwa brzmienie w kierunku wiekszych czestotliwości, w sidzie tak nie ma chyba, ale w innych filtrach przy ustawieniu resonance na maksa filtr oscyluje, przy dobrze zestrojonym filtrze można na nim "grać" przy użyciu klawiatury
    -ewentualnie sprzężenie LFO z cutoff filtra
    -no i musisz to wszystko programowo zmiksować i regulować tym cutoff. W SIDzie chyba cutoff jest 11 bitowe.

    Zaskoczyłeś mnie z tym enkoderem, kilka razy się tym bawiłem i zawsze po jednym kliknięciu był jeden skok w kodzie graya. Raz mi się przydarzyło przy jakimś enkoderze z DVD gdzie śmieci się pojawiały na wyjściu.

    Fajnie jakbyś załączył fotkę jak to teraz wygląda.

    0
  • #19 08 Sty 2012 22:26
    Madman07
    Poziom 19  

    Jakoś nie mam przekonania do laminatu. Ja obecną obudowę mam zrobioną z paneli podłogowych (twardych, nie tych miękkich ściennych) i aluminum + czarna matowa farba. Panel przedni jeszcze nie jest poprawiony, tzn. ma układ do starego kontrolera midi który okazał się bezużyteczny. Muszę zrobić nowy panel.

    Ogólnie programowanie PIC16 w asm jest średnie. Ale PIC17 i wyżej to już bajka. Rozszerzone instrukcje, (przede wszystkim TBLRD, czy CPFSEQ do porównywania wartości używając jednej instrukcji). No i nie ma tutaj już bankowości i ciągłej potrzeby przerzucania się między bankami. Co jak co, nie ogarniam ich środowiska programistycznego MPLAB. Jeżeli posiada się więcej niż 2 pliki asm (ja np. mam ok 5-6, podzieliłem na rzeczy takie jak LCD, klawiatura, SID dla przejrzystości) to są niezłe problemy z kompilacją. Dlatego ja korzystam z Notepad++ i ręcznie kompiluje w MPASMWIN. Do tego mam programator PICKI2 na USB z którego mogę zasilać układ.

    Nie, nie mam ochoty robić jakiś dodatkowych rzeczy. Ogólnie to ja wole więcej programować, niż dawać elektroniki. Jeżeli ta kostka nie będzie dobrze brzmiała to po prostu dźwięk z SID'a bezpośrednio pójdzie na lewy i prawy kanał. Chociaż skoro była używana w głośniczkach to powinna być ok przy odpowiednich ustawieniach. Tak czy siak oryginalny dźwięk SID'a jest w sam sobie świetny i nie powinno być potrzeby go poprawiać :) Tak, 3 oscylatora nie będę używał do LFO, to już zdecydowałem.

    To jest enkoder z jakiegoś starego monitora CRT. Kod wygląda ok, zakłóceń nie ma, ale cuda się dzieją. Obecnie mam 2 przerywania zewnętrzne na opadające zbocze. Teoretycznie gdy jedno zostanie wywołane to czeka na drugie, i wtedy jest ustawiana flaga, że enkoder został poruszony w danym kierunku. Często gdy kręcę w jedną stronę widzę na LCD, że czasami wskazuje obrót w drugą stronę itp. Masakra, chyba będzie trzeba zainwestować w zwyczajny enkoder.

    W tej chwili nic szczególnego, Pic18F + SID + wejście MIDI (ha, zbudowane na diodzie IR i tranzystorze IR) + wyjście SID'a + stabilizator 9V, 5V + klawiatura matrycowa wyjęta z telefonu stacjonarnego (tylko do testów). Wszystko na płytce stykowej, także bałagan niemiłosierny :)

    Dodano po 54 [minuty]:

    Udało się. Wreszcie enkoder działa jak powinien, a kod był banalnie prosty. Po prostu w momencie gdy zadziała narastające zbocze sprawdzam, czy drugi pin jest w stanie wysokim. Jeżeli tak to enkoder kręci się w daną stronę.

    0
  • #20 09 Sty 2012 12:11
    Jimi Hendrix
    Poziom 19  

    Laminat tylko tymczasowo, może kiedyś się doczeka blachy.
    Będę dzisiaj pisał kod programowego ADSR do filtra, podzielę się później, zawsze łatwiej. Muszę tylko pomyśleć nad doborem czasów. Chyba wykorzystam te z SIDA, chociaż jakieś dziwne są, przydługie trochę. Spróbuję podpiąć się pod timer taktujący MIDI, nie pamiętam tylko czy tak można w 8051, zobaczymy. Mam jeszcze jeden wolny w sumie, jeden do midi, jeden bezużyteczny, bo generuje zegar dla SIDa, a wtedy nie może przerwań generować.
    LFO jaki kształt fali planujesz? Zazwyczaj jest sinus, ale nie wiem czy trójkąt by nie wystarczył do prostej modulacji, z lekko wydłużonym minimum i maksimum. Wiesz o co chodzi, jak prostokąt z łagodnie narastającymi i opadającymi zboczami. Odpada mi wtedy czytanie sinusa z tabeli.
    Ciekawe rozwiązanie z tym fototranzystorem i diodą. Taki perfidny transoptor :) Kup sobie PC900 6N138 albo 137 dorzuć rezystor 220om i diodę antyrównolegle do tej w transoptorze, żebyś miał to wszystko zgodne ze specyfikacją MIDI. To pętla prądowa i wszystko jest dosyć ściśle zdefiniowane. Lepiej żeby działało z każdą klawiaturą. Chociaż sam parę razy olewałem ten transoptor i po chamsku od razu do procka dawałem. Miałem nawet kiedyś firmowy (!) interfejs midi-gameport bez żadnej izolacji. I działało.
    pozdrawiam

    0
  • #21 09 Sty 2012 14:35
    Madman07
    Poziom 19  

    Ja bym ustawił timer na najmniejszą działkę (np. 1ms albo 0.5ms) i dzięki temu można go zastosować do wielu dźwięków jednocześnie.
    O sinusie raczej nie myślałem. Trzeba by wyżej wspomnianą tabelkę (albo obliczenia na żywca, może byłby jakiś użytek ze sprzętowego modułu mnożenia). Raczej piła/trójkąt/prostokąt. W razie czego zawsze można dla trójkąta zrobić, że po przekroczeniu danej wartości jego narastanie jest wolniejsze, ot taka imitacja sinusa.

    0
  • #22 10 Sty 2012 22:24
    Jimi Hendrix
    Poziom 19  

    Noo i chyba taką "imitację" sinusa zrobię.

    Miałeś rację z tym, że lepiej badać linię CLK i zbocze narastające zegara. Przy wcześniejsze procedurze zapisu do SIDa, pochodzącej jeszcze z czasów gdy miałem zewnętrzny oscylator, losowo wyłączał/załączał się GATE. Dlaczego akurat on to nie wiem. Dlatego zmieniłem procedurę - najpierw czekam aż zegar będzie=0, potem czekam na narastające zbocze, ustawiam wtedy CS=0, czekam jeden okres zegara i 2 nop'y, potem ustawiam CS=1. No i działa.

    Code:


    write_sid:      ;write to sid data and address latches,
             ;also control chip enable line
    mov dptr,#sid_addr   ;sid address latch
    mov A,reg      ;sid register
    movx @dptr,A      ;latch sid register address
    inc dptr      ;sid data latch
    mov A,dta      ;sid data
    movx @dptr,A      ;latch sid data
    jb sid_clk,$      ;wait for clk falling edge
    jnb sid_clk,$      ;wait for clk rising edge
    clr sid_cs      ;enable sid
    jb sid_clk,$      ;wait for clk falling edge
    jnb sid_clk,$      ;wait for clk rising edge
    nop
    nop
    setb sid_cs      ;disable sid
    ret


    Mam nadzieję, że dzisiaj jeszcze te ADSR ruszę, na razie nad tym gatem pracuję.

    Pytanie jeszcze o MIDI - możesz dokładnie opisać co robisz w przerwaniu portu szeregowego? Bufor jakiś? Rozwiązałeś problem naciśnięcia kilku klawiszy naraz? I opisz co robisz po puszczeniu klawisza.

    0
  • #23 10 Sty 2012 23:46
    Madman07
    Poziom 19  

    Ja mam bardzo podobną procedurkę wysyłania danych do SID'a. Tylko mam więcej nop'ów z racji wyższej częstotliwości zegara. Muszę ją nieco uprościć, trochę zagmatwana jest, i przede wszystkim usunąć te delay'e, nie wiem czemu je tam dałem :P

    Kod: asm
    Zaloguj się, aby zobaczyć kod


    W samym przerywaniu mam 3 elementowy bufor (używam adresowania niebezpośredniego żeby wpisywać do niego dane - i tuaj zakładam jak na razie, że dane przychodzą paczkami po 3, będe to musiał zmienić w razie gdyby przyszedł 2 bajtowy komunikat CC). Jeżeli wpisałem ostatnie pole do bufora, to adres aktualnej pozycji bufora powraca na pozycję początkową i ustawiam flagę, że dane są gotowe do przetworzenia. To samo mam przy naciskaniu/puszczaniu klawisza. W programie głównym po prostu sprawdzam, jakie było velocity i już.
    Trochę brzydka metoda, bo w chwili gdy pętla główna zajmie więcej czasu niż następne naciśnięcia klawiszy - tracę informacje. Myślę że stosowne będzie tutaj użycie następnego przerywania, tak jak to robię z enkoderem. Tzn. w głównym przerywaniu tylko odczytuję w którą stronę go obróciłem, a w tzw. Low Interrupt inkrementuje/dekrementuję liczby. Takie rozwiązanie ma sens o tyle, że mogę się zająć zmianą wartości liczb spokojnie a w przypadku np. gdy przyjdą dane midi to one i tak będą miały pierwszeństwo.

    0
  • #24 12 Sty 2012 10:49
    Jimi Hendrix
    Poziom 19  

    Zmiana planów - attack/release zamiast ADSR do wewnętrznego filtra. Najprościej jak się da, jak w ARP Odyssey i Micromoogu. Dwie gałki mniej.

    Ja bym zrobił tak (i tak zrobiłem) - w przerwaniu uart'a przenoszę odebrany bajt do akumulatora. Jeżeli najstarszy bit jest ustawiony - wtedy odebrano status, jeśli wyzerowany dane. Analizuję status czy jest note on czy off i ustawiam pomocniczy boolean note_on/note_off. W następnym przerwaniu przychodzą dane - wtedy w zaleznosci od ustawienia zmiennych dodaję albo usuwam dane z bufora i ustawiam pomocniczą zmienną "coś się zmieniło" :). Trzeci bajt i kazdy inny jest ignorowany - jeśli nie jest ustawiona zmienna note_on albo note_off, albo najstarszy bit=1.
    W głównej pętli sprawdzam czy "coś się zmieniło", jeżeli było to note off sprawdzam czy bufor jest pusty, jeśli tak to ustawiam GATE=0, jeśli nie to znajduje najwyższą wartość w buforze, przeliczam częstotliwości itd. Dla note on znajduje najwyższą wartość, przeliczam, ustawiam gate.
    Fajną funkcją w 8051 jest możliwość ustawiania priorytetów przerwań, ustawie sobie serial na najwyzszy, wtedy timer mi nie przeszkodzi.

    Wyczyściłem też klawiaturę, którą chcę zastosować, co dziwne, ma 7 wierszy po 7 klawiszy, no i diody wbudowane pod każdym oczywiście. Nie wiem czy nie kupię czegoś innego na allegro, mniejszego. Trochę za duże wyjdzie przy 4 oktawach.

    0
  • #25 12 Sty 2012 14:25
    Madman07
    Poziom 19  

    Jestem ciekaw jaki jest dokładnie odstęp pomiędzy kolejnymi komunikatami. Od tego właściwie zależy sposób wykonania przerywania.

    Myślałem, że będzie to klawiatura nx6 albo nx12. Wydaje mi się, że będzie ok, raczej nie jest za duża. Popularne w takich syntezatorach są też klawiatury 3-oktawowe, ale 4-oktawy to już powinien być wypas.

    0
  • #26 12 Sty 2012 15:37
    Jimi Hendrix
    Poziom 19  

    no 3 by bylo idealnie. I taka podnoszona obudowa z bokami z drewna jak w minimoogu :)

    31250 bitów na sekundę, 8 bitów danych, 1 bit startu i 1 stopu. Co razem czyni 10 bitów, czyli przerwanie wywoływane jest z częstotliwością 3125 Hz, czyli co 320 us. Przy moich 12 MIPSach daje to przerwanie co 3480 cyklów zegara :) Oczywiście zakładając brak przerwy między poszczególnymi bajtami, co raczej jest mało prawdopodobne. Zależy to od sposobu działania programu w klawiaturze, czy są te dane wysyłane bajt po bajcie, ze sprawdzaniem flagi, czy w przerwaniu uaktywnianym po wysłaniu każdego bajtu, gdzie sczytywane są z bufora i wysyłane.
    W każdym razie dużo czasu jest.

    0
  • #27 12 Sty 2012 15:52
    Madman07
    Poziom 19  

    Widziałem dzisiaj mały keyboard 4 oktawowy. Faktycznie, może to być trochę za dużo.
    To wiem. Chodzi mi właśnie o przerwy między poszczególnymi bajtami :)

    0
  • #28 12 Sty 2012 16:08
    Jimi Hendrix
    Poziom 19  

    Standard MIDI nie definiuje jak długie mogą być te przerwy.
    Ale myślę, że tolerancja jest dosyć duża - Atari ST miało podobno 8 timerów zapewniających odpowiednie timinigi, natomiast na windowsie z Cubase SX czytałem że opóźnienia sięgają 4-9 ms!
    Myślę, że warto jednak napisać jak najlepsze procedury obsługi tego przerwania i spaść znacznie poniżej tych 320 us.

    0
  • #29 12 Sty 2012 16:54
    Madman07
    Poziom 19  

    Nie kumam co jest. Mam dwie identyczne kostki, zasilanie jest odfiltrowane a głupoty z nich wychodzą. Czasem podczas grania losowe szumy bądź przełącza się kształt oscylatora, teraz dźwięk jest strasznie cichy, chociaż pojawiają się głośniejsze momenty. Właśnie przepisałem procedurę wysyłania na taką samą, jakiej Ty używasz i dalej to samo.

    0
  • #30 14 Sty 2012 12:08
    Jimi Hendrix
    Poziom 19  

    Daj drabinkę 8x10k na porcie, na którym masz SIDa. Może tam łapie jakiś syf.
    No albo zastosuj sprawdzone rozwiązanie z Midibox SID module, z rejestrami 74HCT595.

    0