DEV Community

Anup Jayant Dharangutti
Anup Jayant Dharangutti

Posted on

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

Generated music does not have to mean unpredictable music.

When developers hear text-to-music today, they often think of generative AI.

The workflow is familiar:

Prompt
   ↓
AI Model
   ↓
Music
Enter fullscreen mode Exit fullscreen mode

It's a powerful approach when your goal is creativity, experimentation, or stylistic exploration.

But what if your requirements are different?

What if:

  • The same input must produce the same output
  • Results must be reproducible in CI/CD
  • Generated music must be testable
  • Output should be inspectable and versionable
  • Media generation should behave like software

That's the problem SoundScript's text composition engine is designed to solve.

Instead of interpreting prompts probabilistically, SoundScript applies a deterministic transformation pipeline.

Plain Text
     ↓
Syllables
     ↓
Phonemes
     ↓
Musical Gestures
     ↓
Musical Program
     ↓
MIDI
Enter fullscreen mode Exit fullscreen mode

Same input.

Same rules.

Same output.

Every time.


Generated Music vs Deterministic Music

Most AI music systems optimise for creative interpretation.

You might ask for:

"An emotional piano piece about space exploration."

The model then decides how to interpret that request.

Two runs may produce two different results.

That's often exactly what you want.

SoundScript asks a different question:

Can text be transformed into musical structure using explicit, repeatable rules?

This distinction is important.

AI Generation

Prompt
   ↓
Generative Model
   ↓
Creative Interpretation
   ↓
Music
Enter fullscreen mode Exit fullscreen mode

SoundScript Composition

Text
  ↓
Deterministic Rules
  ↓
Musical Structure
  ↓
MIDI
Enter fullscreen mode Exit fullscreen mode

Both are useful.

They solve different problems.


Install SoundScript

SoundScript 13 targets .NET 10.

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

SoundScript includes a text composition subsystem capable of transforming ordinary text into musical material.

A minimal example looks like this:

using SoundScript.Compose;
using SoundScript.Midi;

var program =
    PhonemeComposer.ComposeProgram(
        "Twinkle twinkle little star");

using var stream =
    new MemoryStream();

MidiGenerator.Write(
    program,
    stream);

File.WriteAllBytes(
    "twinkle.mid",
    stream.ToArray());
Enter fullscreen mode Exit fullscreen mode

The result is a standard MIDI file generated directly from text.

No hosted AI service.

No prompts.

No random seeds.

No unpredictable interpretation.

Just a deterministic transformation pipeline.


What Happens to the Text?

Consider this input:

Twinkle twinkle little star
Enter fullscreen mode Exit fullscreen mode

Before music appears, SoundScript processes the text through several stages.

Stage 1: Syllable Analysis

Conceptually:

Twinkle twinkle little star
         ↓
 Twin
 kle
 twin
 kle
 lit
 tle
 star
Enter fullscreen mode Exit fullscreen mode

The text is broken into manageable linguistic units.


Stage 2: Phoneme Analysis

Those units are further analysed into phoneme-like components.

For example:

star
  ↓

s
t
aa
r
Enter fullscreen mode Exit fullscreen mode

This stage focuses on how words sound rather than how they're spelled.


Stage 3: Musical Gestures

Phoneme categories are mapped to musical behaviours.

Conceptually:

Phoneme
    ↓
Gesture
Enter fullscreen mode Exit fullscreen mode

Possible gesture categories include:

  • Staccato
  • Legato
  • Accent
  • Swell
  • Fade

These categories influence musical expression.


Stage 4: Musical Structure

The generated gestures become actual musical events.

Word
  ↓
Syllable
  ↓
Phoneme
  ↓
Gesture
  ↓
Pitch + Rhythm + Articulation
  ↓
Phrase
Enter fullscreen mode Exit fullscreen mode

Those phrases are assembled into a complete musical program ready for MIDI generation.


Why Determinism Matters

