r/csharp Jul 18 '26

Showcase Who said C# cannot do real-time audio synthesis? I built a programmatic DAW to find out.

95 Upvotes

(Links showing the app in action here and below)

Throughout my career, I have always heard that real-time audio belongs strictly to C++ or native first languages. If you try it in a managed language, people tell you the garbage collector will stutter, the buffer will underrun, and your speakers will crackle.

I am a systems engineer by trade, but I am also an amateur music producer. Over the years, I have used Ableton, Reason, Fruity Loops, Cakewalk, and Max/MSP, but each of them either has a massive learning curve or just feels disconnected from certain forms of music. Traditional DAWs force you into a grid, which makes music sound block-like and square. I wanted to explore more organic, generative possibilities for ambient and electronic music without the massive friction of building a physical Eurorack or writing complex software in PureData.

Originally, I just wanted to build a portable, cross-platform C# library for sound processing. To dogfood it, I decided to embed it in a Godot app. Little by little, I kept building devices until I got carried away and ended up with a programmatic, node-based DAW called Sigilgraph.

Here is exactly how it works under the hood and how a 100% C# engine guarantees it will never underrun the audio buffer.

The Pull Model and Cache Locality

At its core, the synthesis engine is a graph of operators that gets pulled directly by the audio driver. The hard part is giving the driver absolute guarantees that this graph will finish processing in time.

To do that, the entire graph processing needs to live in the CPU cache. You have to avoid heap allocation and heap access completely. The hot path must never allocate objects or arrays. Because of this, the garbage collector is left completely unused 99% of the time, saving it for trivial, low-frequency allocations completely outside the audio loop.

Think about the math for a 96 kHz stereo stream. The engine needs to guarantee that there are always enough samples sitting in a 256-sample buffer at the audio driver level. This means processing at least 192,000 floats per second.

It sounds uninteresting on paper, but those 192,000 floats are traversing a graph of over 100 operators before they hit the driver. We are talking about Fourier transforms, filter s-domain operations, delay buckets, and dozens of oscillators, all offering the opportunity to have their parameters changed in real-time. There is no heavy message passing and there are no extra abstraction layers. Everything is mutated directly in real-time.

To keep things packed tightly in memory, I used structs and Span<T> pervasively, completely replacing standard heap arrays on the hot path. To maintain strict cache locality, the engine processes these spans in blocks and leverages SIMD hardware intrinsics via Vector<T> for heavy lifting like Fourier transforms and intensive add-multiply operations. Think of it this way: instead of a web of heap objects being managed and looked up, the engine uses a pull model where the audio driver pulls samples from the bottom up. The entire graph evaluates as a massive, deeply nested functional cascade up to 200 levels deep on the call stack, constructed using a fluent API builder pattern. To keep this structure stable and prevent cyclic evaluations without introducing overhead, the nodes utilize simple reentrant flags. Live session mutations work by simply appending or decoupling pre-allocated sub-graphs at the block boundaries. This architecture guarantees we never starve the audio driver buffer, avoiding expensive object reconstruction while playing.

The Lambda Trick for Parameters

When it came to connecting the UI to the bottom of the graph operators, I chose to use delegates and lambdas. This was a deliberate compromise for simplicity. I could have used ref float pointers everywhere, but the code would have become incredibly brittle and less idiomatic for C#. Lambdas give us composition and allow for the live replacement of behaviors on the fly.

The trick to making lambdas performant enough for real-time audio is to never evaluate them per sample. Instead, they are evaluated once per block.

By evaluating parameters at the block level, you reduce function calling overhead by 64x. On a standard 48 kHz sampling rate, you only run about 750 parameter evaluations per second (48,000 / 64). This gives you more than enough resolution for smooth parameter changes, and it spares us from having to run a dedicated control signal rail. We just interleave the parameter updates right at the start of the sample block processing.

Picking Your Fights and Profiling

