atarionline.pl SFX-Tracker - Forum Atarum

Jeśli chcesz wziąć udział w dyskusjach na forum - zaloguj się. Jeżeli nie masz loginu - poproś o członkostwo.

  • :
  • :

Vanilla 1.1.4 jest produktem Lussumo. Więcej informacji: Dokumentacja, Forum.

    • 1:
       
      CommentAuthorpebe
    • CommentTime17 Jun 2021 zmieniony
     
    @mono: Dzięki za tą krótką prockę klika. Zaadoptowałem ją z krótszą pętlą i daje krótki pik - jest akceptowalny :)

    Ogarnąłem naprawdę sporo rzeczy w ostatnim czasie. Doszły nowe funkcje:
    - zintegrowałem opcję DIR z menu IO z opcjami zapisu i odczytu. Teraz wszędzie, gdzie użytkownik jest proszony o nazwę pliku, można wywołać katalog dysku podając nazwę urządzenia z dwukropkiem lub dodając znaki wieloznaczne (wildcard) np. *.SFX, *.NOT, *.SMM lub jakikolwiek inny rozpoznawany przez używany DOS.
    - zapis i odczyt pojedynczych SFXów
    - zapis i odczyt pojedynczych Tablic Nut
    - edycja tablic nut oraz nadawanie im nazwy
    - poprawiłem dużo błędów związanych z UI i z alokacją pamięci
    - Na starcie program sprawdza istnienie dwóch plików w bieżącej lokalizacji:
    DEFAULT.THM - plik z definicjami tematów kolorystycznych oraz wybranym schematem.
    DEFAULT.SNT - plik z domyślnymi tablicami nut.
    Ten plik można też samemu stworzyć przez połączenie pojedynczych plików, stworzonych przez program. Pod linuxem to krótka linijka :P ,np:
    cat PURE.NOT BASS1.NOT BASS2.NOT >> DEFAULT.SNT

    Może pomyślę o podobnym rozwiązaniu dla banków SFX.

    - sporo zoptymalizowałem pod względem zużycia pamięci.

    Obecnie zostało mi do użytku: 705 bajtów :P przy alokacji programu od $2000

    Co zostało? Opcja NEW w menu IO i odtwarzanie SONGów.

    Przygotowałem też tabelę w PDFie, przedstawiająca Mapę pamięci programu SFXMM. Dostępna jest tu ->link<-

    W załączniku XEX oraz image dysku z programem i wymaganymi plikami.
    • 2: CommentAuthorpin
    • CommentTime17 Jun 2021
     
    to może podziel ten program na dwa pliki i ładuj to co będzie aktualnie potrzebne, bo 705 bajtów to szału nie ma.
    • 3:
       
      CommentAuthorpebe
    • CommentTime18 Jun 2021 zmieniony
     
    Udało mi się odzyskać kolejne bajty. Obecnie mam ich już 1469, tracąc nieznacznie na estetyce, ale nie na funkcjonalności.

    @pin: pisałem już o podziale programu na funkcjonalne bloki, które miałyby być wczytywane. Nadal nie mam mechanizmów, które by to zapewniły w wygodny sposób. To wymaga też innego podejścia do projektu, którego teraz, nie chce mi się zmieniać. Może przy następnej wersji pomyślę o takim rozwiązaniu.

    ---

    Wczoraj (przed snem) myślałem nad rozwiązaniem sposobu odtwarzania SONGów. Nie do końca jest to takie proste, przy obecnym sposobie zapisu.

    Problem polega na tym, że każdy TAB może mieć różną długość, co wizualnie, można by zaprezentować tak:
    CHN#
    1: <----#1-----><----#2----->
    2: <-----------#3----------->
    3: <--#4---|---#5---|---#6-->
    4: <-#7-|-#7-|-#7-|-#8-|-#9->

    lub mniej więcej tak:
    TAB#  
    #1: <--#1-->
    #2: <--#1-->
    #3: <------#2------>
    #4: <-#3-|
    #5: |-#3-|
    #6: |-#3->
    #7: <#4|#4|#4|
    #8: |#4|
    #9: |#4>


    Przy obecnym zapisie SONGa, kompletnie się (mi) nie kalkuluje.
    Odsłuch z wybranego miejsca (przez użytkownika) wiązałby się z kalkulacją, tj. prześledzeniem od początku do wybranego miejsca, lub - w przeciwnym wypadku - kompletną desynchronizacją SONGa.

    Wnioski

    Wychodzi na to, że przy obecnym rozwiązaniu konieczne będzie:
    - zaimplementowanie w procedurze odtwarzania SONGów czterech, niezależnych liczników pozycji SONGa.
    - inne podejście do pętli i skoków w definicji SONG - niezależne dla każdej ścieżki (kanału), albo rezygnacja z nich

    albo

    - przeprojektować sposób tworzenia/edycji SONGów, stosując jeden z powyższych zapisów

    Jakieś wskazówki?
    • 4:
       
      CommentAuthorpebe
    • CommentTime18 Jun 2021 zmieniony
     
    Hmm... Tak sobie pomyślałem...

    A gdyby tak rzucić wszystko i wyjechać w Karpaty? :P

    - Cztery niezależne liczniki pozycji SONG - czyli po jednym na kanał (ścieżkę)

    - Zmieniają się, gdy tylko w TABie natrafi na funkcję TAB-END lub odtwarzany TAB się "zawinie" - bo tak się ma zachować, gdy nie ma określonego końca w TABie, a ten ma wtedy długość 128 wierszy.

    - Funkcje w TABie wykonywane są wtedy, gdy którykolwiek z kanałów "przeskoczy" do takiej definicji.
    Każdy "przeskok" sprawdza informację zawartą w pierwszym kanale (tam jest potencjalna instrukcja) następne kanały zawierają dane dla instrukcji.
    Wtedy ustawia wszystkie cztery wskaźniki pozycji na wskazaną pozycję w funkcji (2-gi albo 3-ci kanał, zależy od funkcji)

    "Ciutkę" gorzej z ustalaniem pozycji odtwarzania (opcja SONG->PLY)

    Chociaż... Wystarczyłoby, mieć możliwość wyłączania przetwarzania SFXów (w tym wyjścia audio). W takiej sytuacji, wystarczy wykonywać procedurę SFX_Tick do póki, wskaźniki pozycji (którykolwiek) nie osiągną wskazanej przez użytkownika pozycji.
    Dodatkowo, można by wyłączać tick TABów - ustawić go na zero - co przyspieszy "wyszukiwanie".
    Oczywiście taka opcja TYLKO dla SFXMM, bo w normalnym użytku, raczej zbędna.

    To najprostsze rozwiązanie, mogące powodować małe przekłamania w SFXach, jednak, dla podglądu, powinno w zupełności wystarczyć.

    To może zadziałać.
    • 5:
       
      CommentAuthorpebe
    • CommentTime22 Jun 2021 zmieniony
     
    Trochę mnie nie było, a tu takie zmiany... ;)

    Znowu zabrałem się za ogarnianie pamięci i, znowu odratowałem ponad 1,5KB, poprawiając przy tym:
    - błędy w silniku SFX - błędne wyliczanie adresów SFXów, błąd obsługi modulacji.
    - interface operacji IO
    - lepsza obsługa edycji TAB - wstawianie/usuwanie wierszy, zmiana TABa bez opuszczania trybu edycji (podobne będę chciał zrobić dla SFX i SONG) Może nawet Kopiuj/Wklej zrobię
    - namiastka odtwarzacza SONGów - bez obsługi funkcji na razie
    - i... nawet już nie pamiętam co jeszcze

    To jeden z większych updateów - dwa/trzy dni bez commitów :/ kuleje jakość GITa programu :/

    XEX nie zawiera w sobie tablic nut, poszukuje ich na dyskietce - stąd wersja ATR. Podobnie rzecz się ma z tematami kolorystycznymi.

    Co do modułu SONG.
    Jak pisałem, jest to namiastka, ponieważ jest pewien błąd.
    Jeśli zdefiniowany zostanie SONG, np:
    00: 00 -- -- --
    01: 00 01 -- --

    Nie zostanie odtworzony TAB#01 z drugiego wiersza. Aby to zadziałało, trzeba stworzyć pusty TAB o takiej samej długości co TAB#00, np:
    #63
    000: ... ..
    001: 63>000
    002: ENDTAB

    i taki wprowadzić do tabeli SONG:
    00: 00 63 -- --
    01: 00 01 -- --


    Tak samo będzie dla reszty kanałów.
    Dzieje się tak, gdyż inicjacja SONGa nie inicjuje pusty wpisów z tabli SONG, a procedura odtwarzania działa niezależenie dla każdej ścieżki. To wynik zastosowania niezależnych długości dla TABów.

    Nie bardzo wiem, jak to logicznie rozwiązać.

    Jedynym rozwiązaniem przychodzącym mi do głowy to stała linia czasu na której umieszczane są TABy, jednak wiąże się to z dodatkowym wykorzystaniem pamięci, a tego chcę uniknąć.
    • 6:
       
      CommentAuthorpebe
    • CommentTime26 Jun 2021 zmieniony
     
    Siemandero...

    Opadłem z sił, a w między czasie, wpadł mi idiotyczny pomysł do głowy, by usunąć wątek - dobrze że nie ma takiej opcji w forum. Jednak to nie znaczy, że nic nie robiłem.

    ---

    Zacznę może od tego, że na chwilę obecną, SFX-TRACKER aka SFX Melody Maker, będzie dostępny w formacie ATR i XEX, jednak rekomendowałbym format ATR.

    Jest to związane z tym, że część danych postanowiłem wyrzucić z głównego pliku (ok. 2,5 KB) Dane te to zasoby interfejsu użytkownika i doczytywane są na starcie programu - uznałem, że tak będzie ciekawiej :P Poza tym, plik główny jest ciut mniejszy.
    Są też pliki domyślne, które konfigurują środowisko: tematy kolorystyczne oraz tablice nut.

    Dodałem także prosty techniznie, ale śliczny :P loader, dla hardcorowców takich jak ja, lubiących czekać, aż program się wczyta, zwłaszcza bez patchy SIO i dokładnym odwzorowaniem czasu sektora - boskość :D

    Jest też trochę poprawek, ale nawet już nie pamiętam, co zmieniałem... i nadal nie okiełznałem sprawy z SONGami... i ciągle nie ma opcji NEW - tzn, jest, ale nie zaimplementowałem doń procedury :P

    Zautomatyzowałem też trochę proces kompilacji programu, dodając do repozytorium pliki build.sh (sorki, tylko dla Linuxa), a że w BASHu "ja nie gawarit" to mi trochę zeszło :P

    Nom. Tak się mają sprawy.

    ---

    Przydałoby się teraz trochę zaktualizować dokumentację i zastanawiam się, jaką technologię wybrać do tego? Może ktoś coś doradzi w tym temacie?

    ---

    W załączniku obraz ATR oraz na GitHubie najświeższe źródła.
    • 7:
       
      CommentAuthorjhusak
    • CommentTime26 Jun 2021 zmieniony
     
    w githubie masz format "md".

    ->link<-

    Mogę pomóc w buildzie na OSX.

    A bash to jest mega super narzędzie. Można w tym nawet kompilator pisać lub takiego basica. Powolne, ale do prostych zastosowań miodzio.

    I te operacje na tekstach - też miodzio, np:

    a='coSS'
    echo $a ${a^} ${a^^}
    a='COSs'
    echo $a ${a,} ${a,,} ${a:1} ${a:1:2}

    A o co chodzi z tym usuwaniem wątku? Przypominam. To bardzo bardzo dobry pomysł, że dzielisz się z nami opsiem "trudów tworzenia". Na pewno to spowoduje refleksję u kogoś, kto zechciałby coś skrytykować.
    • 8: CommentAuthorilmenit
    • CommentTime26 Jun 2021
     
    Do "md" polecam ->link<-
    • 9:
       
      CommentAuthorjhusak
    • CommentTime26 Jun 2021
     
    Kojarzy się z "typiarą" :D Nawet beta pod OSX jest. Spróbuję w wolnym czasie.
    • 10: CommentAuthormarok
    • CommentTime27 Jun 2021
     
    Co do sprawy z Songami to jestem zwolennikiem rozwiązania najprostszego dla oprogramowania tego, ale z kolei zapewne niedoskonałego czy nie dość wygodnego dla użytkownika. Otóż, wydaje mi się, że odtwarzanie powinno zwyczajnie odbywać się zawsze od początku songu, więc bez możliwości wyboru linii, od której się to miałoby odbyć. Do tego, aby można było odtwarzanie wstrzymać i "od pauzować", gdyby miało się to faktycznie przydać, jako taka dodatkowa opcja w odtwarzaniu Songu.

    Nie jestem za tym, aby użyteczność z poziomu odsłuchiwania w edytorze odbyła się kosztem uproszczenia formatu w zakresie tworzenia możliwie różnych długości patternów/ tabów czy nawet potencjalnie jeszcze innych rozwiązań pierwotnie przewidywanych dla zapisu w danych song (pętle czy jeszcze coś innego).

    Żeby nie pozostać tak zupełnie gołosłownym, podam pewien w miarę analogiczny przykład rozwiązania dość zbliżonej, a poświęconej, użyteczności na rzecz zachowania elastyczności "formatu" (i niechęci do podejmowania trudniejszych, a może zbyt skomplikowanych, rozwiązań).

    Miałem swego czasu możliwość wpłynąć na decyzję, która ostatecznie oznaczała, że wyświetlany na ekranie (Atari) był tekst zapisany w danych bez znaków końca linii (można to ująć jako technikę "wlewania się" tekstu, ponieważ brakuje tych punktów odniesienia - końca linii), ale równocześnie - z ujęciem możliwości cofania się o długość ekranu w tył (jako tego trudny do uniknięcia koszt). Można było zamiast tego cofać się w przeglądaniu tekstu do początku akapitu (lub całego tekstu), ale już nie o, standardowe przecież, długość jednego ekranu.
    • 11:
       
      CommentAuthorpebe
    • CommentTime27 Jun 2021 zmieniony
     
    @jhusak:
    w githubie masz format "md".

    Tak. Jestem wielkim fanem tego formatu. Jednak nie bardzo znam narzędzia, którymi można by tworzyć złożone teksty.
    Swego czasu zainstalowałem sobie GhostWriter. Próbowałem też działać z dodatkami do obsługi MarkDown w VSCode, jednak tutaj ciut topornie szło.

    A bash to jest mega super narzędzie.

    BASH to narzędzie z którego mocy zdaję sobie doskonale sprawę. Jednak podobnie jak w DOSie (PeCetowym), praktycznie nigdy nie wykorzystywałem przetwarzania wsadowego. Po prostu nie było mi to potrzebne. Większość rzeczy rozwiązywało za mnie IDE w którym pracowałem.
    Teraz, przy rozbiciu projektu na kilka mniejszych, takie przetwarzanie pozwala usprawnić pracę i daje większą swobodę, tzn. nie muszę pamiętać ciągle o tym, co i jak mam skompilować, a co nie.

    Może moje rozwiązanie nie jest z najwyższej półki, ale działa. I wiem, że można to zrobić lepiej ;)

    Mogę pomóc w buildzie na OSX.

    Chętnie bym skorzystał z takowej pomocy.
    Nie lubię zmuszać potencjalnego użytkownika do przeglądania skryptów w celu dowiedzenia się, że np. wymagany jest pakiet taki i taki, aby skrypt zadziałał.

    Poza tym, jeżeli ktoś zrobi skrypt, który wiem jak działa to sam się też czegoś nauczę, a to ZAWSZE procentuje.

    @ilmenit: Dzięki za polecenie. Z pewnością sprawdzę.

    @marok:
    (...)odtwarzanie powinno zwyczajnie odbywać się zawsze od początku songu, więc bez możliwości wyboru linii, od której się to miałoby odbyć.

    Właściwie to tak właśnie się to odbywa teraz. Nie ma możliwości wybrania miejsca początkowego (z poziomu SFXMM)
    Pauza nie jest zaimplementowana, choć możliwa.

    Nie jestem za tym, aby użyteczność z poziomu odsłuchiwania w edytorze odbyła się kosztem uproszczenia formatu

    Też za tym nie jestem, jednak czasami (jak sam o tym wspomniałeś) jest to zwyczajnie nieopłacalne lub niewykonalne.

    ---

    Czas zobaczyć, co "typiara" potrafi :)
    • 12:
       
      CommentAuthorpebe
    • CommentTime27 Jun 2021
     
    @ilmenit: no w końcu porządne narzędzie do MarkDowna. Właśnie o taki program mi chodziło. Dziękuję za tą "polecankę" :)
    • 13: CommentAuthormarok
    • CommentTime27 Jun 2021
     
    "Pauza nie jest zaimplementowana, choć możliwa."

    Właściwie to, po lekkim przemyśleniu sprawy, zamiast klasycznej pauzy lepsze byłoby "zapamiętanie" tego, co wynika w zmiennych z odtworzenia od początku do danej linii song, a później możliwość (wielokrotnego) odtwarzania z tej "zapamiętanej" pozycji song (być może z ograniczeniem, że poprzednia treść w liniach song nie może zostać "istotnie" zmieniona, o ile opcja ta ma być aktualna - ale chyba też nie trzeba robić wcale takiego zastrzeżenia - użytkownik bierze wszelkie ryzyko asynchronizacji zapisu dla kanałów po ponownym odtwarzaniu od początku utworu, na siebie). W między czasie (pomiędzy odtworzeniami z "zapamiętanego" miejsca) można by swobodnie edytować linie song i poszczególne taby (być może z ograniczeniami wynikającymi z poprzedniego zastrzeżenia) . W procesie tworzenia kompozycji można by więc skupić się na aktualnym fragmencie, od danej linii song (pomijać to, co zostało już zrobione i nie odtwarzać za każdym razem, kiedy pilnie potrzeba odsłuchać od konkretnego miejsca).
    • 14:
       
      CommentAuthorpebe
    • CommentTime27 Jun 2021
     
    @marok: To nie jest zły pomysł. Muszę przemyśleć, jak go zaimplementować, by był jasny w odbiorze, bo to (chyba) jedyne dobre rozwiązanie.

    ---

    A na razie, uzupełniając dokumentację, poprawiam błędy, których wcześniej (najzwyczajniej w świecie) nie zauważyłem. Jak choćby, możliwość wykonania skoku w miejsce w którym jest funkcja skoku. Skutek? Zwis :D
    Nieco estetycznych błędów też znajduje.

    @ilmenit: im bardziej korzystam z "typiary" tym bardziej mi się podoba. Ma funkcje, których cholernie mi brakowało w GhostWriterze. Jak chociażby, trywialna w obsłudze, funkcja Spisu treści. Super obsługa tabel i osadzania obrazów. Rewelka.
    • 15: CommentAuthormarok
    • CommentTime28 Jun 2021
     
    "Efektywna długość taba".
    Brakuje łatwego dostępu do takiego wyliczenia (w podglądzie edytora). Jest za to podsumowanie taba liczonego w długości fizycznie zajmowanych bajtów(*2?)/ pozycji wpisu (co łatwo w tej chwili samemu stwierdzić, bo to zawsze wartość o jeden więcej niż pozycja przy końcowym ENDTAB). Nie ma ono takiej wartości informacyjnej, jak właśnie efektywna długość taba, która jest informacją wręcz pierwszorzędnego znaczenia w kontekście edycji taba i korelacji odniesień(?) w utworze.

    Można by więc tylko wymienić wartość tego podsumowania (zajętości wielokrotności bajtów składającej się na fizyczne pozycje w zapisie danych, ograniczonej do 128) na tą postulowaną, albo zrobić to nawet inaczej.

    To inaczej wynika z innego jeszcze postulatu o może lepszej jeszcze czytelności.

    Pozycje w edytorze teraz numerowane są kolejno. Nie ma rozróżnienia, czy jest to "wpis nutowy" czy deklaracja pętli (też ma swój przydzielony numer). Gdyby tak pozbawić deklaracji pętli swojego numeru, a numerować na "sposób efektywny" tylko zapisy nutowe, to łatwiej byłoby też zorientować się "w połówkach i ćwiartkach" względem całej długości taba gdzie się znajduje dany zapis. Ku temu lepsze byłoby operowanie w argumencie deklaracji pętli wartością względną - która jest chyba liczona i tak tylko w górę i nie może (jak się wydaje - aby działać poprawnie) nakładać się na pozycję poprzedzającą poprzednią deklarację pętli (lub początek samego taba).

    Więc podsumowując, jak bym to może widział.

    "Podsumowanie" taba, jakie jest obecnie, w zasadzie mogłoby pozostać, jak jest teraz. Nie jest to wartość, która cokolwiek wnosi dla kompozytora (sam raczej nie musi konktrolować przekroczenia bariery dostępnych pozycji w fizycznym zapisie taba, bo robi to już, zakładam, program), ale daje podgląd "gęstości zapisu" deklaracji konkretnego taba (przy wszystkich jego zastosowanych pętlach). Natomiast, to co się najbardziej może przydawać od strony tworzenia kompozycji, czyli "pozycje lokalizacyjne", celniej w tym sensie precyzowane, inaczej pisząc "efektywne", miałyby numerację odpowiadającą danym zapisom (nutowym). Pamiętając przy tym, że na pozycjach pętli numeracja odpowiada pierwszemu przebiegowi, a pełny efekt pętli (w zajętości pozycji lokalizacyjnych) jest dostrzegalny bezpośrednio już na pierwszej pozycji za pętlą. Dlatego też, jeśli pętlą miałaby się kończyć cała deklaracja taba, zastosowaną bezpośrednio przed TABEND, to z tego właśnie względu, na taką ewentualność chcąc się szczególnie przygotować, przy TABEND, o ile nie zrezygnuje się z "podsumowania" taba w jego właściwym miejscu (i tam tej wartości nie umieści), to gdzieś przy tej etykiecie TABEND wartałoby, koniecznie nawet, umieścić końcową długość efektywną taba.

    Żeby tylko dobrze być zrozumianym w kwestii postulatu względności argumentu dla pętli. Nie chodzi, aby zmieniać coś w obecnym zapisie w danych - aby inaczej interpretować tą wartość, ale aby tylko jej reprezentacja w edytorze była przedstawiona na sposób wartości względnej (po przeliczeniu). To ułatwi nawet percepcję o jaki rząd wielkości skaczemy w górę (może nawet kopiowanie fragmentów taba mogłoby odbywać się 'lepiej', łączanie z deklaracją pętli?).

    Jeszcze jedna "porządkowa" myśl, w podobnym kontekście.
    Nawet podoba mi się zapis "pozornej pętli" (gdy pętla jest deklaratywna, ale jest jednego przebiegu, więc pozostaje bez znaczenia dla uzyskanego efektu). To wizualnie odgranicza poszczególne obszary tych różnych "ćwiartek i połówek" taba. Uczytelnia to zapis. Wszystko to dobrze, ale ortodoks może zauważyć, iż powiększamy tak długość zapisu taba, przez coś, co nie ma żadnego przełożenia na treść muzyczną. Dodać do tego może, że "przez ten zbędny zapis" wykonuje się odrobinę wolniej procedura odgrywająca. Nie ma się czym przejmować, dla estetyki i przyjemności korzystania z edytora warto to niewiele poświęcić. Tyle tylko, że w przypadku efektywnego liczenia pozycji dla wyłącznie zapisów nutowych ta "ornamentyka" może wciąż być chętnie wykorzystywana, ale nie będzie już tak przydatna, jak w obecnej konfiguracji edytora (z jego numeracją pozycji).
    • 16:
       
      CommentAuthorpebe
    • CommentTime28 Jun 2021 zmieniony
     
    @marok: Przeczytałem Twój post i ciężko mi rozpracować, co masz na myśli - przepraszam.

    Informacje które są podawane w programie, dotyczące długości TABa są właściwą informacją, tzn. zawiera ilość wierszy, jakie wchodzą w jego skład.
    Jeśli chodzi o pętle to miejsce skoku (parametr) NIE JEST wartością względną. To wartość bezwzględna, liczona od początku definicji, czyli od wiersza 000. Więc podanie skoku, czy to w funkcji JUMP TO, czy REPEAT odwołuje się do konkretnego wiersza. Można to czytać tak:

    000:+>+>C-1 00
    001:| | D-1 00
    002:| | E-1 00
    003:| +-03<000 (powtórz jeszcze 3x od wiersza 0)
    004:| --- --
    005:| +>F-1 00
    006:| | G-1 00
    007:| | A-1 00
    008:| | H-1 00
    009:| +-05<005 (powtórz jeszcze 5x od wiersza 5)
    010:+--- <000 (skocz do wiersza 0)


    Względne odwołania (w tym przypadku, wg mnie) bardziej by wprowadzały w błąd - chociaż sam nie wiem. W każdym razie, na pewno dodają kodu do silnika, gdyż trzeba by wyliczać, np:
    clc
    lda currentTabOfs
    adc (tabPtr),y
    asl @
    tay

    a tak to pobieram tylko wartość z definicji TABa:
    lda (tabPtr),y
    asl @
    tay

    gdzie w Y trzymam aktualny offset TABa.

    Nie wiem, czy dokładnie to odwzorowałem, ale mniej więcej tak jest.

    Programowo starałem się zabezpieczyć, aby nie można było skoczyć dalej, niż wskazuje na to ilość wierszy w TABie.
    Jednak, można łatwo zawiesić silnik (a tym samym cały program), bo nie analizuje takich sytuacji jak poniższa, która jest jak najbardziej do wprowadzenia:
    000:    --- --
    001: +> <005 >+
    002: | --- -- |
    003: | --- -- | pętla bez końca
    004: | --- -- |
    005: +- <001 <+


    Dzieje się tak, ponieważ silnik analizuje w jednym przebiegu funkcje, tzn.:
    - początek analizy TABa
    - jeśli nuta, pobiera parametry, ustawia rejestry kanału wychodzi z analizy do przetwarzania SFX.
    - jeśli napotka na funkcję (bit 7 pierwszego bajtu wiersza), sprawdza, co to za funkcja
    - jeżeli to JUMP TO/REPEAT, pobiera parametry (skrótowo)
    - ustawia rejestr Y (offset TABa)
    - skacze (JMP) do początku analizy TABa,

    Objawia się to tym, że w trakcie odtwarzania TABa, po wykonaniu funkcji, można zauważyć, że nuta tuż po wykonaniu funkcji nie jest zaznaczana kursorem, tylko następna.

    Wydaje mi się, że musi się to tak odbywać, bo inaczej traciło by się jeden cykl TABa, co skutkowało by, potraktowaniem funkcji jak nuty która trwa np. 5 tików na wiersz - a tak być nie może.

    Jak można się łatwo domyślić, całość skutkuje bardzo różnym czasem wykonywania się przerwania (mówiąc kompleksowo).
    ---

    Podsumowując.
    Nie wiem, czy w ogóle Cię zrozumiałem. Jednak są pewne niuanse samego silnika SFX, które objawiają się w edytorze dość "dziwnie", jednak, przy zachowaniu ostrożności, nie powodują niepowołanego działania.

    Zapewne będę pracował jeszcze na tymi krytycznymi przypadkami, bo nie mogę narazić użytkownika na utratę danych z powodu swoistej nieuwagi.
    • 17:
       
      CommentAuthorpebe
    • CommentTime28 Jun 2021 zmieniony
     
    OKI. nie jestem pewny, ale chyba załapałem o co Ci chodziło (przynajmniej w pewnej części)

    Załóżmy przypadek z powyższego posta, ale bez ostatniego JUMP TO:
    000:  +>C-1 00
    001: | D-1 00
    002: | E-1 00
    003: +-03<000 (powtórz jeszcze 3x od wiersza 0)
    004: --- --
    005: +>F-1 00
    006: | G-1 00
    007: | A-1 00
    008: | H-1 00
    009: +-05<005 (powtórz jeszcze 5x od wiersza 5)


    Ja pokazuje w edytorze, że długość TABa wynosi 10 wierszy, a w rzeczywistości, jego długość jest znacznie większa.
    Bo powyższy zapis przekłada się na:
    000:    C-1 00
    001: D-1 00
    002: E-1 00
    003: C-1 00 # pierwsza iteracja pętli
    004: D-1 00
    005: E-1 00
    006: C-1 00 # druga
    007: D-1 00
    008: E-1 00
    009: C-1 00 # trecia
    010: D-1 00
    011: E-1 00
    012: --- --
    013: F-1 00
    014: G-1 00
    015: A-1 00
    016: H-1 00
    017: F-1 00 # pierwsza
    018: G-1 00
    019: A-1 00
    020: H-1 00
    021: F-1 00 # druga
    022: G-1 00
    023: A-1 00
    024: H-1 00
    025: F-1 00 # trzecia
    026: G-1 00
    027: A-1 00
    028: H-1 00
    029: F-1 00 # czwarta
    030: G-1 00
    031: A-1 00
    032: H-1 00
    033: F-1 00 #piąta
    034: G-1 00
    035: A-1 00
    036: H-1 00


    Czyli efektywna długość TABa to 37 wierszy.

    A w przypadku oryginału (z posta), długość nieskończona, o ile w SONGu nie wystąpi funkcja.

    Hmm... taka analiza mogła by być bardzo przydatna, zwłaszcza, że działała by prewencyjnie na przypadki takie jak w drugim przykładzie.

    I po chwili namysłu, okazuje się, że taki JUMP TO "być" całkowicie zbędną funkcją.

    (ciekawe spostrzeżenie)
    • 18: CommentAuthormarok
    • CommentTime28 Jun 2021 zmieniony
     
    Hej.

    Jeśli się (kompletnie) nie zrozumieliśmy, a tak to oceniam, to przepraszam za wywołanie nieprzyjemnego wrażenia.

    Będę cytował teraz Twoją odpowiedź i się odniosę. (Może to pomoże jeszcze zrozumieć poprzedni wywód.)

    Informacje które są podawane w programie, dotyczące długości TABa są właściwą informacją, tzn. zawiera ilość wierszy, jakie wchodzą w jego skład.

    Przejmując teraz identyczną stylistykę określania rzeczy (żebyśmy się rozumieli) chcę napisać, że informacja o ilości wierszy wchodzących w skład TABa dotyczy tego, co jest zapisane w pamięci (- prawda?).
    Natomiast, z powodu stosowania użytecznych pętli w TABie, dzieje się jednak tak, że to nie jest to samo, gdzie aktualnie znajdujemy się, jeśli chodzi o pozycję "w rozpisanym" (powiedzmy, że po rozpętleniu wszystkich pętli) TABie. Czyli, że z przykładu podanego wyżej, jako pierwszego, pozycja 004 to "w rozpisanym" TABie jest już pozycja 009 (0+ 3*3) - "rzeczywista" (tak ją teraz określę).
    Zasadniczo cały problem widzę w tym, że chcąc orientować się na bieżąco w "rzeczywistej" pozycji w TABie przy wprowadzaniu nut, nie mam z miejsca tej użytecznej informacji i muszę sobie radzić chyba licząc lub "oflagowując" pętlami z jednym przebiegiem i tak oddzielając poszczególne partie całego TABa (w 1/4, 1/2 itp.).
    To może nie jest do końca wygodne dla kompozytora, choć to tylko moja spekulacja.

    Więc podanie skoku, czy to w funkcji JUMP TO, czy REPEAT odwołuje się do konkretnego wiersza.

    To wiedziałem.

    W każdym razie, na pewno dodają kodu do silnika, gdyż trzeba by wyliczać

    Pisałem jednak, żeby silnik i format pozostał bez zmian, ale żeby przeliczane to było do wartości względnych pod edytor dla pewnej wygody użytkownika. To taki mniejszej wagi postulat z mojej strony, sam rozumiem poniekąd, że nieco kłopotliwy by go zrealizować.

    Objawia się to tym, że w trakcie odtwarzania TABa, po wykonaniu funkcji, można zauważyć, że nuta tuż po wykonaniu funkcji nie jest zaznaczana kursorem, tylko następna.

    Przyznam, że tego szczegółu sam nie odnotowałem (nie przyjrzałem się temu). W zasadzie, jak rozumiem ten opis, zgadzam się z taką koniecznością, choć godną rozważenia alternatywą dla tego jest - o ile tylko dobrze rozumiem całą sytuację - by zamiast kursora, który przystaje na funkcji JUMP TO/REPEAT od razu przeskakiwać z nim na docelową pozycję (wtedy ta nie zostanie pominięta, ale z kolei szybko stracimy z oczu widok funkcji, od której nas przeniosło - też może nie idealnie).

    PS.
    Zdążyłem jeszcze zauważyć, że napisałeś nową odpowiedź, więc to, co napisałem też jest poniekąd (chyba już) zbędne. Ale co tam... ;)
    • 19:
       
      CommentAuthorpebe
    • CommentTime28 Jun 2021 zmieniony
     
    @marok: zacznę może od:
    Zdążyłem jeszcze zauważyć, że napisałeś nową odpowiedź, więc to, co napisałem też jest poniekąd (chyba już) zbędne.

    Dla mnie nic nie jest zbędne, jeżeli tylko potwierdza moje postrzeganie i zrozumienie (kogoś).

    (...)by zamiast kursora, który przystaje na funkcji JUMP TO/REPEAT od razu przeskakiwać z nim na docelową pozycję(...)

    Śledzenie w trakcie odsłuchu opiera się na odczytywaniu wskazań rejestrów kanałów silnika SFX, a dokładnie, jednego z nich: offsetu TABa (TABOfs=wiersz*2) na kanale na którym jest odtwarzany. Można by powiedzieć, że silnik robi swoje, a GUI nasłuchuje tego, co jest rejestrach silnika.
    A że wykonanie funkcji odbywa się w jednym (zamkniętym) przebiegu, nie sposób "namierzyć" nuty po wykonaniu funkcji.
    Dokładniej, dzieje się tak, że wskaźnik pozycji, praktycznie zawsze wskazuje na jedną pozycję na przód - taki urok bloku PLAYBACK_TAB. Podobnie sprawa się ma z blokiem PLAYBACK_SFX, tylko tu, nie śledzę już pozycji, bo mija się to z celem. Przy tak niskiej rozdzielczości i niewielu informacjach na ekranie, nie sposób by zauważyć zmiany.

    (...)informacja o ilości wierszy wchodzących w skład TABa dotyczy tego, co jest zapisane w pamięci (- prawda?)

    W gruncie rzeczy, tak. Pomnożona przez 2 da ilość miejsca, jaką zajmuje w pamięci sama definicja. Dodając do tego 8 bajtów nazwy, to będzie dokładnie tyle, ile zabiera z pamięci jeden TABa.

    Jeśli się (kompletnie) nie zrozumieliśmy, a tak to oceniam, to przepraszam za wywołanie nieprzyjemnego wrażenia.

    Ludziom zdarza się czasami nie zrozumieć, jednak (jak przypuszczam) nie jesteśmy z tych, co od razu sięgają po "czerwony guzik" by anihilować przeciwną stronę XD ;)

    ---

    Wracając do tematu rozpisywania/wskazywania rzeczywistej pozycji w TABie.

    Zastanawiam się nad tym, czy nie wpłynie to niekorzystnie na szybkość odświeżania informacji w oknie edycji, a tym bardziej w trakcie odtwarzania TABa z podglądem.
    Chodzi o to, że procedura wyświetlająca treść TABa jest jedna - to zrozumiałe, po co dublować. Analizowanie treści TABa pod kątem rzeczywistej pozycji to nie dość, że czas, ale przede wszystkim miejsce.
    Są trzy wyjścia:
    1. minimum zużycia pamięci - tylko kod analizujący na bieżąco w głównej procedurze wyświetlania treści TABa.
    2. dodatkowa procedura, która analizuje treść TAB a wynik przetrzymuje w jakiejś tymczasowej tablicy. Procedura wyświetlająca treść, korzysta z danych tablicy tymczasowej.
    3. wymyślić inny sposób na ogarnięcie tematu :P ;)

    "Prześpię się" z tematem. Może coś mi wpadnie do głowy. Na chwilę obecną, jeśli miałbym podjąć decyzję to najpewniej obstawiał bym opcje 2.

    ---

    Zrezygnowałem z opcji JUMP TO w TABie. Po głębszym przemyśleniu, okazuje się częściowo nieracjonalna.
    W definicji SONG, jeżeli w ścieżce zostanie wpisany TAB, np:
    00: 00 -- -- -- <- tu zacznie się TAB#00
    01: -- -- -- --
    02: -- -- -- -- <- będzie odtwarzany aż dotąd.
    03: 01 -- -- -- <- tu zacznie się TAB#01

    Po natrafieniu funkcji TABEND (lub też przeskoczeniu z pozycji 127 na 0) jeżeli w definicji SONG, nie jest określony TAB (jest blank '--') TAB jest odtwarzany od początku. Funkcja JUMP TO "trochę" psuła ten przebieg, ponieważ:
    - mimo iż była (wizualnie) traktowana jak TABEND, taka nie była
    - nie sprawdzała, czy w ścieżce SONG występował nowy TAB, czy też "blank".
    - po prostu wykonywała skok
    W takiej sytuacji, nie daje się opuścić pętli, ponieważ nigdy nie dochodziło do funkcji TABEND.

    Nie wiem. Sam się już zgubiłem w tym :P W każdym razie.
    Nie ma już funkcji JUMP TO w TABach i wydaje mi się, że to dobra decyzja.

    Co ciekawe, praktycznie nic to nie zmieniło w kodzie silnika SFX - jest tylko inny adres skoku :) A sam program nie wiele na tym zyskał (kilkanaście bajtów, dosłownie)
    • 20:
       
      CommentAuthorpebe
    • CommentTime28 Jun 2021
     
    SONG. Here go again.

    Właściwie, czemu nie zastosować zasady "kto skończy ten zmienia", tzn.
    Podczas odtwarzania SONGa, każdy TAB gra niezależnie (stwierdzam fakt :P) Teraz. Ten który pierwszy zakończy grać (trafi na TABEND lub się "zawinie") zmienia pozycję SONGa, przy czym, czytane są wszystkie wartości wiersza SONG i jeżeli nie są NOP to są ustawiane. Jak są NOP to grają od początku tego samego TAB co grały. Jak trafi na funkcję to jedzie kompleksowo z koksem.

    Czy dobrze myślę, że to by wyeliminowało problem z posta #7 (tej strony wątku)? Krótka retrospekcja: aby zagrała ścieżka, która nie grała od początku, musiał być zdefiniowany "Pusty" TAB (np. z pętlą REPEAT) o konkretnej długości i ustawiony w tejże ścieżce.

    Chyba to jutro sprawdzę, bo coś mi się widzi, że to jest to.
    • 21: CommentAuthormarok
    • CommentTime29 Jun 2021 zmieniony
     
    Jednak zacznę od erraty do swoich własnych wywodów. Ponieważ znów mi się zdarzyło, że coś źle zbadałem, oceniłem, i na tej podstawie pisałem pewne rzeczy (nawet względnie rozbudowane koncepcje).

    Pomyliłem się w interpretacji znaczenia pierwszej wartości przy funkcji REPEAT. Prosto pisząc, ujmowałem 1 od właściwego znaczenia tej wartości, sądząc po prostu, że odejmuje ona do zera ZANIM następuje ewenatualny powrót (pozytywna weryfikacja). Jakoś źle spojrzałem na przykład TAB "laserman" - konkretnie stąd mi się to wzięło.

    Taraz dostrzegam, że można wpisać z edytora wartość powtórzeń z przedziału 1-63 (wyrazić ją w 6. bitach). Brakuje mi jednej wartości (kombinacji) w całym przedziale przewidzianym dla kodujących bitów, czyli 0. Jak zachowa się silnik playera wobec takiej wartości?
    Podejrzewam, że cierpliwie wykona 256 właściwych powtórzeń.
    Piszę też o tym, bo we wcześniejszych swoich wpisach odwoływałem się do "oflagowywania" czy podobnych haseł i niestworzonych historii z tym związanych (przedzielania "stylistycznego" ćwiartek całego TABa), co miałoby sens, gdyby działało to (interpretacja tej wartości przy funkcji REPEAT), jak to rozumiałem wcześniej.
    W tej postaci, jaka realnie występuje, w związku z silnikiem, nie można tego w żaden sposób urzeczywistnić. Wyszło trochę głupio - ale typowo, jeśli o mnie chodzi. Tyle tytułem tej "erraty".


    Po natrafieniu funkcji TABEND (lub też przeskoczeniu z pozycji 127 na 0) jeżeli w definicji SONG, nie jest określony TAB (jest blank '--') TAB jest odtwarzany od początku. Funkcja JUMP TO "trochę" psuła ten przebieg, ponieważ:
    - mimo iż była (wizualnie) traktowana jak TABEND, taka nie była
    - nie sprawdzała, czy w ścieżce SONG występował nowy TAB, czy też "blank".
    - po prostu wykonywała skok
    W takiej sytuacji, nie daje się opuścić pętli, ponieważ nigdy nie dochodziło do funkcji TABEND.


    Nie jestem pewien wszystkiego o funkcji JUMP TO, a w szczególności nie wiem, czy miała faktycznie wybór skoku pod inną niż 0 (jego początek) pozycję TABa (zakładam, że jednak tak). W sumie jednak niewiele to zmienia w całej sytuacji, bo jeśli działała w ten sposób, że zajmowała odtwarzany kanał na stałe - jeśli dobrze rozumiem - i TAB z jej udziałem nie dał się z niego 'przegonić' żadnym innym już wpisem w SONG, to do kompozycji muzycznej nie pasowała. Ale, domyślam się, do czystego SFX (przy założeniu, że był możliwy skok pod jeszcze inną, niż pozycja 0) - już jak najbardziej.


    Dokładniej, dzieje się tak, że wskaźnik pozycji, praktycznie zawsze wskazuje na jedną pozycję na przód - taki urok bloku PLAYBACK_TAB.

    Ciekawe, czy się dobrze domyślam:
    Praktycznie zawsze - czy chodzi o wszystkie poza pierwszym tikiem w danym cyklu (liczonym na kilka tików) zajmowania się określoną pozycją?


    Zastanawiam się nad tym, czy nie wpłynie to niekorzystnie na szybkość odświeżania informacji w oknie edycji, a tym bardziej w trakcie odtwarzania TABa z podglądem.


    Jeśli jest tego rodzaju problem, którego nie można sprytniej obejść (nie umiem wglądnąć w kod, więc nic nie poradzę), to jest jeszcze opcja działania edytora na TAGu polegająca na dostarczeniu 'jednorazowo' informacji o tym, ile faktycznie (globalnie) zajmuje on pozycji, zamiast tego "podsumowania", które jest wyświetlane obecnie po prawej stronie i od góry, na jego temat. Domyślam się, że jest to też "liczone" tylko (względnie) raz (nie na bieżąco, za każdą zmianą pozycji TABa). Nawet więc tylko taka padmiana da już lepsze rozeznanie w tym, co mamy sumarycznie w TABie - jak długi on faktycznie jest.
    Więc, jeśli nie ma pamięci lub czasu, nie ma co się forsować na siłę w uwzględnianiu tamtego (pełniejszej wersji) postulatu.

    Jak są NOP to grają od początku tego samego TAB co grały.

    Myślałem, że w opisanej sytuacji, są teraz po prostu nie ruszane - a nie, że mają obligatoryjnie grać od początku.
    Ale, to w zwykłym okolicznościach nie zmienia sytuacji, ponieważ te krótsze TABy, na których wymuszany miałby być start od początku, tym jednym dłuższym, ze względu na nowy wpis na własnej ścieżce SONG, są 1/ którąś częścią w (rzeczywistej) długości pozycji, a więc i tak wypadają tamte na swój początek (bo ten jeden się akurat kończy w swym naturalnym przebiegu, a wszystkie startują w którymś tam wcześniejszym kroku SONG równocześnie - start ich jest względem siebie wyrównany).

    Ja bym tą nową koncepcję potraktował jak takie dodatkowe zabezpieczenie tego, co już i tak pewnie działa.

    W związku z tym, nie wiem, czy jest to do końca potrzebne.
    • 22:
       
      CommentAuthorpebe
    • CommentTime29 Jun 2021 zmieniony
     
    Brakuje mi jednej wartości (kombinacji) w całym przedziale przewidzianym dla kodujących bitów, czyli 0. Jak zachowa się silnik playera wobec takiej wartości?


    Wartość zero, była przewidziana dla JUMP TO. Takie dwa w jednym ;)

    Nie jestem pewien wszystkiego o funkcji JUMP TO, a w szczególności nie wiem, czy miała faktycznie wybór skoku pod inną niż 0 (jego początek) pozycję TABa (zakładam, że jednak tak).


    Tak. JUMP TO, mogła wykonywać skok w obrębie całego TABa, nie tylko na pozycję 0. Co ciekawe, mogła też skakać do przodu, byle nie poza obszar TABa.
    Generalnie miała zapętlać danego TAB, z możliwością ustawienia miejsca od którego miał się zaczynać - taki TABEND z "presetem" pozycji startowej.

    Teoretycznie, nie było to złe rozwiązanie, tylko brak możliwości wyjścia trochę to psuł.

    czy chodzi o wszystkie poza pierwszym tikiem w danym cyklu (liczonym na kilka tików) zajmowania się określoną pozycją?


    Ustaw TEMPO na np. 15 (SONG->OPT->TEMPO) i wrzuć sobie odtwarzanie TABa z funkcjami. Przypatrz się, jak skacze kursor przy funkcjach.
    Generalnie, przy przetwarzaniu funkcji TABa wykonywany jest dodatkowy "obrót" bloku TAB, do póki nie natrafi na nutę/blank/NOTE OFF

    Jeśli jest tego rodzaju problem, którego nie można sprytniej obejść (...), to jest jeszcze opcja działania edytora na TAGu polegająca na dostarczeniu 'jednorazowo' informacji

    TAGu? Rozwiń temat, bo nie bardzo rozumiem. Może jakiś semigraficzny przykład? :D

    Domyślam się, że jest to też "liczone" tylko (względnie) raz (nie na bieżąco, za każdą zmianą pozycji TABa)

    Długść jest liczona (sprawdzana) przy każdej zmianie TABa.
    To funkcja, która "determinuje długość TABa".

    Teoretycznie mógłbym tu sprawdzać "Realną" długość TABa (w sumie to chyba lepszym określeniem byłoby Czas trwania TABa?)

    To nie jest integralna część silnika SFX, więc ten czas to kwestia sporna - chodzi bardziej o wrażenia użytkownika, niż o to, że coś będzie się długo wykonywało.

    Myślałem, że w opisanej sytuacji, są teraz po prostu nie ruszane - a nie, że mają obligatoryjnie grać od początku.

    NOP nie zmienia TABa, ale też go "nie kończy". Ustawia wskaźnik pozycji TABa (w ścieżce) na 0 i puszcza go od początku.
    Takim zakończeniem odtwarzania ścieżki jest funkcja "TRACK OFF" (oznaczona "==")
    Problem w tym, że po takim wyłączeniu ścieżki, już nic nie będzie mogło zagrać na tej ścieżce, czyli:
    #1 #2 #3 #4
    00: 00 -- -- -- TAB #00 będzie odtworzony
    01: -- -- -- -- TAB #00 będzie nadal grał (od początku)
    02: == -- -- -- Wyłączenie ścieżki 1
    03: 00 -- -- -- TAB #00 już nie zagra



    Właściwie problem z koncepcją "Kto kończy, ten zmienia" jest taki:
    #1 #2 #3 #4
    00: 00 01 -- --
    01: -- 02 -- --
    02: 00 03 -- --
    03: -- -- -- --
    04: -- -- -- --
    05: 00 04 -- --

    Rzeczywista długość TABów:
    TAB#0: 32 wiersze
    TAB#1: 16 wierszy
    TAB#2: 16 wierszy
    TAB#3: 48 wierszy


    Założenie synchronicznych długości TABów:
    TAB #0 w wierszach 00 i 01 zagrałby dwa razy.
    wiersz 00: #1 kończy się pierwszy, więc zmienia pozycję SONGa na 01.
    wiersz 01: Ścieżka #1 nie ulega zmianie (bo blank) - #0 jest odtwarzany drugi raz. Ścieżka #2 jest zmieniana na #02.

    Niesynchroniczne długości TABów
    TAB #0 w wierszach 02 i 03 zagrałby 1,5 raza, bo:
    wiersz 03: TAB #3 kończy się w połowie drugiego odtwarzania TAB #0, a ten kończy się pierwszy, więc zmienia pozycję SONGa na 03. Ścieżka #1 się nie zmienia, gra nadal #0. Ścieżka #2 też się nie zmienia, gra dalej #3. W połowie TABa #0, kończy się TAB #3, więc zmienia poz. SONGa na 04.
    wiersz 04: TAB #0 kończy granie po 16 wierszach i kończy zmieniąc poz. SONGa na 05. W miedzy czasie TAB #3 odtwarza się od początku do wiersza 16 i zmiana (wywołana przez koniec TAB #0) powoduje przerwanie jego grania, bo na ścieżce #2 jest w wierszu 05 wpis "graj #04"

    O ile się gdzieś nie walnąłem, tak by wyglądało zastosowanie reguły "Kto kończy, ten zmienia". Niby logiczne, ale...

    - mam problem z długością bloku SONG
    - nie pozwala na wykonanie skoku warunkowego, bo przekracza on rozmiar 127 bajtów :(
    - dubluje mi się kod z wyciszaniem dźwięku
    - nie chcę by główna procedura silnika SFX korzystała ze stosu (nie chcę skoków JSR)
    • 23:
       
      CommentAuthorpebe
    • CommentTime29 Jun 2021
     
    PS do
    Myślałem, że w opisanej sytuacji, są teraz po prostu nie ruszane - a nie, że mają obligatoryjnie grać od początku.

    Niekontynuowanie TABa w nowym wierszu SONG, gdy ten jest BLANK, miało by sens, gdyby był prawidłowo działający JUMP TO - tzn. taki, z którego dałoby się wyjść.
    • 24: CommentAuthormarok
    • CommentTime29 Jun 2021 zmieniony
     
    TAGu? Rozwiń temat, bo nie bardzo rozumiem.

    napisałem "na TAGu" a miało być "na TABie" (ma się rozumieć)

    (w sumie to chyba lepszym określeniem byłoby Czas trwania TABa?)

    Pewnie, że tak, jak uważasz, możesz to oficjalnie nazwać. Dla mnie, jeśli mnie byś zapytał, czas odnosi się do wymiernych wartości liczonych już w ramkach (jednostkach czasu), a sama długość TABa o tym jeszcze jednoznacznie nie przesądza (dopiero trzeba ją przeliczyć przez aktualne tempo), ile taki czas wynosi.

    NOP nie zmienia TABa, ale też go "nie kończy". Ustawia wskaźnik pozycji TABa (w ścieżce) na 0 i puszcza go od początku.

    Intuicyjnie przyjmowałem, że pozostawia bez ingerencji (nie przestawia pozycji TABa). Czy tak nie było może na początku? (i jeszcze może nie jest?)

    Takim zakończeniem odtwarzania ścieżki jest funkcja "TRACK OFF" (oznaczona "==")
    Problem w tym, że po takim wyłączeniu ścieżki, już nic nie będzie mogło zagrać na tej ścieżce

    Pewnie ta funkcja ma większy sens znów dla czystych SFXów (jak w przypadku JUMP TO, czyli bez czytania SONG, a z bezpośredniego wywołania).

    O ile się gdzieś nie walnąłem

    Może nie już tu (albo - w ogóle), ale dla mnie niejasne pozostaje:
    TAB #0 w wierszach 00 i 01 zagrałby dwa razy.


    Wg. tych danych rzeczywistej długości, które podałeś, dla TABów #0 oraz #1 i #2, to wydawać by się mogło, że TAB #0 powinien zagrać tylko raz.
    Chyba, że go właśnie "zresetuje" NOPem* (przerzuci przy zmianie wiersza na odtwarzanie od początku), ale wtedy zagra, co prawda, dwa razy, ale tylko pierwszą swoją połówkę (o drugiej swojej połówce TAB "zapomni"). Trochę "nietegez", jak dla mnie, bo jak w takim razie uzyskać efekt, o którym napisałem, że tak powinien się zachować silnik? (względem tego konkretnego fragmentu zapisu SONG w wierszach 0 i 1, z przykładu)

    No chyba, że całkiem z tym wnioskowaniem swoim "odleciałem" i "chrzanię" od rzeczy (możliwe). (Wtedy - sorry.)

    wiersz 03: TAB #3 kończy się w połowie drugiego odtwarzania TAB #0, a ten kończy się pierwszy, więc zmienia pozycję SONGa na 03. [...]

    Dość trudno to przeanalizować (może mi), choć być może nie ma tu najmniejszego błędu przewidywania. Mimo wszystko trudno zapanować (siłą wyobraźni) nad takimi, a względnie niewielkimi jeszcze, niesynchronizacjami w długościach TABów, odtwarzanych na sąsiednich ścieżkach. Z tego już powodu, nie mam do tego rozwiązania osobistego przekonania, ale mogę się oczywiście grubo w swym osądzie mylić (co jest właściwe). Nie muszę pisać, że jako autor masz wszelkie prawo decydować całkowicie dowolnie o kierunku rozwojowym własnego programu i sam go ustalasz.

    Reszty argumentów nie przemawiających za tym koncepcyjnym rozwiązaniem nie ogarniam (ale to chyba zrozumiałe).

    Przepraszam, że tak dużo ostatnio komentuję ten Twój temat.
    • 25: CommentAuthorgolomolo
    • CommentTime29 Jun 2021
     
    Ten temat czyta się jak dobrą książkę, z niecierpliwością czekając na nowy rozdział :)
    A przy okazji dodając swoje 3 grosze, to mi się marzy, aby w sekwencji TABów można było ustawiać wartość transpozycji np. od -12 do +12 półtonów. Umożliwiłoby to potraktowanie TABów jako ścieżek arpeggiatora. W tym przypadku kilka zapętlonych TABów wystarczyłoby na akompaniament dla całego utworu. Biorąc pod uwagę, że TABy zapewne będą upchane różnymi instrumentami, potrzebny będzie dodatkowy znacznik (np. w definicji instrumentu), czy dana nuta/instrument ma być poddany transpozycji, czy też nie (np. w jednym TABie bass poddawałby się transpozycji, a perkusja już nie). Funkcjonalnie działają podobnie (na PC) stary AODIX i RENOISE, choć tam jest to bardziej rozbudowane i pattern może być traktowany jak zwykły instrument a transpozycja odbywa się automatycznie przy graniu nut na klawiaturze.
    • 26: CommentAuthormarok
    • CommentTime29 Jun 2021 zmieniony
     
    @golomolo: Nic z tych rzeczy nie wiem i nie bardzo rozumiem, o których piszesz, ale przyjemnie mi, że dodajesz własne propozycje i pomysły do tego wątku (sam trochę "bredzę" i lepiej że koncepcje z wyższej trochę półki też się tu dzięki temu przeczyta). Trochę zaczynam jednak współczuć tego wszystkiego @pebe, bo musi wszystko to ogarnąć swoim umysłem i wyobraźnią.

    ---


    rozpisanie tego przykładu na grane pozycje w wierszach
    02: 00-31 00-31
    03: 00-15 32-47
    04: 16-31 00-15

    wiersz 04: TAB #0 kończy granie po 16 wierszach i kończy zmieniąc poz. SONGa na 05.

    Pisząc dokładnie tak, miałeś na myśli zapewne drugą połówkę TAB #0 (drugie 16 pozycji), ponieważ użyłeś sformułowania, że ten TAB "zmienia poz. SONGa na 05.", a aby to zrobić, wg zasady, którą sam określiłeś, musi dojść do ENDTAB (w swoim zapisie). Więc w bilansie tego pewnie się pomyliłeś pisząc o 1,5 (odtwarzanych TAB #0), gdyż to ostatnie 0,5 wliczane do bilansu trochę zaciemniło sprawę (tak zupełnie pobieżnie, w pamięci szybko licząc).

    Taka rozpiska jednak znacznie ułatwia sprawę. Stąd było mi niepomiernie łatwiej dojść tej drobniejszej nieścisłości (w pamięci - nie doszedłem, a długo "analizowałem").

    P.S.
    Muszę sobie wbić jeszcze do głowy, żeby pisać BLANK nie NOP w odniesieniu do pustych wpisów w SONG.
    • 27:
       
      CommentAuthorpebe
    • CommentTime29 Jun 2021 zmieniony
     
    2b || !2b - To Be or not to Be

    Zacznę może od @golomolo:
    Ten temat czyta się jak dobrą książkę, z niecierpliwością czekając na nowy rozdział :)

    No nie wiem ;) Ale jeśli się podoba to się cieszę.
    (...)mi się marzy, aby w sekwencji TABów można było ustawiać wartość transpozycji np. od -12 do +12 półtonów.

    To by faktycznie było mocne i nie spotykane rozwiązanie w trackerach na Atari. Teoretycznie, można by zarezerwować grupę SFX na taki patent. Jest ich trochę więc, można poświęcić np. 8 może 16 - choć nie wiem, czy taka liczba byłaby wystarczająca. Nigdy nie korzystałem z takich funkcjonalności, więc nie wiem, jak bardzo by to było przydatne i wykorzystywane.
    Jest jeden problem w tym pomyśle, bo:
    - zapis SONGa w pamięci jest następujący:
    00: T1 T2 T3 T4
    04: T1 T2 T3 T4
    08: T1 T2...
    .
    .
    .

    gdzie wartość z lewej to offset.
    T1: może zawierać funkcje i wtedy T2-T3: jest miejscem na parametr dla niej.


    Nie zmieszczę zapisu transpozycji dla TABa w jednym bajcie - nie ma bata, bo sam TAB to wartości od 0-63 (6 bitów) a na +/-12 potrzebuję 5 bitów.
    Fakt. Można by określać to za pomocą hipotetycznej funkcji TAB-TRANSPOSE, gdzie parametrem byłaby ścieżka i wartość transpozycji dla niej, np.
    #1 #2 #3 #4
    00: 00 10 20 30 ; tu TABy są grane normalnie
    01: TT 01 -5 ; funkcja TAB Transpose dla ścieżki #1 o -5 półtonu
    02: 00 11 21 31 ; TAB 00 na ścieżce #1 jest grany dla instrumentów od 48-63 o wartość transpozycji, reszta ścieżek pozostaje bez zmian.


    Musiałbym to przemyśleć, jednak, tak niecodzienny (jak na tracker) pomysł, zostawiłbym raczej na nową wersję - choć sam nie wiem :P

    W ogóle, chodzi mi cały czas po głowie, pewien szalony pomysł, tylko nie do końca wiem, jak go zrealizować.
    Coś na wzór zapisu MIDI - liniowego zapisu TABów ze znacznikami czasu. Strasznie mnie kusi, bo (mam wrażenie że) to by rozwiązało kilka nierozwiązanych obecnie problemów :P Tylko ile by mogło ich stworzyć? that is a question

    (...)AODIX i RENOISE, choć tam jest to bardziej rozbudowane(...)

    Kiedyś bym się rzucił od razu na te tytuły - uwielbiałem programy dźwiękowe.
    Maluch mógłby nie udźwignąć takiego skomplikowania spraw, nie mówiąc już o zastosowaniu tak rozbudowanego silnika w innych produkcjach. Może się mylę, ale gdzie czas na właściwy program, przy takim obłożeniu przez przerwanie ;) (taka niesforna dygresja intelektualno-retoryczna)

    Oki, @marok:
    TAGu=TABie. Przyjąłem :D

    Co do rozpiski, mogłem popełnić błąd - jak już pisałem wcześniej. Zaczynam się troszkę gubić w swoich przemyśleniach. Upały też nie sprzyjają intelektualnemu wykazywaniu się, a dodatkowo mam "remont osiedla" (wymiana rur CO) i jest tak potworny hałas, że można zwariować.

    Jak najbardziej masz rację co do rozpiski. Walnąłem się i "cisnąłem" dalej. Ehh.. Cały ja. :P

    Przepraszam, że tak dużo ostatnio komentuję ten Twój temat.

    Człowieku, gdyby nie Ty, ten wątek byłby martwy jak moje myślenie w godzinach szczytu po 12h pracy w hucie :D
    Nie przepraszaj. Jak chcesz to pisz, nawte nei zorzumaile ;)

    Nie muszę pisać, że jako autor masz wszelkie prawo decydować całkowicie dowolnie o kierunku rozwojowym własnego programu i sam go ustalasz.

    Wiem. :D ale ja jestem osobą ulegającą sugestiom :) (to tak pół żartem-pół serio)
    Są pomysły które po prostu mi się podobają. Lubię wyzwania, jednak nie lubię, jak brakuje mi wiedzy, czy możliwości (to chyba idzie w parze). A już kompletnie nie lubię, jak brakuje budżetu (czyt. miejsca w RAM) na wdrożenie świetnego pomysłu.

    Trochę zaczynam jednak współczuć tego wszystkiego @pebe, bo musi wszystko to ogarnąć swoim umysłem i wyobraźnią.

    Wyobraźnia jest - nawet aż za duża. Niestety, z umysłem, coraz gorzej, ale na to już częściowo odpisałem powyżej. Częściowo, bo są jeszcze inne czynniki, które wpływają na motywację i siłę do działania, ale to nie jest miejsce na takie wywody.

    Muszę sobie wbić jeszcze do głowy, żeby pisać BLANK nie NOP w odniesieniu do pustych wpisów w SONG.

    Sam się mylę z NOP i BLANK. Nie wiedzieć czemu, stosuje to zamiennie.

    Powinno się przyjąć nomenklaturę SFXMM (jeśli o nim piszemy, a o nim piszemy :D), gdzie pusty wpis "--" w ścieżce SONGa jest oznaczony w liście funkcji SONG jako NOP (No OPeration)

    BLANK raczej pasuje do pustego TABa, np:
    00: --- --
    01: 31>000
    02: ENDTAB


    To byłby BLANK :D

    Ale... to taka luźna dygresja.

    ---

    Dzisiejszy rozdział sponsorowały literki W, T, F oraz cyferka 8 (lubię 8)
    Bije mi już - idę spać.
    • 28:
       
      CommentAuthorpebe
    • CommentTime29 Jun 2021 zmieniony
     
    małe PS.

    Zaimplementowałem wyliczanie rzeczywistej długości TABa.
    W module edycji TABa, za raz za nazwą są dwie wartości:
    - pierwsza: ilość wierszy TABa; po pomnożeniu tej wartości przez dwa, otrzymamy rozmiar w pamięci (w SFXMM należy dodać jeszcze 8, na nazwę)
    - druga: rzeczywista długość TABa

    Działa, ale chciałbym to jeszcze upchać do np. listy TABów, albo w linii statusu w module SONG.
    • 29: CommentAuthormarok
    • CommentTime30 Jun 2021
     
    Po przemyśleniu, ja już nie widzę problemu w tym, że nie da się prosto rozpocząć odtwarzania od wybranego wiersza SONG.

    Nie ma w istocie takiego problemu, realnie.

    Nic nie trzeba też zapamiętywać, żeby potem od tego odtwarzać ("na zmiennych"), co sam też proponowałem - to w gruncie rzeczy całkowiecie zbędne.

    Także nie jest problemem pełna obsługa funkcji JUMP TO jako komendy z linii SONG. Wszystko do siebie pasuje i jest proste. Trzeba tylko uzmysłowić sobie dobrze, że teoretyczny problem, jaki mógłby się pojawić z asynchronicznością odtwarzania kanałów, to pewien mit z założenia, na który w realnym świecie nie ma specjalnie miejsca.

    Zawsze jest tak, że chcąc nawet rozpocząć dany utwór z innego niż jego początek miejsca (choćby w procesie twórczym), rozpoczynamy i tak od jakiegoś pewnego początku - nowego motywu, nowej "zwrotki", etc. A więc w zapisie uceluje to dokładnie na początek wszystkich TABów w kroku, wybranego wiersza, SONG.

    Moim jedynym postulatem jest tylko to, że skoro założyliśmy sobie, że natrafimy na początek TABów w każdej ze ścieżek (one się ze sobą mają zbiegać w tym miejscu, synchronizują w sumie długości wszystkich poprzednich TABów, licząc oddzielnie dla każdej ze ścieżek), to odpowiednio do tego zerujemy zmienne, które lokalizują pozycję wszystkich TABów z odczytywanego wskazaniem wiersza SONG (bo przerwanie wcześniejszego odgrywania mogło nas "złapać" w jakimś innym momencie aktualnego na tamten moment TABa), i to jest akurat oczywiste, że trzeba to zrobić.

    Problemem jest tylko asynchronizacja, która wyniknie "z niewłaściwego" wyboru wiersza. Takiego jednak, który nie pasuje najlepiej do odtwarzania właśnie od niego - nie jest tym początkiem wątku w utworze, etc. Ale czy to taki wielki problem? Uważam, że prawie żaden. Użytkownik szybko "zaczai" że popełnił małe fopa i zaraz się sam poprawi. W sensie przerwie to błędne odtarzanie i wybierze inny dla jego realizacji wiersz.

    Czy nie można spojrzeć na ten cały problem w ten właśnie prosty i praktyczny sposób?

    Aha. Jest jeszcze małe do tego uzupełnienie. Są dwie możliwości zaradcze pewnej sytuacji, która ma prawo się zdarzyć i (ewentualnie) powinno się wyjść temu na przeciw.
    Kiedy wybierzemy "dobre" miejsce, ale nie mamy oczywistości w tym (z tego wiersza jedynie czytając), który TAB na kanale nie zapisanym w tym wierszu należy kontynuować. Właśnie chodzi o ten zapis BLANK/ NULL na pozycji SONG.
    Można to zrobić na sposób łatwy, ale nieco mało elegancki. Cóż nam szkodzi wstawić w te miejsca wpisy TABów, które i tak mają tam >>rozpoczynać<< (choć ponownie po sobie samych) swoje odgrywanie. To kwestia pewnej stylistyki, gdyż nie zmienia to nawet wielkości pliku wynikowego. Jeśli więc ktoś potrzebuje odznaczyć wiersz zdatny do startowania od niego odtwarzania utworu, to mógłby przecież uzupełnić wpisy w wierszu (trywialna sprawa).
    Drugim rozwiązaniem jest wyposażenie samego silnika (ponieważ mamy konieczność obsługi JUMP TO) o zdolność odnalezienia ostatniego z zapisanych na tej ścieżce TABa. Ponieważ wiemy, że to właśnie go mamy odwarzać. Też nie jest to tak bardzo skomplikowane, ale trochę dodaje kodu do silnika.
    Alternatywą wobec tego byłoby odwarzanie bez tej ścieżki (do czasu pojawienia się nowego wpisu w kolejnych wierszach) mimo, że powinna ona uczestniczyć w grze od wskazanego miejsca. "Od biedy", też ok dla mnie (wiedząc, że aby tego uniknąć wystarczy wpisać TAB do ścieżki pod "czekający" BLANK/ NULL). Może to być nawet czasem celowe, żeby ten akompaniament czasem był, a czasem go nie było (wpisując i kasując TAB na pozycji ścieżki SONG), w procesie twórczym. Byłaby więc ku temu taka (dodatkowa?) sposobność tego wymuszenia/ uzyskania.
    • 30:
       
      CommentAuthorpebe
    • CommentTime1 Jul 2021 zmieniony
     
    @marok: Jak najbardziej się zgadza. To nie tyle problem (choć mogłem tak to nazwać) co, przedstawienie tego, jak silnik by "ogarniał" takie sytuacje.

    "By ogarniał", bo jak na razie jeszcze nie ogarnia.

    ---
    Zaś odzyskałem kilkaset bajtów pamięci, optymalizując kod.
    Dodałem wskazania realne pozycji TABa w jego edycji. Prawa kolumna z liczbami w trybie edycji TABa, pokazuje realną pozycję TABa.
    Dobrze to wygląda - wypełniło to ekran.

    W edycji SONGa:
    - CTRL+INSERT, CTRL+DELETE wstawia i kasuje wiersz SONGa (tak jak w edycji TABów)
    - w przypadku wpisów dotyczących TABów, w pasku statusu pokazuje się jego nazwa oraz rzeczywista długość.
    Wydaje mi się, że to powinno wystarczyć, by ogarniać niepewne sytuacje związane z synchronizacją i innymi kłopotliwymi sprawami.

    Niestety nie udało mi się zaimplementować pokazywania rzeczywistej długości w liście TABów.

    Coś, co mnie zaskoczyło. Myślałem, że "wyrzucając" dane z zasobami, zyskam na pamięci. Jakże się zdziwiłem, że program bez zasobów jest większy, niż z zasobami :|
    Fakt, jest plik jest mniejszy, ale kodu programu więcej.

    ---

    Powiem szczerze, czuję się ostatnio cholernie zmęczony (nie tylko projektem). Dokonywanie zmian, czy dodawanie funkcjonalności to dla mnie ogromny wysiłek. Nawet pisanie tu, jest ciężkie :/

    Przede mną jeszcze:
    - ogarnięcie silnika, tak aby wszystkie założenia były zgodne z oczekiwaniami.
    - dodatkowe procedury do biblioteki SFX_ENGINE, do obsługi plików SMM, SFX, tak aby można było już bez większych problemów wykorzystać silnik w innych produkcjach.
    - przemyślenie kwestii transpozycji TABów - bo coś mi ostatnio zaświtało, że nie będzie to takie trudne do realizacji
    - "matko bosko" zrobić w końcu IO->NEW!!!
    - aktualizacja zapisu pliku SMM (bo nie zapisuje informacji dotyczących początkowych wartości tempa)
    - dodanie funkcji ustawiania tempa w module TAB (TAB->OPT->SET TEMPO) tak, by nie trzeba było przemieszczać się do SONGa i tam zmieniać (taki skrót)
    - jest jeszcze miejsce na kilka "ficzerów", ale najpierw to co powyżej.

    Co więcej:
    - program do tworzenia schematów kolorystycznych
    - program do wygodnego i zaawansowanego tworzenia SFXów
    - program do eksportu utworu do OBJota.

    Nota hipotetyczna do transpozycji TABów
    Tak jakoś przyszło mi do głowy, że wystarczy dodać do rejestrów kanału, informację o wartości transpozycji.
    Jej wartość byłaby uwzględniana przy wynikowej nucie, tuż przed pobraniem wartości dzielnika częstotliwości dla tej nuty. Dla wartości 0 transpozycji oraz dla SFXów z danego przedziału, ten blok byłby pomijany.
    Ból jest jedynie przy dźwiękach opisywanych za pomocą NOTE VALUE, gdyż tu nie występuje odwołanie do tablic nut.

    Hmm.. właśnie minie znowu naszło...
    Można też wykorzystać też ten fakt, że niema możliwości transpozycji zapisów z NOTE VALUE. Może to niezbyt czytelne, ale jest to pewna "blokada" dla transpozycji SFXów z przedziału podlegających transpozycji.

    ---

    Obraz dysku w załączniku.
    • 31:
       
      CommentAuthorpebe
    • CommentTime1 Jul 2021 zmieniony
     
    last minute update...

    Gapiłem w monitor na którym był uruchomiony SFXMM. Przewijał się na nim leniwie TAB z sekcją perkusyjną. Nuty, nuty, nuty, nuty...
    Pomyślałem sobie: "A gdyby tak zamiast nut, były nazwy SFXów?"
    No tak, ale jak je tu wpisać? Nie ma na to miejsca.
    I wpadł mi do głowy pomysł.
    Ponieważ jest możliwość zdefiniowania SFXa w trybie modulacji DFD, gdzie nie ma możliwości określenia nuty, jaką będzie grany, to wykorzystam ten fakt i zamiast nut dla tego typu SFXów, będę wyświetlał ich nazwy.

    I oto przed Wami, a dokładniej w załączniku, automat perkusyjny SFXMM.
    Przykład w obrazie, plik SONG.SMM

    Dobrze to wygląda ^_^
    • 32: CommentAuthormarok
    • CommentTime1 Jul 2021
     
    (Ja, ze swoim tu, jeszcze do poprzedniego wpisu @pebe)

    Powiem szczerze, czuję się ostatnio cholernie zmęczony (nie tylko projektem).


    (Zdążyłem na brudno dużo napisać w odpowiedzi na ten cytat, ale - teraz krótko.)

    Odpoczywaj, więcej śpij, korzystaj z kontaktu z naturą (może i słońca) dla wyciszenia i równowagi, nie myśl wciąż o problemach związanych z projektem lub by odpowiadać na kolejne wpisy różnych* osób. Trochę jesteś za obowiązkowy i emocjonalny, nieco zbyt grzeczny i traktujący wszystkich z równym, dużym szacunkiem (niezależnie od prezentowanego poziomu zrozumienia rzeczy, które komentują, i rodzaju tych komentarzy). Wciągasz się i wymagasz od siebie trochę za dużo. Warto przystopować, sam to rozumiesz, ale jest Ci trudno walczyć z własną naturą. Czasem spróbuj.


    A teraz jeszcze komentarz do pozostałej treści (może na jakiś inny czas, by odpowiedzieć).



    TABów, w pasku statusu pokazuje się jego nazwa oraz rzeczywista długość


    To pierwsze, co po uruchomieniu nowej wersji, rzuciło mi się w oczy, że "w podsumowaniu" TABa (trzymam się już tego swojego slangu) jest już podawana wartość taka, jaką się spodziewałem - a poprzednia, jak zauważyłem, wyświetlała o 1 większą, bo chyba brała pod uwagę (liczyła) ENDTAB. Miałem nawet wspomnieć o tym szczególe (aczkolwiek w miarę znaczącym dla ogólnej czytelności, tym bardziej dla samodzielnie zaznajamiających się z edytorem), więc cieszy mnie to, że tak się już "samo" stało.

    Z uzupełnień do tego co pisałem ostatnio, to jeśli robisz JUMP TO lub startujesz z dowolnego wiersza SONG (wywołanie z edytora), to warto jeszcze, upewniam się by o tym dla zasady wspomnieć (choć na pewno byś o tym pamiętał), skasować aktualne TABy przypisane do ścieżek (poza samym zresetowaniem pozycji w TABach; wstępnie wyciszyć kanały). Po prostu o tym zapomniałem napisać poprzednio.

    Niestety nie udało mi się zaimplementować pokazywania rzeczywistej długości w liście TABów.

    W liście TABów, nie - ok. Fajnie dla mnie, że nawet brałeś to pod uwagę. Mnie przyszedł dopiero co na myśl jeszcze taki pomysł, że będąc na danej pozycji w liście TAB, można by mieć, wybierając OPT, dostęp do takiego wyliczenia na (specjalne) żądanie. :) Użytkownik chce się upewnić, przy komponowaniu, czy jest na tym miejscu w TAB, gdzie sądzi, że jest? (byłoby mu tak łatwiej, niż może to sobie "policzyć", w obliczu stosowania wcześniej pętli?) - to by miał możliwość skorzystać. Ot, taki drobny pomysł - niekoniecznie trafiony, choć wart może chwilowego zastanowienia, mam nadzieję.

    To nie tyle problem [..] co, przedstawienie tego, jak silnik by "ogarniał" takie sytuacje.

    Mogę nie rozumieć, ale wydaje mi się, że mówisz o tym, jak edytor by sygnalizować miał, w jakiś dodatkowy sposób(?), efekt rozjechania się synchronizacji (lub nawet samego takiego niebezpieczeństwa), w przypadku "wadliwego" (lub potencjalnie "wadliwego") wyboru wiersza SONG? Nie jestem tej interpretacji pewien (takiej, jak napisałem, trochę sensu nie rozumiem), więc dlatego ją przedstawiam.
    Dla mnie, nie trzeba robić nic. Ktoś słuszy, że mu się rozjeżdża synchronizacja? - Zaraz ją przerywa (odgrywanie) i wie z czego ona wynika i o co chodzi. Komunikacja edytora z użytkownikiem, co do zasady, zachodzi.

    "By ogarniał", bo jak na razie jeszcze nie ogarnia.

    (To o silniku.) Mnie się wydaje jednak, że już w zasadzie ogarnia. Poza tylko implementacją JUMP TO (i dodaniem resetu TABów).


    Z pomysłów jakie mi przyszły jeszcze do głowy. Od razu napiszę, że to nic dużego.

    Ponieważ rozważałeś szybsze skończenie kroku (danego wiersza) SONG przez jeden z TABów ostatnią zapisaną w nim pozycją, wymuszając to na pozostałych (wtedy przez ENDTAB), to rozważ jakiś dodatkowy jeden rozkaz, który to samo zapewni. Coś więc w stylu ENDTABS (ale inaczej, bo to za długa nazwa i chyba nie najtrafniej oddająca znaczenie tego, o co chodzi). Mógłby się może też przydać, by nie definiować dodatkowo krótkich TABów w sytuacjach, gdy dałoby się je zastąpić długimi (z pasującą do nich zawartością na tym krótszym, odgrywanym odcinku).
    • 33:
       
      CommentAuthorsun
    • CommentTime1 Jul 2021
     
    Nie no, chwilę się się zdrzemnąłem od ostatniej wersji jaką oglądałem, ale widzę, że tu robota idzie z gazem ;)
    • 34:
       
      CommentAuthorpebe
    • CommentTime1 Jul 2021 zmieniony
     
    @marok:
    Ostatni rok (a nawet ciut ponad) jest jak odpoczynek. Praktycznie zero stresu. Śpię po 8-9h zależy, ale nie dłużej (prędzej krócej, ale na szczęście, rzadko się to ostatnio zdarza). Natura - tu jest gorzej. "Fobia społeczna" która wykształciła się przez ostatni rok, daje się we znaki, ale na szczęście jest gdzie wyjechać (działka z rodzicami jest dobrym miejscem, choć nie jest wolna od "ludzi")
    Obowiązkowość? Nie lubię przerywać prac, bo do powoduje u mnie demobilizację. Często muszę dużo czasu poświęcić, by wrócić do "pierwotnego toku myślenia".
    Grzeczny? Dziękuję ;) Zdarza mi się :D
    O tak, wiem, że się mocno angażuje. To wynika z pasji jaką jest dla mnie programowanie - ja to kocham, a jak coś kocham to na zabój (suicide)

    Z uzupełnień (...) jeśli robisz JUMP TO(...)

    Jak na razie funkcje w SONGu nie są zaimplementowane w 100%, ale dzięki za wskazówkę, z pewnością zwrócę uwagę na to, tworząc kod do obsługi.

    (...) taki pomysł, że będąc na danej pozycji w liście TAB, można by mieć, wybierając OPT, dostęp do takiego wyliczenia na (specjalne) żądanie. :)

    Aż "specjalne żądanie"? ;) wystarczyłoby "żądanie" to już dużo :D
    OPT nie jest dostępne z poziomu trybu edycji.
    Ale rozumiem, że ten pomysł już rozwiałem tym co zrobiłem? Bo jak nie, to wybacz, ale nie bardzo go rozumiem :(

    Mogę nie rozumieć, ale wydaje mi się, że mówisz o tym, jak edytor by sygnalizować miał, w jakiś dodatkowy sposób(?), efekt rozjechania się synchronizacji

    Chodziło TYLKO o przedstawienie zjawiska. Konfrontację z innymi (potencjalnymi) użytkownikami programu, jak oni to widzą. Rozmowę na ten temat, czy to "złe", czy "normalne". Propozycje rozwiązań.
    Nic ponad to.

    A sygnalizacja takiego zjawiska w trakcie tworzenia. Hmm... :D To nie byłoby głupie.
    Odtwarzając SONG (jakby nie patrzeć) tracisz czas na odsłuch. A jakby to było już na etapie "pisania" sygnalizowane... nom... zastanawiające. Taki "parser offline dla nut" hihi - czy jakoś tak ;)

    Z pomysłów jakie mi przyszły jeszcze do głowy.

    Trochę mi zajęło "co poeta miał na myśli" :) Ale chyba już wiem - jak się mylę to mnie popraw.

    "Ponieważ rozważałeś szybsze skończenie kroku..." - chodzi Ci o przedstawioną "zasadę Kto pierwszy, ten zmienia", tak?
    "...rozważ jakiś dodatkowy jeden rozkaz, który to samo zapewni." - jeśli by zmienić sposób działania funkcji "CHANNEL OFF", którą to w przykładzie SONG.SMM stosuje jako "END SONG", bo ta nie jest zaimplementowana, to właśnie ją, bym do tego celu wykorzystał, jako taki "szybki synchronizator"

    Mógłby się może też przydać, by nie definiować dodatkowo krótkich TABów w sytuacjach, gdy dałoby się je zastąpić długimi

    Myślałem o takiej funkcji wypełniającej. Generowała by NOPy (czyli "nic" :) ) do jakiejś, np. konkretnej ścieżki (TABa na ścieżce) Do póki by się nie skończył, funkcja wypełniająca by utrzymywała "tik TABa'.

    Będę nad tym myślał, jeśli nie wykombinuje innego algorytmu dla odtwarzania TABów i SONGów, a coś z tym trzeba zrobić, bo... nie podoba mi się, że konstrukcja obecnego algorytmu sprawia tyle problemów.

    @sun: Jak mogłeś spać, gdy ja tworzyłem??? ;)(bo ja nie mogłem :D:D) "To ja tu o mało ducha nie wyzionąłem, a Ty będziesz sobie drzemał w najlepsze?" hihihi...
    Żartuę.
    Idzie, ale czy gazem? Tak na pół sprzęgle, bo ciut pod górkę cały czas (nie mam prawa jazdy i nie mam zielonego pojęcia, o czym teraz napisałem ;) ale brzmi ciekawie, hihi)
    • 35:
       
      CommentAuthorsun
    • CommentTime1 Jul 2021
     
    @pebe: z gazem. Mam projekty rozgrzebane, najstarszy ma 2 lata i nie ma kiedy kończyć, także... z gazem.
    Pewnie dlatego, że śpię, to mi się roboty odkłada :)
    • 36: CommentAuthormarok
    • CommentTime2 Jul 2021 zmieniony
     
    OPT nie jest dostępne z poziomu trybu edycji.

    Racja. Znów mnie złapałeś na nieznajomości edytora (który tyle komentuję).

    Natomiast wciskając return w liście TAB na podświetlanej pozycji pokazuje się lista możliwości edycyjnych. Podejrzewam, że gdzieś na niej dałoby się umieścić taką dodatkową informację ("bez zwrotną"), chociaż pewnie średnio by to pasowało do kontekstu. Więc niekoniecznie to ma sens.

    Ale rozumiem, że ten pomysł już rozwiałem tym co zrobiłem?

    Ten inny pomysł jest pokrewny i trochę "maksymalistyczny". Z tego też powodu mniej potrzebny, skoro jest to, co zrobiłeś (jakby podstawowa potrzeba - aby się upewnić w rzeczywistej długości redagowanego TABa).

    Chodziło TYLKO o przedstawienie zjawiska. Konfrontację z innymi (potencjalnymi) użytkownikami programu, jak oni to widzą. Rozmowę na ten temat, czy to "złe", czy "normalne". Propozycje rozwiązań.

    Jeśli chodzi o ocenę, to ja oddaję swój głos, że to "normalne". Może jestem optymistycznie do takich mniej standardowych zachowań programu nastawiony (chodzi mi o to, że może być z edytora kompozycja łatwo puszczona asynchronicznie, gdy ktoś tylko ma taki kaprys - a na takie "dictum" nie każdy szanujący się program by sobie pozwolił), ale dla mnie takie rozwiązanie przejdzie, jak nic (o ile ktoś się przekona do edytora, jako takiego).


    jak się mylę to mnie popraw.

    Jest, jak piszesz - o to mi chodziło.

    jeśli by zmienić sposób działania funkcji "CHANNEL OFF"

    To nie wiem czy warto tym kosztem (bo nie ma już "miejsca"). A ta funkcja może się jednak przyda mimo wszystko (albo inaczej jeszcze się jej miejsce do czegoś wykorzysta)

    Myślałem o takiej funkcji wypełniającej. Generowała by NOPy (czyli "nic" :) ) do jakiejś, np. konkretnej ścieżki (TABa na ścieżce) Do póki by się nie skończył, funkcja wypełniająca by utrzymywała "tik TABa'.

    Może z opisu łapię, co masz na myśli, ale to jest troszkę inna myśl, niż to, co sam sugerowałem.

    Mnie chodziło (także w tym zdaniu, do którego się odniosłeś) o coś takiego:
    Masz TABy "a","b","c" i są one na 64 pozycje (każda). Masz TAB "x" i ma on w swoim zapisie na samym końcu, powiedzmy zaraz po 16 "normalnych" pozycjach, funkcję "terminacji" odgrywania wiersza SONG (czyli wszystkich ścieżek w danym wierszu).
    Więc, jeśli działa ta funkcja dokładnie tak, jak sobie tu "postulujemy", to nie trzeba pisać oddzielnych TABów "a`","b`","c`", które mają tylko 16 pozycji i są te ich pozycje identyczne ze swoimi odpowiednikami z tamtych (dłuższych) TABów, gdy chcesz, by zagrały w swojej skróconej (ograniczonej do 16 pozycji) wersji.

    Czyli, że będzie działać:
    xx: a b c x
    tak, iż wszystko zmieści się, w czasie odgrywania, w 16 pozycjach;
    bo inaczej, gdyby funkcja w TAB x nie działała (jak sobie tu zażyczyliśmy), to by mógł TAB x grać w tym przypadku, 4 razy pod rząd, z wywołania tego wiersza (SONG), a TABy a, b i c wszystkie swoje 64 pozycje.
    A nam by nie o to tu chodziło (aczkolwiek mamy dużo TABów do zagospodarowania, gdyby nawet trzeba było przygotować "skrótowce" do tych pierwszych i nimi te zastąpić w takim wierszu).
    Przepraszam, że tak drobiazgowo o tym napisałem, ale to żeby było wszystko jasne (w miarę możliwości, w całej rozciągłości).

    Będę nad tym myślał, jeśli nie wykombinuje innego algorytmu dla odtwarzania TABów i SONGów

    to ja bym zachęcał, żeby chociaż spróbować, jak to by wyglądało i byś przygotował taką wersję testową może, z jakąś też muzyczką, która mogłaby się asynchronizować, gdyby była z "niewłaściwego" wiersza SONG startowana.
    • 37: CommentAuthormarok
    • CommentTime2 Jul 2021
     
    Przypadkiem, jednak dotarło do mnie (przyznaję, trochę późno), w czym trudność i niemały problem, a co związane jest z pracą silnika procedury odgrywającej song. Rozumiem teraz przesłankę dla tego rozważania, że ten TAB który kończy pierwszy - ten zmienia (wszystkim ścieżkom) wiersz SONG. To przez te oddzielne kursory dla każdej ścieżki osobno - nie wiedziałem, że są od siebie zupełnie niezależne (przedstawia i uzmysławia to najlepiej pracę silnika, choć było o tym słusznie już mówione, że tak to działa - jako "tylko stwierdzenie faktu").

    Widzę to w złożonym dość algorytmie postępowania tak, choć dalece tego nie wiem, czy to będzie działać (jest to zupełnie nie poparte niczym).

    Ten TAB, który kończy pierwszy (od wspólnego startu) powoduje, że jeden wspólny kursor (a więc i realnie odczyt z wiersza SONG) schodzi niżej. I ta zasada nadal potem obowiązuje, z każdym kolejnym krokiem SONG, ale tylko o ile w tym wierszu konkretny TAB zaczął grać od początku na którym teraz kończy - jeśli tylko był choć jeden taki TAB w wierszu, który w nim zaczął grać - jeśli żaden TAB nie zaczął grać w tym wierszu, to ten dodatkowy warunek nie obowiązuje - trzeba więc przesunąć kursor, mimo że ten który się skończył, w nim nie zaczął (inaczej zaś: jeśli grał już w poprzednim wierszu, a jest taki TAB, który zaczął w nim dopiero grać - ten jest kontynuacją, to nie). To oznacza, że może zostać podjęta próba odczytu nowego TABa w każdej ze ścieżek (nie tylko tej która zainicjowała zmianę wiersza na kolejny). Jeśli pozycja na ścieżce SONG jest pusta, to jest to prosta kontynuacja odgrywania TABa (bez zmiany pozycji), jeśli jest tam jednak numer TABa - jest on 'zapamiętywany na zapas' (a szczegół już, "w źle" skonstruowanych songach - nadpisywany poprzedni z zapamiętanych, jeśli ten wcześniej zapamiętany nie zdążył być jeszcze użyty), chyba że właśnie poprzedni (ze ścieżki) się skończył (wtedy nie czekamy z nim i nie zapamiętujemy go, ale jest on teraz już do gry), i jest on przewidziany do odgrywania zaraz kiedy ten obecny (który się jeszcze nie zdążył skończyć) dojdzie wreszcie do swojego końca (pomimo zapamiętania nowego, odgrywanie starego TABa idzie więc normalnym trybem - kontynuacja od tej samej pozycji).

    Teraz nie mam pomysłu, jak zweryfikować ten "algorytm" i ewentualnie w których punktach należałoby go głęboko poprawić (czy też może nie jest generalnie "do bani", czyli że jest alogiczny). W sumie oparłem się na intuicji, co ma jakąś szansę działać, a nie zimnej kalkulacji, opartej na odpowiednio dobranych przykładach. Zgadywanie takie. Trochę już późno, żeby do tego bardziej samokrytycznie się odnieść (z dystansem i rozmysłem), a więc niech idzie to tak, jak wyszło oryginalnie "spod pióra".
    • 38: CommentAuthormarok
    • CommentTime2 Jul 2021
     
    Ten mój ostatni komentarz może nie mieć sensu, gdyż okazuje się, że problem z kursorem wskazującym na różne wiersze dla ścieżek pojawia się w przypadku braku zaznaczenia w TABie ENDTAB i chyba tylko wtedy. Cały więc wywód wygląda więc bez sensu, bo nic takiego nie zachodzi normalnie, o czym tam napisałem (moźe jakaś inna wersja silnika była bardziej podatna na to osobne traktowanie ścieżek).

    Natomiast coś jest nie tak, gdy TAB nie ma ENDTAB w którymś miejscu i jest on odgrywany w wierszu SONG.
    • 39: CommentAuthormarok
    • CommentTime2 Jul 2021
     
    Problem jest w tym, że ścieżki całościowo (na długości SONG) mogą mieć różną długość i się nie zbiegać w jednym momencie (bardzo ciężko od strony kompozycji nad tym zapanować, żeby się zbiegły).
    Powodem jest dla mnie to, że każdy BLANK / NULL w ścieżce oznacza bezwzględnie wykonanie poprzedniego TABa (bo każda ścieżka obligatoryjnie musi wykonać dokładnie tyle samo TABów, co inna). Więc nie daje się go pominąć i potraktować jako miejsce do pominięcia "przez interpreter", które nic nie znaczy (puste miejsce), w uzasadnionym kontekście układu TABów na innych ścieżkach.

    W przebrnięciu przez to bym też widział główne i może jedyne potrzebne rozwiązanie.

    Dodam na marginesie tego wywodu, że chyba rozumiem więc po części lepiej już potrzebę rozważania, niedawno opisanego przez @pebe, żeby wydłużać (przez wyczekiwanie w bezczynności) odgrywanie TABa tak, by właśnie wyrównał się z odgrywaniem jakiegoś dłuższego, równolegle odtwarzanego w wierszu SONG, z którym byłby zestawiony. Chyba ta propozycja (jak ją zrozumiałem) nie rozwiązuje tego problemu.

    Osobne kursory to chyba nie problem, a być może nawet konieczność, ponieważ jest to pochodna odczytu z aktualnych wkazań na zmiennych silnika. Może to razić w pierwszym momencie, ale nie powinno przerazić "na amen" (zrazić na przyszłość).

    Najprostsze w tej sytuacji, byłoby wypełnianie BLANK/ NULL alternatywnie czymś co opisowo określę SKIP. Dla prostoty rozróżnienia sytuacyjnego (o co nam w kompozycji chodzi z tym konkretnym BLANK, traktowane jako powtórzenie czy bardziej SKIP). To oznacza inny numer rozkazu, a więc jakąś osobną kombinację, więc jest to koszt po stronie formatu.

    Cała więc strategia związana z algorytmem wyznaczania wspólnego kursora, nie byłaby więc wcale do niczego potrzebna, choć ta opisana wczoraj jest na pewno do poprawy, gdyby chcieć z niej skorzystać. Ponieważ są tam kwestie nieco nieprecyzyjnie określone i do jakiegoś wyprostowania.

    Ponieważ to zaproponowane teraz rozwiązanie wydaje się optymalne, nie wgłębiam się na ten moment w poprawę schematu tamtego algorytmu, który chyba mógłby po poprawkach jakoś się sprawdzać.
    • 40: CommentAuthormarok
    • CommentTime2 Jul 2021 zmieniony
     
    Ale rozumiem, że ten pomysł już rozwiałem tym co zrobiłem?

    Odpowiadam drugi raz - zupełnie odmiennie, bo to był mój poważny błąd, co napisałem za pierwszym razem. Przez gapiostwo nie zauważyłem, że jest już wyświetlana prawa kolumna liczb w liście TABa, która odpowiada "rzeczywistym pozycjom" - czyli to jest dokładnie to, o co mi chodziło (ten postulat w "wersji maksymalistycznej") w 100%.
    • 41:
       
      CommentAuthorpebe
    • CommentTime3 Jul 2021
     
    Jeśli kogoś (?) zastanawia, co się dzieje, to odpowiadam:

    Rozrysowuje kod silnika SFX na schemat blokowy.

    ->link<-

    Jak na razie, rozpisałem blok obsługi TABów i już widzę, gdzie są błędy (nawet w nierozrysowanym bloku SONG)

    Jeszcze trochę pracy mnie czeka, jednak wiem, że będę musiał napisać obsługę TABów od nowa. Prawdopodobnie, nie obejdzie się bez JSRów, których tak bardzo chciałem uniknąć. Może nie będzie aż tak źle.

    Trzeba czekać, a póki co, będę się powoli szykował na KWASa.
    • 42:
       
      CommentAuthorpebe
    • CommentTime6 Jul 2021 zmieniony
     
    Tak bardzo rozczarowany...

    Nie licząc dnia który spędziłem na KWASie, starałem się coś zrobić z SFXMM.
    Przerobiłem całą sekcję odpowiedzialną za odtwarzanie SONGów, ale nie jestem z tego zadowolony.
    Co prawda gra, przetwarza funkcje, ale:
    - jest tylko jeden wskaźnik pozycji SONG (wcześniej były cztery) - tzn. nie chodzi o to, że chciałem iść na ilość :P
    - jakoś straciła sens cecha różnych długości TABów. W wierszu SONG, jeśli któraś ze ścieżek skończy odtwarzanie wcześniej niż inne, reszta jest ucinana.
    - nie można utworzyć w pierwszym odtwarzanym wierszu żadnej funkcji, tzn. można, ale nie zostanie ona przetworzona, czyli:
    00: T: 05
    01: 00 01 02 03
    .
    .
    .

    Nie zadziała. Trzeba poprzedzić ustawienie tempa, wierszem z przynajmniej jednym wpisem (TABem).
    Jest "pseudo" rozwiązanie na ten przypadek.
    Ustawienie tempa w SONG->OPT->TEMPO jest odgórne i towarzyszy rozpoczęciu odtwarzania SONGa, więc utwór zaczynający się od ustalenia tempa jest nieco na wyrost, jednak:
    00: 00 01 -- --
    01: J> 00
    02: T: 10
    03: 03 04 05 --
    .
    .
    .

    (czyli dwa utwory w SONGu) Rozpoczęcie odtwarzania od wiersza 2, nie spowoduje ustawienia tempa :/
    Trochę to dzikie.

    - dodałem status odtwarzania, który przedstawia: aktualne tempo odtwarzania, licznik pętli SONG, pozycje w poszczególny TABach. Wszystkie wartości podawane są szesnastkowo - brakło miejsca w linii - co trochę burzy całościową koncepcję użycia liczb dziesiętnych w programie. Przy pozycjach ścieżek, można zauważyć symbol kwadratu, jest on pokazywany, gdy TAB wchodzi w pętlę REPEAT.

    - w końcu jest IO->NEW :P - myślałem o zaimplementowaniu jej, z możliwością pozostawienia SFXów, jednak zrezygnowałem z tej opcji, gdyż można zapisywać SFXy do osobnych plików, a w nowym "projekcie" po prostu można je wczytać.

    ---

    Kod silnika urósł do 736 bajtów - wydaje mi się to dużą wartością, choć nie porównywałem tego z innymi "playerami".
    Aby nie dublować pewnych fragmentów, wykorzystałem JSRy, co zaburzyło założenie (bo takie miałem) "nie operować na stosie w trakcie przetwarzania przerwania"

    Ehh... Oceńcie sami, czy takie rozwiązanie jest godne pozostawienia.
    Ja się skłaniam do przywrócenia poprzedniego.

    W załączniku przedstawiona wersja SFXMM.
    • 43:
       
      CommentAuthorpebe
    • CommentTime6 Jul 2021 zmieniony
     
    Dla ciekawskich kodu SFX-Engine, skleciłem jeden duży plik (936 linii surowego assemblera) nie zawierający include.

    ->link<-

    Nie wiem, czy na coś się taki wynalazek przyda, ale może akurat.

    @pin: Wspominałeś na (pos 20 maj/druga strona, post #42) o zdublowaniu pokeya dla stereo:
    Co do stereo, to zagraj na dodatkowym pokeyu to, co idzie na pierwszego (4 kanały o których mówisz), i daj możliwość regulacji opóźnienia tego, co leci na drugi układ.


    Moje pytanie do tego jest następujące. Jaki zakres opóźnienia wchodzi w rachubę?

    Bo opóźnienie od ramki w górę, będzie wymagało buforowania wyjścia audio, zaś mniejsze, przedłuży czas działania przerwania (przynajmniej tak mi się wydaje)
    Nie bardzo wiem, jak mógłbym to rozwiązać :/

    Jeszcze sobie zerknę na MegaPlayer MacGyvera o którym wspominałes, aby ocenić efekt.
    • 44: CommentAuthorsolo/ng
    • CommentTime6 Jul 2021 zmieniony
     
    2 ramki robi roznice (ma sie takie pseudo echo), w wiekszosci naszych produkcji puszczamy echo na drugiego pokeya (w przerobionych playerach buforujemy).

    generalnie zakres 1-4 wystarczy (generalnie zwykle uzywa sie 1-2 ramki opoznienia).

    tutaj masz przyklad (nie pamietam ile bylo ustawione, byc moze o 1 ramke za duzo, ale mi sie podoba;):


    caly poglos/echo to wlasnie ten efekt.

    zrob echo buffer na $d210-$d218 (czyli maksymalnie 4 x 9 bajtow) i w zaleznosci od glebokosci echa na drugim pokeyu bedzie odgrywane z danym opoznieniem. w niektorych przypadkach robi robote.

    Mozna robic tylko buforowanie, a odgrywanie poglosu zostawic po stronie usera, procedura w stylu:

    .proc stereoEcho
    ldy #8
    @ lda SFX_tracker.stereoBuffer,y ; lub +9 / +18 / +27 - glebsze echo
    sta $d210,y
    dey
    bpl @-
    rts
    .endp
    • 45: CommentAuthormarok
    • CommentTime6 Jul 2021
     
    Typowo bardziej ogólnie się wypowiadam.
    Odgrywanie łączne TABów różnej długości tak, aby grały do swojego końca, jest sporym nowum i nie wiadomo, jak by się to w praktyce mogło przyjąć. Czy chętnie by się z tego korzystało? Może jednak niekoniecznie? Isnieje pewna obiektywna trudność korzystania z takiej możliwości (trzeba sobie policzyć, aby się zgadzały łączne długości TABów na każdym kanale). Mnie się takie rozwiązanie (więc to z poprzednich wersji) koncepcyjnie podoba, ale jak wiadomo, wprowadza ono z miejsca swoje utrudnienia (dla projektanta tego rozwiązania) i ciężko koncepcyjnie je domknąć.

    Proponowałem do tamtego, zupełnie proste rozwiązanie. Załóżmy, że na pierwszym kanale grają kolejno 3 TABy o długości 32, a na drugim kanale grać mają 2 TABy o długości 48 (1,5 raza tyle długie, co na pierwszym). Aby się to zeszło ze sobą na koniec (3 = 3), trzeba sprawić (w silniku), żeby przeskoczyć w drugim kanale 1 wiersz / wpis (nie robi różnicy w zapisie który z tych 3 wierszy, ale trzeba to jednak "ręcznie" zaznaczyć dla odróżnienia).

    Oczywiście, ten "patent" nie zadziała, jak sobie coś źle policzymy (zestawimy źle / nieprecyzyjnie TABy) i to tak puścimy. Wtedy nam się muzyczka (w którymś miejscu) "rozjedzie", co jest już niecodzienną sytuacją, z którą można byłoby się spotkać "w programie". Więc do tego pewnie trzeba byłoby się jakoś przekonać i przyzwyczaić (od strony końcowego użytkownika - muzyka).
    • 46:
       
      CommentAuthorjhusak
    • CommentTime6 Jul 2021
     
    Softsynth daje możliwość sekwencji zmiennej długości. Albo się zapętli, albo skończy. I jest to bardzo użyteczne.
    • 47:
       
      CommentAuthorpebe
    • CommentTime6 Jul 2021 zmieniony
     
    Czyli jednak nie jeden licznik śledzący ogólną pozycję w SONGu, tylko jednak cztery niezależne (dla każdej ścieżki)

    Też mi się tak wydaję, że to będzie lepsze rozwiązanie.
    Nic to, pozostaje mi przywrócić to co było.

    ---

    Zapomniałem (chyba) napisać, że w najnowszym SFX-Engine nie ma już przeliczania adresów względnych (offsetów względem adresu miejsca danych) na absolutne (konkretne miejsce w pamięci). Trochę straciłem na tym, pod względem ilości wolnej pamięci, bo zamiast w jednym miejscu, wyliczam adresy w kilkunastu, ale czyni to program, a nie silnik.
    Tak już zostanie, bo dzięki temu silnik jest lżejszy (nie tylko rozmiarem, ale i dla samego przerwania) i bardziej czytelny.

    ---
    W ogóle wpadłem na pomysł i nie wiem, na ile byłby ciekawy.
    Chodzi o możliwość podzielenia jednego SFXa na części.
    W zamierzeniu, miał być to sposób na zaimplementowanie obsługi zwalniania klawisza. O co chdodzi?
    Jak wpisujemy nutę w TABie, to tak jakby był wciskany klawisz w organach - on zaczyna brzmieć. Jeżeli puścimy klawisz, on zaczyna wybrzmiewać.
    To by pozwoliło zastosować bardzo klasyczne podejście do dźwięku, tzw. obwiedni ADSR:

    vol
    + .
    | /|\
    | / | \
    | / | \________
    | / | | |\
    | / | | | \
    |/ | | | \
    +------+---+------+---+--+ time
    | A | D | S | R |

    (wg. wiki)
    [A]ttack – czas narastania amplitudy od zera do poziomu maksymalnego,
    [D]ecay – czas opadania amplitudy z poziomu maksymalnego do poziomu podtrzymania (sustain),
    [S]ustain – amplituda, poziom podtrzymania (wybrzmiewania),
    [R]elease – czas opadania amplitudy od poziomu podtrzymania do zera (wybrzmiewanie końcowe, zanikanie).


    Jedna instrukcja TABa, dla SFXów w trybie modulacji NLM (Note Level Modulation - czyli stricte dla zapisu nutowego), mogłaby to załatwić. Zapis w SFX byłby (mniej więcej) taki, że każdą sekcję ADSR ograniczałoby się pętlą, np:
    vol
    + _______
    | /| |
    | / | |__
    | / | | --__
    |/ | | --__
    +----+------+----------------+ time
    pos: 0123456789ABCDEF012345

    vol: 048BFFFFFFF9876543210-
    dst: AAAAAAAAAAAAAAAAAAAAA-
    mod: ----8-----8----------9
    val: ----4-----5----------5
    | | | |
    +AD-*<-S--+----R-----+
    | | |
    | | +-- koniec definicji SFXa to też pętla
    | +-- pętla dla sekcji Sustain
    +-- pętla dla sekcji Attack/Decay



    Zapis w TABie mógłby wyglądać tak:
    000: C#1 00 ; rozpoczęcie odtwarzania SFXa, czyli Attack
    001: ### -- ; tu rozpoczyna się sekcja Sustain (generalnie wypada w "tickach" dokładnie w tym miejscu)
    002: --- -- ; i trwa
    ...
    007: ### -- ; np. dotąd.
    008: --- --
    009: --- -- ; tu kończy się jej sekcja Release


    Każde wywołanie funkcji "###" (nazwijmy ją roboczo Release) powoduje, że silnik wymusza jednorazowe ominięcie pętli - np. poprzez oznaczenie w rejestrach kanałów (tu już kwestia programowa)

    Pomysł wydaje się całkiem ciekawy. Jak się zapatrujecie na takie rozwiązanie?
    • 48: CommentAuthormarok
    • CommentTime7 Jul 2021
     
    Zacząć muszę od tego, że oczywiście się nie orientuję w temacie ADSR (jak i w większości innych). Kojarzy mi się tylko z formatem midi, co pewnie jest akurat słuszne.

    W zapisie TAB trudno o większą precyzję momentu przechodzenia między fazami ADSR, chyba że tempo, na którym będzie odtwarzany song, będzie wyznaczone na bardzo niewielką wartość (chyba głównie 1 albo 2). To może uczynić możliwość korzystania z ADSR nieco uciążliwym, bo inne TABsy, te nie korzystające z dźwięków pod konstrukcję z ADSR, musiałyby być przeorientowane na taki sam speed tempa (a więc mieć większe przerwy między nutami). Przy czym korzystanie z pętli powtarzanego nopa w TAB jest niezłym z tego wyjściem i czyni zapis TAB na nowo bardziej zwartym / czytelniejszym (choć może nieco uciążliwszym sposobem w edycji jeszcze nieco pozostaje).
    Można pewnie myśleć (w różnych teoretycznych zapędach) nad różnicowaniem tempa odgrywania TABów, właśnie z uwagi na możliwość stosowania ADSR w ogóle, ale to chyba wychodzi już ponad zwykłą potrzebę i rozsądne oczekiwania.
    Osobiście byłbym nawet "na tak", dla takiego pomysłu, o ile nie za trudne w implementacji na ten moment i zapasuje do reszty konstrukcji kodu. Czyli, jak by to miało przyjść bez specjalnie dużej trudności, aby to dołożyć do reszty.
    • 49:
       
      CommentAuthorpebe
    • CommentTime7 Jul 2021 zmieniony
     
    @marok: uzupełniłem posta o poglądowe informacje związane z ADRS - to powinno wystarczyć, by pojąć mniej więcej z czym się to je.

    @solo/ng: WOW, ale przyjemnie rozwinięty temat - serio. Pozwoliło mi to ogarnąć sprawę pseudo-echa. Dzięki.

    Zrobiłem to tak, że dane audio wpisywane są tak, jak były, tzn. do bufora Audio, a te są odtwarzane pod koniec przerwania). Jednocześnie, podczas ich przenoszenia do rejestru, przenoszę też dane z dalszej części bufora audio (tu następuje regulacja). Po przerzuceniu danych, kopiuję dane w buforze, przenosząc je o 8 bajtów (rozmiar 4 rejestrów kanałów) dalej:
    ; move audio buffer data, direct to audio registers
    ldx #7
    audio_loop
    lda AUDIOBUF,x
    sta audf,x
    lda AUDIOBUF+16,x <- +16 to wartość wynikowa (regulowana)
    0=bez opóźnienia
    8=1 ramka opóźnienia
    16=2 ramki opóźnienia
    24=3 ramki opóźnienia
    sta aud2f,x
    dex
    bpl audio_loop

    ; shift echo effect buffer
    ldx #$17 <- tu mam maksymalne opóźnienie echa
    echo_loop
    lda AUDIOBUF,x
    sta AUDIOBUF+8,x
    dex
    bpl echo_loop
    • 50: CommentAuthormono
    • CommentTime7 Jul 2021
     
    A nie wystarczy rejestrem indeksowym? Po co te kopiowania?