Example #1
0
        public int Read(ref ComplexF[] dest, int cnt)
        {
            int free_cnt = ReadSpace();
            if (free_cnt == 0) return 0;

            int to_read = cnt > free_cnt ? free_cnt : cnt;
            int cnt2 = rptr + to_read;
            int n1 = 0, n2 = 0;

            if (cnt2 > size)
            {
                n1 = size - rptr;
                n2 = cnt2 & mask;
            }
            else
            {
                n1 = to_read;
                n2 = 0;
            }

            Array.Copy(buf, rptr, dest, 0, n1);
            rptr = (rptr + n1) & mask;

            if (n2 != 0)
            {
                Array.Copy(buf, rptr, dest, n1, n2);
                rptr = (rptr + n2) & mask;
            }

            return to_read;
        }
Example #2
0
 private ComplexF CsclF(ComplexF x, float a)
 {
     ComplexF z;
     z.Re = x.Re * a;
     z.Im = x.Im * a;
     return z;
 }
Example #3
0
        public void Exchange_samples(ref ComplexF[] output, ref ComplexF[] monitor, int buflen)
        {
            if (MainForm.output_ring_buf.ReadSpace() < buflen)
            {
                while (MainForm.output_ring_buf.ReadSpace() < buflen)
                {
                    if (run_transmiter)
                    {
                        audio_event.Set();
                        Thread.Sleep(1);
                    }
                    else
                        return;
                }
            }

            EnterCriticalSection(cs_audio);

            MainForm.output_ring_buf.Read(ref iq_buffer, buflen);
            correctIQ(ref iq_buffer);
            MainForm.mon_ring_buf.Read(ref mon_iq_buffer, buflen);
            Array.Copy(iq_buffer, output, buflen);
            Array.Copy(mon_iq_buffer, monitor, buflen);

            LeaveCriticalSection(cs_audio);
        }
Example #4
0
 //-----------------------------------------------------------------------------------
 //-----------------------------------------------------------------------------------
 /// <summary>
 /// Determine whether two complex numbers are almost (i.e. within the tolerance) equivalent.
 /// </summary>
 /// <param name="a"></param>
 /// <param name="b"></param>
 /// <param name="tolerance"></param>
 /// <returns></returns>
 public static bool IsEqual( ComplexF a, ComplexF b, float tolerance )
 {
     return
         ( Math.Abs( a.Re - b.Re ) < tolerance ) &&
         ( Math.Abs( a.Im - b.Im ) < tolerance );
 }
Example #5
0
 private ComplexF CmulF(ComplexF x, ComplexF y)
 {
     ComplexF z;
     z.Re = x.Re * y.Re - x.Im * y.Im;
     z.Im = x.Im * y.Re + x.Re * y.Im;
     return z;
 }
Example #6
0
 private double carg(ComplexF x)
 {
     return Math.Atan2(x.Im, x.Re);
 }
Example #7
0
        /// <summary>
        /// Compute a 1D fast Fourier transform of a dataset of complex numbers.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="length"></param>
        /// <param name="direction"></param>
        public void FFT_Quick( ComplexF[] data, int length, FourierDirection direction )
        {
            /*if( data == null ) {
                throw new ArgumentNullException( "data" );
            }
            if( data.Length < length ) {
                throw new ArgumentOutOfRangeException( "length", length, "must be at least as large as 'data.Length' parameter" );
            }
            if( IsPowerOf2( length ) == false ) {
                throw new ArgumentOutOfRangeException( "length", length, "must be a power of 2" );
            }*/

            SyncLookupTableLength( length );

            int ln = Log2( length );

            // reorder array
            ReorderArray( data );

            // successive doubling
            int N = 1;
            int signIndex = ( direction == FourierDirection.Forward ) ? 0 : 1;

            for( int level = 1; level <= ln; level ++ ) {
                int M = N;
                N <<= 1;

                float[] uRLookup = _uRLookupF[ level, signIndex ];
                float[] uILookup = _uILookupF[ level, signIndex ];

                for( int j = 0; j < M; j ++ ) {
                    float uR = uRLookup[j];
                    float uI = uILookup[j];

                    for( int even = j; even < length; even += N ) {
                        int odd	 = even + M;

                        float	r = data[ odd ].Re;
                        float	i = data[ odd ].Im;

                        float	odduR = r * uR - i * uI;
                        float	odduI = r * uI + i * uR;

                        r = data[ even ].Re;
                        i = data[ even ].Im;

                        data[ even ].Re	= r + odduR;
                        data[ even ].Im	= i + odduI;

                        data[ odd ].Re	= r - odduR;
                        data[ odd ].Im	= i - odduI;
                    }
                }
            }
        }