Suppose your application generates media.

Many software systems require reproducibility.

Input A
   ↓
Output A
Enter fullscreen mode Exit fullscreen mode

Run again:

Input A
   ↓
Output A
Enter fullscreen mode Exit fullscreen mode

And again:

Input A
   ↓
Output A
Enter fullscreen mode Exit fullscreen mode

The same result every time.

That property is valuable in:

  • 🧪 Automated testing
  • 🔄 CI/CD
  • 🎓 Educational software
  • 📊 Data sonification
  • 🧬 Research
  • 🎮 Procedural content generation
  • 📦 Build-time asset generation
  • 📚 Reproducible demonstrations

For software engineers, repeatability is often more valuable than creativity.


Verify It in Code

Let's turn composition into a reusable function.

using SoundScript.Compose;
using SoundScript.Midi;

static byte[] Compose(
    string text)
{
    var program =
        PhonemeComposer.ComposeProgram(
            text);

    using var stream =
        new MemoryStream();

    MidiGenerator.Write(
        program,
        stream);

    return stream.ToArray();
}
Enter fullscreen mode Exit fullscreen mode

Generate output twice:

var first =
    Compose("Hello world");

var second =
    Compose("Hello world");

Console.WriteLine(
    first.AsSpan()
         .SequenceEqual(second));
Enter fullscreen mode Exit fullscreen mode

For identical inputs, the generated MIDI can be compared directly.

That's a very different engineering goal from probabilistic generation.


Deterministic Doesn't Mean Boring

Repeatability does not mean every input sounds the same.

Change:

Hello world
Enter fullscreen mode Exit fullscreen mode

to:

Hello from SoundScript
Enter fullscreen mode Exit fullscreen mode

and the generated musical structure changes.

Conceptually:

Text A
   ↓
 Rules
   ↓
Melody A
Enter fullscreen mode Exit fullscreen mode

and:

Text B
   ↓
 Rules
   ↓
Melody B
Enter fullscreen mode Exit fullscreen mode

The important guarantee is:

Text A
   ↓
Same Rules
   ↓
Melody A
Enter fullscreen mode Exit fullscreen mode

every single time.


Think of It Like a Compiler

A useful mental model isn't:

Text
  ↓
AI Musician
Enter fullscreen mode Exit fullscreen mode

Instead think:

Text
  ↓
Transformation Pipeline
  ↓
Music
Enter fullscreen mode Exit fullscreen mode

Developers already work with systems like this every day.

Compiler

Source Code
     ↓
    Parse
     ↓
Intermediate Representation
     ↓
Machine Code
Enter fullscreen mode Exit fullscreen mode

Template Engine

Template + Data
         ↓
      Render
         ↓
     Document
Enter fullscreen mode Exit fullscreen mode

Code Generator

Schema
   ↓
Generator
   ↓
Code
Enter fullscreen mode Exit fullscreen mode

SoundScript

Text
  ↓
Linguistic Analysis
  ↓
Musical Gestures
  ↓
Musical Program
  ↓
MIDI
Enter fullscreen mode Exit fullscreen mode

Generated doesn't automatically imply random.


Use the CLI

The same workflow is available from the SoundScript CLI.

soundscript compose \
  "Twinkle twinkle little star" \
  twinkle.mid
Enter fullscreen mode Exit fullscreen mode

Or from a repository checkout:

dotnet run \
  --project src/SoundScript.Cli \
  -- compose \
  "Twinkle twinkle little star" \
  twinkle.mid
Enter fullscreen mode Exit fullscreen mode

Generate the same text twice:

dotnet run --project src/SoundScript.Cli -- compose "Hello world" first.mid

dotnet run --project src/SoundScript.Cli -- compose "Hello world" second.mid
Enter fullscreen mode Exit fullscreen mode

The workflow remains simple:

Text
  ↓
Compose
  ↓
MIDI
Enter fullscreen mode Exit fullscreen mode

