# Deterministic Audio Fixtures for Automated Testing in .NET

*We generate JSON fixtures, images, database records, and API payloads for tests. Why not audio?*

Most engineering teams already treat test data as code.

We generate:

*   JSON fixtures
    
*   Database records
    
*   API payloads
    
*   Configuration files
    
*   Images
    

Yet audio is often handled differently.

A WAV file gets copied into a test directory and remains there as a binary asset that nobody wants to touch.

```text
tests/
└── fixtures/
    └── notification.wav
```

The test passes.

The build is green.

But a future developer reviewing the repository may have no idea:

*   What sound does this contain?
    
*   Which notes are being played?
    
*   Why was it generated?
    
*   Can it be reproduced?
    
*   Was that binary change intentional?
    

In many projects, the WAV file becomes the only source of truth.

**What if the source of the sound was the artifact you reviewed instead?**

That's where SoundScript becomes interesting.

* * *

## The Problem with Binary Audio Fixtures

Consider a pull request containing:

```text
notification.wav changed
```

What exactly changed?

*   Tempo?
    
*   Pitch?
    
*   Instrument?
    
*   Duration?
    
*   Volume?
    
*   Entire musical phrase?
    

Without specialised tooling, the answer is usually:

> "I don't know. Someone changed the WAV."

Compare that to a textual audio definition:

```text
tempo 120

track notification {
    instrument piano
    mf

    C4 e
    E4 e
    G4 q
}
```

Now the intent is visible.

A code reviewer can understand the change before listening to anything.

* * *

## Install SoundScript

SoundScript 13 targets .NET 10.

```bash
dotnet add package SoundScript --version 13.0.0
```

Create a deterministic audio fixture directly from C#:

```csharp
using SoundScript;

var source = """
    tempo 120

    track fixture {
        instrument piano

        C4 e
        E4 e
        G4 e
        B4 e
        D5 e
        G4 e
    }
    """;

var compilation =
    SoundScriptEngine.Compile(source);

var wav = compilation.RenderWave();
var midi = compilation.RenderMidi();

File.WriteAllBytes("fixture.wav", wav);
File.WriteAllBytes("fixture.mid", midi);
```

The key idea isn't that we generated a WAV file.

The important part is that the fixture now has a readable, reviewable definition:

```text
tempo 120

track fixture {
    instrument piano

    C4 e
    E4 e
    G4 e
    B4 e
    D5 e
    G4 e
}
```

* * *

## Treat Audio Like Generated Test Data

Instead of this:

```text
fixture.wav
```

your workflow becomes:

```text
Test Intent
      ↓
SoundScript Source
      ↓
Compile
      ↓
WAV / MIDI Fixture
      ↓
System Under Test
```

This is the same pattern developers already use elsewhere.

```text
Schema
   ↓
Generated Client

Template
   ↓
Document

Source Code
   ↓
Executable

SoundScript
   ↓
Audio Fixture
```

Audio stops being a mysterious binary asset and becomes another generated artifact.

* * *

## Verify Deterministic Rendering

One of the most useful properties for testing is reproducibility.

Render the same source twice:

```csharp
var compilation =
    SoundScriptEngine.Compile(source);

var first =
    compilation.RenderWave();

var second =
    compilation.RenderWave();

var identical =
    first.AsSpan().SequenceEqual(second);

Console.WriteLine(identical);
```

Or make it a test:

```csharp
Assert.True(
    first.AsSpan().SequenceEqual(second));
```

If the source and rendering conditions remain unchanged, SoundScript is designed to produce repeatable output.

That means the generated audio itself can participate in automated regression testing.

* * *

## Add SHA-256 Regression Checks

In many cases, you don't need to store expected byte arrays.

A hash is enough.

```csharp
using System.Security.Cryptography;

var wav =
    SoundScriptEngine
        .Compile(source)
        .RenderWave();

var hash =
    Convert.ToHexString(
        SHA256.HashData(wav));

Console.WriteLine(hash);
```

Conceptually:

```text
SoundScript Source
        ↓
    Render WAV
        ↓
      SHA-256
        ↓
Expected Hash?
    ↙       ↘
 PASS   Investigate
```

Generated audio can now be validated much like any other build artifact.

* * *

## Example: Testing Audio Upload Pipelines

Suppose you're testing an audio upload endpoint.

Many teams would commit a WAV fixture:

```text
upload-test.wav
```

Instead, generate one during test execution.

```csharp
var wav =
    SoundScriptEngine
        .Compile("""
            tempo 100

            track upload {
                instrument piano

                C4 q
                E4 q
                G4 h
            }
            """)
        .RenderWave();

await File.WriteAllBytesAsync(
    "upload-test.wav",
    wav);
```

Now the fixture is:

✅ Generated

✅ Readable

✅ Reproducible

✅ Versionable

✅ Easy to modify

The musical intent lives inside the test itself.

* * *

## Store Fixture Sources in Files

For larger test suites, keep the musical definitions separate.

```text
tests/
└── fixtures/
    ├── notification.ss
    ├── warning.ss
    └── failure.ss
```

Then load them:

```csharp
using SoundScript;

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

var wav =
    compilation.RenderWave();
```

Now audio changes show up naturally in pull requests.

Instead of:

```text
Binary files differ
```

you review:

```diff
-tempo 100
+tempo 120

-track notification {
-    C4 q E4 q
+track notification {
+    C4 e
+    E4 e
+    G4 q
}
```

That's significantly easier to reason about.

* * *

## A Simple Deterministic Fixture Test

A complete test might look like this:

