示例#1
0
        private void PlatformApply3D(AudioListener listener, AudioEmitter emitter)
        {
            // If we have no voice then nothing to do.
            if (_voice == null)
            {
                return;
            }

            // Convert from XNA Emitter to a SharpDX Emitter
            var e = ToDXEmitter(emitter);

            e.CurveDistanceScaler = SoundEffect.DistanceScale;
            e.DopplerScaler       = SoundEffect.DopplerScale;
            e.ChannelCount        = _effect._format.Channels;

            // Convert from XNA Listener to a SharpDX Listener
            var l = ToDXListener(listener);

            // Number of channels in the sound being played.
            // Not actually sure if XNA supported 3D attenuation of sterio sounds, but X3DAudio does.
            var srcChannelCount = _effect._format.Channels;

            // Number of output channels.
            var dstChannelCount = SoundEffect.MasterVoice.VoiceDetails.InputChannelCount;

            // XNA supports distance attenuation and doppler.
            var dpsSettings = SoundEffect.Device3D.Calculate(l, e, CalculateFlags.Matrix | CalculateFlags.Doppler, srcChannelCount, dstChannelCount);

            // Apply Volume settings (from distance attenuation) ...
            _voice.SetOutputMatrix(SoundEffect.MasterVoice, srcChannelCount, dstChannelCount, dpsSettings.MatrixCoefficients, 0);

            // Apply Pitch settings (from doppler) ...
            _voice.SetFrequencyRatio(dpsSettings.DopplerFactor);
        }
示例#2
0
        public void Start(bool skipIntro, bool skipToEnd = false)
        {
            if (!skipIntro)
            {
                SubmitSourceBuffer(m_loopBuffers[(int)MyCueBank.CuePart.Start]);
            }
            else
            {
                Debug.Assert(m_isLoopable, "Only loops should skip intro");
            }

            if (m_isLoopable)
            {
                if (!skipToEnd)
                {
                    SubmitSourceBuffer(m_loopBuffers[(int)MyCueBank.CuePart.Loop]);
                }
                SubmitSourceBuffer(m_loopBuffers[(int)MyCueBank.CuePart.End]);
            }
            if (m_voice.State.BuffersQueued > 0)
            {
                m_voice.SetFrequencyRatio(FrequencyRatio);
                m_voice.Start();
                m_isPlaying = true;
            }
            else
            {
                OnStopPlaying(m_voice.NativePointer);
            }
        }
示例#3
0
 /// <summary>
 /// Applies 3-D settings represented by the supplied settings object to the sound.
 /// </summary>
 /// <param name="settings">The DspSettings object that represents changes that should be made to this sound.</param>
 /// <param name="sourceChannels">The source channel count.</param>
 /// <param name="destinationChannels">The destination channel count.</param>
 /// <param name="flags">The 3D flags to calculate. The default will calculate volume and doppler shift. This parameter is useful if it is not desirable for XAudio2 to calculate doppler on sounds that modify their own frequencies as an example; in this case, the flags should omit doppler.</param>
 public void apply3D(DspSettings settings, int sourceChannels, int destinationChannels, CalculateFlags flags)
 {
     voice.SetOutputMatrix(sourceChannels, destinationChannels, settings.MatrixCoefficients);
     if ((flags & CalculateFlags.Doppler) == CalculateFlags.Doppler)
     {
         voice.GetFrequencyRatio(out float freq);
         voice.SetFrequencyRatio(settings.DopplerFactor * freq);
     }
 }