This makes text-to-music useful both in application code and automation pipelines.


Generated Music Doesn't Have to Be the Final Result

One interesting possibility is using generated music as a starting point.

Text
  ↓
Composition
  ↓
SoundScript Source
  ↓
Manual Edit
  ↓
Render
Enter fullscreen mode Exit fullscreen mode

Instead of:

Generate
   ↓
Accept Result
Enter fullscreen mode Exit fullscreen mode

you get:

Generate
   ↓
Inspect
   ↓
Edit
   ↓
Render
Enter fullscreen mode Exit fullscreen mode

This feels much closer to code generation than AI prompting.

The generated material becomes editable.

Developers stay in control.


Example: Refining Generated Music

Suppose the generated material contains:

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

You might decide to change it to:

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

Or adjust:

tempo 96
Enter fullscreen mode Exit fullscreen mode

to:

tempo 120
Enter fullscreen mode Exit fullscreen mode

Render again.

The workflow becomes:

Generated Structure
        ↓
Developer Edit
        ↓
New Output
Enter fullscreen mode Exit fullscreen mode

That's a blend of automation and deliberate authorship.


Use Case: Stable Musical Identities

Imagine an application containing named entities:

Alpha
Bravo
Charlie
Delta
Enter fullscreen mode Exit fullscreen mode

Each name can deterministically generate its own motif.

Alpha
  ↓
Motif A

Bravo
  ↓
Motif B

Charlie
  ↓
Motif C
Enter fullscreen mode Exit fullscreen mode

Every occurrence of "Alpha" produces the same musical identity.

Potential applications include:

  • 🎮 Games
  • 📊 Sonification
  • 🎓 Education
  • ♿ Accessibility research
  • 🖥 Interactive systems

Use Case: Procedural Games

Imagine a game generates locations dynamically:

Aurora Station
Crimson Valley
Echo Ridge
Silent Harbor
Enter fullscreen mode Exit fullscreen mode

Instead of manually designing audio for every generated location:

Location Name
        ↓
Text Composition
        ↓
Location Motif
Enter fullscreen mode Exit fullscreen mode

The same location name always generates the same identity.

That's extremely useful for procedural worlds.


Use Case: Education

Text-to-melody can help students explore relationships between language and sound.

Try entering:

computer
Enter fullscreen mode Exit fullscreen mode

then:

automation
Enter fullscreen mode Exit fullscreen mode

then:

deterministic audio
Enter fullscreen mode Exit fullscreen mode

Students can compare the resulting structures.

Because the transformation is rule-based, the system can explain why a result occurred.

That's much harder with purely generative systems.


Use Case: Automated Testing

A deterministic composer naturally fits testing workflows.

"Hello world"
      ↓
Known MIDI
Enter fullscreen mode Exit fullscreen mode

Generate twice:

var first =
    Compose("Hello world");

var second =
    Compose("Hello world");

Assert.True(
    first.AsSpan()
         .SequenceEqual(second));
Enter fullscreen mode Exit fullscreen mode

Or verify a hash:

using System.Security.Cryptography;

var midi =
    Compose("Hello world");

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

Console.WriteLine(hash);
Enter fullscreen mode Exit fullscreen mode

The text itself becomes a reproducible media fixture.


Use Case: Data Sonification

Labels can become stable auditory signatures.

Imagine:

service-authentication
service-payments
service-orders
service-shipping
Enter fullscreen mode Exit fullscreen mode

Each service generates its own musical identity.

Service Name
       ↓
Musical Motif
Enter fullscreen mode Exit fullscreen mode

Generation remains deterministic, allowing users to learn those identities over time.


Deterministic Doesn't Mean Intelligent

An important distinction:

SoundScript doesn't claim to understand the meaning of a sentence.

For example:

The deployment succeeded
Enter fullscreen mode Exit fullscreen mode

and

The deployment failed
Enter fullscreen mode Exit fullscreen mode

produce different musical structures because they're different inputs.

But the composer is not automatically deciding:

Success = Happy Music
Failure = Sad Music
Enter fullscreen mode Exit fullscreen mode

unless your application explicitly defines those rules.

This keeps behaviour predictable and inspectable.


Let Application Logic Handle Meaning

In many systems, semantics belong in the application.

For example:

Status = Success
Text = Deployment Complete
Enter fullscreen mode Exit fullscreen mode

The application might choose:

tempo 120
dynamic mf
Enter fullscreen mode Exit fullscreen mode

while the text composer generates melodic material.

Conceptually:

Application Meaning
         +
Text-Derived Motif
         ↓
Final Musical Behaviour
Enter fullscreen mode Exit fullscreen mode

This separation keeps business logic where it belongs.


Text-to-Music as Software Architecture

The bigger idea isn't turning sentences into tunes.

It's treating musical generation like any other software transformation.

Instead of:

Developer
    ↓
Creates Asset
    ↓
Stores Binary File
Enter fullscreen mode Exit fullscreen mode

you can have:

Data
  ↓
Rules
  ↓
Musical Structure
  ↓
Media
Enter fullscreen mode Exit fullscreen mode

That's a pattern software engineers already understand.


Where This Approach Fits

🎓 Education

Teach relationships between language and music.

🎮 Games

Generate stable motifs for people, locations, and factions.

🧪 Testing

Create reproducible MIDI fixtures from text.

📊 Sonification

Give labels and identifiers musical identities.

♿ Accessibility

Explore alternative non-visual representations.

🧬 Research

Run repeatable language-to-music experiments.

🛠 Developer Tooling

Generate music from build metadata, logs, or structured text.


When Should You Use AI Instead?

If your goal is:

Create an emotional two-minute orchestral score with piano, strings, and a cinematic climax.

then an AI music system is probably the better fit.

If your goal is:

This exact input should always produce the same inspectable musical result inside my application.

then deterministic composition becomes much more interesting.

The distinction is simple:

AI Music

Creative Interpretation
Enter fullscreen mode Exit fullscreen mode

SoundScript Composition

Predictable Transformation
Enter fullscreen mode Exit fullscreen mode

Both are valuable.

They support different architectures.


Try It Yourself

Install SoundScript:

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

Create a small composer:

using SoundScript.Compose;
using SoundScript.Midi;

static byte[] ComposeText(
    string text)
{
    var program =
        PhonemeComposer.ComposeProgram(
            text);

    using var stream =
        new MemoryStream();

    MidiGenerator.Write(
        program,
        stream);

    return stream.ToArray();
}
Enter fullscreen mode Exit fullscreen mode

Generate a melody:

var midi =
    ComposeText(
        "Hello SoundScript");

File.WriteAllBytes(
    "hello.mid",
    midi);
Enter fullscreen mode Exit fullscreen mode

Generate it again:

var first =
    ComposeText(
        "Hello SoundScript");

var second =
    ComposeText(
        "Hello SoundScript");

Console.WriteLine(
    first.AsSpan()
         .SequenceEqual(second));
Enter fullscreen mode Exit fullscreen mode

Then change the text and compare the result:

Hello deterministic music
Enter fullscreen mode Exit fullscreen mode

The workflow is straightforward:

Write Text
     ↓
Compose
     ↓
Generate MIDI
     ↓
Inspect
     ↓
Modify
     ↓
Repeat
Enter fullscreen mode Exit fullscreen mode

Try SoundScript

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

Resources


SoundScript Developer Series

Previous

Deterministic Audio Fixtures for Automated Testing in .NET

Coming Next

Generate Background Music from JSON in .NET

We'll connect application configuration and runtime data to SoundScript, turning ordinary JSON into predictable, programmable musical behaviour.


SoundScript

Write audio and media like code.

📧 info@dharangutti.in

🌐 https://www.dharangutti.in/

Top comments (0)