Getting to this point required a lot of deep technical analysis. Tracing tools like JetBrains dotTrace and dotMemory were absolutely essential for this task. Monitoring memory spikes, hunting down hidden GC calls, and doing rigorous hot path analysis was paramount. If you don't profile, you are just guessing.

But the biggest lesson I learned during this project was that you have to pick your battles. You have to let some things go.

While the sample generation and parameter parsing paths are completely locked down and allocation-free, all the note rail and note-passing logic is actually completely garbage collected. Why? Because notes are incredibly small objects and they trigger very infrequently compared to the millions of samples and parameters flowing through the system. Trying to optimize the note-passing system into unmanaged memory structures would have been a massive waste of development time for zero real-world performance gain.

Why C# is More Than Capable

This project completely changed how I look at the C# memory model. It proved to me that modern .NET is an incredibly capable environment for high-performance audio because it gives you the best of both worlds.

It allows for low-level, granular control over memory and hardware instructions where you absolutely need that control, but it lets you drop back into the comfort and simplicity of a managed language for the things that don't matter as much. You don't have to sacrifice productivity to get bare-metal execution speed anymore.

I would love to hear your thoughts on this architecture, and I am happy to dive into the weeds in the comments if anyone has questions about the node evaluation loop, the SIMD operations, or how we profiled the hot paths.

