Quantcast
Channel: GameDev.net
Viewing all articles
Browse latest Browse all 17825

FM Synth and Plotting with PowerShell

$
0
0
Beep boop, making progress on my FM synthesizer. Had a nasty popping sound with my phase-feedback logic and needed some way to rapidly graph out the logic. Powershell to the rescue: # plot-sample.ps1 $samples = 1024; $width = 2048; $height = 512; [Reflection.Assembly]::LoadWithPartialName("System.Drawing"); $bmp = new-object Drawing.Bitmap $width, $height; $g = [Drawing.Graphics]::FromImage($bmp); $g.SmoothingMode = "AntiAlias"; $penAxis = new-object Drawing.Pen 0xFF808080, 2; $penLineA = new-object Drawing.Pen 0xFF0000F0, 2; $penLineB = new-object Drawing.Pen 0xFFF00000, 2; $ptsA = new-object Drawing.PointF[] $samples; $ptsB = new-object Drawing.PointF[] $samples; 0..($samples-1) |% { $Q = 4*[Math]::pi/$samples; $feedback = 0; } { $ampA = [Math]::sin($_*$Q + $feedback); # A[t] = sin(t + 1.05*A[t-1]) $ampB = [Math]::sin($_*$Q); # B[t] = sin(t) $feedback = $ampA * 1.05; $x = $bmp.Width * $_/$samples; $yA = $bmp.Height * (-$ampA/2.1 + .5); $yB = $bmp.Height * (-$ampB/2.1 + .5); $ptsA[$_] = new-object Drawing.PointF $x, $yA; $ptsB[$_] = new-object Drawing.PointF $x, $yB; } { $g.Clear([Drawing.Color]::White); $g.DrawLine($penAxis,0,$bmp.Height/2,$bmp.Width,$bmp.Height/2); $g.DrawLines($penLineB,$ptsB); $g.DrawLines($penLineA,$ptsA); $bmp.Save("$pwd\plot.png"); } Looks like the logic should be sound. I did find that the phase-feedback wasn't being sin'd in the synthesizer, and that was causing the popping noise. And here's a sample of what it sounds like right now: fm-sample.ogg (36.4KB) And here's the instrument used to generate that sound: /* unit: mul frequency multiplier ofs additive frequency amp volume feed phase feedback envelope: A attack rate, in degrees D1 decay rate to sustain level, in degrees D2 decay rate to silence, in degrees R release rate, in degrees S sustain level program: u unit to render in phase buffer input slot, 0 for null input out phase buffer output slot, 0 for audio data */ instrument i; int idx = 0; // mul ofs amp feed A D1 D2 R S i.units[idx++] = { 2.00f, 0.00f, 0.50f, 1.00f, {80.0, 20.0, 10.0, 45.0, 0.75 }}; i.units[idx++] = { 1.00f, 0.00f, 0.25f, 0.00f, {85.0, 45.0, 5.0, 60.0, 0.50 }}; i.units[idx++] = { 7.00f, 0.33f, 0.12f, 0.00f, {88.5, 60.0, 5.0, 60.0, 0.25 }}; i.units[idx++] = { 1.00f, 0.33f, 0.50f, 0.00f, {87.0, 30.0, 5.0, 60.0, 0.67 }}; i.ct_units = idx; // program: // ┌─┐┌─┐ // │0├──►│1├──┐ // └─┘└─┘│┌─┐ // ├──►│3├──►out // ┌─┐│└─┘ // │2├──┘ // └─┘ idx = 0; // u in out i.program[idx++] = { 0, 0, 2 }; i.program[idx++] = { 1, 2, 1 }; i.program[idx++] = { 2, 0, 1 }; i.program[idx++] = { 3, 1, 0 }; i.ct_program = idx; Hue.

Viewing all articles
Browse latest Browse all 17825

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>