Example #8
0
 /// <summary>
 /// Compute a 1D fast Fourier transform of a dataset of complex numbers.
 /// </summary>
 /// <param name="data"></param>
 /// <param name="direction"></param>
 public void FFT( ComplexF[] data, FourierDirection direction )
 {
     if( data == null ) {
         throw new ArgumentNullException( "data" );
     }
     FFT(data, data.Length, direction );
 }
Example #9
0
 private float Cabs(ComplexF z)
 {
     return (float)Math.Sqrt(z.Re * z.Re + z.Im * z.Im);
 }
Example #10
0
        private void send_symbol(int index, int sym)
        {
            float delta, mon_delta;
            float ival, qval;
            ComplexF symbol = new ComplexF();
            int i;

            try
            {
                if (trx.modem[index].qpsk && trx.reverse)
                    sym = (4 - sym) & 3;

                /* differential QPSK modulation - top bit flipped */
                switch (sym)
                {
                    case 0:
                        symbol.Re = -1.0f;	/* 180 degrees */
                        symbol.Im = 0.0f;
                        break;
                    case 1:
                        symbol.Re = 0.0f;	/* 270 degrees */
                        symbol.Im = -1.0f;
                        break;
                    case 2:
                        symbol.Re = 1.0f;	/*   0 degrees */
                        symbol.Im = 0.0f;
                        break;
                    case 3:
                        symbol.Re = 0.0f;	/*  90 degrees */
                        symbol.Im = 1.0f;
                        break;
                }

                symbol = CmulF(trx.modem[index].tx_prevsymbol, symbol);
                delta = (float)(TWOPI * (trx.modem[index].tx_frequency) / trx.modem[index].tx_samplerate);
                mon_delta = (float)(TWOPI * trx.mon_frequency / Audio.SampleRate);

                if (trx.modem[index].qpsk)
                {
                    for (i = 0; i < trx.modem[index].tx_symbollen; i++)
                    {
                        ival = (float)(trx.modem[index].txshape[i] * trx.modem[index].tx_prevsymbol.Re +
                            (1.0 - trx.modem[index].txshape[i]) * symbol.Re);

                        qval = (float)(trx.modem[index].txshape[i] * trx.modem[index].tx_prevsymbol.Im +
                            (1.0 - trx.modem[index].txshape[i]) * symbol.Im);

                        if (ptr >= 2048)
                        {
                            ptr = 0;
                            Array.Copy(output, 0, Tx[index].input_buf, 2048, 2048);
                            Array.Copy(Tx[index].input_buf, Tx[index].filter.vector, 4096);
                            fft.FFT(Tx[index].filter.vector, 4096, FourierDirection.Forward);

                            for (int j = 0; j < 4096; j++)
                                Tx[index].filter.vector[j] = CmulF(Tx[index].filter.vector[j],
                                    Tx[index].filter.zfvec[j]);

                            fft.FFT(Tx[index].filter.vector, 4096, FourierDirection.Backward);
                            Array.Copy(Tx[index].input_buf, 2048, Tx[index].input_buf, 0, 2048);

                            if (MainForm.output_ring_buf.WriteSpace() < 2048)
                            {
                                if (run_transmiter)
                                {
                                    while (MainForm.output_ring_buf.WriteSpace() < 2048)
                                        audio_event.WaitOne(1);
                                }
                            }

                            EnterCriticalSection(cs_audio);
                            MainForm.output_ring_buf.Write(Tx[index].filter.vector, 2048);
                            LeaveCriticalSection(cs_audio);
                        }

                        output[ptr].Re = (float)((ival * (float)Math.Sin(trx.modem[index].tx_phaseacc) +
                            qval * (float)Math.Cos(trx.modem[index].tx_phaseacc)));
                        output[ptr].Im = -output[ptr].Re;

                        ptr++;

                        trx.mon_outbuf[i].Re = (float)(ival * (float)Math.Cos(trx.modem[index].mon_phaseacc));
                        trx.mon_outbuf[i].Im = (float)(qval * (float)Math.Sin(trx.modem[index].mon_phaseacc));

                        trx.modem[index].tx_phaseacc += delta;
                        trx.modem[index].mon_phaseacc += mon_delta;

                        if (trx.modem[index].tx_phaseacc > M_PI)
                            trx.modem[index].tx_phaseacc -= TWOPI;

                        if (trx.modem[index].mon_phaseacc > M_PI)
                            trx.modem[index].mon_phaseacc -= TWOPI;
                    }

                }
                else
                {
                    for (i = 0; i < trx.modem[index].tx_symbollen; i++)
                    {
                        ival = (float)(trx.modem[index].txshape[i] * trx.modem[index].tx_prevsymbol.Re +
                            (1.0 - trx.modem[index].txshape[i]) * symbol.Re);

                        if (ptr >= 2048)
                        {
                            ptr = 0;
                            Array.Copy(output, 0, Tx[index].input_buf, 2048, 2048);
                            Array.Copy(Tx[index].input_buf, Tx[index].filter.vector, 4096);
                            fft.FFT(Tx[index].filter.vector, 4096, FourierDirection.Forward);

                            for (int j = 0; j < 4096; j++)
                                Tx[index].filter.vector[j] = CmulF(Tx[index].filter.vector[j],
                                    Tx[index].filter.zfvec[j]);

                            fft.FFT(Tx[index].filter.vector, 4096, FourierDirection.Backward);
                            Array.Copy(Tx[index].input_buf, 2048, Tx[index].input_buf, 0, 2048);

                            if (MainForm.output_ring_buf.WriteSpace() < 2048)
                            {
                                if (run_transmiter)
                                {
                                    while (MainForm.output_ring_buf.WriteSpace() < 2048)
                                        audio_event.WaitOne(1);
                                }
                            }

                            EnterCriticalSection(cs_audio);
                            MainForm.output_ring_buf.Write(Tx[index].filter.vector, 2048);
                            LeaveCriticalSection(cs_audio);
                        }

                        output[ptr].Re = (float)(ival * (float)Math.Cos(trx.modem[index].tx_phaseacc));
                        output[ptr].Im = -output[ptr].Re;  // (float)(ival * (float)Math.Sin(trx.modem[index].tx_phaseacc));

                        ptr++;

                        trx.mon_outbuf[i].Im = (float)(ival * (float)Math.Cos(trx.modem[index].mon_phaseacc));
                        trx.mon_outbuf[i].Re = (float)(ival * (float)Math.Sin(trx.modem[index].mon_phaseacc));

                        trx.modem[index].tx_phaseacc += delta;
                        trx.modem[index].mon_phaseacc += mon_delta;

                        if (trx.modem[index].tx_phaseacc > M_PI)
                            trx.modem[index].tx_phaseacc -= TWOPI;

                        if (trx.modem[index].mon_phaseacc > M_PI)
                            trx.modem[index].mon_phaseacc -= TWOPI;
                    }
                }

                if (MainForm.output_ring_buf.WriteSpace() < trx.modem[index].tx_symbollen)
                {
                    if (run_transmiter)
                    {
                        while (MainForm.output_ring_buf.WriteSpace() < trx.modem[index].tx_symbollen)
                            audio_event.WaitOne(10);
                    }
                }

                EnterCriticalSection(cs_audio);
                MainForm.mon_ring_buf.Write(trx.mon_outbuf, trx.modem[index].tx_symbollen);
                LeaveCriticalSection(cs_audio);

                /* save the current symbol */
                trx.modem[index].tx_prevsymbol = symbol;
            }
            catch (Exception ex)
            {
                Debug.Write(ex.ToString());
            }
        }
Example #11
0
        private void rx_symbol(int index, ComplexF symbol)
        {
            try
            {
                double error;
                int n;

                if ((trx.modem[index].phase = carg(ccor(trx.modem[index].rx_prevsymbol, symbol))) < 0)
                    trx.modem[index].phase += TWOPI;

                trx.modem[index].rx_prevsymbol = symbol;

                if (trx.modem[index].qpsk)
                {
                    trx.modem[index].bits = ((int)(trx.modem[index].phase / M_PI_2 + 0.5)) & 3;
                    n = 4;
                }
                else
                {
                    trx.modem[index].bits = (((int)(trx.modem[index].phase / M_PI + 0.5)) & 1) << 1;
                    n = 2;
                }

                trx.modem[index].quality.Re = (float)decayavg(trx.modem[index].quality.Re,
                    Math.Cos(n * trx.modem[index].phase), 50.0);
                trx.modem[index].quality.Im = (float)decayavg(trx.modem[index].quality.Im,
                    Math.Sin(n * trx.modem[index].phase), 50.0);

                /*trx.modem[index].quality.Re = (float)(0.02f * Math.Cos(n * trx.modem[index].phase) +
                    0.98f * trx.modem[index].quality.Re);
                trx.modem[index].quality.Im = (float)(0.02f * Math.Sin(n * trx.modem[index].phase) +
                    0.98f * trx.modem[index].quality.Im);*/

                trx.modem[index].dcdshreg = (trx.modem[index].dcdshreg << 2) | (uint)trx.modem[index].bits;

                switch (trx.modem[index].dcdshreg)
                {
                    case 0xAAAAAAAA:	/* DCD on by preamble */
                        trx.modem[index].dcd = true;
                        trx.modem[index].quality.Re = 1;
                        trx.modem[index].quality.Im = 0;
                        trx.acquire = 0;
                        break;

                    case 0:			/* DCD off by postamble */
                        trx.modem[index].dcd = false;
                        trx.modem[index].quality.Re = 0;
                        trx.modem[index].quality.Im = 0;
                        break;

                    default:
                        double pwr = Math.Abs(trx.modem[index].quality.Re * trx.modem[index].quality.Re +
                            trx.modem[index].quality.Im * trx.modem[index].quality.Im);

                        if (pwr > (trx.squelch * sql))
                        {
                            trx.modem[index].dcd = true;
                        }
                        else
                        {
                            trx.modem[index].dcd = false;
                        }
                        break;
                }

                if (index == 0)
                {
                    if (trx.modem[index].dcd == true)
                    {
                        MainForm.lblPSKDCDCh1.BackColor = Color.Green;
                    }
                    else
                    {
                        MainForm.lblPSKDCDCh1.BackColor = Color.Red;
                    }
                }
                else if (index == 1)
                {
                    if (trx.modem[index].dcd == true)
                    {
                        MainForm.lblPSKDCDCh2.BackColor = Color.Green;
                    }
                    else
                    {
                        MainForm.lblPSKDCDCh2.BackColor = Color.Red;
                    }
                }

                if (trx.modem[index].dcd == true || trx.squelchon == false)
                {
                    if (trx.modem[index].qpsk)
                        rx_qpsk(index, trx.modem[index].bits);
                    else
                    {
                        if (trx.modem[index].bits > 0)
                            rx_bit(index, 0);
                        else
                            rx_bit(index, 1);
                    }

                    if (trx.modem[index].dcd)
                    {
                        error = (trx.modem[index].phase - trx.modem[index].bits * M_PI / 2);

                        if (error < M_PI / 2)
                            error += TWOPI;
                        if (error > M_PI / 2)
                            error -= TWOPI;

                        error *= (double)(trx.modem[index].rx_samplerate / (trx.modem[index].rx_symbollen * TWOPI));
                        trx.modem[index].rx_frequency -= (error / 16.0);
                        trx.modem[index].tx_frequency -= (error / 16.0);

                        if (trx.modem[index].rx_frequency > MainForm.PSKPitch + 7.0)
                        {
                            trx.modem[index].rx_frequency = MainForm.PSKPitch + 7.0;
                            trx.modem[index].tx_frequency = tx_if_shift + 7.0;
                        }
                        else if (trx.modem[index].rx_frequency < MainForm.PSKPitch - 7.0)
                        {
                            trx.modem[index].rx_frequency = MainForm.PSKPitch - 7.0;
                            trx.modem[index].tx_frequency = tx_if_shift - 7.0;
                        }

                        if (trx.afcon)
                        {
                            double difference = 0.0;
                            pll++;

                            if (pll > 20)
                            {
                                switch (index)
                                {
                                    case 0:
                                        double diff = trx.modem[index].rx_frequency - MainForm.PSKPitch;

                                        if (diff > 1.0)
                                        {
                                            difference = 0.000001;
                                            MainForm.Invoke(new CrossThreadSetText(MainForm.CommandCallback), "VFO", 1,
                                                difference.ToString());
                                        }
                                        else if (diff < -1.0)
                                        {
                                            difference = -0.000001;
                                            MainForm.Invoke(new CrossThreadSetText(MainForm.CommandCallback), "VFO", 1,
                                                difference.ToString());
                                        }
                                        break;

                                    case 1:
                                        diff = trx.modem[index].rx_frequency - MainForm.PSKPitch;

                                        if (diff > 1.0)
                                        {
                                            difference = 0.000001;
                                            MainForm.Invoke(new CrossThreadSetText(MainForm.CommandCallback), "VFO", 2,
                                                difference.ToString());
                                        }
                                        else if (diff < -1.0)
                                        {
                                            difference = -0.000001;
                                            MainForm.Invoke(new CrossThreadSetText(MainForm.CommandCallback), "VFO", 2,
                                                difference.ToString());
                                        }

                                        break;
                                }

                                pll = 0;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.Write(ex.ToString());
            }
        }
Example #12
0
        private int RXprocess(int index, int len)
        {
            try
            {
                double delta;
                ComplexF z = new ComplexF();
                ComplexF z2 = new ComplexF();
                int i, j = 0;
                string dcd = "";
                int ptr = 0;

                delta = TWOPI * trx.modem[index].rx_frequency / trx.modem[index].rx_samplerate;

                while (len-- > 0)
                {
                    trx.modem[index].rx_phaseacc += delta;

                    if (trx.modem[index].rx_phaseacc >= M_PI)
                        trx.modem[index].rx_phaseacc -= TWOPI;

                    // Filter and downsample by 16 or 8
                    if (trx.modem[index].decimate >= trx.modem[index].decimate_ratio - 1)
                    {
                        trx.modem[index].decimate = 0;
                        double sum, ampsum;
                        int idx;

                        z2.Re = 0.0f;
                        z2.Im = 0.0f;

                        // NCO mixer
                        if (index == 0)
                        {
                            z.Re = (float)(buffer_ch1[j] * Math.Cos(trx.modem[index].rx_phaseacc));
                            z.Im = (float)(buffer_ch1[j] * Math.Sin(trx.modem[index].rx_phaseacc));
                        }
                        else if (index == 1)
                        {
                            z.Re = (float)(buffer_ch2[j] * Math.Cos(trx.modem[index].rx_phaseacc));
                            z.Im = (float)(buffer_ch2[j] * Math.Sin(trx.modem[index].rx_phaseacc));
                        }

                        // MAC filtering
                        trx.modem[index].ibuffer[trx.modem[index].pointer] = z.Re;
                        trx.modem[index].qbuffer[trx.modem[index].pointer] = z.Im;
                        trx.modem[index].pointer++;
                        ptr = trx.modem[index].pointer - trx.modem[index].length;

                        for (i = 0; i < trx.modem[index].length; i++)
                        {
                            z2.Re += (float)(trx.modem[index].ibuffer[ptr] * trx.modem[index].filter[i]);
                            z2.Im += (float)(trx.modem[index].qbuffer[ptr] * trx.modem[index].filter[i]);
                            ptr++;
                        }

                        if (trx.modem[index].pointer >= trx.modem[index].FIRBufferLen)
                        {
                            Array.Copy(trx.modem[index].ibuffer, (trx.modem[index].FIRBufferLen - trx.modem[index].length),
                                trx.modem[index].ibuffer, 0, trx.modem[index].length);
                            Array.Copy(trx.modem[index].qbuffer, (trx.modem[index].FIRBufferLen - trx.modem[index].length),
                                trx.modem[index].qbuffer, 0, trx.modem[index].length);
                            trx.modem[index].pointer = trx.modem[index].length;
                        }

                        // sync correction
                        idx = (int)Math.Min(trx.modem[index].bitclk, 15);
                        idx = Math.Max(0, idx);
                        trx.modem[index].syncbuf[idx] = 0.9 * trx.modem[index].syncbuf[idx] + 0.1 *
                            Math.Sqrt(z2.Re * z2.Re + z2.Im * z2.Im);

                        sum = 0.0;
                        ampsum = 0.0;

                        for (i = 0; i < 8; i++)
                        {
                            sum += trx.modem[index].syncbuf[i] - trx.modem[index].syncbuf[i + 8];
                            ampsum += trx.modem[index].syncbuf[i] + trx.modem[index].syncbuf[i + 8];
                        }

                        sum = (ampsum == 0 ? 0 : sum / ampsum);

                        if (sum == float.NaN)
                            sum = 0.0;

                        trx.modem[index].bitclk -= sum / 5.0f;

                        // bit clock
                        trx.modem[index].bitclk += 1;

                        if (trx.modem[index].bitclk >= 16.0)
                        {
                            trx.modem[index].bitclk -= 16.0;
                            rx_symbol(index, z2);
                        }
                    }
                    else
                        trx.modem[index].decimate++;

                    j++;
                }

                dcd = Math.Round(MainForm.PSKPitch - trx.modem[index].rx_frequency, 3).ToString("f3");
                dcd = dcd.PadRight(3, '0');
                MainForm.Invoke(new CrossThreadSetText(MainForm.CommandCallback), "Set text", 100 + index, dcd);

                return 0;
            }
            catch (Exception ex)
            {
                Debug.Write(ex.ToString());
                return -1;
            }
        }
Example #13
0
        private unsafe float normalize_vec_COMPLEX(ComplexF[] z, int n, float scale)
        {
            if (z != null && n > 0)
            {
                int i;
                float big = -(float)1e15;

                for (i = 0; i < n; i++)
                {
                    float a = Cabs(z[i]);
                    big = Math.Max(big, a);
                }

                if (big > 0.0)
                {
                    float scl = (float)(scale / big);

                    for (i = 0; i < n; i++)
                        z[i] = CsclF(z[i], scl);

                    return scl;
                }
                else return 0.0f;
            }

            return 0.0f;
        }
Example #14
0
        private ComplexFIR Create_FIR_Bandpass_COMPLEX(float lofreq, float hifreq, float samplerate, int size)
        {
            ComplexFIR p = new ComplexFIR();
            ComplexF[] h;
            float[] w;
            float fc, ff, midpoint;
            int i, msize;
            float pi = 3.14159265358928f;
            float twopi = 2 * pi;
            h = new ComplexF[size];

            if ((lofreq < -(samplerate / 2.0)) || (hifreq > (samplerate / 2.0)) || (hifreq <= lofreq))
                return p;
            else if (size < 1)
                return p;
            else
            {
                msize = size - 1;
                midpoint = (float)(0.5f * msize);
                p = Create_FIR_COMPLEX(size);
                p.frq.lo = lofreq;
                p.frq.hi = hifreq;
                h = p.coef;
                w = new float[size];
                w = makewindow(size, w);

                lofreq /= samplerate;
                hifreq /= samplerate;
                fc = (float)((hifreq - lofreq) / 2.0f);
                ff = (float)((lofreq + hifreq) * pi);

                for (i = 0; i < size; i++)
                {
                    float k = (float)i - midpoint;
                    float tmp, phs = ff * k;
                    if ((float)i != midpoint)
                        tmp = (float)((Math.Sin(twopi * k * fc) / (pi * k)) * w[i]);
                    else
                        tmp = (float)(2.0f * fc);
                    tmp *= 2.0f;
                    h[i].Re = (float)(tmp * Math.Cos(phs));
                    h[i].Im = (float)(tmp * Math.Sin(phs));
                }

                return p;
            }
        }
Example #15
0
        private unsafe void CreateTXFilter(int index, int samplerate, double low_freq, double high_freq)
        {
            try
            {
                int fftlen = Tx[index].filter.fftlen;
                int ncoef = Tx[index].filter.buflen + 1;
                ComplexF[] vector = new ComplexF[fftlen];

                Tx[index].filter.coef = Create_FIR_Bandpass_COMPLEX((float)low_freq,
                    (float)high_freq, samplerate, ncoef);

                for (int i = 0; i < ncoef; i++)
                {
                    vector[fftlen - ncoef + i] = Tx[index].filter.coef.coef[i];
                }

                fft.FFT(vector, fftlen, FourierDirection.Forward);

                normalize_vec_COMPLEX(vector, Tx[index].filter.fftlen,
                    Tx[index].filter.scale);

                for (int i = 0; i < fftlen; i++)
                {
                    Tx[index].filter.zfvec[i] = vector[i];
                }
            }
            catch (Exception ex)
            {
                Debug.Write(ex.ToString());
            }
        }
Example #16
0
 public void Clear()
 {
     ComplexF[] zero = new ComplexF[size];
     Array.Clear(zero, 0, size);
     Array.Copy(zero, buf, size);
 }
Example #17
0
        private float Utility(ref ComplexF[] iq, float phase, float gain)
        {
            float[] spectrum = new float[4096];
            Array.Copy(iq, 0, fftPtr, 2048, 2048);
            //Array.Copy(zero, 0, fftPtr, 0, 2048);

            for (var i = 0; i < 2048; i++)
            {
                fftPtr[i].Im += phase * fftPtr[i].Re;
                fftPtr[i].Re *= gain;
                fftPtr[i].Re *= window[i];
                fftPtr[i].Im *= window[i];
            }

            fft.FFT_Quick(fftPtr, 4096, FourierDirection.Forward);
            SpectrumPower(ref fftPtr, ref spectrumPtr, 4096, 50.0f);
            Array.Copy(spectrumPtr, 0, spectrum, 2048, 2048);
            Array.Copy(spectrumPtr, 2048, spectrum, 0, 2048);
            /*Array.Copy(spectrumPtr, 0, DX.new_display_data, 2048, 2048);
            Array.Copy(spectrumPtr, 2048, DX.new_display_data, 0, 2048);
            Array.Copy(DX.new_display_data, DX.new_waterfall_data, 4096);*/

            var result = 0.0f;

            for (var i = 0; i < 4096 / 2; i++)
            {
                var distanceFromCenter = 4096 / 2 - i;

                if (distanceFromCenter > (0.05f * 4096 / 2))
                {
                    result += Math.Abs(spectrum[i] - spectrum[4096 - 2 - i]);
                }
            }

            Array.Copy(iq, 0, fftPtr, 0, 2048);

            return result;
        }
Example #18
0
 private double carg(ComplexF x)
 {
     double z;
     z = Math.Atan2(x.Im, x.Re);
     return z;
 }
Example #19
0
        /// <summary>
        /// Compute a 3D fast fourier transform on a data set of complex numbers
        /// </summary>
        /// <param name="data"></param>
        /// <param name="xLength"></param>
        /// <param name="yLength"></param>
        /// <param name="zLength"></param>
        /// <param name="direction"></param>
        public void FFT3( ComplexF[] data, int xLength, int yLength, int zLength, FourierDirection direction )
        {
            if( data == null ) {
                throw new ArgumentNullException( "data" );
            }
            if( data.Length < xLength*yLength*zLength ) {
                throw new ArgumentOutOfRangeException( "data.Length", data.Length, "must be at least as large as 'xLength * yLength * zLength' parameter" );
            }
            if( IsPowerOf2( xLength ) == false ) {
                throw new ArgumentOutOfRangeException( "xLength", xLength, "must be a power of 2" );
            }
            if( IsPowerOf2( yLength ) == false ) {
                throw new ArgumentOutOfRangeException( "yLength", yLength, "must be a power of 2" );
            }
            if( IsPowerOf2( zLength ) == false ) {
                throw new ArgumentOutOfRangeException( "zLength", zLength, "must be a power of 2" );
            }

            int xInc = 1;
            int yInc = xLength;
            int zInc = xLength * yLength;

            if( xLength > 1 ) {
                SyncLookupTableLength( xLength );
                for( int z = 0; z < zLength; z ++ ) {
                    for( int y = 0; y < yLength; y ++ ) {
                        int xStart = y * yInc + z * zInc;
                        LinearFFT_Quick( data, xStart, xInc, xLength, direction );
                    }
                }
            }

            if( yLength > 1 ) {
                SyncLookupTableLength( yLength );
                for( int z = 0; z < zLength; z ++ ) {
                    for( int x = 0; x < xLength; x ++ ) {
                        int yStart = z * zInc + x * xInc;
                        LinearFFT_Quick( data, yStart, yInc, yLength, direction );
                    }
                }
            }

            if( zLength > 1 ) {
                SyncLookupTableLength( zLength );
                for( int y = 0; y < yLength; y ++ ) {
                    for( int x = 0; x < xLength; x ++ ) {
                        int zStart = y * yInc + x * xInc;
                        LinearFFT_Quick( data, zStart, zInc, zLength, direction );
                    }
                }
            }
        }
Example #20
0
        //-----------------------------------------------------------------------------------
        //-----------------------------------------------------------------------------------

        /// <summary>
        /// Determine whether two complex numbers are almost (i.e. within the tolerance) equivalent.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="tolerance"></param>
        /// <returns></returns>
        static public bool IsEqual(ComplexF a, ComplexF b, float tolerance)
        {
            return
                ((Math.Abs(a.Re - b.Re) < tolerance) &&
                 (Math.Abs(a.Im - b.Im) < tolerance));
        }
Example #21
0
        private void LinearFFT( ComplexF[] data, int start, int inc, int length, FourierDirection direction )
        {
            Debug.Assert( data != null );
            Debug.Assert( start >= 0 );
            Debug.Assert( inc >= 1 );
            Debug.Assert( length >= 1 );
            Debug.Assert( ( start + inc * ( length - 1 ) ) < data.Length );

            // copy to buffer
            ComplexF[]	buffer = null;
            LockBufferCF( length, ref buffer );
            int j = start;
            for( int i = 0; i < length; i ++ ) {
                buffer[ i ] = data[ j ];
                j += inc;
            }

            FFT(buffer, length, direction );

            // copy from buffer
            j = start;
            for( int i = 0; i < length; i ++ ) {
                data[ j ] = buffer[ i ];
                j += inc;
            }
            UnlockBufferCF( ref buffer );
        }
Example #22
0
        public float Mag()
        {
            ComplexF z = this;

            return((float)Math.Sqrt(z.Re * z.Re + z.Im * z.Im));
        }
Example #23
0
        ComplexF ccor(ComplexF x, ComplexF y)
        {
            ComplexF z;

            z.Re = x.Re * y.Re + x.Im * y.Im;
            z.Im = x.Re * y.Im - x.Im * y.Re;

            return z;
        }
Example #24
0
 /// <summary>
 /// Create a complex number based on an existing complex number
 /// </summary>
 /// <param name="c"></param>
 public ComplexF(ComplexF c)
 {
     this.Re = c.Re;
     this.Im = c.Im;
 }
Example #25
0
        private void correctIQ(int index, ref ComplexF[] buffer)
        {
            int i;

            for (i = 0; i < 2048; i++)
            {
                buffer[i].Im += trx.modem[index].tx_phase * buffer[i].Re;
                buffer[i].Re *= trx.modem[index].tx_gain;
            }
        }
Example #26
0
        private void LockBufferCF( int length, ref ComplexF[] buffer )
        {
            Debug.Assert( length >= 0 );
            Debug.Assert( _bufferCFLocked == false );

            _bufferCFLocked = true;
            if( length != _bufferCF.Length ) {
                _bufferCF	= new ComplexF[ length ];
            }
            buffer =	_bufferCF;
        }
Example #27
0
 /// <summary>
 /// Create a complex number based on an existing complex number
 /// </summary>
 /// <param name="c"></param>
 public ComplexF( ComplexF c )
 {
     this.Re		= c.Re;
     this.Im	= c.Im;
 }
Example #28
0
        private void ReorderArray( ComplexF[] data )
        {
            Debug.Assert( data != null );

            int length = data.Length;

            Debug.Assert( IsPowerOf2( length ) == true );
            Debug.Assert( length >= cMinLength );
            Debug.Assert( length <= cMaxLength );

            int[] reversedBits = GetReversedBits( Log2( length ) );
            for( int i = 0; i < length; i ++ ) {
                int swap = reversedBits[ i ];
                if( swap > i ) {
                    ComplexF temp = data[ i ];
                    data[ i ] = data[ swap ];
                    data[ swap ] = temp;
                }
            }
        }
Example #29
0
        private void correctIQ(ref ComplexF[] buffer)
        {
            int i;

            for (i = 0; i < 2048; i++)
            {
                buffer[i].Im += tx_phase * buffer[i].Re;
                buffer[i].Re *= tx_gain;
            }
        }
Example #30
0
 private void Swap( ref ComplexF a, ref ComplexF b )
 {
     ComplexF temp = a;
     a = b;
     b = temp;
 }
Example #31
0
        public int Write(ComplexF[] src, int cnt)
        {
            int free_cnt = WriteSpace();

            if (free_cnt == 0 || free_cnt < 0)
                return 0;
            else if (free_cnt < cnt)
                cnt = free_cnt;

            int to_write = cnt > free_cnt ? free_cnt : cnt;
            int cnt2 = wptr + to_write;
            int n1 = 0, n2 = 0;

            if (cnt2 > size)
            {
                n1 = size - wptr;
                n2 = cnt2 & mask;
            }
            else
            {
                n1 = to_write;
                n2 = 0;
            }

            Array.Copy(src, 0, buf, wptr, n1);
            wptr = (wptr + n1) & mask;

            if (n2 != 0)
            {
                Array.Copy(src, n1, buf, wptr, n2);
                wptr = (wptr + n2) & mask;
            }

            return to_write;
        }
Example #32
0
        private void UnlockBufferCF( ref ComplexF[] buffer )
        {
            Debug.Assert( _bufferCF == buffer );
            Debug.Assert( _bufferCFLocked == true );

            _bufferCFLocked = false;
            buffer = null;
        }
Example #33
0
        /// <summary>
        /// Compute a 1D fast Fourier transform of a dataset of complex numbers.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="length"></param>
        /// <param name="direction"></param>
        public void FFT(ComplexF[] data, int length, FourierDirection direction )
        {
            try
            {
                if (data == null)
                {
                    throw new ArgumentNullException("data");
                }
                if (data.Length < length)
                {
                    throw new ArgumentOutOfRangeException("length", length, "must be at least as large as 'data.Length' parameter");
                }
                if (IsPowerOf2(length) == false)
                {
                    throw new ArgumentOutOfRangeException("length", length, "must be a power of 2");
                }

                SyncLookupTableLength(length);

                int ln = Log2(length);

                // reorder array
                ReorderArray(data);

                // successive doubling
                N = 1;
                int signIndex = (direction == FourierDirection.Forward) ? 0 : 1;

                for (level = 1; level <= ln; level++)
                {
                    M = N;
                    N <<= 1;

                    uRLookup = _uRLookupF[level, signIndex];
                    uILookup = _uILookupF[level, signIndex];

                    for (int j = 0; j < M; j++)
                    {
                        uR = uRLookup[j];
                        uI = uILookup[j];

                        for (even = j; even < length; even += N)
                        {
                            odd = even + M;

                            r = data[odd].Re;
                            i = data[odd].Im;

                            odduR = r * uR - i * uI;
                            odduI = r * uI + i * uR;

                            r = data[even].Re;
                            i = data[even].Im;

                            data[even].Re = r + odduR;
                            data[even].Im = i + odduI;

                            data[odd].Re = r - odduR;
                            data[odd].Im = i - odduI;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.Write(ex.ToString());
            }
        }
Example #34
0
 public void Clear()
 {
     ComplexF[] zero = new ComplexF[size];
     Array.Clear(zero, 0, size);
     Array.Copy(zero, buf, size);
 }