示例#4
0
        public void Apply3D(SourceVoice voice, Listener listener, Emitter emitter, int srcChannels, int dstChannels, CalculateFlags flags, float maxDistance, float frequencyRatio)
        {
            unsafe
            {
                DspSettings settings;

                int matrixCoefficientCount = srcChannels * dstChannels;

                float *matrixCoefficients = stackalloc float[matrixCoefficientCount];
                float *delay = stackalloc float[dstChannels];

                settings.SrcChannelCount           = srcChannels;
                settings.DstChannelCount           = dstChannels;
                settings.MatrixCoefficientsPointer = new IntPtr(matrixCoefficients);
                settings.DelayTimesPointer         = new IntPtr(delay);

                Calculate(listener, emitter, flags, &settings);

                if (emitter.InnerRadius == 0f)
                {
                    // approximated decay by distance
                    float decay = MathHelper.Clamp(1f - settings.EmitterToListenerDistance / maxDistance, 0f, 1f);
                    for (int i = 0; i < matrixCoefficientCount; i++)
                    {
                        matrixCoefficients[i] *= decay;
                    }
                }

                voice.SetOutputMatrix(null, settings.SrcChannelCount, settings.DstChannelCount, matrixCoefficients);
                voice.SetFrequencyRatio(frequencyRatio * settings.DopplerFactor);
            }
        }
示例#5
0
        private void UpdateSourcePosition()
        {
            Listener listener = PositionKind == AudioPositionKind.ListenerRelative ? s_centeredListener : _engine.Listener;

            _engine.X3DAudio.Calculate(
                listener,
                _emitter,
                CalculateFlags.Matrix | CalculateFlags.Doppler,
                _dspSettings);
            _sourceVoice.SetOutputMatrix(_channelCount, 2, _dspSettings.MatrixCoefficients);
            _sourceVoice.SetFrequencyRatio(_pitch * _dspSettings.DopplerFactor);
        }
示例#6
0
        public float Apply3D(SourceVoice voice, Listener listener, Emitter emitter, int srcChannels, int dstChannels, CalculateFlags flags, float maxDistance, float frequencyRatio, bool silent, bool use3DCalculation = true)
        {
            unsafe
            {
                DspSettings settings;

                int matrixCoefficientCount = srcChannels * dstChannels;

                float *matrixCoefficients = stackalloc float[matrixCoefficientCount];
                float *delay = stackalloc float[dstChannels];

                settings.SrcChannelCount           = srcChannels;
                settings.DstChannelCount           = dstChannels;
                settings.MatrixCoefficientsPointer = new IntPtr(matrixCoefficients);
                settings.DelayTimesPointer         = new IntPtr(delay);

                if (use3DCalculation)
                {
                    Calculate(listener, emitter, flags, &settings);

                    voice.SetFrequencyRatio(frequencyRatio * settings.DopplerFactor);
                }
                else
                { //realistic sounds
                    settings.EmitterToListenerDistance = Vector3.Distance(new Vector3(listener.Position.X, listener.Position.Y, listener.Position.Z), new Vector3(emitter.Position.X, emitter.Position.Y, emitter.Position.Z));
                    for (int i = 0; i < matrixCoefficientCount; i++)
                    {
                        matrixCoefficients[i] = 1f;
                    }
                }

                if (emitter.InnerRadius == 0f)
                {
                    // approximated decay by distance
                    float decay;
                    if (silent)
                    {
                        decay = 0f;
                    }
                    else
                    {
                        decay = MathHelper.Clamp(1f - settings.EmitterToListenerDistance / maxDistance, 0f, 1f);
                    }
                    for (int i = 0; i < matrixCoefficientCount; i++)
                    {
                        matrixCoefficients[i] *= decay;
                    }
                }
                voice.SetOutputMatrix(null, settings.SrcChannelCount, settings.DstChannelCount, matrixCoefficients);
                return(settings.EmitterToListenerDistance);
            }
        }
示例#7
0
        public int Play(PlayOptions options)
        {
            if (!isLoaded)
            {
                Load();
            }

            if (options.Repeats != defaultRepeat)
            {
                int loopCount;
                if (options.Repeats == -1)
                {
                    loopCount = AudioBuffer.LoopInfinite;
                }
                else
                {
                    loopCount = options.Repeats;
                }

                LoadNextVoice(loopCount);
            }

            if (options.Pan != 0)
            {
                float   panLeft    = (float)0.5 - (options.Pan / 2);
                float   panRight   = (float)0.5 + (options.Pan / 2);
                int     matrixSize = masteringVoice.VoiceDetails.InputChannelCount * nextVoice.VoiceDetails.InputChannelCount;
                float[] matrix     = new float[matrixSize];

                for (int i = 0; i < matrixSize; i++)
                {
                    if (i % 2 == 0)
                    {
                        matrix[i] = panLeft;
                    }
                    else
                    {
                        matrix[i] = panRight;
                    }
                }

                nextVoice.SetOutputMatrix(nextVoice.VoiceDetails.InputChannelCount, masteringVoice.VoiceDetails.InputChannelCount, matrix);
            }

            nextVoice.SetFrequencyRatio(options.Pitch);
            nextVoice.SetVolume(options.Volume);

            Play();

            return(voiceListKey);
        }
示例#8
0
文件: Playback.cs 项目: XAYRGA/JPlay
 public void NoteOn(byte num, byte key, byte velocity)
 {
     try
     {
         Instrument  instrument  = instrumentTable[new Tuple <byte, byte>(Bank, Instrument)];
         int         value       = instrument.GetSampleEntry(key).Value;
         Sample      sample      = soundData.SampleBanks[soundData.InstrumentBanks[Bank].Wsys][(short)instrument.Samples[value].Id];
         AudioBuffer audioBuffer = new AudioBuffer();
         audioBuffer.AudioBytes = sample.Data.Length;
         audioBuffer.Stream     = new DataStream(sample.Data.Length, canRead: true, canWrite: true);
         audioBuffer.Stream.Write(sample.Data, 0, sample.Data.Length);
         audioBuffer.PlayBegin  = 0;
         audioBuffer.PlayLength = 0;
         audioBuffer.LoopCount  = (sample.IsLooping ? 255 : 0);
         audioBuffer.LoopBegin  = sample.LoopStart;
         audioBuffer.LoopLength = 0;
         WaveFormat  sourceFormat = new WaveFormat(sample.SamplesPerSecond, sample.BitsPerSample, sample.Channels);
         SourceVoice sourceVoice  = new SourceVoice(engine, sourceFormat, VoiceFlags.None, 1024f);
         sourceVoice.SetOutputVoices(new VoiceSendDescriptor(submix));
         sourceVoice.SubmitSourceBuffer(audioBuffer, null);
         float num2 = XAudio2.SemitonesToFrequencyRatio((!instrument.IsPercussion) ? (key - sample.RootKey) : 0) * instrument.Samples[value].FrequenyMultiplier * instrument.FrequencyMultiplier;
         sourceVoice.SetFrequencyRatio(num2);
         sourceVoice.SetVolume(ValueToAmplitude(velocity));
         NoteData noteData = new NoteData(sourceVoice, num2, velocity, instrument.IsPercussion);
         if (instrument.IsPercussion)
         {
             noteData.PercussionPan = instrument.Samples[value].Pan.Value;
             sbyte b = (sbyte)(noteData.PercussionPan - 63);
             sourceVoice.SetOutputMatrix(1, 2, new float[2]
             {
                 0.5f - (float)b / 127f,
                 0.5f + (float)b / 127f
             });
         }
         else
         {
             sourceVoice.SetOutputMatrix(1, 2, outputMatrix);
         }
         noteData.BufferStream = audioBuffer.Stream;
         noteData.Voice.Start();
         voiceTable.Add(num, noteData);
         sourceFormat = null;
         GC.Collect();
     }
     catch
     {
     }
 }
示例#9
0
        public void Apply3D(SourceVoice voice, Listener listener, Emitter emitter, float maxDistance, float frequencyRatio)
        {
            m_x3dAudio.Calculate(listener, emitter, CalculateFlags.Matrix | CalculateFlags.Doppler, m_dsp);

            if (emitter.InnerRadius == 0f)
            {
                // approximated decay by distance
                float decay = MathHelper.Clamp(1f - m_dsp.EmitterToListenerDistance / maxDistance, 0f, 1f);
                for (int i = 0; i < m_dsp.MatrixCoefficients.Length; ++i)
                {
                    m_dsp.MatrixCoefficients[i] *= decay;
                }
            }

            voice.SetOutputMatrix(m_dsp.SourceChannelCount, m_dsp.DestinationChannelCount, m_dsp.MatrixCoefficients);
            voice.SetFrequencyRatio(frequencyRatio * m_dsp.DopplerFactor);
        }
示例#10
0
        private void PlayNextBuffer()
        {
            if (_currentBuffer == _maxBuffers)
            {
                return;
            }

            var newCurrentBuffer = Interlocked.Increment(ref _currentBuffer);

            AudioBuffer buffer;

            if (!_audioBuffers.TryGetValue(newCurrentBuffer, out buffer) || buffer == null)
            {
                return;
            }

            if (PreviousWorkItem.Volume != CurrentPlayWorkItem.Volume)
            {
                SourceVoice.SetVolume((float)CurrentPlayWorkItem.Volume, OperationId);
                PreviousWorkItem.Volume = CurrentPlayWorkItem.Volume;
            }

            if (PreviousWorkItem.Pan != CurrentPlayWorkItem.Pan)
            {
                SourceVoice.SetPan(CurrentPlayWorkItem.Pan, OperationId);
                PreviousWorkItem.Pan = CurrentPlayWorkItem.Pan;
            }

            if (PreviousWorkItem.Pitch != CurrentPlayWorkItem.Pitch)
            {
                SourceVoice.SetFrequencyRatio((float)CurrentPlayWorkItem.Pitch, OperationId);
                PreviousWorkItem.Pitch = CurrentPlayWorkItem.Pitch;
            }

            SourceVoice.SubmitSourceBuffer(buffer, null);

            AudioDefines.XAudio.CommitChanges(OperationId);
        }
