[#1] Kolejkowanie requestów audio.device
Dlaczego kolejkowanie komend CMD_WRITE audio.device nie działa? Dokumentacja mówi, że polecenia CMD_WRITE audio.device powinny ustawiać się w kolejce. System zawiesza się gdy podejmuję takiej próby. Odkryłem, że pewnym obejściem jest krótka przerwa pomiędzy wywołaniami BeginIO(), ale czy da się zrobić by te wywołania były bezpośrednio po sobie? Więc oto kod przykładowy:

Procedura Play_Sample() powinna odtworzyć zapętlony dźwięk taki jaki znamy z MODów lub MEDów to znaczy, że najpierw jednorazowo odtworzony jest cały sampel po czym wielokrotnie odtworzona zostaje część zapętlona. Pobiera następujące parametry
- ioa, aux - zainicjalizowane struktury IOAudio, pierwsza użyta do jednorazowego odegrania sampla, druga do odegrania jego częśći zapętlonej.
- data - ciało sampla
- length - długość sampla
- rep - pozycja początku zapętlenia
- replen - długość zapętlenia
- period - okres (częstotliwość)
- volume - głośność
void Play_Sample(struct IOAudio *ioa, struct IOAudio *aux, ULONG data, ULONG length, ULONG rep, ULONG replen, ULONG period, ULONG volume)
{
 ioa->ioa_Request.io_Command = CMD_WRITE;
 ioa->ioa_Request.io_Flags = ADIOF_PERVOL;
 ioa->ioa_Data = data;
 ioa->ioa_Length = length;
 ioa->ioa_Period = period;
 ioa->ioa_Volume = volume;
 ioa->ioa_Cycles = 1;
 BeginIO((struct IORequest *)ioa);

 aux->ioa_Request.io_Command = CMD_WRITE;
 aux->ioa_Request.io_Flags = ADIOF_PERVOL;
 aux->ioa_Data = rep;
 aux->ioa_Length = replen;
 aux->ioa_Period = period;
 aux->ioa_Volume = volume;
 aux->ioa_Cycles = 10; // tutaj można wstawić 0 dla nieskończonej pętli
 BeginIO((struct IORequest *)aux);
}

Powyższy kod zawiesza się o ile między kolejnymi BeginIO() nie ma żadnej przerwy. Tymczasowo rozwiązuję ten problem sprawdzając w programie za pomocą CheckIO(), czy jednorazowa część sampla została odegrana i puszczam wtedy część zapętloną, ale zależy mi na szybkości, tj. by część zapętlona sampla była odgrywana w przerwaniu.

No nic, jeśli ten kod nie zadziała to spróbuję odtwarzać część zapętloną po krótkiej przerwie. Mam jeszcze pytanie - jak wykorzystać flagę ADIOF_WRITEMESSAGE?

[#2] Re: Kolejkowanie requestów audio.device

@Minniat, post #1

Pewnie by kolejkowanie działało, jakbyś wysyłał requesty przez SendIO() zamiast BeginIO().

[#3] Re: Kolejkowanie requestów audio.device

@Grzegorz Kraszewski, post #2

Próbowałem też SendIO(), jednak jak wynika z dokumentacji i przykładów do wysyłania komend audio.device
używa się BeginIO()! (tym różni się od SendIO(), że nie kasuje pola io_Flags).

[#4] Re: Kolejkowanie requestów audio.device

@Minniat, post #3

Wydaje mi się, że używanie asynchronicznych komend powoduje ten błąd, brak jest obsługi na sygnał zakończenia działania komend IO. Inaczej mówiąc, albo zamienić na obsługę synchroniczną, albo dorobić obsługę sygnału końca obsługi ioreq. Czyli drugie BeginIO wywołujesz po otrzymaniu wiadomości, że pierwsze BeginIO zostało zakończone. Po to używasz portu i wspomnianej flagi.
[#5] Re: Kolejkowanie requestów audio.device

@cholok, post #4

Zależy mi na obsłudze asynchronicznej, ponieważ to odtwarzanie sampla jest częśćią odgrywania modułu.

Teraz jest tak, że w przerwaniu software'owym timer.device, które następuje co pewien stały odcinek czasu odgrywam początek sampla i działa to bardzo dobrze, moduł jest odtwarzany szybko i nie spowalnia systemu. Zależy mi na tym, aby w tym samym przerwaniu została wysłana prośba (request) o odegranie reszty sampla, jednak tak jak napisałem jest problem z kolejkowaniem.

Dotychczas rozwiązuję ten problem robiąc tak jak radzisz (o czym napisałem), sprawdzam za pomocą CheckIO() czy zakończone zostało odgrywanie pierwszej części sampla po czym wywołuję drugie BeginIO(). Daje to dość dobry rezultat, ale nie w pełni mnie zadowalający, ponieważ zależy mi na szybkości.

Reasumując jak to rozwiązać, czyli jak sprawić by dwa BeginIO() następujące po sobie działały poprawnie?

Jest jeszcze jedna sprawa: przerwanie software'owe timer.device jest wywoływane gdy dotrze do portu zawiadomienie o upłynięciu pewnego odcinka czasu. Być może można zrobić analogicznie dla audio.device, to znaczy że sprawić, by wywoływane było przerwanie po zakończeniu odtwarzania części sampla! Próbowałem troszkę nad tym popracować ale bez rezultatu.



Ostatnia modyfikacja: 18.09.2009 12:39:26
[#6] Re: Kolejkowanie requestów audio.device

@Minniat, post #1

Mam takie pytanie. Czy może się zdarzyć w twojej funkcji coś takiego jak ioa == aux ?
Dodaj stosowną asercję żeby się upewnić że taka sytuacja sie nie pojawi.



Ostatnia modyfikacja: 18.09.2009 13:42:19
[#7] Re: Kolejkowanie requestów audio.device

@Minniat, post #5

>Dotychczas rozwiązuję ten problem robiąc tak jak radzisz ...

No nie. Radzę inaczej. Mniej więcej w teorii: trzeba stworzyć MessagePort, ustawić flagę adiof_writemessage. Teraz użycie komendy write spowoduje wysłanie wiadomości po zakończeniu jej działania. Nie trzeba uzywać CheckIO. Użycie komendy waitcycle spowoduje to samo, ale po zakończeniu odgrywania sampla (tak mi się wydaje).

Swoją drogą, to teraz wiesz czemu nikt nie używał audio.device do odtwarzania muzyki.
[#8] Re: Kolejkowanie requestów audio.device

@asman, post #6

Wywołuję Play_Sample() z parametrami ioa[ i ] i ioa[ i + 4 ], więc taka sytuacja jak ioa == aux nie zajdzie, jednak mogę oczywiście wprowadzić taką asercję dla pewności.



Ostatnia modyfikacja: 18.09.2009 13:49:21
[#9] Re: Kolejkowanie requestów audio.device

@cholok, post #7

Nie do końca rozumiem co piszesz. Czy wiesz jak działa ta flaga ADIOF_WRITEMESSAGE, bo w dokumentacji piszą, że powoduje ona wysłanie do portu wiadomości gdy CMD_WRITE zacznie zapisywać dane do urządzenia audio. Interesuje mnie to z tego względu, że być może jak poczekam na WriteMessage i użyję BeginIO() to kolejkowanie się uda!



Ostatnia modyfikacja: 18.09.2009 13:53:47
[#10] Re: Kolejkowanie requestów audio.device

@Minniat, post #9

Faktycznie, poknociłem, ale widziałem playera, gdzie użyto dwa razy pod rząd BeginIO, z tym, że dwa różne audioio.
[#11] Re: Kolejkowanie requestów audio.device

@Minniat, post #8

Proszę podaj dokładnie deklaracje tej tablicy ioa i inicjalizację tej tablicy.

Jeśli możesz to wprowadź taką asercję. Po to się wprowadza asercję dla takich sytuacji które nie mogą zajść. Ja bym poszedł tropem asercji dalej i dodał asercję dla pustego wskaźnika ( przecież sytuacje niemożliwe się zdarzają :) ). Poza tym myślę, że warto sprawdzić wyrzucając dokładne informacje gdzie konkretnie znajdują się ( pod jakim adresem pamięci ) dwa pierwsze parametry. Napisz co dostałeś.

[#12] Re: Kolejkowanie requestów audio.device

@asman, post #11

@Asman
Umieszczę niedługo to o co prosisz.

--
Co mnie jeszcze zaintrygowało to to, że w Amidze istnieją przerwania hardware'owe, (AUD0 - AUD3) które są wywoływane, gdy zakończony zostanie blok kanału dźwiękowego. To jest właśnie to czego potrzebuję, odegrać zapętloną część sampla po ukończeniu jego jednorazowej części. Tylko, że interesują mnie rozwiązania systemowe, nie sprzętowe (więc audio.device). Popracuję jeszcze nad tym.



Ostatnia modyfikacja: 18.09.2009 16:50:11
[#13] Re: Kolejkowanie requestów audio.device

@Minniat, post #12

Obejrzyj sobie źródła MaxTrax playera (są na stronie Wanted Teamu). Ten format używa audio device do odgrywania muzyki w największym znanym mi stopniu.
[#14] Re: Kolejkowanie requestów audio.device

@Don_Adan, post #13

Już rozwiązałem problem. Sprawiam, że jak dotrze do portu wiadomość o skończeniu bloku dźwiękowego (czyli pierwszego requestu BeginIO()) wywoływane jest przerwanie software'owe. Przerwanie to odgrywa zapętloną część sampla. Wszystko działa bardzo dobrze. Wykorzystuję to, że port po otrzymaniu wiadomości może albo wywołać przerwanie, bądź dać sygnał zadaniu. Wystarczy ustawić odpowiednią flagę w strukturze MsgPort i podpiąć strukturę Interrupt pod ten port.

Po sprawdzeniu kodu przykładowego z RKM okazało się, że niemożność kolejkowania requestów audio.device to tylko przypadłość OS4.0. Ale rozwiązałem ten problem sam obsługując taką kolejkę wiadomości (jak opisałem powyżej). Myślę, że skorzystanie z AHI da jeszcze lepsze rezultaty pod OS4.x.

Pozdrawiam.

Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem