private static void Slide8Render(bool drawOriginal = false, bool drawSamples = false, bool drawFiltered = false) { if (frequencyText == null) frequencyText = new Text(Text.FontSize._24pt, "0Hz @ 1000Hz", Slides.Common.TextColor); float f = t * 0.05f; if (f * 5000 > Math.PI * 1000) t = 0; frequencyText.String = string.Format("{0:0.0}Hz @ 1000Hz", f / Math.PI * 5000); float[] sine = new float[441]; for (int i = 0; i < sine.Length; i++) sine[i] = 0.5f * (float)Math.Sin((i - 441 / 2) * f); Slides.Common.DrawPlotter(Utilities.FastMatrix4(new Vector3(72, 720 - 227 - 410, 0), new Vector3(441, 410, 1))); if (drawOriginal) Slides.Common.DrawPlotLeft(sine, Slides.Common.TitleColor); float[] samples = new float[441]; for (int i = 0; i < sine.Length; i++) { samples[i] = sine[(int)(i / 10) * 10]; } FilterTools.BiQuad lpf = new FilterTools.BiQuad(2205, 0.707, 44100, 0, FilterTools.BiQuad.Type.LPF); lpf.Child = (FilterTools.BiQuad)lpf.Clone(); float[] filter = new float[441]; lpf.Load(samples[0]); for (int i = 0; i < filter.Length; i++) filter[i] = (float)lpf.GetOutput(samples[i]); if (drawSamples) Slides.Common.DrawPlotLeft(samples, new Vector3(1, 0, 0)); if (drawFiltered) Slides.Common.DrawPlotLeft(filter, new Vector3(0, 1, 0)); if (drawSamples || drawFiltered) { frequencyText.ModelMatrix = Matrix4.CreateTranslation(new Vector3(70, 500, 0)); frequencyText.Draw(); } }
private static void SampleRateConverter(bool oversamples = false, bool sampleAndHold = false, bool fftStairStep = false, bool filter = false) { // the previous slide uses the audio device, so lets disable it StopAudioDevice(); // build a sine wave to use for this example float[] sine = new float[882 * 4]; for (int i = 0; i < sine.Length; i++) sine[i] = (fftStairStep ? 0.1f : 0.5f) * (float)Math.Sin((i - 441 / 2) * 0.06); // build a low pass filter to use if we are filtering the samples sine wave FilterTools.BiQuad lpf = new FilterTools.BiQuad(18000, 0.707, 44100 * 4, 0, FilterTools.BiQuad.Type.LPF); lpf.Child = (FilterTools.BiQuad)lpf.Clone(); lpf.Load(sine[0]); // get the initial DC value from the filter // draw the plotter and the sine wave (if required) Slides.Common.DrawPlotter(Utilities.FastMatrix4(new Vector3(72, 720 - 227 - 410, 0), new Vector3(441, 410, 1))); if (!fftStairStep) Slides.Common.DrawPlotLeft(sine, Slides.Common.TitleColor); // build two sample buffers, one for 1x and one for 4x sampling float[] samples1 = new float[sine.Length]; float[] samples2 = new float[sine.Length]; for (int i = 0; i < sine.Length; i++) { if (sampleAndHold) { samples1[i] = (filter ? (i % 4 == 0 ? (float)lpf.GetOutput(sine[(i / 16) * 16]) : samples1[(i / 4) * 4]) : sine[(i / 16) * 16]); samples2[i] = sine[(i / 16) * 16]; } else { if ((i % 16) == 0) samples1[i] = sine[i]; if ((i % 4) == 0) samples2[i] = sine[i]; } } if (fftStairStep) { // FFT the samples1 data (which is either sample and hold or filtered data) float[] fft = new float[882]; for (int i = 0; i < fft.Length; i++) fft[i] = samples1[i * 4]; Slides.Common.DrawFFTLeft(fft); } else { // draw the two types of sampled or filtered data Slides.Common.DrawPlotLeft(samples1, new Vector3(1, 0, 0)); if (oversamples) Slides.Common.DrawPlotLeft(samples2, new Vector3(0, 1, 0)); } }