示例#11
0
        private void Apply3D(Vector3 listenerForward, Vector3 listenerUp, Vector3 listenerPosition, Vector3 listenerVelocity, Vector3 emitterForward, Vector3 emitterUp, Vector3 emitterPosition, Vector3 emitterVelocity)
        {
            if (!Effect.AudioManager.IsSpatialAudioEnabled)
            {
                throw new InvalidOperationException("Spatial audio must be enabled first.");
            }

            if (emitter == null)
            {
                emitter = new Emitter();
            }

            emitter.OrientFront         = emitterForward;
            emitter.OrientTop           = emitterUp;
            emitter.Position            = emitterPosition;
            emitter.Velocity            = emitterVelocity;
            emitter.DopplerScaler       = SoundEffect.DopplerScale;
            emitter.CurveDistanceScaler = SoundEffect.DistanceScale;
            emitter.ChannelCount        = Effect.Format.Channels;

            //TODO: work out what ChannelAzimuths is supposed to be.
            if (emitter.ChannelCount > 1)
            {
                emitter.ChannelAzimuths = new float[emitter.ChannelCount];
            }

            if (listener == null)
            {
                listener = new Listener();
            }

            listener.OrientFront = listenerForward;
            listener.OrientTop   = listenerUp;
            listener.Position    = listenerPosition;
            listener.Velocity    = listenerVelocity;

            if (dspSettings == null)
            {
                dspSettings = new DspSettings(Effect.Format.Channels, Effect.AudioManager.MasteringVoice.VoiceDetails.InputChannelCount);
            }

            CalculateFlags flags = CalculateFlags.Matrix | CalculateFlags.Doppler | CalculateFlags.LpfDirect;

            if ((Effect.AudioManager.Speakers & Speakers.LowFrequency) > 0)
            {
                // On devices with an LFE channel, allow the mono source data to be routed to the LFE destination channel.
                flags |= CalculateFlags.RedirectToLfe;
            }

            if (Effect.AudioManager.IsReverbEffectEnabled)
            {
                flags |= CalculateFlags.Reverb | CalculateFlags.LpfReverb;

                if (!isReverbSubmixEnabled)
                {
                    VoiceSendFlags        sendFlags    = Effect.AudioManager.IsReverbFilterEnabled ? VoiceSendFlags.UseFilter : VoiceSendFlags.None;
                    VoiceSendDescriptor[] outputVoices = new VoiceSendDescriptor[]
                    {
                        new VoiceSendDescriptor {
                            OutputVoice = Effect.AudioManager.MasteringVoice, Flags = sendFlags
                        },
                        new VoiceSendDescriptor {
                            OutputVoice = Effect.AudioManager.ReverbVoice, Flags = sendFlags
                        }
                    };

                    voice.SetOutputVoices(outputVoices);
                    isReverbSubmixEnabled = true;
                }
            }

            Effect.AudioManager.Calculate3D(listener, emitter, flags, dspSettings);

            voice.SetFrequencyRatio(dspSettings.DopplerFactor);
            voice.SetOutputMatrix(Effect.AudioManager.MasteringVoice, dspSettings.SourceChannelCount, dspSettings.DestinationChannelCount, dspSettings.MatrixCoefficients);

            if (Effect.AudioManager.IsReverbEffectEnabled)
            {
                if (reverbLevels == null || reverbLevels.Length != Effect.Format.Channels)
                {
                    reverbLevels = new float[Effect.Format.Channels];
                }

                for (int i = 0; i < reverbLevels.Length; i++)
                {
                    reverbLevels[i] = dspSettings.ReverbLevel;
                }

                voice.SetOutputMatrix(Effect.AudioManager.ReverbVoice, Effect.Format.Channels, 1, reverbLevels);
            }

            if (Effect.AudioManager.IsReverbFilterEnabled)
            {
                FilterParameters filterDirect = new FilterParameters
                {
                    Type = FilterType.LowPassFilter,
                    // see XAudio2CutoffFrequencyToRadians() in XAudio2.h for more information on the formula used here
                    Frequency = 2.0f * (float)Math.Sin(X3DAudio.PI / 6.0f * dspSettings.LpfDirectCoefficient),
                    OneOverQ  = 1.0f
                };

                voice.SetOutputFilterParameters(Effect.AudioManager.MasteringVoice, filterDirect);

                if (Effect.AudioManager.IsReverbEffectEnabled)
                {
                    FilterParameters filterReverb = new FilterParameters
                    {
                        Type = FilterType.LowPassFilter,
                        // see XAudio2CutoffFrequencyToRadians() in XAudio2.h for more information on the formula used here
                        Frequency = 2.0f * (float)Math.Sin(X3DAudio.PI / 6.0f * dspSettings.LpfReverbCoefficient),
                        OneOverQ  = 1.0f
                    };

                    voice.SetOutputFilterParameters(Effect.AudioManager.ReverbVoice, filterReverb);
                }
            }
        }