```csharp
using SoundScript;

var source = """
    tempo 120

    track fixture {
        instrument piano

        C4 e
        E4 e
        G4 q
    }
    """;

var compilation =
    SoundScriptEngine.Compile(source);

var first =
    compilation.RenderWave();

var second =
    compilation.RenderWave();

Assert.True(
    first.AsSpan().SequenceEqual(second));
```

The same idea applies to MIDI:

```csharp
var firstMidi =
    compilation.RenderMidi();

var secondMidi =
    compilation.RenderMidi();

Assert.True(
    firstMidi.AsSpan()
        .SequenceEqual(secondMidi));
```

The tests aren't just verifying behaviour.

They're also verifying reproducibility.

* * *

## Should Every Test Compare Exact Bytes?

No.

And that's an important distinction.

Exact byte comparisons are useful when renderer stability matters.

Many audio tests care about different guarantees:

*   Is the WAV valid?
    
*   Is the duration correct?
    
*   Is the sample rate correct?
    
*   Is the channel count correct?
    
*   Does the MIDI contain expected notes?
    
*   Is the file size reasonable?
    

Choose assertions based on what the test is actually promising.

* * *

## Think in Testing Layers

A useful strategy is to separate validation into layers.

### Level 1: Format Validation

```text
Generated Bytes
       ↓
 Format Parser
       ↓
Valid?
```

Is the output a valid WAV or MIDI file?

* * *

### Level 2: Structural Validation

Verify characteristics such as:

*   Duration
    
*   Sample rate
    
*   Channels
    
*   Tracks
    
*   Notes
    
*   Tempo
    

* * *

### Level 3: Deterministic Regression

Verify exact reproducibility.

```text
Expected Hash
      =
 Actual Hash
```

SoundScript makes this level possible without forcing every test to use it.

* * *

## CI/CD Gets Interesting Too

This pattern isn't limited to testing.

Build and deployment results can also be represented as sound.

Imagine:

```text
0 failures
    ↓
Success motif

Few failures
    ↓
Warning motif

Many failures
    ↓
Failure motif
```

Conceptually:

```text
tempo 120

track passed {
    mf

    G4 e
    G4 e
    G4 e
    G4 e
}

track failed {
    f

    C3 e
    C3 e
}
```

The same test results produce the same audio.

That's deterministic sonification.

* * *

## Why Sonify CI?

Not as a replacement for dashboards.

As an additional information channel.

Potential use cases include:

*   Long-running test environments
    
*   Monitoring stations
    
*   Accessibility experiments
    
*   Engineering demonstrations
    
*   Industrial control systems
    
*   Background build awareness
    

The goal isn't to add sound everywhere.

The goal is to use sound when sound communicates useful information.

* * *

## Where Deterministic Audio Fixtures Fit Best

### 🧪 Media Upload Testing

Generate valid WAV files during setup.

### 🔔 Notification Systems

Verify generated notification sounds.

### 🎮 Games

Create repeatable audio scenarios.

### ♿ Accessibility Testing

Produce controlled audio feedback.

### 🚦 Monitoring Applications

Validate state-to-sound mappings.

### 🏭 Industrial Systems

Test machine-state signalling.

### 🔄 CI/CD Experiments

Generate repeatable build sonification.

### 📦 Demo Data Generation

Create reproducible audio assets during builds.

* * *

## Audio as Source Code

The bigger idea isn't WAV generation.

It's moving intent into something developers can inspect.

Instead of:

```text
mysterious binary asset
```

you have:

```text
human-readable source
        ↓
deterministic build
        ↓
binary artifact
```

Developers already embrace this model everywhere else:

```text
Source Code → Executable

Schema → Client

Template → Document

Build Script → Package

SoundScript → Audio
```

SoundScript applies the same engineering principle to sound.

* * *

## Try It Yourself

Install SoundScript:

```bash
dotnet add package SoundScript --version 13.0.0
```

Create a simple fixture:

```text
tempo 120

track fixture {
    instrument piano
    mf

    C4 e
    E4 e
    G4 q
}
```

Render twice:

```csharp
var compilation =
    SoundScriptEngine.Compile(source);

var a =
    compilation.RenderWave();

var b =
    compilation.RenderWave();

Console.WriteLine(
    a.AsSpan().SequenceEqual(b));
```

Then compute a hash:

```csharp
var hash =
    Convert.ToHexString(
        SHA256.HashData(a));

Console.WriteLine(hash);
```

You now have an audio fixture that can be:

```text
Written
   ↓
Reviewed
   ↓
Generated
   ↓
Hashed
   ↓
Tested
   ↓
Regenerated
```

That's a very software-engineering way to think about audio.

* * *

## Try SoundScript

```bash
dotnet add package SoundScript --version 13.0.0
```

### Resources

*   🌐 Website: https://soundscript.net/
    
*   📦 NuGet: https://www.nuget.org/packages/SoundScript
    
*   💻 GitHub: https://github.com/dharangutti/sound-script
    
*   📚 Documentation: https://soundscript.net/doc.html?p=documentation.md
    
*   🚀 V13 Release: https://github.com/dharangutti/sound-script/releases/tag/v13.0.0
    

* * *

## SoundScript Developer Series

### Previous

**Generate MIDI and WAV from the Same C# Source**

### Coming Next

**Text-to-Music with SoundScript: Deterministic Composition Instead of Prompting**

We'll take ordinary text, transform it into musical structures, and explore why deterministic composition differs fundamentally from probabilistic AI-generated music.

* * *

**SoundScript**  
*Write audio and media like code.*

📧 info@dharangutti.in  
🌐 https://www.dharangutti.in/
