Ejemplo n.º 1
0
        public static void MainLoop<U>(
            WaveTableTestGeneratorParams<T, W> generatorParams,
            Synthesizer.DataOutCallbackMethod<OutputGeneric<T, U, W>> dataCallback,
            OutputGeneric<T, U, W> dataCallbackState,
            Synthesizer.StopTask stopper)
        {
            try
            {
                // Unoptimized - since only one runs at a time this codepath is not perf critical (unlike the
                // resampler loops in the synth engine)

                int NumTables = generatorParams.data.NumTables;
                float[][] ReferenceArray = new float[NumTables][];
                for (int i = 0; i < NumTables; i++)
                {
                    ReferenceArray[i] = generatorParams.data.ListOfTables[i].frames;
                }

                int PlaybackSamplingRate = generatorParams.samplingRate;
                if (PlaybackSamplingRate < Constants.MINSAMPLINGRATE)
                {
                    PlaybackSamplingRate = Constants.MINSAMPLINGRATE;
                }
                if (PlaybackSamplingRate > Constants.MAXSAMPLINGRATE)
                {
                    PlaybackSamplingRate = Constants.MAXSAMPLINGRATE;
                }

                int FramesPerTable = generatorParams.data.NumFrames;

                /* this is the initial index into the wave table */
                Synthesizer.Fixed64 WaveformIndex = new Synthesizer.Fixed64();
                /* this is the 16.16 bit fixed point number used to increment the index */
                /* into the wave table */
                Synthesizer.Fixed64 WaveformIncrementor = new Synthesizer.Fixed64(
                    FramesPerTable * generatorParams.frequency / PlaybackSamplingRate);

                /* the number of times each wave slice has to be used */
                int NumberOfIterationsAttack = (int)(generatorParams.attack * PlaybackSamplingRate);
                int NumberOfIterationsDecay = (int)(generatorParams.decay * PlaybackSamplingRate);

                const int SOUNDBUFFERLENGTHFRAMES = 256;
                float[] OutputBuffer = new float[SOUNDBUFFERLENGTHFRAMES * 2];
                int OutputIndex = 0;

                for (int i = 0; i < NumberOfIterationsAttack + NumberOfIterationsDecay; i++)
                {
                    /* compute wave table index for attack/decay phase */
                    double TableIndex;
                    if (i < NumberOfIterationsAttack)
                    {
                        TableIndex = (double)i / NumberOfIterationsAttack;
                    }
                    else
                    {
                        TableIndex = (double)(NumberOfIterationsDecay + NumberOfIterationsAttack - i) / NumberOfIterationsDecay;
                    }

                    float Value = Synthesizer.WaveTableIndexer(
                        WaveformIndex.Double,
                        TableIndex * (NumTables - 1),
                        NumTables,
                        FramesPerTable,
                        ReferenceArray,
                        true/*EnableCrossWaveTableInterpolation*/);
                    WaveformIndex += WaveformIncrementor;

                    OutputBuffer[2 * OutputIndex + 0] = OutputBuffer[2 * OutputIndex + 1] = Value * .5f;
                    OutputIndex++;
                    if (OutputIndex == SOUNDBUFFERLENGTHFRAMES)
                    {
                        dataCallback(
                            dataCallbackState,
                            OutputBuffer,
                            0,
                            SOUNDBUFFERLENGTHFRAMES);
                        OutputIndex = 0;

                        if (stopper.Stopped)
                        {
                            return;
                        }
                    }
                }
                dataCallback(
                    dataCallbackState,
                    OutputBuffer,
                    0,
                    OutputIndex);
            }
            catch (Exception exception)
            {
                generatorParams.exception = exception;
                stopper.Stop();
            }
        }