示例#12
0
        /// <summary>
        /// SharpDX X3DAudio sample. Plays a generated sound rotating around the listener.
        /// </summary>
        static void Main(string[] args)
        {
            var xaudio2 = new XAudio2();

            using (var masteringVoice = new MasteringVoice(xaudio2))
            {
                // Instantiate X3DAudio
                var x3dAudio = new X3DAudio(Speakers.Stereo);

                var emitter = new Emitter
                {
                    ChannelCount        = 1,
                    CurveDistanceScaler = float.MinValue,
                    OrientFront         = new Vector3(0, 0, 1),
                    OrientTop           = new Vector3(0, 1, 0),
                    Position            = new Vector3(0, 0, 0),
                    Velocity            = new Vector3(0, 0, 0)
                };

                var listener = new Listener
                {
                    OrientFront = new Vector3(0, 0, 1),
                    OrientTop   = new Vector3(0, 1, 0),
                    Position    = new Vector3(0, 0, 0),
                    Velocity    = new Vector3(0, 0, 0)
                };

                var waveFormat  = new WaveFormat(44100, 32, 1);
                var sourceVoice = new SourceVoice(xaudio2, waveFormat);

                int bufferSize = waveFormat.ConvertLatencyToByteSize(60000);
                var dataStream = new DataStream(bufferSize, true, true);

                int numberOfSamples = bufferSize / waveFormat.BlockAlign;
                for (int i = 0; i < numberOfSamples; i++)
                {
                    float value = (float)(Math.Cos(2 * Math.PI * 220.0 * i / waveFormat.SampleRate) * 0.5);
                    dataStream.Write(value);
                }
                dataStream.Position = 0;

                var audioBuffer = new AudioBuffer
                {
                    Stream = dataStream, Flags = BufferFlags.EndOfStream, AudioBytes = bufferSize
                };

                //var reverb = new Reverb();
                //var effectDescriptor = new EffectDescriptor(reverb);
                //sourceVoice.SetEffectChain(effectDescriptor);
                //sourceVoice.EnableEffect(0);

                sourceVoice.SubmitSourceBuffer(audioBuffer, null);

                sourceVoice.Start();

                Console.WriteLine("Play a sound rotating around the listener");
                for (int i = 0; i < 1200; i++)
                {
                    // Rotates the emitter
                    var rotateEmitter      = Matrix.RotationY(i / 5.0f);
                    var newPosition        = Vector3.Transform(new Vector3(0, 0, 1000), rotateEmitter);
                    var newPositionVector3 = new Vector3(newPosition.X, newPosition.Y, newPosition.Z);
                    emitter.Velocity = (newPositionVector3 - emitter.Position) / 0.05f;
                    emitter.Position = newPositionVector3;

                    // Calculate X3DAudio settings
                    var dspSettings = x3dAudio.Calculate(listener, emitter, CalculateFlags.Matrix | CalculateFlags.Doppler, 1, 2);

                    // Modify XAudio2 source voice settings
                    sourceVoice.SetOutputMatrix(1, 2, dspSettings.MatrixCoefficients);
                    sourceVoice.SetFrequencyRatio(dspSettings.DopplerFactor);

                    // Wait for 50ms
                    Thread.Sleep(50);
                }
            }
        }
        /// <summary>
        /// Applies the 3D effect to the current sound effect instance.
        /// </summary>
        /// <param name="listenerAgent">Listener</param>
        /// <param name="emitterAgent">Emitter</param>
        private void Apply3D()
        {
            UpdateListener(Listener);
            UpdateEmitter(Emitter);

            var flags = Calculate3DFlags();

            if (dspSettings == null)
            {
                dspSettings = new DspSettings(
                    this.Effect.WaveFormat.Channels,
                    this.Effect.GameAudio.MasteringVoice.VoiceDetails.InputChannelCount);
            }

            this.Effect.GameAudio.Calculate3D(listener, emitter, flags, dspSettings);

            voice.SetFrequencyRatio(dspSettings.DopplerFactor);

            voice.SetOutputMatrix(
                this.Effect.GameAudio.MasteringVoice,
                dspSettings.SourceChannelCount,
                dspSettings.DestinationChannelCount,
                dspSettings.MatrixCoefficients);

            if (!this.Effect.GameAudio.UseReverb)
            {
                return;
            }

            if (reverbLevels?.Length != this.Effect.WaveFormat.Channels)
            {
                reverbLevels = new float[this.Effect.WaveFormat.Channels];
            }

            for (int i = 0; i < reverbLevels.Length; i++)
            {
                reverbLevels[i] = dspSettings.ReverbLevel;
            }

            voice.SetOutputMatrix(this.Effect.GameAudio.ReverbVoice, this.Effect.WaveFormat.Channels, 1, reverbLevels);

            if (!this.Effect.GameAudio.UseReverbFilter)
            {
                return;
            }

            var filterDirect = new FilterParameters
            {
                Type      = FilterType.LowPassFilter,
                Frequency = 2.0f * (float)Math.Sin(MathUtil.Pi / 6.0f * dspSettings.LpfDirectCoefficient),
                OneOverQ  = 1.0f
            };

            voice.SetOutputFilterParameters(this.Effect.GameAudio.MasteringVoice, filterDirect);

            var filterReverb = new FilterParameters
            {
                Type      = FilterType.LowPassFilter,
                Frequency = 2.0f * (float)Math.Sin(MathUtil.Pi / 6.0f * dspSettings.LpfReverbCoefficient),
                OneOverQ  = 1.0f
            };

            voice.SetOutputFilterParameters(this.Effect.GameAudio.ReverbVoice, filterReverb);
        }
