/* **************************************************************************************************** * QAM_MODULATION.ASM -AM modulation of using common wavetable * * * * Developed for the 21161 EZ-KIT Lite Evaluation Board * * * * * * Based on Sec.8.1.3 of Introduction to Signal Processing * * By S. J. Orfanidis - 1996, Prentice-Hall * * ISBN 0-13-209172-0 * * * * * * I/O equation #1: y(n) = x(n)*sin(2*pi*fc*t) * * * * A(n)=sin(2*PI*fc*t) * * | * * | * * | * * x(n) ----------------->O---------------> y(n) * * * * * * * * I/O equation #2: y(n) = A(n)*sin(2*pi*f*t) where A(n) = Aenv * sin(2*pi*fenv*t) * * * * A(n) * * | * * | * * | * * sin(2*PI*fc*t) ------->O---------------> y(n) * * * * For each input sample, the sample processing algorithm does the following: * * generated AM carrier, A = sin(2*pi*fc*t) * * y = A * x or y = A * sin(2*pi*f*t) * * * * * * Why use frequency modulation? * * You can develop complex waveforms with rich sounds for synthesis applications by generating * * frequency modulated signals, then combine them with other amplitude and frequency modulated * * signals. * * * * * *******************************************************************************************************/ /* ADSP-21161 System Register bit definitions */ #include "def21161.h" .GLOBAL Amplitude_Modulation; .GLOBAL Init_AM_Buffers; .GLOBAL select_amplitude_freq; .GLOBAL select_signal_frequency; .EXTERN Left_Channel_In1; .EXTERN Right_Channel_In1; .EXTERN Left_Channel_Out0; .EXTERN Right_Channel_Out0; .section /dm amp_modu; /* AM Control Knobs */ #define WaveSize 4000 /* sinusoidal wavetable */ #define Aenv 0x7FFFFFFF /* Aenv = 1 = envelope amplitude */ .var sine[WaveSize] = "sinetbl.dat"; /* min frequency f1 = fs/WaveSize = 48k/4k = 12 Hz */ /* load one period of the wavetable */ .var cenv = 1; /* envelope fenv = cenv * f1 = 2 Hz */ .var c = 600; /* signal frequency f = c * f1 = 200 Hz */ .var AM_rate = 6; .var wavetbl_counter = 0x00000000; .var IRQ1_counter = 10; .var IRQ2_counter = 10; /* ------------------------------------PROGRAM MEMORY CODE---------------------------------------*/ .section /pm pm_code; Init_AM_Buffers: B0 = sine; /* pointer for signal generator */ L0 = @sine; /* get size of sine table lookup */ M0 = 1; B1 = sine; /* pointer for signal generator */ L1 = @sine; /* get size of sine table lookup */ M1 = 1; RTS; Init_AM_Buffers.end: /* //////////////////////////////////////////////////////////////////////////////////////////// */ /* */ /* AM Modulation Generator */ /* */ /* //////////////////////////////////////////////////////////////////////////////////////////// */ Amplitude_Modulation: /* combine both left and right input samples together into 1 signal */ r0 = dm(Left_Channel_In1); /* left input sample */ r1 = dm(Right_Channel_In1); /* right input sample */ r0 = ashift r0 by -1; /* scale signal by 1/2 for equal mix */ r1 = ashift r1 by -1; /* scale signal by 1/2 for equal mix */ r0 = r0 + r1; /* 1/2xL(n) + 1/2 xR(n) */ test_wav_update: /* update sine value from lookup table? Update every 6 SPORT rx interrupts */ /* frequency = 6 * c * 4000 / fs = 96000 /48k = ? sec */ r11 = DM(AM_rate); /* count up to 80 interrupts */ r10 = DM(wavetbl_counter); /* get last count from memory */ r10 = r10 + 1; /* increment preset */ comp (r10, r11); /* compare current count to max count */ if ge r10 = r10 - r10; /* if count equals max, reset to zero and start over */ DM(wavetbl_counter) = r10; /* save updated count */ r12 = pass r10; /* test for wave count 0? */ if eq jump update_wavetbl_ptr; /* if you are here, reuse same wavetable values for now */ jump AM_done; /* if necessary, calculate updated pointer to wavetable */ update_wavetbl_ptr: /* Calculate A(t) = Aenv * sin(2*pi*fenv*t) */ m0 = DM(cenv); /* desired increment cenv - frequency f = cenv x fs / WaveSize */ r1 = Aenv; /* Amplitude Envelope */ r2 = dm(i0, m0); /* get next value in wavetable */ r3 = r1 * r2 (SSFR); /* r3 = A(t) = Aenv * sin(2*pi*fenv*t) */ if FLAG2_IN jump modulate_audio_input; // if NOT FLAG2_IN jump modulate_audio_input; /* Calculate A(t) * sin(2*pi*f*t) */ m1 = DM(c); /* desired increment c - frequency f = c x fs / WaveSize */ r2 = dm(i1, m1); /* get next value in wavetable */ r4 = r3 * r2 (SSFR); /* r4 = A(t) * sin(2*pi*f*t) */ r4 = ASHIFT r4 by -6; /* saves your ears when using headphones */ jump AM_done; modulate_audio_input: /* Calculate A(t) * x(n) (This is often called a "ring modulator" effect */ r4 = r3 * r0 (SSFR); /* r4 = A(t) * x(n) */ AM_done: /* write output sample to AD1836 Master Codec channels */ dm(Left_Channel_Out0) = r4; /* left output sample */ dm(Right_Channel_Out0) = r4; /* right output sample */ rts; Amplitude_Modulation.end: ////////////////////////////////////////////////////////////////////////////////////////// /* ------------------------------------------------------------------------------------ */ /* */ /* IRQ2 Pushbutton Interrupt Service Routine */ /* */ /* This routine allows the user to modify flanger width and rate presets. */ /* */ /* Default before 1st IRQ push: */ /* 12th Pushbutton Press: Reverts back to 1st Pushbutton Press */ /* */ /* The pushbutton setting is shown by the active LED setting, all others are off */ /* ------------------------------------------------------------------------------------ */ select_amplitude_freq: bit set mode1 SRRFH; /* enable background register file */ NOP; /* 1 CYCLE LATENCY FOR WRITING TO MODE1 REGISER!! */ r13 = 12; /* number of presets */ r15 = DM(IRQ2_counter); /* get preset count */ r15 = r15 + 1; /* increment preset */ comp (r15, r13); if ge r15 = r15 - r15; /* reset to zero */ DM(IRQ2_counter) = r15; /* save preset count */ r10 = pass r15; /* get preset mode */ if eq jump amplitude_settings_2; /* check for count == 0 */ r10 = r10 - 1; if eq jump amplitude_settings_3; /* check for count == 1 */ r10 = r10 - 1; if eq jump amplitude_settings_4; /* check for count == 2 */ r10 = r10 - 1; if eq jump amplitude_settings_5; /* check for count == 3 */ r10 = r10 - 1; if eq jump amplitude_settings_6; /* check for count == 5 */ r10 = r10 - 1; if eq jump amplitude_settings_7; /* check for count == 5 */ r10 = r10 - 1; if eq jump amplitude_settings_8; /* check for count == 6 */ r10 = r10 - 1; if eq jump amplitude_settings_9; /* check for count == 7 */ r10 = r10 - 1; if eq jump amplitude_settings_10; /* check for count == 8 */ r10 = r10 - 1; if eq jump amplitude_settings_11; /* check for count == 9 */ r10 = r10 - 1; if eq jump amplitude_settings_12; /* check for count == 10 */ amplitude_settings_1: /* count therefore, is == 11 if you are here */ r14 = 1; DM(cenv) = r14; ustat1=DM(IOFLAG); bit clr ustat1 0x3E; /* turn on Flag4 LED */ bit set ustat1 0x01; dm(IOFLAG)=ustat1; jump done_AM_freq_change; amplitude_settings_2: r14 = 2; DM(cenv) = r14; ustat1=DM(IOFLAG); bit clr ustat1 0x3D; /* turn on Flag5 LED */ bit set ustat1 0x02; dm(IOFLAG)=ustat1; jump done_AM_freq_change; amplitude_settings_3: r14 = 4; DM(cenv) = r14; ustat1=DM(IOFLAG); bit clr ustat1 0x3B; /* turn on Flag6 LED */ bit set ustat1 0x04; dm(IOFLAG)=ustat1; jump done_AM_freq_change; amplitude_settings_4: r14 = 8; DM(cenv) = r14; ustat1=DM(IOFLAG); bit clr ustat1 0x37; /* turn on Flag7 LED */ bit set ustat1 0x08; dm(IOFLAG)=ustat1; jump done_AM_freq_change; amplitude_settings_5: r14 = 16; DM(cenv) = r14; ustat1=DM(IOFLAG); bit clr ustat1 0x2F; /* turn on Flag8 LED */ bit set ustat1 0x10; dm(IOFLAG)=ustat1; jump done_AM_freq_change; amplitude_settings_6: r14 = 32; DM(cenv) = r14; ustat1=DM(IOFLAG); bit clr ustat1 0x1F; /* turn on Flag9 LED */ bit set ustat1 0x20; dm(IOFLAG)=ustat1; jump done_AM_freq_change; amplitude_settings_7: r14 = 64; DM(cenv) = r14; ustat1=DM(IOFLAG); bit clr ustat1 0x3E; /* turn on Flag5 LED */ bit set ustat1 0x01; dm(IOFLAG)=ustat1; jump done_AM_freq_change; amplitude_settings_8: r14 = 128; DM(cenv) = r14; ustat1=DM(IOFLAG); bit clr ustat1 0x3D; /* turn on Flag5 LED */ bit set ustat1 0x02; dm(IOFLAG)=ustat1; jump done_AM_freq_change; amplitude_settings_9: r14 = 256; DM(cenv) = r14; ustat1=DM(IOFLAG); bit clr ustat1 0x3B; /* turn on Flag6 LED */ bit set ustat1 0x04; dm(IOFLAG)=ustat1; jump done_AM_freq_change; amplitude_settings_10: r14 = 512; DM(cenv) = r14; ustat1=DM(IOFLAG); bit clr ustat1 0x37; /* turn on Flag7 LED */ bit set ustat1 0x08; dm(IOFLAG)=ustat1; jump done_AM_freq_change; amplitude_settings_11: r14 = 1024; DM(cenv) = r14; ustat1=DM(IOFLAG); bit clr ustat1 0x2F; /* turn on Flag8 LED */ bit set ustat1 0x10; dm(IOFLAG)=ustat1; jump done_AM_freq_change; amplitude_settings_12: r14 = 2048; DM(cenv) = r14; ustat1=DM(IOFLAG); bit clr ustat1 0x1F; /* turn on Flag9 LED */ bit set ustat1 0x20; dm(IOFLAG)=ustat1; done_AM_freq_change: rti(db); bit clr mode1 SRRFH; /* switch back to primary register set */ nop; select_amplitude_freq.end: /* ------------------------------------------------------------------------------------ */ /* */ /* IRQ1 Pushbutton Interrupt Service Routine */ /* */ /* */ /* Default before 1st IRQ push: Delay = 20.83 msec */ /* 7th Pushbutton Press: Reverts back to 1st Pushbutton Press */ /* */ /* The pushbutton setting is shown by the inactive LED setting, all others are on */ /* (reverse of IRQ1 LED settings, which show lit LED for setting #) */ /* ------------------------------------------------------------------------------------ */ select_signal_frequency: bit set mode1 SRRFH; /* enable background register file */ NOP; /* 1 CYCLE LATENCY FOR WRITING TO MODE1 REGISER!! */ r13 = 12; /* number of presets */ r15 = DM(IRQ1_counter); /* get preset count */ r15 = r15 + 1; /* increment preset */ comp (r15, r13); if ge r15 = r15 - r15; /* reset to zero */ DM(IRQ1_counter) = r15; /* save preset count */ r10 = pass r15; /* get preset mode */ if eq jump frequency_settings_2; /* check for count == 0 */ r10 = r10 - 1; if eq jump frequency_settings_3; /* check for count == 1 */ r10 = r10 - 1; if eq jump frequency_settings_4; /* check for count == 2 */ r10 = r10 - 1; if eq jump frequency_settings_5; /* check for count == 3 */ r10 = r10 - 1; if eq jump frequency_settings_6; /* check for count == 4 */ r10 = r10 - 1; if eq jump frequency_settings_7; /* check for count == 5 */ r10 = r10 - 1; if eq jump frequency_settings_8; /* check for count == 6 */ r10 = r10 - 1; if eq jump frequency_settings_9; /* check for count == 7 */ r10 = r10 - 1; if eq jump frequency_settings_10; /* check for count == 8 */ r10 = r10 - 1; if eq jump frequency_settings_11; /* check for count == 9 */ r10 = r10 - 1; if eq jump frequency_settings_12; /* check for count == 10 */ frequency_settings_1: /* count therefore, is == 11 if you are here */ r14 = 50; DM(c) = r14; ustat1=DM(IOFLAG); bit set ustat1 0x3E; /* turn off Flag4 LED */ bit clr ustat1 0x01; dm(IOFLAG)=ustat1; jump exit_frequency_tweak; frequency_settings_2: r14 = 100; DM(c) = r14; ustat1=DM(IOFLAG); bit set ustat1 0x3D; /* turn off Flag5 LED */ bit clr ustat1 0x02; dm(IOFLAG)=ustat1; jump exit_frequency_tweak; frequency_settings_3: r14 = 150; DM(c) = r14; ustat1=DM(IOFLAG); bit set ustat1 0x3B; /* turn off Flag6 LED */ bit clr ustat1 0x04; dm(IOFLAG)=ustat1; jump exit_frequency_tweak; frequency_settings_4: r14 = 200; DM(c) = r14; ustat1=DM(IOFLAG); bit set ustat1 0x37; /* turn off Flag7 LED */ bit clr ustat1 0x08; dm(IOFLAG)=ustat1; jump exit_frequency_tweak; frequency_settings_5: r14 = 300; DM(c) = r14; ustat1=DM(IOFLAG); bit set ustat1 0x2F; /* turn off Flag8 LED */ bit clr ustat1 0x10; dm(IOFLAG)=ustat1; jump exit_frequency_tweak; frequency_settings_6: r14 = 400; DM(c) = r14; ustat1=DM(IOFLAG); bit set ustat1 0x1F; /* turn off Flag9 LED */ bit clr ustat1 0x20; dm(IOFLAG)=ustat1; jump exit_frequency_tweak; frequency_settings_7: /* count therefore, is == 5 if you are here */ r14 = 500; DM(c) = r14; ustat1=DM(IOFLAG); bit set ustat1 0x3E; /* turn off Flag4 LED */ bit clr ustat1 0x01; dm(IOFLAG)=ustat1; jump exit_frequency_tweak; frequency_settings_8: r14 = 600; DM(c) = r14; ustat1=DM(IOFLAG); bit set ustat1 0x3D; /* turn off Flag5 LED */ bit clr ustat1 0x02; dm(IOFLAG)=ustat1; jump exit_frequency_tweak; frequency_settings_9: r14 = 800; DM(c) = r14; ustat1=DM(IOFLAG); bit set ustat1 0x3B; /* turn off Flag6 LED */ bit clr ustat1 0x04; dm(IOFLAG)=ustat1; jump exit_frequency_tweak; frequency_settings_10: r14 = 1000; DM(c) = r14; ustat1=DM(IOFLAG); bit set ustat1 0x37; /* turn off Flag7 LED */ bit clr ustat1 0x08; dm(IOFLAG)=ustat1; jump exit_frequency_tweak; frequency_settings_11: r14 = 1200; DM(c) = r14; ustat1=DM(IOFLAG); bit set ustat1 0x2F; /* turn off Flag8 LED */ bit clr ustat1 0x10; dm(IOFLAG)=ustat1; jump exit_frequency_tweak; frequency_settings_12: r14 = 1600; DM(c) = r14; ustat1=DM(IOFLAG); bit set ustat1 0x1F; /* turn off Flag9 LED */ bit clr ustat1 0x20; dm(IOFLAG)=ustat1; exit_frequency_tweak: rti(db); bit clr mode1 SRRFH; /* switch back to primary register set */ nop; select_signal_frequency.end: