Exemplo n.º 1
0
        private SignalGeneratorResult GenerateSineWave(PcmSamples1Channel ch, int sampleRate, double freq, int amplitude)
        {
            Console.WriteLine("CreateSineWave sampleRate={0} freq={1} amp={2}", sampleRate, freq, amplitude);

            SignalGeneratorResult result = SignalGeneratorResult.Success;

            double step = 2.0 * Math.PI * (freq / sampleRate);

            Parallel.For(0, ch.NumSamples, delegate(int i) {
                int v    = (int)(amplitude * Math.Sin(step * i));
                short sv = (short)v;
                if (v < -32768)
                {
                    result = SignalGeneratorResult.LevelOver;
                    sv     = -32768;
                }
                if (32767 < v)
                {
                    result = SignalGeneratorResult.LevelOver;
                    sv     = 32767;
                }
                ch.Set16(i, sv);
            });
            return(result);
        }
Exemplo n.º 2
0
        ////////////////////////////////////////////////////////

        public SignalGeneratorResult GenerateSignal(SignalGenerateParams s, out WavData wavData)
        {
            List <PcmSamples1Channel> samples = new List <PcmSamples1Channel>();

            int nSample           = s.seconds * s.sampleRate;
            PcmSamples1Channel ch = new PcmSamples1Channel(nSample, s.bitsPerSample);

            samples.Add(ch);

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            SignalGeneratorResult result = SignalGeneratorResult.Success;
            double truncFreq             = (s.sampleRate / 2) * s.truncationRatio;

            switch (s.ss)
            {
            case SignalShape.SineWave:
                result = GenerateSineWave(ch, s.sampleRate, s.freq, s.amplitude);
                break;

            case SignalShape.SquareWave:
                result = GenerateSquareWave(ch, s.sampleRate, s.freq, s.amplitude, truncFreq);
                break;

            case SignalShape.SawToothWaveDesc:
                result = GenerateSawToothWave(ch, s.sampleRate, s.freq, s.amplitude, truncFreq, false);
                break;

            case SignalShape.SawToothWaveAsc:
                result = GenerateSawToothWave(ch, s.sampleRate, s.freq, s.amplitude, truncFreq, true);
                break;

            case SignalShape.TriangleWave:
                result = GenerateTriangleWave(ch, s.sampleRate, s.freq, s.amplitude, truncFreq);
                break;

            default:
                System.Diagnostics.Debug.Assert(false);
                break;
            }

            sw.Stop();
            Console.WriteLine("{0} ms", sw.ElapsedMilliseconds);


            wavData = new WavData();
            wavData.Create(s.sampleRate, s.bitsPerSample, samples);
            return(result);
        }
Exemplo n.º 3
0
        private SignalGeneratorResult GenerateSawToothWave(PcmSamples1Channel ch, int sampleRate, double freq, int amplitude, double truncFreq, bool bInvert)
        {
            Console.WriteLine("CreateSawToothWave sampleRate={0} freq={1} amp={2} trunc={3} invert={4}", sampleRate, freq, amplitude, truncFreq, bInvert);

            double ampWithPhase = amplitude;

            if (bInvert)
            {
                ampWithPhase = -amplitude;
            }

            SignalGeneratorResult result = SignalGeneratorResult.Success;
            double step = 2.0 * Math.PI * (freq / sampleRate);

            Parallel.For(0, ch.NumSamples, delegate(int i) {
                double v = 0.0;
                for (int h = 1; ; ++h)
                {
                    double harmonics = h;
                    if (amplitude / harmonics < 1.0)
                    {
                        break;
                    }
                    if (truncFreq <= harmonics * freq)
                    {
                        break;
                    }
                    double x = ampWithPhase / harmonics * Math.Sin((step * i * harmonics) % (2.0 * Math.PI));
                    v       += x;
                }

                short sv = (short)v;
                if (v < -32768)
                {
                    result = SignalGeneratorResult.LevelOver;
                    sv     = -32768;
                }
                if (32767 < v)
                {
                    result = SignalGeneratorResult.LevelOver;
                    sv     = 32767;
                }
                ch.Set16(i, sv);
            });

            return(result);
        }
Exemplo n.º 4
0
        private SignalGeneratorResult GenerateTriangleWave(PcmSamples1Channel ch, int sampleRate, double freq, double amplitude, double truncFreq)
        {
            Console.WriteLine("CreateTriangleWave sampleRate={0} freq={1} amp={2} trunc={3}", sampleRate, freq, amplitude, truncFreq);

            SignalGeneratorResult result = SignalGeneratorResult.Success;
            double step = 2.0 * Math.PI * (freq / sampleRate);

            Parallel.For(0, ch.NumSamples, delegate(int i) {
                double v = 0.0;
                for (int h = 1; ; ++h)
                {
                    double harmonics = 2 * h - 1;
                    if (amplitude / harmonics / harmonics < 1.0)
                    {
                        break;
                    }
                    if (truncFreq <= harmonics * freq)
                    {
                        break;
                    }
                    double x = amplitude / harmonics / harmonics * Math.Sin((step * i * harmonics) % (2.0 * Math.PI));
                    if ((h & 1) == 0)
                    {
                        // hが偶数のときは-1倍する
                        x = -x;
                    }
                    v += x;
                }

                short sv = (short)v;
                if (v < -32768)
                {
                    result = SignalGeneratorResult.LevelOver;
                    sv     = -32768;
                }
                if (32767 < v)
                {
                    result = SignalGeneratorResult.LevelOver;
                    sv     = 32767;
                }
                ch.Set16(i, sv);
            });

            return(result);
        }
Exemplo n.º 5
0
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            SignalGeneraterWorkerArg sgwa = (SignalGeneraterWorkerArg)e.Argument;
            SignalGenerator          sg   = new SignalGenerator();

            backgroundWorker1.ReportProgress(1, "出力データの準備開始。\r\n");

            WavData wavData;
            SignalGeneratorResult cwdr
                = sg.GenerateSignal(sgwa.sgParams, out wavData);

            switch (cwdr)
            {
            case SignalGeneratorResult.Success:
                backgroundWorker1.ReportProgress(2, "出力データの準備完了。\r\n");
                break;

            case SignalGeneratorResult.LevelOver:
                backgroundWorker1.ReportProgress(2, "レベルオーバー。出力レベルを下げて下さい。\r\n");
                break;

            default:
                System.Diagnostics.Debug.Assert(false);
                break;
            }

            switch (sgwa.outputMode)
            {
            case OutputMode.WavFile:
                if (!WriteWavFile(wavData, sgwa.outputPath))
                {
                    backgroundWorker1.ReportProgress(3, string.Format("書き込み失敗: {0}\r\n", sgwa.outputPath));
                    return;
                }
                backgroundWorker1.ReportProgress(3, string.Format("書き込み成功: {0}\r\n", sgwa.outputPath));
                break;

            case OutputMode.Asio:
            {
                // short → int に拡張
                int[] asioData = new int[wavData.NumSamples];
                for (int i = 0; i < wavData.NumSamples; ++i)
                {
                    asioData[i] = wavData.Sample16Get(0, i) << 16;
                }
                // 出力デバイスに出力データをセット
                foreach (int ch in sgwa.outputChannels)
                {
                    asio.OutputSet(ch, asioData, true);
                }
                // 開始
                asio.Start();

                /* backgroundWorker1.ReportProgress(3,
                 *  string.Format("出力開始。{0}Hz {1} {2}dB\r\n", sgwa.sgParams.freq, sgwa.sgParams.ss, sgwa.sgParams.dB)); */
                while (!asio.Run())
                {
                }
                backgroundWorker1.ReportProgress(3, "出力終了。\r\n");
            }
            break;

            default:
                System.Diagnostics.Debug.Assert(false);
                break;
            }
        }