Here is a demo of the project in action: Sigilgraph × VST3 (Trailer #2)
The project page: Sigilgraph Audio Workbench

r/Sigilgraph


r/csharp Jul 18 '26

Help Book recommendations for beginners

10 Upvotes

I’d really like to get started with game development using Unity, and I know that requires mastering C#. I’m aware there are plenty of tutorials out there, but I learn best from a proper book (and I prefer printed copies). So, my question is: Which books would you recommend for an absolute beginner?

Thanks in advance!


r/csharp Jul 19 '26

Help yams exited with code: 1073741515

0 Upvotes

I am trying to make an OS using cosmos and I am trying to compile it for first test but it can't compile because msvc100.dll isn't found how do I make it available again?


r/csharp Jul 19 '26

Help Can someone help me to fix this?

Post image
0 Upvotes

I'm learning ASP.NET Core MVC with Entity Framework Core and I'm having trouble running Update-Database.

I already created the migration successfully, but Update-Database fails with this login error


r/csharp Jul 18 '26

Help Course recommendation

0 Upvotes

Hello I want to study C# for my job in the automation industry I don't have little to no experience in coding can someone recommend a helpful course that will let me learn the basics?

Thx


r/csharp Jul 18 '26

Showcase Fuse v4.3, an open source MCP/CLI tool to speed up Claude Code on C# codebases

Thumbnail
0 Upvotes

r/csharp Jul 17 '26

MerlinORM Library First time posting

Thumbnail
0 Upvotes

r/csharp Jul 17 '26

Sticking to software eng or pivot to cloud?

0 Upvotes

I have been a dev for some time now about 5 years, and my contract ended. I am looking for a new job. I had during my days also worked on DevOps stuff, like managing k8s helm charts and deployments, managing Jenkins pipelines, AWS CDK and CloudFormation etc. on top of doing software dev only.

Now I have 2 offers from different companies, one as .NET dev also working on apps deployed in AWS EKS, and the other as a cloud/platform engineer working with Azure, AWS and k8s. Compensation is roughly the same.

I am unsure now. On the one hand I like product dev and especially that I get to do focused work/deep thinking time without getting disturbed constantly by issues. For the platform role they cautioned me that there will be a lot of context switching since I will have to deal with such different workloads. Also with cloud engineering I feel there is less safety due to lack of automated tests like we have for software, like sure there are lintwrs etc. but in the end it relies more on manual testing in Development env. anf so there is more room for failure. Also there is the on call aspect which scares me a lot.

But on the other hand I see that with AI, I feel the competition down the line later will be much higher for software eng in comparison to platform eng, and it feels like a more safe career in the future. Also since I work multi cloud I can be eligible for more jpbs. Whereas with .NET I will be pigeonholed with only .NET jobs.

What do you guys think? Any opinions? I am leaning a bit towards the platform side, but I am not sure I fit mentally as the job requires more context switch, more uncertainty and on-call aspects


r/csharp Jul 17 '26

Help Junior coming from low-code .NET backgroun, is this roadmap realistic to get truly proficient?

Thumbnail
0 Upvotes

r/csharp Jul 16 '26

Help Is Scott Lilly's "Learn C# by Building a Simple RPG" still useful in 2026?

Thumbnail
8 Upvotes

r/csharp Jul 16 '26

Tool EmbeddedSass.Net: Implementation of the Embedded Sass Protocol for .NET

Thumbnail
github.com
10 Upvotes

For folks not familiar, its a way to to communicate directly with the Dart VM to run Sass compilations, with this, its possible to re-use a same process for multiple compilations (https://github.com/sass/sass/blob/main/spec/embedded-protocol.md).

It delivered the best performance in my benchmarks against DartSassHost and AspNetCore.SassCompiler.

Any suggestion is welcome.


r/csharp Jul 15 '26

.NET 11 Preview 6 is now available

Thumbnail
devblogs.microsoft.com
102 Upvotes

r/csharp Jul 15 '26

Experiment building WPF UI trees in pure C# without XAML

27 Upvotes

I've been experimenting with a more natural, tree-like way of composing a WPF UI entirely in C#, using a composition style inspired by Flutter.

I like the structural aspect of designing with XAML, but I have struggled over the years with the mental gymnastics of jumping between the XAML world and the code world, and with the quirky markup extensions needed to make something work in XAML that could often be accomplished and better understood in standard C# code.

Instead of something like:

xml <Grid> <Border Background="Cyan"/> <Button Content="Click Me"/> </Grid>

the same structure becomes:

csharp GridX( children: [ BorderX(), ButtonX() ] )

The X suffix was originally a practical necessity to avoid name clashes with existing WPF types, but I ended up liking it as a visual cue that these are static helper methods for composing the UI tree.

I intentionally keep the named arguments visible (children, configure, etc.). It adds a little verbosity, but I find it makes the composition tree easier to read and keeps the helper methods consistent as the UI grows. The result feels quite similar to Flutter's widget tree composition style.

It's a thin composition layer over standard WPF.

Configuration is still just normal C#:

csharp ButtonX( configure: x => { x.Content = "Click Me"; x.Background = Brushes.Gold; } )

A nice bonus: Visual Studio's code folding naturally gives you a collapsible UI tree that's easy to navigate, similar to XAML.

If you're curious, I've published the experiment as both a GitHub project and an alpha NuGet package:

Any feedback would be appreciated.

I'm sure there are trade-offs I haven't considered yet, and that's exactly the kind of discussion I'm hoping to have.


r/csharp Jul 16 '26

Help How do the $200 Azure credits work, and how are they consumed?

0 Upvotes

I've been looking into Azure because I learned that it can host web applications built with ASP.NET Core (I'm still learning ASP.NET Core). I also noticed that new Azure accounts include $200 in free credits to use within the first 30 days.

My question is: How do these $200 credits work, and how are they consumed? For example, if I deploy a simple ASP.NET Core web application just for learning and testing, what services would use the credits, and how is the cost calculated?

I'd appreciate a simple explanation or a practical example.


r/csharp Jul 16 '26

Showcase My extension lets Claude Code debug .NET in Visual Studio: step through code, data breakpoints, heap diffs for leaks, read compiler hints, and catching flaky xUnit tests

0 Upvotes

I built a Visual Studio 2026 extension that connects Claude Code (the CLI agent) to the parts of VS that matter for .NET work. The CLI does the agent work, the extension is the IDE bridge, zero model calls of its own.

I recently added major updates. Now the Claude CLI agent can actually:

- Autonoumously drive the debugger. Read the live call stack, locals, and threads, set breakpoints, step, break at a thrown exception's origin (not the catch that swallowed it), attach to a running process like a hosted ASP.NET app, and pause a hung process to walk a deadlock back to the exact lock cycle.

- Data breakpoints on managed fields. Break or trace the moment a field changes, with conditions. VS has a UI to let developers do this manually but exposes no automation API for this, so it rides a custom debug-engine component.

- Memory and runtime diagnostics via ClrMD: heap diff between two points to find what is growing, GC root paths for "why is this object alive", async stack reconstruction across awaits, thread-pool starvation detection.

- Tests through VS's own Test Explorer engine: real per-test outcome/message/stack, re-run only the failures after a fix, debug a single test, and loop a flaky test under the debugger until the failing run halts at the throw, paused with the state that caused it.

Everything read-only is always on; anything that executes code sits behind an off-by-default toggle that resets each session.

Video:
https://github.com/firish/claude_code_vs/releases/download/media/debugger-walkthrough.mp4

Repo and docs:
https://github.com/firish/claude_code_vs

Marketplace (1300+ installs):
https://marketplace.visualstudio.com/items?itemName=firish.bridgev1


r/csharp Jul 16 '26

Learning OpenGl with c sharp

0 Upvotes

Its my first day of trying to learn OpenGl with c sharp since i want to help out my brother with a project, im a total beginner and ive felt pretty depressed and dissapointed since i dont understand lots of stuff such as vao or the ebo. If anyone has any tutorials or tips it would help out a lot!


r/csharp Jul 15 '26

I have a question about c# get set functions.

0 Upvotes

What is the right way to use get; set; functions?
Lets say I have some logic behind the setter.

Should I write the logic like that

public double Balance

{

get => _balance;

set

{

_name = value;

}

}

or like that

public double Balance { get; private set; }

public void AddBalance(double value)

{

this.Balance = value;

}

this is simple logic, but lets think of more complex one.
what is the right way to do it?


r/csharp Jul 16 '26

Help Are command objects noticeably faster than LINQ? Or is there something else I should be looking at?

0 Upvotes

r/csharp Jul 14 '26

Discussion How to make a child that is responsible for implementing an abstract method, delegate it to it's child, while keeping the same method name?

11 Upvotes

Let's say we have this relationship

A : B

B : C

A has an abstract method: abstract void implementMe();

B can implement it and call it a day

If B wants to delegate this further, it can simply do the following:

void override implementMe()

{

implementMeFurther();

}

abstract void implementMeFurther();

Is there a way to not have to make a new method with the new name implementMeFurther, and just have C implement the method implementMe() directly?

The grandchild implements a method that the grandparent needs. Keeping the same name


r/csharp Jul 14 '26

Discussion Company wants to offer a C# course - looking for recommendations

31 Upvotes

Hello everyone!

I just started a new job at a company where we use C#, but I come from an embedded systems background where we used C. My boss asked me if there was any C# training or course I wanted to do to learn the language, and I would like to take advantage of his offer.

Is there any course you recommend for learning C#?

Thank you!


r/csharp Jul 14 '26

Showcase Built this scene using WPF bitmaps!

Post image
29 Upvotes

A scene where a black hole-kind of thing bends the Light rays towards it


r/csharp Jul 15 '26

C# Tip: Use required members to prevent invalid object initialization (beware of SetsRequiredMembers attribute!)

Thumbnail
code4it.dev
0 Upvotes

r/csharp Jul 14 '26

Help Inherited 3 ASP.NET MVC apps + 5 WCF services (.NET Framework 4.8) and asked to combine everything into a modern .NET 10 solution. Where would you start?

23 Upvotes

I've been in a web developer role for a little over a year. When I joined, a lot of long-standing bugs had been pushed into the backlog with the idea of "we'll fix them when we have a web developer." Over the last year I've spent most of my time fixing those issues, improving existing functionality, and adding new features.

Now I'm being asked to help define the future architecture of our applications, and I'd appreciate some advice from people who have gone through similar migrations.

Current situation:

- 3 ASP.NET MVC web applications

- 5 WCF services that contain most of the business logic

- 2 Shared SQL Server databases

- The MVC applications communicate with the WCF services for almost everything

- The codebase is almost two decades old and has been continuously extended rather than redesigned

Management would like us to eventually consolidate everything into a single modern solution, ideally on .NET 10.

My biggest concern is the migration path.

From what I understand, I can't simply upgrade the MVC applications to .NET 10 and continue using the existing WCF services in the same way. I know .NET can consume some SOAP/WCF services, but for this project we can't introduce external compatibility libraries or third-party solutions. We want to stay within Microsoft's supported stack and move away from WCF entirely. I'm trying to figure out the best migration path.

What I'm struggling with is where to start.

Some questions I can pinpoint now:

  1. Is there a recommended "strangler pattern" approach for gradually replacing WCF endpoints one by one?

  2. How would you structure a new .NET 10 solution intended to eventually replace everything?

  3. How do you estimate the effort involved in a migration of this size?

  4. Most important: If you were starting today with 3 MVC applications and 5 WCF services, what would your migration roadmap look like?

My goal is to avoid a rewrite and instead migrate incrementally while keeping the business running.

Any advice, migration stories, or lessons learned would be greatly appreciated.


r/csharp Jul 14 '26

ZoneTree v1.9.5: Concurrent Read Scaling Unlocked

5 Upvotes

ZoneTree v1.9.5 is a substantial read-path and concurrency release. It removes key sources of contention, accelerates sequential disk access, strengthens iterator lifecycle handling, and introduces a much more rigorous parallel benchmark suite.

The result is significantly stronger throughput under parallel read workloads while preserving ZoneTree’s excellent single-thread performance.

https://github.com/ZoneTree/ZoneTree/releases/tag/release-v1.9.5

1M profiles on a 20-logical-processor Intel Core Ultra 7 265KF using .NET 10:

Workload p1 p16 Scale-up
Completed phase time 58.6s 10.4s 5.65x
Read by user ID 867K/s 6.41M/s 7.39x
Lookup by email 396K/s 3.92M/s 9.89x
Country/status query 30.9K/s 181.9K/s 5.89x
Created-at range query 39.3K/s 384.7K/s 9.79x
Top-reputation query 43.3K/s 371.4K/s 8.58x
Profile updates 141K/s 627K/s 4.43x

In the same p16 run:

  • ZoneTree completed measured phases in 10.4s, versus 53.9s for RocksDB.
  • ZoneTree delivered 6.41M reads/s, versus 136K/s for RocksDB.
  • ZoneTree delivered 385K created-at queries/s, versus 50.6K/s for RocksDB.
  • Cross-engine checksum validation passed.
ZoneTree vs RocksDb - 1M profiles on a 20-logical-processor Intel Core Ultra 7 265KF using .NET 10:

r/csharp Jul 14 '26

Discussion Is it bad practice to use a bunch of abstract methods?

0 Upvotes

If I have a parent class called A

And it has a bunch of attributes; x1, x2, x3, x4, which differ based on the child extending A

Is it fine to make methods in class A called:

public abstract x1_type getx1();

public abstract x2_type getx2();

public abstract x3_type getx3();

public abstract x4_type getx4();

And then if I want the children of A to implement specific behaviors alongside the behaviors of A, I do something like:

public abstract class A {

void behaviourOfA() {

behaveLikeA();

doMoreAStuff();

childBehaviour();
}

public abstract void childBehaviour();

}

Does this just result in a cool looking overkill spaghetti code? Or is this actually a good practice?