示例#14
0
 private void UpdatePitch()
 {
     SourceVoice.SetFrequencyRatio(MathUtil.Clamp((float)Math.Pow(2, Pitch) * dopplerPitchFactor, 0.5f, 2f)); // conversion octave to frequencyRatio
 }
示例#15
0
        private void Play()
        {
            if (!(treeView.SelectedNode is SpcDirectoryEntry entry))
            {
                return;
            }

            if (entry.Start > entry.Loop ||
                entry.Start == 0 ||
                entry.Loop == 0)
            {
                return;
            }

            Voice.SetFrequencyRatio(float.Parse(speedTextBox.Text));

            var stream = entry.Source.GetStream();
            var reader = new BinaryReader(stream);

            stream.Position = 0x100 + entry.Start;

            //var blocks = (entry.Loop - entry.Start) / 9;

            //var data2 = new short[blocks * 16];
            var data2 = new List <short>();

            //var index = 0;

            while (true)
            {
                var header = reader.ReadByte();

                var range  = header >> 4;
                var filter = (header >> 2) & 0x3;
                var loop   = (header & 0x2) != 0;
                var end    = (header & 0x1) != 0;

                var data    = reader.ReadBytes(8);
                var samples = data.SelectMany(x => new int[] { SignedNibbleToInt(x >> 4), SignedNibbleToInt(x & 0xf) }).ToArray();
                //var samples = data.SelectMany(x => new int[] { SignedNibbleToInt(x & 0xf), SignedNibbleToInt(x >> 4) }).ToArray();

                foreach (var sample in samples)
                {
                    var value = sample << range;

                    switch (filter)
                    {
                    case 1:
                        if (data2.Count > 0)
                        {
                            value += (int)(data2[data2.Count - 1] * (15.0f / 16.0f));
                        }
                        break;

                    case 2:
                        if (data2.Count > 1)
                        {
                            value += (int)((data2[data2.Count - 1] * (61.0f / 32.0f)) - (data2[data2.Count - 2] * (15.0f / 16.0f)));
                        }
                        break;

                    case 3:
                        if (data2.Count > 1)
                        {
                            value += (int)((data2[data2.Count - 1] * (115.0f / 64.0f)) - (data2[data2.Count - 2] * (13.0f / 16.0f)));
                        }
                        break;
                    }

                    data2.Add((short)value);
                }

                if (end)
                {
                    break;
                }
            }

            var data3 = data2.ToArray();

            Buffers  = new AudioBuffer[2];
            Pointers = new DataPointer[Buffers.Length];
            //Data = new byte[1024];
            //Random = new Random();

            for (int buffer = 0; buffer < Buffers.Length; buffer++)
            {
                Pointers[buffer] = new DataPointer(Utilities.AllocateClearedMemory(data3.Length * 2), data3.Length * 2);
                Buffers[buffer]  = new AudioBuffer(Pointers[buffer]);

                Pointers[buffer].CopyFrom(data3);

                if (Loop || buffer == 0)
                {
                    Voice.SubmitSourceBuffer(Buffers[buffer], null);
                }
            }

            Index = 0;

            //Pointers[0] = new DataPointer(Utilities.AllocateClearedMemory(data2.Length * 2), data2.Length * 2);
            //Buffers[0] = new AudioBuffer(Pointers[0]);

            //Pointers[0].CopyFrom(data2);

            //Voice.SubmitSourceBuffer(Buffers[0], null);
        }