示例#1
0
        public virtual void generateTones(ChannelUnitContext ctx, int chNum, int sb, float[] @out, int outOffset)
        {
            float[]   wavreg1   = new float[128];
            float[]   wavreg2   = new float[128];
            WavesData tonesNow  = ctx.channels[chNum].tonesInfoPrev[sb];
            WavesData tonesNext = ctx.channels[chNum].tonesInfo[sb];

            // reconstruct full envelopes for both overlapping regions
            // from truncated bitstream data
            if (tonesNext.pendEnv.hasStartPoint && tonesNext.pendEnv.startPos < tonesNext.pendEnv.stopPos)
            {
                tonesNext.currEnv.hasStartPoint = true;
                tonesNext.currEnv.startPos      = tonesNext.pendEnv.startPos + 32;
            }
            else if (tonesNow.pendEnv.hasStartPoint)
            {
                tonesNext.currEnv.hasStartPoint = true;
                tonesNext.currEnv.startPos      = tonesNow.pendEnv.startPos;
            }
            else
            {
                tonesNext.currEnv.hasStartPoint = false;
                tonesNext.currEnv.startPos      = 0;
            }

            if (tonesNow.pendEnv.hasStopPoint && tonesNow.pendEnv.stopPos >= tonesNext.currEnv.startPos)
            {
                tonesNext.currEnv.hasStopPoint = true;
                tonesNext.currEnv.stopPos      = tonesNow.pendEnv.stopPos;
            }
            else if (tonesNext.pendEnv.hasStopPoint)
            {
                tonesNext.currEnv.hasStopPoint = true;
                tonesNext.currEnv.stopPos      = tonesNext.pendEnv.stopPos + 32;
            }
            else
            {
                tonesNext.currEnv.hasStopPoint = false;
                tonesNext.currEnv.stopPos      = 64;
            }

            // is the visible part of the envelope non-zero?
            bool reg1EnvNonzero = (tonesNow.currEnv.stopPos < 32 ? false : true);
            bool reg2EnvNonzero = (tonesNext.currEnv.startPos >= 32 ? false : true);

            // synthesize waves for both overlapping regions
            if (tonesNow.numWavs > 0 && reg1EnvNonzero)
            {
                wavesSynth(ctx.wavesInfoPrev, tonesNow, tonesNow.currEnv, ctx.wavesInfoPrev.phaseShift[sb] && (chNum > 0), 128, wavreg1);
            }

            if (tonesNext.numWavs > 0 && reg2EnvNonzero)
            {
                wavesSynth(ctx.wavesInfo, tonesNext, tonesNext.currEnv, ctx.wavesInfo.phaseShift[sb] && (chNum > 0), 0, wavreg2);
            }

            // Hann windowing for non-faded wave signals
            if (tonesNow.numWavs > 0 && tonesNext.numWavs > 0 && reg1EnvNonzero && reg2EnvNonzero)
            {
                vectorFmul(wavreg1, 0, wavreg1, 0, hann_window, 128, 128);
                vectorFmul(wavreg2, 0, wavreg2, 0, hann_window, 0, 128);
            }
            else
            {
                if (tonesNow.numWavs > 0 && !tonesNow.currEnv.hasStopPoint)
                {
                    vectorFmul(wavreg1, 0, wavreg1, 0, hann_window, 128, 128);
                }
                if (tonesNext.numWavs > 0 && !tonesNext.currEnv.hasStartPoint)
                {
                    vectorFmul(wavreg2, 0, wavreg2, 0, hann_window, 0, 128);
                }
            }

            // Overlap and add to residual
            for (int i = 0; i < 128; i++)
            {
                @out[outOffset + i] += wavreg1[i] + wavreg2[i];
            }
        }
示例#2
0
        /// <summary>
        ///  Synthesize sine waves according to given parameters.
        ///
        ///  @param[in]    synthParam   common synthesis parameters
        ///  @param[in]    wavesInfo    parameters for each sine wave
        ///  @param[in]    envelope     envelope data for all waves in a group
        ///  @param[in]    phaseShift   flag indicates 180 degrees phase shift
        ///  @param[in]    regOffset    region offset for trimming envelope data
        ///  @param[out]   out          receives synthesized data
        /// </summary>
        private void wavesSynth(WaveSynthParams synthParams, WavesData wavesInfo, WaveEnvelope envelope, bool phaseShift, int regOffset, float[] @out)
        {
            int waveParam = wavesInfo.startIndex;

            for (int wn = 0; wn < wavesInfo.numWavs; wn++, waveParam++)
            {
                // amplitude dequantization
                double amp = amp_sf_tab[synthParams.waves[waveParam].ampSf] * (synthParams.amplitudeMode == 0 ? (synthParams.waves[waveParam].ampIndex + 1) / 15.13f : 1.0f);

                int inc = synthParams.waves[waveParam].freqIndex;
                int pos = DEQUANT_PHASE(synthParams.waves[waveParam].phaseIndex) - (regOffset ^ 128) * inc & 2047;

                // waveform generation
                for (int i = 0; i < 128; i++)
                {
                    @out[i] += (float)(sine_table[pos] * amp);
                    pos      = (pos + inc) & 2047;
                }
            }

            if (phaseShift)
            {
                // 180 degrees phase shift
                for (int i = 0; i < 128; i++)
                {
//JAVA TO C# CONVERTER TODO TASK: The following line could not be converted:
                    @out[i] = -@out[i];
                }
            }

            // fade in with steep Hann window if requested
            if (envelope.hasStartPoint)
            {
                int pos = (envelope.startPos << 2) - regOffset;
                if (pos > 0 && pos <= 128)
                {
                    Arrays.Fill(@out, 0, pos, 0f);
                    if (!envelope.hasStopPoint || envelope.startPos != envelope.stopPos)
                    {
                        @out[pos + 0] *= hann_window[0];
                        @out[pos + 1] *= hann_window[32];
                        @out[pos + 2] *= hann_window[64];
                        @out[pos + 3] *= hann_window[96];
                    }
                }
            }

            // fade out with steep Hann window if requested
            if (envelope.hasStopPoint)
            {
                int pos = (envelope.stopPos + 1 << 2) - regOffset;
                if (pos > 0 && pos <= 128)
                {
                    @out[pos - 4] *= hann_window[96];
                    @out[pos - 3] *= hann_window[64];
                    @out[pos - 2] *= hann_window[32];
                    @out[pos - 1] *= hann_window[0];
                    Arrays.Fill(@out, pos, 128, 0f);
                }
            }
        }