示例#1
0
        // If you want to see what WSJT-X is putting in its common block
        // for its jt9.exe, then this button is useful
        // Set a break down in the native code it calls and the
        // debugger will show you the FORTRAN common block.
        private void buttonSpy_Click(object sender, EventArgs e)
        {
            var sharedMem = new XDft.WsjtSharedMemory("WSJT-X", true);

            sharedMem.Spy();
            sharedMem.Dispose();
        }
示例#2
0
        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            /* Failure to call Dispose will keep certain Windows handles
             * on, for example, shared memory, active for an interminate amount
             * of time before garbage collection. Its OK to fail if this process
             * is exiting: the OS will clean up. But if your process instances
             * multiple forms, then you had better do the Dispose's
             */
            if (demodulator != null)
            {
                demodulator.Dispose();
            }
            demodulator = null;

            if (wsjtExe != null)
            {
                wsjtExe.Dispose();
            }
            wsjtExe = null;

            if (wsjtSharedMem != null)
            {
                wsjtSharedMem.Dispose();
            }
            wsjtSharedMem = null;

            if (waveDevicePlayer != null)
            {
                waveDevicePlayer.Dispose();
            }
            waveDevicePlayer = null;
        }
示例#3
0
        private XDft.RxSinkRepeater rxSinkRepeater; // need help repeating the RX audio to each decoder

        // have to know at construction time how many decoders
        public MultiDemodulatorWrapper(int instanceNumber, uint numDemodulators = 1)
        {
            if (numDemodulators > MAX_MULTIPROC)
            {
                numDemodulators = (uint)MAX_MULTIPROC;
            }
            if (numDemodulators == 0)
            {
                numDemodulators = 1;
            }

            demodulators     = new XDft.Demodulator[numDemodulators];
            wsjtSharedMems   = new XDft.WsjtSharedMemory[numDemodulators];
            wsjtExes         = new XDft.WsjtExe[numDemodulators];
            enabled          = new bool[numDemodulators];
            sharedMemoryKeys = new string[numDemodulators];

            for (uint i = 0; i < numDemodulators; i++)
            {
                demodulators[i] = new XDft.Demodulator();
                enabled[i]      = true;

                // The first decoder gets the same subdirectory name as a single decoder
                string sharedMemoryKey = "DigiRite-" + instanceNumber.ToString();
                if (i != 0) // subsequent ones get extra goop in their names
                {
                    sharedMemoryKey += "-" + i.ToString();
                }
                wsjtSharedMems[i] = new XDft.WsjtSharedMemory(sharedMemoryKey, false);
                if (!wsjtSharedMems[i].CreateWsjtSharedMem())
                {
                    throw new System.Exception("Failed to create Shared Memory from " + sharedMemoryKey);
                }

                // The subprocess itself is managed by the XDft
                wsjtExes[i]             = new XDft.WsjtExe();
                wsjtExes[i].AppDataName = sharedMemoryKey;
                sharedMemoryKeys[i]     = sharedMemoryKey;

                if (!wsjtExes[i].CreateWsjtProcess(wsjtSharedMems[i]))
                {
                    Dispose();
                    throw new System.Exception("Failed to launch wsjt exe");
                }
            }
            multibandManager = new MultibandManagerOneDemod(demodulators);
        }
示例#4
0
        /* Note to programmers reading this for the first time:
         * Please do NOT be intimidated by all the comments in InitDemodulator!
         * They describe everything in gory detail. All you MUST know is this:
         * Instance these three objects from the XDft8 namespace:
         *      Demodulator
         *      WsjtSharedMemory
         *      WsjtExe
         *
         *  For the last two, choose the names in their properties carefully IF you
         *  are going to  run multiple instances of the Demodulator on the same PC.
         *
         *  Set the Demodulator's callback delegate for decoded messages.
         *  ...and do nothing more at initialization time.
         *
         *  You also need a timer to call Demodulator.Clock(). See below.
         */
        private void InitDemodulator(SetupForm sf)
        {
            // The objects implement IDisposable. If you fail to
            // dispose of one you quit using, its Windows resources
            // remain allocated until garbage collection.
            if (null != demodulator)
            {
                demodulator.Dispose();
            }
            demodulator = null;
            if (null != wsjtSharedMem)
            {
                wsjtSharedMem.Dispose();
            }
            wsjtSharedMem = null;
            if (null != wsjtExe)
            {
                wsjtExe.Dispose();
            }
            wsjtExe = null;
            if (null != waveDevicePlayer)
            {
                waveDevicePlayer.Dispose();
            }
            waveDevicePlayer = null;

            // The demodulator invokes the wsjtx decoder
            demodulator = new XDft.Demodulator();
            // the names of its parameters are verbatim from the wsjt-x source code.
            // Don't ask this author what they mean.
            demodulator.nftx         = 1500;
            demodulator.nfqso        = 1500;
            demodulator.nQSOProgress = 5;
            demodulator.nzhsym       = digiMode == XDft.DigiMode.DIGI_FT8 ? 50 : 18;
            mycall             = sf.myCall.ToUpper();
            demodulator.mycall = mycall;
            if (xmitForm != null)
            {
                xmitForm.mycall = mycall;
            }

            demodulator.digiMode = digiMode;
            // When the decoder finds an FT8 message, it calls us back...
            // ...on a foreign thread. Call BeginInvoke to get back on this one. See below.
            demodulator.DemodulatorResultCallback = new XDft.DemodResult(Decoded);

            // The wsjt-x code is run in a subprocess and we communicate with it using
            // cross-process shared memory. Such a construct requires the parent/sub-process
            // to agree on a name. That name must be unique to all the parent/sub's running
            // concurrently. That means that whatever name you give here must NOT
            // also be given to a copy of this programming running concurrently on the
            // same PC. For the test program, we leave it up to the user in the setup form.
            // that is a VERY bad idea for production...you have been warned.
            wsjtSharedMem = new XDft.WsjtSharedMemory(sf.sharedMemoryKey, false);
            if (!wsjtSharedMem.CreateWsjtSharedMem())
            {
                MessageBox.Show("Failed to create Shared Memory from " + sf.sharedMemoryKey);
                return;
            }

            // The subprocess itself is managed by the XDft
            wsjtExe             = new XDft.WsjtExe();
            wsjtExe.AppDataName = sf.appDataName;

            if (!wsjtExe.CreateWsjtProcess(wsjtSharedMem))
            {
                MessageBox.Show("Failed to launch wsjt exe");
                demodulator.Dispose();
                wsjtExe.Dispose();
                wsjtExe = null;
                wsjtSharedMem.Dispose();
                wsjtSharedMem = null;
                demodulator   = null;
                return;
            }
            checkBoxEnableAP.Checked     = demodulator.lft8apon;
            comboBoxnDepth.SelectedIndex = demodulator.ndepth - 1;

#if DEBUG
            /* demonstrate how to use a native C++ dll to process
            ** incoming audio. Processing does not affect decoding. This is useful if you want to
            ** multi-instance XDft.Demodulator. Only one of XDft.Demodulator
            ** can call GetSignalSpectrum. The AudioProcessor interface can be instanced
            ** for multiple decodes concurrently and you can, for example, compute
            ** a spectrum in this processor .*/
            IntPtr ip = XDft8RxAudioProcess.RxAudio.GetAudioProcessor();
            demodulator.SetAudioSamplesCallback(new XDft.AudioCallback(SamplesCallback), 1000, 512, ip);
#endif
        }