@mateusz_s, post #1
Czy musze sam ogarnąć format 8SVX czy może są dostepne juz gotowe funkcje w API?Są gotowe, zainteresuj się datatypami i datatypes.library. Wtedy w ogóle nie trzeba zajmować się ani zdekodowaniem formatu 8SVX, ani nawet audio.device, po prostu masz metody PLAY i STOP. Możesz też ograniczyć użycie datatypów do załadowania dźwięku, a potem użyć AHI (patrz niżej).
Moim docelowym sprzętem są CPU 040+ Zastanawiam się jak uzyskać dobry balans między ciekawa muzyką, a efektami dzwiękowymi bez zagłuszania dzwięków gdy braknie kanału.Przy takim docelowym procesorze możesz użyć systemu AHI (Audio Hardware Interface), gdzie masz dowolną (w miarę mocy procesora) ilość kanałów miksowanych programowo.
@Krashan, post #2
@mateusz_s, post #7
Zastanawiam się tylko jak wykryć w jakim miejscu jest aktualnie odgrywany dzwięk,
czy zbliża się do końca bufora? Moge jakos zwrócic pozycję? Czy to timerem zrobić, zakładając
ze próbka trwa np. 1 sekunde.
@Hexmage960, post #8
@Norbert, post #11
@Hexmage960, post #8
@mateusz_s, post #13
Jeszcze nawiązując do Twojego przykładu.
Żeby otrzymać informację zwrotną od audio device o zakończeniu odgrywania to musiałbym uzyc Wait(..)
Wiec wtedy moja główna pętla programu by się zastopowała bo czekałaby na komunikat. Więc chyba lepiej CheckIO(..) dać w głównej pętli.
ULONG signalSet = SetSignal(0L, 0L);
if (signalSet & (1L << audioMsgPort->mp_SigBit)) { /* Obsługa sygnału */ }
SetSignal(0L, 1L << audioMsgPort->mp_SigBit);
@mateusz_s, post #13
Wiec wtedy moja główna pętla programu by się zastopowała bo czekałaby na komunikat.
@mateusz_s, post #7
Zastanawiam się tylko jak wykryć w jakim miejscu jest aktualnie odgrywany dzwięk,Nie da się i nie możesz zwrócić pozycji. Możesz to zrobić timerem, ale zazwyczaj nie ma takiej potrzeby. Doublebuffering organizujesz tak, że najpierw wypełniasz oba bufory, potem puszczasz pierwszy i drugi z synchrem na pierwszy (tak jak opisał Hexmage). Gdy pierwszy się odegra (IORequest "wróci"), wypełniasz jego bufor dźwiękiem i od razu wysyłasz request z synchrem na drugi. Gdy wróci drugi, wypełniasz go i od razu wysyłasz z synchrem na pierwszy. I tak dalej. Synchronizacja jest precyzyjna, efekt końcowy jest dokładnie taki sam, jakbyś to wszystko puścił z jednego długiego bufora.
czy zbliża się do końca bufora? Moge jakos zwrócic pozycję? Czy to timerem zrobić, zakładając
ze próbka trwa np. 1 sekunde.
Potem chciałem też sprawdzić jaki bedzie efekt, jesli na lewym kanale puszczę lewą sciezke muzykiAudio.device posiada możliwość puszczenia kilku kanałów jednocześnie, precyzyjnie co do próbki. Wtedy jeżeli na dwóch kanałach Pauli puścisz dwa kanały stereo, masz stereo. Oczywiście musisz wybrać kanały Pauli odpowiednio skierowane do L i R stereo.
a na prawym prawą, żeby osiągnąc jakiś efekt stereo...
@mateusz_s, post #13
Żeby otrzymać informację zwrotną od audio device o zakończeniu odgrywania to musiałbym uzyc Wait(..)W typowej pętli głównej programu i tak masz Wait() więc wystarczy dodać sygnał msgportu od requestów audio do maski. Chyba że timing programu masz sterowany bezpośrednio przerwaniem.
@mateusz_s, post #18
struct IOAudio *AudioIO; struct MsgPort *Audio_port; struct IOAudio *AudioIO_2; struct MsgPort *Audio_port_2; ULONG device; BYTE *chip_mem_1, *chip_mem_2; // bloki w pamieci chip BYTE* fast_audio; // tu w fast ram lezy caly plik #define CHIP_SIZE 23040 // cały jeden bufor w chip (bedzie podzielony na 2) #define CHUNK_SIZE 768 // tyle kopiuje bajtów na w kazdej klatce #define PARTS ( (CHIP_SIZE/2) / CHUNK_SIZE ) // 15 - tyle razy łacznie musze przekopiować 768 // init { ... chip_mem_1 = (BYTE*)AllocMem( CHIP_SIZE, MEMF_CHIP | MEMF_CLEAR); chip_mem_2 = chip_mem_1 + CHIP_SIZE/2; // uzupelniam pierwszy raz obydwa bufory chip memcpy(chip_mem_1, fast_audio, CHIP_SIZE/2); memcpy(chip_mem_2, fast_audio + CHIP_SIZE/2, CHIP_SIZE/2); AudioIO = (struct IOAudio *)AllocMem( sizeof(struct IOAudio),MEMF_PUBLIC | MEMF_CLEAR); Audio_port = CreatePort(0,0); AudioIO_2 = (struct IOAudio *)AllocMem( sizeof(struct IOAudio),MEMF_PUBLIC | MEMF_CLEAR); Audio_port_2 = CreatePort(0,0); AudioIO->ioa_Request.io_Message.mn_ReplyPort = Audio_port; AudioIO->ioa_Request.io_Message.mn_Node.ln_Pri = 127; AudioIO->ioa_Request.io_Command = ADCMD_ALLOCATE; AudioIO->ioa_Request.io_Flags = ADIOF_NOWAIT; AudioIO->ioa_AllocKey = 0; AudioIO->ioa_Data = (whichannel); AudioIO->ioa_Length = sizeof(whichannel); device = OpenDevice(AUDIONAME,0L, (struct IORequest *) AudioIO ,0L); // sprawdzam jakie kanaly zostaly zaalokowane - otrzymuje tutaj - 4 - w powinienem chyba 15. SYS_CONSOLE__write("\nDEVICES ALLOCATED: %d", AudioIO->ioa_Request.io_Unit->unit_flags & 0x0F); *AudioIO_2 = *AudioIO; AudioIO->ioa_Request.io_Message.mn_ReplyPort =Audio_port; AudioIO_2->ioa_Request.io_Message.mn_ReplyPort =Audio_port_2; AudioIO->ioa_Request.io_Command =CMD_WRITE; AudioIO->ioa_Request.io_Flags =ADIOF_PERVOL; AudioIO->ioa_Data =(BYTE *)chip_mem_1; AudioIO->ioa_Length =CHIP_SIZE/2; AudioIO->ioa_Period = (UWORD)(clock / 22050); AudioIO->ioa_Volume =64; AudioIO->ioa_Cycles =1; AudioIO_2->ioa_Request.io_Command =CMD_WRITE; AudioIO_2->ioa_Request.io_Flags =ADIOF_PERVOL; AudioIO_2->ioa_Data =(BYTE *)chip_mem_2; AudioIO_2->ioa_Length =CHIP_SIZE/2; AudioIO_2->ioa_Period = (UWORD)(clock / 22050); AudioIO_2->ioa_Volume =64; AudioIO_2->ioa_Cycles = 1; ... } // pętla głowna { ... // uruchamiam obie probki z chip które się kolejkują. BeginIO((struct IORequest *) AudioIO ); BeginIO((struct IORequest *) AudioIO_2 ); // wylaczam filtr audio *((char *)0x0bfe001)|=0x02; int start_copy_1 = 0; int parts_copied_1 = 0; int start_copy_2 = 0; int parts_copied_2 = 0; int offset = CHIP_SIZE; BYTE* chip_1_ptr = chip_mem_1; BYTE* chip_2_ptr = chip_mem_2; BYTE* fast_ptr = fast_audio+CHIP_SIZE; while (E_io__prefs.is_loop) { // message loop okna if(SetSignal(0L, signal_mask) & signal_mask) { struct IntuiMessage *imsg; while( imsg = (struct IntuiMessage *)GetMsg(SYS__window->UserPort) ) { switch (imsg->Class) { .. } ReplyMsg((struct Message *)imsg); } } /// BUFOROWANIE z FAST DO CHIP if ( CheckIO((struct IORequest*)AudioIO) ) { WaitIO( (struct IORequest*)AudioIO ) ; start_copy_1 = 1; } if (start_copy_1) { memcpy(chip_1_ptr, fast_ptr, CHUNK_SIZE); fast_ptr += CHUNK_SIZE; chip_1_ptr += CHUNK_SIZE; parts_copied_1++; if (parts_copied_1 >= PARTS) { parts_copied_1 = 0; start_copy_1 = 0; chip_1_ptr = chip_mem_1; BeginIO((struct IORequest *) AudioIO ); } } if ( CheckIO((struct IORequest*)AudioIO_2) ) { WaitIO( (struct IORequest*)AudioIO_2 ) ; start_copy_2 = 1; } if (start_copy_2) { memcpy(chip_2_ptr, fast_ptr, CHUNK_SIZE); fast_ptr += CHUNK_SIZE; chip_2_ptr += CHUNK_SIZE; parts_copied_2++; if (parts_copied_2 >= PARTS) { parts_copied_2 = 0; start_copy_2 = 0; chip_2_ptr = chip_mem_2; BeginIO((struct IORequest *) AudioIO_2 ); } } // reszta programu/gry .... }
@mateusz_s, post #19
// Definicja kanałów UBYTE whichannel[] = { 1, // Lewy kanał 2 // Prawy kanał }; struct IOAudio *AudioIO; struct MsgPort *Audio_port; struct IOAudio *AudioIO_2; struct MsgPort *Audio_port_2; // Konfiguracja portów audio AudioIO = (struct IOAudio *)AllocMem(sizeof(struct IOAudio), MEMF_PUBLIC | MEMF_CLEAR); Audio_port = CreatePort(0,0); AudioIO_2 = (struct IOAudio *)AllocMem(sizeof(struct IOAudio), MEMF_PUBLIC | MEMF_CLEAR); Audio_port_2 = CreatePort(0,0); // Konfiguracja pierwszego kanału AudioIO->ioa_Request.io_Message.mn_ReplyPort = Audio_port; AudioIO->ioa_Request.io_Message.mn_Node.ln_Pri = 127; AudioIO->ioa_Request.io_Command = ADCMD_ALLOCATE; AudioIO->ioa_Request.io_Flags = ADIOF_NOWAIT; AudioIO->ioa_AllocKey = 0; AudioIO->ioa_Data = whichannel; AudioIO->ioa_Length = sizeof(whichannel); device = OpenDevice(AUDIONAME, 0L, (struct IORequest *)AudioIO, 0L); // Kopiowanie konfiguracji do drugiego kanału *AudioIO_2 = *AudioIO; AudioIO->ioa_Request.io_Message.mn_ReplyPort = Audio_port; AudioIO_2->ioa_Request.io_Message.mn_ReplyPort = Audio_port_2; // Konfiguracja parametrów odtwarzania dla pierwszego kanału (lewy) AudioIO->ioa_Request.io_Command = CMD_WRITE; AudioIO->ioa_Request.io_Flags = ADIOF_PERVOL; AudioIO->ioa_Data = (BYTE *)chip_mem_1; AudioIO->ioa_Length = CHIP_SIZE/2; AudioIO->ioa_Period = (UWORD)(clock / 22050); AudioIO->ioa_Volume = 64; AudioIO->ioa_Cycles = 1; // Konfiguracja parametrów odtwarzania dla drugiego kanału (prawy) AudioIO_2->ioa_Request.io_Command = CMD_WRITE; AudioIO_2->ioa_Request.io_Flags = ADIOF_PERVOL; AudioIO_2->ioa_Data = (BYTE *)chip_mem_2; AudioIO_2->ioa_Length = CHIP_SIZE/2; AudioIO_2->ioa_Period = (UWORD)(clock / 22050); AudioIO_2->ioa_Volume = 64; AudioIO_2->ioa_Cycles = 1;
@sand, post #20
@Hexmage960, post #21
AudioIO->ioa_Request.io_Unit->unit_flags & 0x0Fdostawałem chyba 12,
@Hexmage960, post #21
enum { AUDIO_LEFT_BUFFER_1, AUDIO_RIGHT_BUFFER_1, AUDIO_LEFT_BUFFER_2, AUDIO_RIGHT_BUFFER_2, AUDIO_COUNT }; struct MsgPort *AudioPort; struct IOAudio *Audio[AUDIO_COUNT]; UBYTE AnyChannel[] = { 3 } // dla rezerwacji kanalu lewego 1 i prawego 1 AudioPort = CreateMsgPort(); Audio[AUDIO_LEFT_BUFFER_1] = (struct IOAudio *)AllocMem(sizeof(struct IOAudio), MEMF_PUBLIC | MEMF_CLEAR); Audio[AUDIO_LEFT_BUFFER_2] = (struct IOAudio *)AllocMem(sizeof(struct IOAudio), MEMF_PUBLIC | MEMF_CLEAR); Audio[AUDIO_RIGHT_BUFFER_1] = (struct IOAudio *)AllocMem(sizeof(struct IOAudio), MEMF_PUBLIC | MEMF_CLEAR); Audio[AUDIO_RIGHT_BUFFER_2] = (struct IOAudio *)AllocMem(sizeof(struct IOAudio), MEMF_PUBLIC | MEMF_CLEAR); Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Request . io_Message . mn_Node . ln_Type = 125; Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Request . io_Message . mn_Length = sizeof(struct IOAudio); Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Request . io_Command = ADCMD_ALLOCATE; Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Request . io_Flags = ADIOF_NOWAIT; Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Data = AnyChannel; Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Length = sizeof(AnyChannel); Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Request . io_Message . mn_ReplyPort = AudioPort; ULONG device = OpenDevice(AUDIONAME,0,(struct IORequest*)Audio[AUDIO_LEFT_BUFFER_1],0); CopyMem(Audio[AUDIO_LEFT_BUFFER_1],Audio[AUDIO_LEFT_BUFFER_2],sizeof(struct IOAudio)); CopyMem(Audio[AUDIO_LEFT_BUFFER_1],Audio[AUDIO_RIGHT_BUFFER_1],sizeof(struct IOAudio)); CopyMem(Audio[AUDIO_LEFT_BUFFER_1],Audio[AUDIO_RIGHT_BUFFER_2],sizeof(struct IOAudio)); Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Request . io_Unit = (APTR)1; // maska bitowa dla kanalu 1 lewego Audio[AUDIO_LEFT_BUFFER_2] -> ioa_Request . io_Unit = (APTR)1; Audio[AUDIO_RIGHT_BUFFER_1] -> ioa_Request . io_Unit = (APTR)2; // maska bitowa dla kanalu 1 prewego Audio[AUDIO_RIGHT_BUFFER_2] -> ioa_Request . io_Unit = (APTR)2; Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Request . io_Command = CMD_WRITE; Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Request . io_Flags = ADIOF_PERVOL; Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Period = (UWORD)( 3546895 / 22050); Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Volume = 64; Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Cycles = 1; Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Data = chip_mem_1; Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Length = CHIP_SIZE/2; Audio[AUDIO_RIGHT_BUFFER_1] -> ioa_Request . io_Command = CMD_WRITE; Audio[AUDIO_RIGHT_BUFFER_1] -> ioa_Request . io_Flags = ADIOF_PERVOL; Audio[AUDIO_RIGHT_BUFFER_1] -> ioa_Period = (UWORD)( 3546895 / 22050); Audio[AUDIO_RIGHT_BUFFER_1] -> ioa_Volume = 64; Audio[AUDIO_RIGHT_BUFFER_1] -> ioa_Cycles = 1; Audio[AUDIO_RIGHT_BUFFER_1] -> ioa_Data = chip_mem_1; Audio[AUDIO_RIGHT_BUFFER_1] -> ioa_Length = CHIP_SIZE/2; Audio[AUDIO_LEFT_BUFFER_2] -> ioa_Request . io_Command = CMD_WRITE; Audio[AUDIO_LEFT_BUFFER_2] -> ioa_Request . io_Flags = ADIOF_PERVOL; Audio[AUDIO_LEFT_BUFFER_2] -> ioa_Period = (UWORD)( 3546895 / 22050);; Audio[AUDIO_LEFT_BUFFER_2] -> ioa_Volume = 64; Audio[AUDIO_LEFT_BUFFER_2] -> ioa_Cycles = 1; Audio[AUDIO_LEFT_BUFFER_2] -> ioa_Data = chip_mem_2; Audio[AUDIO_LEFT_BUFFER_2] -> ioa_Length = CHIP_SIZE/2; Audio[AUDIO_RIGHT_BUFFER_2] -> ioa_Request . io_Command = CMD_WRITE; Audio[AUDIO_RIGHT_BUFFER_2] -> ioa_Request . io_Flags = ADIOF_PERVOL; Audio[AUDIO_RIGHT_BUFFER_2] -> ioa_Period = (UWORD)( 3546895 / 22050);; Audio[AUDIO_RIGHT_BUFFER_2] -> ioa_Volume = 64; Audio[AUDIO_RIGHT_BUFFER_2] -> ioa_Cycles = 1; Audio[AUDIO_RIGHT_BUFFER_2] -> ioa_Data = chip_mem_2; Audio[AUDIO_RIGHT_BUFFER_2] -> ioa_Length = CHIP_SIZE/2; .... BeginIO((struct IORequest*)Audio[AUDIO_LEFT_BUFFER_1]); BeginIO((struct IORequest*)Audio[AUDIO_RIGHT_BUFFER_1]); BeginIO((struct IORequest*)Audio[AUDIO_LEFT_BUFFER_2]); BeginIO((struct IORequest*)Audio[AUDIO_RIGHT_BUFFER_2]); ...
@mateusz_s, post #23
Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Request . io_Message . mn_Node . ln_Type = 125; Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Request . io_Message . mn_Length = sizeof(struct IOAudio); Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Request . io_Command = ADCMD_ALLOCATE; Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Request . io_Flags = ADIOF_NOWAIT; Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Data = AnyChannel; Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Length = sizeof(AnyChannel); Audio[AUDIO_LEFT_BUFFER_1] -> ioa_Request . io_Message . mn_ReplyPort = AudioPort;
struct IOAudio *pAudioLeftBuffer1 = Audio[AUDIO_LEFT_BUFFER_1]; pAudioLeftBuffer1 -> ioa_Request . io_Message . mn_Node . ln_Type = 125; pAudioLeftBuffer1 -> ioa_Request . io_Message . mn_Length = sizeof(struct IOAudio); pAudioLeftBuffer1 -> ioa_Request . io_Command = ADCMD_ALLOCATE; pAudioLeftBuffer1 -> ioa_Request . io_Flags = ADIOF_NOWAIT; pAudioLeftBuffer1 -> ioa_Data = AnyChannel; pAudioLeftBuffer1 -> ioa_Length = sizeof(AnyChannel); pAudioLeftBuffer1 -> ioa_Request . io_Message . mn_ReplyPort = AudioPort;
@mateusz_s, post #25
// globalne enum { SYS_AUDIO__LEFT_1_BUFFER_1, SYS_AUDIO__RIGHT_1_BUFFER_1, SYS_AUDIO__LEFT_1_BUFFER_2, SYS_AUDIO__RIGHT_1_BUFFER_2, SYS_AUDIO__LEFT_2_BUFFER, SYS_AUDIO__RIGHT_2_BUFFER, SYS_AUDIO__COUNT }; static struct MsgPort* sys_audio__port; static struct IOAudio* sys_audio[SYS_AUDIO__COUNT]; static UBYTE sys_audio__channels[] = { 15 }; // 15 - For reservation for all 4 channels.
// inicjalizacja audio i wszsytkich kanałów int SYS_audio__create(void) { // What clock, PAL or NTSC. GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",0L); if (GfxBase==0L) return 0; if (GfxBase->DisplayFlags & PAL) sys_audio__clock = 3546895L; /* PAL clock */ else sys_audio__clock = 3579545L; /* NTSC clock */ if (GfxBase) CloseLibrary( (struct Library *) GfxBase); // Alloc chip ram for duble buffering long sounds from fast ram. sys_audio__chip_buf_1 = (BYTE*)AllocMem( SYS_AUDIO__CHIP_SIZE, MEMF_CHIP | MEMF_CLEAR ); if (sys_audio__chip_buf_1 == NULL) return 0; sys_audio__chip_buf_2 = sys_audio__chip_buf_1 + (SYS_AUDIO__CHIP_SIZE / 2); if (sys_audio__chip_buf_2 == NULL) return 0; // Alloc elements for audio. sys_audio__port = CreateMsgPort(); if (sys_audio__port == NULL) return 0; sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1] = (struct IOAudio *)AllocMem(sizeof(struct IOAudio) * SYS_AUDIO__COUNT, MEMF_PUBLIC | MEMF_CLEAR); if (sys_audio == NULL) return 0; sys_audio[SYS_AUDIO__RIGHT_1_BUFFER_1] = sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1] + 1; sys_audio[SYS_AUDIO__LEFT_1_BUFFER_2] = sys_audio[SYS_AUDIO__RIGHT_1_BUFFER_1] + 1; sys_audio[SYS_AUDIO__RIGHT_1_BUFFER_2] = sys_audio[SYS_AUDIO__LEFT_1_BUFFER_2] + 1; sys_audio[SYS_AUDIO__LEFT_2_BUFFER] = sys_audio[SYS_AUDIO__RIGHT_1_BUFFER_2] + 1; sys_audio[SYS_AUDIO__RIGHT_2_BUFFER] = sys_audio[SYS_AUDIO__LEFT_2_BUFFER] + 1; // Open audio.device, allocate the channels on the fly.. sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]->ioa_Request.io_Message.mn_Node.ln_Type = 125; sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]->ioa_Request.io_Message.mn_Length = sizeof(struct IOAudio); sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]->ioa_Request.io_Message.mn_ReplyPort = sys_audio__port; sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]->ioa_Request.io_Command = ADCMD_ALLOCATE; sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]->ioa_Request.io_Flags = ADIOF_NOWAIT; sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]->ioa_Length = sizeof(sys_audio__channels); sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]->ioa_Data = sys_audio__channels; ULONG audio_device = OpenDevice(AUDIONAME, 0, (struct IORequest*)sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1], 0); if (audio_device != 0) return 0; // Check if all desired channels were allocated. if ( (((LONG)sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]->ioa_Request.io_Unit) & 0x0F) != sys_audio__channels[0] ) return 0; // Initializing all audio requests. sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]->ioa_Request.io_Command = CMD_WRITE; sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]->ioa_Request.io_Flags = ADIOF_PERVOL; sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]->ioa_Period = (UWORD)( sys_audio__clock / SYS_AUDIO__FREQ ); sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]->ioa_Volume = 64; sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]->ioa_Cycles = 1; sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]->ioa_Length = (SYS_AUDIO__CHIP_SIZE / 2); // Copy audio request data to all remaining requests. *sys_audio[SYS_AUDIO__LEFT_1_BUFFER_2] = *sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]; *sys_audio[SYS_AUDIO__RIGHT_1_BUFFER_1] = *sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]; *sys_audio[SYS_AUDIO__RIGHT_1_BUFFER_2] = *sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]; *sys_audio[SYS_AUDIO__LEFT_2_BUFFER] = *sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]; *sys_audio[SYS_AUDIO__RIGHT_2_BUFFER] = *sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]; // Assign correct channels to all audio requests. sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]->ioa_Request.io_Unit = (APTR)SYS_AUDIO__LEFT_1; sys_audio[SYS_AUDIO__LEFT_1_BUFFER_2]->ioa_Request.io_Unit = (APTR)SYS_AUDIO__LEFT_1; sys_audio[SYS_AUDIO__RIGHT_1_BUFFER_1]->ioa_Request.io_Unit = (APTR)SYS_AUDIO__RIGHT_1; sys_audio[SYS_AUDIO__RIGHT_1_BUFFER_2]->ioa_Request.io_Unit = (APTR)SYS_AUDIO__RIGHT_1; sys_audio[SYS_AUDIO__LEFT_2_BUFFER]->ioa_Request.io_Unit = (APTR)SYS_AUDIO__LEFT_2; sys_audio[SYS_AUDIO__RIGHT_2_BUFFER]->ioa_Request.io_Unit = (APTR)SYS_AUDIO__RIGHT_2; // Assign correct chip buffers sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]->ioa_Data = sys_audio__chip_buf_1; sys_audio[SYS_AUDIO__RIGHT_1_BUFFER_1]->ioa_Data = sys_audio__chip_buf_1; sys_audio[SYS_AUDIO__LEFT_1_BUFFER_2]->ioa_Data = sys_audio__chip_buf_2; sys_audio[SYS_AUDIO__RIGHT_1_BUFFER_2]->ioa_Data = sys_audio__chip_buf_2; sys_audio__sfx_current_channel = SYS_AUDIO__LEFT_2_BUFFER; // Turn off Amiga Audio Filter for clearer sounds. *((char *)0x0bfe001)|=0x02; return 1; }
// przygotowanie do buforowania void SYS_audio__music_buffer_prepare(char* _music_buffer, int _size) { sys_audio__music_buf = _music_buffer; sys_audio__music_buf_size = _size; memcpy(sys_audio__chip_buf_1, sys_audio__music_buf, SYS_AUDIO__CHIP_SIZE / 2); memcpy(sys_audio__chip_buf_2, sys_audio__music_buf + SYS_AUDIO__CHIP_SIZE / 2, SYS_AUDIO__CHIP_SIZE / 2); sys_audio__chip_buf_1__ptr = sys_audio__chip_buf_1; sys_audio__chip_buf_2__ptr = sys_audio__chip_buf_2; sys_audio__music_buf__ptr = sys_audio__music_buf + SYS_AUDIO__CHIP_SIZE; sys_audio__db_music_buf_position = SYS_AUDIO__CHIP_SIZE; sys_audio__db_start_copy_1 = 0; sys_audio__db_parts_copied_1 = 0; sys_audio__db_start_copy_2 = 0; sys_audio__db_parts_copied_2 = 0; }
// procedura buforowania z fast do chip z zapętleniem void SYS_audio__music_buffer_to_chipram(void) { // Perform double buffering routine to copy chunks of sounds from fast to chip buffers. // Perform play end test only if any requester sent signal. ULONG signal_mask = ( 1 << sys_audio__port->mp_SigBit); if (SetSignal(0L, signal_mask) & signal_mask) { // If music from chip buffer 1 is finished... if ( CheckIO((struct IORequest*)sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1]) && CheckIO((struct IORequest*)sys_audio[SYS_AUDIO__RIGHT_1_BUFFER_1]) ) { WaitIO( (struct IORequest*)sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1] ) ; WaitIO( (struct IORequest*)sys_audio[SYS_AUDIO__RIGHT_1_BUFFER_1] ) ; sys_audio__db_start_copy_1 = 1; } // If music from chip buffer 2 is finished... if ( CheckIO((struct IORequest*)sys_audio[SYS_AUDIO__LEFT_1_BUFFER_2]) && CheckIO((struct IORequest*)sys_audio[SYS_AUDIO__RIGHT_1_BUFFER_2]) ) { WaitIO( (struct IORequest*)sys_audio[SYS_AUDIO__LEFT_1_BUFFER_2] ); WaitIO( (struct IORequest*)sys_audio[SYS_AUDIO__RIGHT_1_BUFFER_2] ); sys_audio__db_start_copy_2 = 1; } } // Copying from fast ram to from chip buffer 1. if (sys_audio__db_start_copy_1) { // We need to test against end of music and loop it. if ( (sys_audio__db_music_buf_position + SYS_AUDIO__CHUNK_SIZE) >= sys_audio__music_buf_size) { // If the next chunk exceeds music size we copy the last chunk. int last_chunk_size = sys_audio__music_buf_size - sys_audio__db_music_buf_position; memcpy(sys_audio__chip_buf_1__ptr, sys_audio__music_buf__ptr, last_chunk_size); sys_audio__chip_buf_1__ptr += last_chunk_size; // Reset music buffer position and pointer. sys_audio__music_buf__ptr = sys_audio__music_buf; sys_audio__db_music_buf_position = 0; // We also have to copy remaining chunk from the beginning. int remaining_chunk_size = SYS_AUDIO__CHUNK_SIZE - last_chunk_size; memcpy(sys_audio__chip_buf_1__ptr, sys_audio__music_buf__ptr, remaining_chunk_size); sys_audio__chip_buf_1__ptr += remaining_chunk_size; sys_audio__music_buf__ptr += remaining_chunk_size; sys_audio__db_music_buf_position += remaining_chunk_size; } else { // If next chunk doesn't exceed music buffer we copy SYS_AUDIO__CHUNK_SIZE. memcpy(sys_audio__chip_buf_1__ptr, sys_audio__music_buf__ptr, SYS_AUDIO__CHUNK_SIZE); sys_audio__chip_buf_1__ptr += SYS_AUDIO__CHUNK_SIZE; sys_audio__music_buf__ptr += SYS_AUDIO__CHUNK_SIZE; sys_audio__db_music_buf_position += SYS_AUDIO__CHUNK_SIZE; } sys_audio__db_parts_copied_1++; if (sys_audio__db_parts_copied_1 >= SYS_AUDIO__PARTS) { sys_audio__db_parts_copied_1 = 0; sys_audio__db_start_copy_1 = 0; sys_audio__chip_buf_1__ptr = sys_audio__chip_buf_1; BeginIO((struct IORequest *)sys_audio[SYS_AUDIO__LEFT_1_BUFFER_1] ); BeginIO((struct IORequest *)sys_audio[SYS_AUDIO__RIGHT_1_BUFFER_1] ); } } // Copying from fast ram to from chip buffer 2. if (sys_audio__db_start_copy_2) { // We need to test against end of music and loop it. if ( (sys_audio__db_music_buf_position + SYS_AUDIO__CHUNK_SIZE) >= sys_audio__music_buf_size) { // If the next chunk exceeds music size we copy the last chunk. int last_chunk_size = sys_audio__music_buf_size - sys_audio__db_music_buf_position; memcpy(sys_audio__chip_buf_2__ptr, sys_audio__music_buf__ptr, last_chunk_size); sys_audio__chip_buf_2__ptr += last_chunk_size; // Reset music buffer position and pointer. sys_audio__music_buf__ptr = sys_audio__music_buf; sys_audio__db_music_buf_position = 0; // We also have to copy remaining chunk from the beginning. int remaining_chunk_size = SYS_AUDIO__CHUNK_SIZE - last_chunk_size; memcpy(sys_audio__chip_buf_2__ptr, sys_audio__music_buf__ptr, remaining_chunk_size); sys_audio__chip_buf_2__ptr += remaining_chunk_size; sys_audio__music_buf__ptr += remaining_chunk_size; sys_audio__db_music_buf_position += remaining_chunk_size; } else { // If next chunk doesn't exceed music buffer we copy SYS_AUDIO__CHUNK_SIZE. memcpy(sys_audio__chip_buf_2__ptr, sys_audio__music_buf__ptr, SYS_AUDIO__CHUNK_SIZE); sys_audio__chip_buf_2__ptr += SYS_AUDIO__CHUNK_SIZE; sys_audio__music_buf__ptr += SYS_AUDIO__CHUNK_SIZE; sys_audio__db_music_buf_position += SYS_AUDIO__CHUNK_SIZE; } sys_audio__db_parts_copied_2++; if (sys_audio__db_parts_copied_2 >= SYS_AUDIO__PARTS) { sys_audio__db_parts_copied_2 = 0; sys_audio__db_start_copy_2 = 0; sys_audio__chip_buf_2__ptr = sys_audio__chip_buf_2; BeginIO((struct IORequest *)sys_audio[SYS_AUDIO__LEFT_1_BUFFER_2] ); BeginIO((struct IORequest *)sys_audio[SYS_AUDIO__RIGHT_1_BUFFER_2] ); } } }
// procedura odtwarzajaca dzwięk ktory jest w chip ram, naprzemiennie - raz na lewym 2 i raz na prawym 2 void SYS_audio__sfx_start(char* _sfx_buffer, int _size) { // We have 2 channels to use left 2 and right 2, // lets use them alternately. sys_audio__sfx_current_channel ^= 1; sys_audio[sys_audio__sfx_current_channel]->ioa_Request.io_Command = ADCMD_FINISH; BeginIO((struct IORequest*)sys_audio[sys_audio__sfx_current_channel]); sys_audio[sys_audio__sfx_current_channel]->ioa_Request.io_Command = CMD_WRITE; sys_audio[sys_audio__sfx_current_channel]->ioa_Data = _sfx_buffer; sys_audio[sys_audio__sfx_current_channel]->ioa_Length = _size; BeginIO((struct IORequest*)sys_audio[sys_audio__sfx_current_channel]); }