/* /////////////////////////////////////////////////////////////////////////////////// / talkthru.asm / / / / Receives input from the AD1836 internal ADCs via the ADSP-21161 serial port / / (SPORT0), and transmits the data back to the AD1836 internal DACs (SPORT2). / / / / The samples from the AD1836 are 24 bit and are left-justified in the upper / / 24-bits of the the 32-bit word (timeslot). No shifting of the data is required / / in order to preserve the sign of the samples when they are converted to / / floating point numbers, as the audio data is already in the assumed 1.31 format./ / The values are also scaled to the range +/-1.0 with the integer to float / / conversion (f0 = float r0 by r1). / /////////////////////////////////////////////////////////////////////////////////// */ /* ADSP-21161 System Register bit definitions */ #include "def21161.h" /*----------------------------------------------------------------------------------*/ .GLOBAL process_audio; #define TAPS 67 // ilość wspolczynnikow filtru //#define - stala w programie .section /pm pm_data; //define your user program memory variables here //wszelkie dane wchodzace w sklad programu-np. wspolczynniki roznych filtrow itp. .VAR coef_bp_800Hz[TAPS] = "Filter_BP_2000_67.dat"; // definicja wspolczynnikow filtru FIR .section /dm dm_data; //define your user data memory variables here //tutaj zawsze bedziemy okresleć wszelkie zmienne w programie // .VAR dline[TAPS]; // wejsciowa linia opozniajaca .section /pm pm_code; .EXTERN RX_left_flag; .EXTERN Left_Channel_In0; .EXTERN Right_Channel_In0; .EXTERN Left_Channel_In1; .EXTERN Right_Channel_In1; .EXTERN Left_Channel_Out0; .EXTERN Right_Channel_Out0; .EXTERN Left_Channel_Out1; .EXTERN Right_Channel_Out1; .EXTERN Left_Channel_Out2; .EXTERN Right_Channel_Out2; .EXTERN Left_Channel_AD1852; .EXTERN Right_Channel_AD1852; .GLOBAL process_audio; .GLOBAL user_code_init; user_code_init: b0 = dline; // inicjalizacja DAGS l0 = @dline; // wskaznik do wejsciowej linii opozniajacej m0 = 1; // co ile będzie się zmieniał wskaźnik /* - bufor kolowy b-adres od ktorego zaczyna sie dany bufor- adres bazowy l-dlugosc bufora m-o ile bedziemy "skakac w buforze" modyfikowac adres bazowy i- rejestr i jest automatycznie inicjalizowany w momencie inicjalizacji rejestru b i-to rejest w ktorym przychowywana jest aktualna wartosc adresu <-patrz zasada dzialania bufora kolowego */ b8 = coef_bp_800Hz; // inicjalizacja DAGS l8 = @coef_bp_800Hz; // wskaźnik do współczynników filtra FIR m8 = 1; // co ile będzie się zmieniał wskaźnik r12 = 0; lcntr=TAPS, do clear until lce; // czyszczenie wejsciowej linii opozniajacej clear: dm(i0,m0)=f12; rts; // powrot z procedury filtracji init_fir_filter /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ /* insert your initialization code for circular (delay) buffers */ /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ user_code_init.end: /* //////////////////////////////////////////////////////////////////////////////// * * audio processing routine * * //////////////////////////////////////////////////////////////////////////////// */ process_audio: /* loop back 'non-processed' ADC0/ADC1 data to DAC0, DAC2, and external AD1852 DAC */ // r0 = dm(Left_Channel_In0); dm(Left_Channel_Out1) = r0; // r0 = dm(Right_Channel_In0); dm(Right_Channel_Out1) = r0; // r0 = dm(Left_Channel_In1); dm(Left_Channel_Out2) = r0; dm(Left_Channel_AD1852) = r0; // r0 = dm(Right_Channel_In1); dm(Right_Channel_Out2) = r0; dm(Right_Channel_AD1852) = r0; r2 = -31; r0 = DM(Left_Channel_In0); // pobranie probek z lewego i prawego kanału układu AD1881 r1 = DM(Right_Channel_In0); f0 = float r0 by r2 ; // konwersja probek z formatu stałoprzecinkowego na zmiennoprzecinkowy f1 = float r1 by r2 ; //#1 store input sample (f0) in delay line } // } // D = delay line storage element } // C = filter coefficient } // P = product } // S = accumulated sum } // } // ____ L O O P P R O L O G U E___________________________________________} //#2 get D[0], get C[0] } //#3 P[0]=D[0]*C[0], (S[0]=P[0]) get D[1], get C[1] } //#4 P[1]=D[1]*C[1], get D[2], get C[2] } // } //#5____ L O O P____B O D Y__________________________________________________} //#6 P[n]=D[n]*C[n], S[n-1]=S[n-2]+P[n-1], get D[n+1], get C[n+1] } // } //#7____ L O O P____E P I L O G U E__________________________________________} //#8 P[N-1]=D[N-1]*C[N-1], S[N-2]=S[N-3]+P[N-2] } //#9 S[N-1]=S[N-2]+P[N-1] } // output (S[N-1]) in f0 //f0=dm(i0,m0) zaladuj do rejestru f0 probke z lokacji o adresie i0, nastepnie // zmien adres i0 -> i0=i0+m0, <-patrz zasada dzialania bufora kolowego!!! //rts(db) powrot do procedury "(db)" wykonaja sie jeszcze dwie instrukcje i dopiero nastapi skok //<-wykorzystanie cykli procesora fir_01: dm(i0,m0)=f0; // #1 } f0=dm(i0,m0), f4=pm(i8,m8); // #2 } f8=f0*f4, f0=dm(i0,m0), f4=pm(i8,m8); // #3 } f12=f0*f4, f0=dm(i0,m0), f4=pm(i8,m8); // #4 } lcntr=TAPS-3, do macs until lce; // #5 } macs: f12=f0*f4, f8=f8+f12, f0=dm(i0,m0), f4=pm(i8,m8); // #6 } // rts (db); // #7 } f12=f0*f4, f8=f8+f12; // #8 } f0=f8+f12; // #9 } r1 = 31; // konwersja próbek z formatu zmiennoprzecinkowego na stałoprzecinkowy r8 = fix f0 by r1; //poniewaz kodek pracuje z danymi w formacjie staloprzecinkowym r9 = fix f0 by r1; DM(Left_Channel_Out0) = r8; // przesłanie wyników filtracji do AD1881 DM(Right_Channel_Out0) = r9; //dm(costamcostam)=r9 - przypisanie danej z rejestru r9 // do etykiety "costamcostam" ulatwia operowanie danymi:) rts; // powrot z procedury filtracji fir process_audio.end: