DEV Community

Anup Jayant Dharangutti
Anup Jayant Dharangutti

Posted on

Generate MIDI and WAV from the Same C# Source with SoundScript

Less audio plumbing. More programmable sound.

Generating a MIDI file in C# isn't particularly difficult.

Generating MIDI, rendering audio, keeping everything reproducible, and making the musical source easy to review in Git is where complexity starts to accumulate.

SoundScript takes a different approach.

Instead of manually creating MIDI events or building audio pipelines, you describe musical intent and let SoundScript render the outputs.

Let's build something.


Install SoundScript

SoundScript 13 targets .NET 10.

dotnet add package SoundScript --version 13.0.0
Enter fullscreen mode Exit fullscreen mode

Create a small C# program:

using SoundScript;

var cue = SoundScriptEngine.Compile(
    "tempo 120 track cue { instrument piano mf C4 e E4 e G4 q }");

File.WriteAllBytes("success.mid", cue.RenderMidi());
File.WriteAllBytes("success.wav", cue.RenderWave());
Enter fullscreen mode Exit fullscreen mode

That's it.

One musical definition produces two outputs:

  • ๐ŸŽน MIDI
  • ๐Ÿ”Š WAV

No DAW project.

No MIDI event plumbing.

No duplicated definitions.


The Musical Source

Here's the SoundScript source in a more readable format:

tempo 120

track cue {
    instrument piano
    mf

    C4 e
    E4 e
    G4 q
}
Enter fullscreen mode Exit fullscreen mode

Where:

Symbol Meaning
C4, E4, G4 Notes
e Eighth note
q Quarter note
mf Mezzo-forte dynamic

Instead of manually creating:

  • note-on events
  • note-off events
  • timestamps
  • velocities

you describe the musical idea and let SoundScript generate the implementation details.


Why Use a Language Instead of a MIDI API?

Libraries such as DryWetMIDI are excellent when you need direct control over MIDI data.

They expose concepts like:

  • Notes
  • Timed events
  • Tempo maps
  • Patterns
  • MIDI devices
  • Playback
  • File manipulation

That's exactly what a MIDI library should do.

SoundScript operates at a higher level.

Traditional MIDI Workflow

Application
    โ†“
Create musical objects
    โ†“
Manage timing
    โ†“
Build MIDI structure
    โ†“
Serialize MIDI
Enter fullscreen mode Exit fullscreen mode

SoundScript Workflow

Application
    โ†“
Describe music
    โ†“
Compile
    โ†“
Render MIDI / WAV
Enter fullscreen mode Exit fullscreen mode

SoundScript isn't trying to replace MIDI libraries.

It provides a different abstraction when your application cares about musical intent rather than individual MIDI events.

If you're building a MIDI editor, DAW, or hardware integration tool, a MIDI library is likely the right choice.

If your application simply needs to say:

Play this deterministic musical cue.

then a higher-level representation can dramatically reduce application code.


Change the Music Without Changing the Application

Suppose a designer wants a different sound.

Only the musical definition changes:

var cue = SoundScriptEngine.Compile("""
    tempo 96

    track notification {
        instrument violin
        mp

        C4 q
        E4 q
        G4 q
        C5 h
    }
    """);
Enter fullscreen mode Exit fullscreen mode

The rendering code remains identical:

File.WriteAllBytes(
    "notification.mid",
    cue.RenderMidi());

File.WriteAllBytes(
    "notification.wav",
    cue.RenderWave());
Enter fullscreen mode Exit fullscreen mode

Separating musical behaviour from application logic becomes increasingly useful as audio requirements evolve.


One Source, Multiple Outputs

MIDI and WAV serve different purposes.

MIDI

MIDI contains symbolic musical information.

Useful for:

  • Sequencing
  • Editing
  • DAW workflows
  • MIDI processing
  • Compact storage

WAV

WAV contains rendered audio.

Useful for:

  • Direct playback
  • HTTP delivery
  • Asset generation
  • Application packaging
  • Audio processing pipelines

Using separate systems for MIDI and audio often means maintaining multiple representations of the same cue.

SoundScript generates both from a single source:

                โ”Œโ”€โ”€โ†’ MIDI
SoundScript โ”€โ”€โ”€โ”€โ”ค
                โ””โ”€โ”€โ†’ WAV
Enter fullscreen mode Exit fullscreen mode

One definition.

Two outputs.

No duplication.


Move Music Out of C

Embedding short cues in code is convenient.

For larger projects, store music in .ss files.

scores/
โ””โ”€โ”€ notification.ss
Enter fullscreen mode Exit fullscreen mode

Load and compile:

using SoundScript;

var compilation =
    SoundScriptEngine.CompileFile(
        "scores/notification.ss");

File.WriteAllBytes(
    "notification.wav",
    compilation.RenderWave());
Enter fullscreen mode Exit fullscreen mode

Now musical content can evolve independently of application code.


Audio Becomes Versionable

One of the most interesting side effects of representing music as text is that audio becomes part of normal software workflows.

You can:

  • โœ… Commit audio definitions to Git
  • โœ… Review them in pull requests
  • โœ… Compare changes with diffs
  • โœ… Regenerate assets during builds
  • โœ… Automate fixture generation
  • โœ… Track exactly what changed

Instead of comparing:

notification-old.wav
notification-new.wav
Enter fullscreen mode Exit fullscreen mode

you review:

-tempo 100
+tempo 120

-track alert {
-    C4 q E4 q
+track alert {
+    C4 e
+    E4 e
+    G4 q
}
Enter fullscreen mode Exit fullscreen mode

For developers, that's a much more useful workflow.


Deterministic Rendering

SoundScript is designed around reproducible generation.

Given the same:

  • SoundScript source
  • Renderer version
  • Render options
  • Referenced assets

the output is designed to be repeatable.

That enables workflows such as:

Source
   โ†“
Build
   โ†“
WAV / MIDI
   โ†“
Hash
   โ†“
Regression Test
Enter fullscreen mode Exit fullscreen mode

This becomes particularly valuable when audio is part of:

  • Automated testing
  • CI/CD pipelines
  • Generated assets
  • Research workflows
  • Reproducible demonstrations

We'll explore this in a future article.


Interesting Use Cases

๐Ÿ”” Application Notifications

Generate cues for:

  • Success
  • Warning
  • Failure
  • New messages
  • Deployment completion

๐ŸŽฎ Game Prototypes

Create state-driven audio behaviours without manually managing countless variations.

๐Ÿงช Automated Testing

Generate WAV and MIDI fixtures as part of test setup.

๐Ÿšฆ Monitoring Systems

Map operational state into repeatable audio signals.

โ™ฟ Accessibility Experiments

Explore alternative non-visual feedback mechanisms.

๐ŸŽ“ Education

Programmatically demonstrate:

  • Notes
  • Intervals
  • Tempo
  • Dynamics
  • Musical structure

๐Ÿญ Industrial Applications

Represent machine or process state through structured audio.


When Not to Use SoundScript

SoundScript is not a replacement for a DAW.

A traditional DAW remains the right tool for:

  • Recording
  • Mixing
  • Mastering
  • Complex arrangements
  • Plugin-heavy workflows
  • Live performance

SoundScript addresses a different question:

What if audio is part of your application's programmable behaviour?


Try Modifying the Example

Start with:

C4 e
E4 e
G4 q
Enter fullscreen mode Exit fullscreen mode

Then experiment.

Change the tempo:

tempo 80
Enter fullscreen mode Exit fullscreen mode

Change the instrument:

instrument violin
Enter fullscreen mode Exit fullscreen mode

Change the dynamics:

p
Enter fullscreen mode Exit fullscreen mode

Change the phrase:

C4 q
G4 q
C5 h
Enter fullscreen mode Exit fullscreen mode

Recompile.

Render again.

Listen to the WAV.

Inspect the MIDI.

Commit the source.

That's the entire SoundScript workflow:

Write
  โ†“
Compile
  โ†“
Render
  โ†“
Version
Enter fullscreen mode Exit fullscreen mode

Get Started

Install SoundScript:

dotnet add package SoundScript --version 13.0.0
Enter fullscreen mode Exit fullscreen mode

Resources


SoundScript Developer Series

This article is part of a series exploring programmable audio with .NET.

Coming next:

Deterministic Audio for Automated Testing in .NET

We'll generate WAV and MIDI fixtures from source, render them repeatedly, and verify the output programmatically.


SoundScript

Write audio and media like code.

๐Ÿ“ง info@dharangutti.in

๐ŸŒ https://www.dharangutti.in/

Top comments (0)