Exemple #1
0
        static void ModulateQPSK()
        {
            // Manual adjust values
            int    sampleRate  = 8000;
            int    symbolCount = 1000;
            float  symbolRate  = 250; // Symbols per second
            int    carrierHz   = 1000;
            string outputPath  = Path.Combine(LocalPath, "qpsk_output.8k.3ch.pcm32f");

            // Fixed values
            float        symbolPeriod        = 1f / symbolRate;
            int          symbolLengthSamples = sampleRate / (int)symbolRate;
            Vco          vco    = new Vco(sampleRate, carrierHz);
            PseudoRandom random = new PseudoRandom(23);

            using (Stream output = File.Create(outputPath))
            {
                for (int i = 0; i < symbolCount; i++)
                {
                    // Generate 2 data bits
                    int bits = (int)random.Next(0, 4);

                    // Generate symbol samples
                    for (int p = 0; p < symbolLengthSamples; p++)
                    {
                        // Generate symbol sample
                        float sampleI = (float)vco.Cos() * ((bits >> 1) * 2 - 1);
                        float sampleQ = (float)vco.Sin() * ((bits & 1) * 2 - 1);

                        vco.Next();

                        // Reduce amplitude so the sum equals 1.0
                        sampleI *= 0.707f;
                        sampleQ *= 0.707f;

                        // Combine I and Q samples
                        float sampleOutput = sampleI + sampleQ;

                        // Output sample to file
                        output.Write(BitConverter.GetBytes(sampleOutput), 0, 4);
                        output.Write(BitConverter.GetBytes(((bits >> 1) * 2f - 1)), 0, 4);
                        output.Write(BitConverter.GetBytes(((bits & 1) * 2f - 1)), 0, 4);
                    }
                }
            }
        }
Exemple #2
0
        static void ModulateOffsetQPSK()
        {
            // Manual adjust values
            int    sampleRate  = 8000;
            int    symbolCount = 1000;
            float  symbolRate  = 250; // Symbols per second
            int    carrierHz   = 1000;
            string outputPath  = Path.Combine(LocalPath, "oqpsk_output.8k.3ch.pcm32f");

            // Fixed values
            float        symbolPeriod        = 1f / symbolRate;
            int          symbolLengthSamples = sampleRate / (int)symbolRate;
            Vco          vco    = new Vco(sampleRate, carrierHz);
            PseudoRandom random = new PseudoRandom(23);

            BiQuadraticFilter iFilter = new BiQuadraticFilter(BiQuadraticFilter.Type.LOWPASS, symbolRate, sampleRate, 0.707);
            BiQuadraticFilter qFilter = new BiQuadraticFilter(BiQuadraticFilter.Type.LOWPASS, symbolRate, sampleRate, 0.707);

            using (Stream output = File.Create(outputPath))
            {
                int bits     = 0;
                int nextBits = 0;
                for (int i = 0; i < symbolCount * 2; i++)
                {
                    bool even = i % 2 == 0;

                    // On each half-symbol period, shift in one data bit for transmission
                    //   while keeping the previous other arm's bit transmitting
                    if (even)
                    {
                        nextBits = (int)random.Next(0, 4);
                        bits     = (bits & 0x01) | (nextBits & 0x02);
                    }
                    else
                    {
                        bits = (bits & 0x02) | (nextBits & 0x01);
                    }

                    // Generate symbol samples
                    for (int p = 0; p < symbolLengthSamples / 2; p++)
                    {
                        // Generate symbol sample
                        // Also filter symbols with a low pass filter for basic pulse shaping
                        float sampleI = (float)vco.Cos() * (float)iFilter.filter((bits >> 1) * 2 - 1);
                        float sampleQ = (float)vco.Sin() * (float)qFilter.filter((bits & 1) * 2 - 1);

                        vco.Next();

                        // Reduce amplitude so the sum equals 1.0
                        sampleI *= 0.707f;
                        sampleQ *= 0.707f;

                        // Combine I and Q samples
                        float sampleOutput = sampleI + sampleQ;

                        // Output sample to file
                        output.Write(BitConverter.GetBytes(sampleOutput), 0, sizeof(float));
                        output.Write(BitConverter.GetBytes(((bits >> 1) * 2f - 1)), 0, sizeof(float));
                        output.Write(BitConverter.GetBytes(((bits & 1) * 2f - 1)), 0, sizeof(float));
                    }
                }
            }
        }