Wu, Donahue, Watanabe & Bryan (CMU + Adobe), 2023

Music ControlNet:
Multiple Time-varying Controls
for Music Generation

Text tells a music model the genre and mood. But how do you say "play THIS melody, swell louder here, and land the beat on my video cut"? Music ControlNet borrows ControlNet from image generation and rebuilds it for sound — giving creators frame-level control over melody, dynamics, and rhythm at once.

Prerequisites: Diffusion models + Spectrograms + Convolutions
11
Chapters
8
Simulations

Chapter 0: The Problem

Imagine you have a text-to-music model. You type "happy jazz, upbeat" and out comes thirty seconds of plausible jazz. Magic — until you actually want to compose something. You hum a melody and want the model to play it. You want the music to start quiet and swell at the chorus. You want the downbeat to hit exactly when your video cuts to the next shot.

Try expressing any of that in text. You'd have to write something like: "the song starts at 80 BPM with a quarter note on middle C played mezzo-forte on the saxophone..." — and the model still probably wouldn't get it right. This is the gap the paper names directly.

The core question: Text is great for global style (genre, mood). But musical expression lives in time-varying attributes — the notes, the rises and falls of loudness, the placement of beats. How do we give a music generation model precise, frame-by-frame control over melody, dynamics, and rhythm — without forcing creators to compose an entire MIDI score first?

Two obstacles, stated plainly

The authors identify exactly two reasons text fails at precise control:

What's been tried, and why it falls short

Prior approachWhat it doesWhy it isn't enough
MIDI-to-audio synthesisRender a full symbolic score to audioYou must compose the entire piece first — no improvisation, no "just the melody"
Style transferConvert recording A's style to B'sUsually one trained model per style; needs a complete reference recording
Text-to-musicGlobal style from a captionNo precise time-varying control at all

Notice the pattern: every method either demands too much input (a full score) or gives too little control (just a vibe). Music ControlNet wants the sweet spot — partial, optional, composable time-varying controls layered on top of text style.

The dream interface: A creator draws a melody contour, sketches a loudness curve, picks a rhythm template — uses any subset, fully or only for part of the clip — and the model fills in everything else musically. That is the target. Everything in this paper is engineering toward it.
Why is text a poor interface for controlling time-varying musical attributes?

Chapter 1: The Key Insight

Here is the leap. In image generation, there is already a solved version of "precise local control": ControlNet. You give Stable Diffusion an edge map, a depth map, or a pose skeleton, and it generates an image that obeys that spatial layout, pixel by pixel, while still following the text prompt for style.

Music ControlNet's insight is an analogy: a spectrogram is an image (time on one axis, frequency on the other), so a time-varying musical control is like a pixel-wise control in the image world. Melody-over-time is to a spectrogram what a depth map is to a photo.

The insight: Adapt image-domain ControlNet (and its multi-control cousin Uni-ControlNet) to audio. Take a pretrained text-to-music diffusion model, freeze it, and attach a small trainable adaptor branch that injects time-varying melody / dynamics / rhythm controls into the generation — the same recipe that gave images spatial control, now giving audio temporal control.

The three differences that make it non-trivial

If it were a literal copy of image ControlNet, this wouldn't be a paper. The audio domain breaks three assumptions:

axes are not symmetric
In an image both axes are spatial. In a spectrogram one axis is time, the other is frequency — and the controls couple tightly to time but loosely to frequency.
controls are not pixel-shaped
"Dynamics" is one number per time frame (1 value), not a value per frequency bin. The control's frequency dimension differs from the spectrogram's — you can't just stack them.
controls should be optional & partial
Creators want to specify melody for part of the clip and let the model improvise the rest. Image ControlNet assumes a full, dense control map.

The three contributions, in one breath

The paper delivers: (1) a general framework to bolt composable time-varying controls onto any text-to-music diffusion model; (2) a new masking strategy so controls can be partially specified in time; and (3) concrete, annotation-free melody / dynamics / rhythm control signals extracted directly from audio. We'll build each one.

The headline result it earns: Against MusicGen (a 1.5-billion-parameter model), Music ControlNet — at just 41 million parameters, trained on 11× less data — is 49% more faithful to an input melody, while also controlling dynamics and rhythm. Small, controllable, and more obedient. That's the payoff we're working toward.
What is Music ControlNet's central analogy?

Chapter 2: Background — Diffusion on Spectrograms

Before control, we need the thing being controlled: the base generator. Music ControlNet builds on a DDPM (Denoising Diffusion Probabilistic Model) that generates spectrograms, which a separate vocoder turns into audio.

The hierarchical factorization (why two stages)

Modeling a raw waveform w directly is hard — at 22 kHz, six seconds is ~130,000 numbers. So the paper splits the job using a spectrogram s as a middle representation:

p(w, s | ctext, C) = pφ(w | s) · pθ(s | ctext, C)

Symbol by symbol:

The split assumes w is conditionally independent of the controls given the spectrogram — reasonable, because everything the controls specify (melody, loudness, beats) is already visible in the spectrogram. The whole paper focuses on pθ(s | ctext, C) — generating a controlled spectrogram. The vocoder is off-the-shelf.

Diffusion in 60 seconds (the forward process)

Diffusion has a forward process that destroys data and a reverse process that learns to rebuild it. Forward: take a clean spectrogram x(0) and add Gaussian noise in M small steps until it's pure noise x(M)∼N(0,I). The convenient closed form lets you jump to any noise level in one shot:

x(m) = √(ám) · x(0) + √(1−ám) · ε,   ε ∼ N(0, I)

Where m is the noise level (0 = clean, M = pure noise), ám is the cumulative "how much signal survives" factor (1 at m=0, →0 at m=M), and ε is the random noise we mixed in. The network's whole job is to look at the noisy x(m) and predict the noise ε that was added, trained with a simple loss:

L = E [ ‖ ε − fθ(x(m), m, ctext, C) ‖2 ]

Subtract the predicted noise, step by step, and you walk from static back to music. (The paper uses 100-step DDIM sampling at inference — a faster shortcut through the reverse process.)

Forward / Reverse Diffusion on a Spectrogram — Drag the Noise Level

A stylized spectrogram (horizontal bands = harmonics). Drag the noise slider to see the forward process bury it in Gaussian noise; hit Denoise to watch the reverse process recover it. The clean signal at m=0 is what pθ ultimately produces.

Why does Music ControlNet generate spectrograms instead of raw waveforms directly?

Chapter 3: ControlNet & Zero Convolutions

To understand the audio version, you must first understand the image trick it adapts. The base diffusion model is a U-Net fθ: an encoder that downsamples the noisy image into features, a decoder that upsamples back, with skip connections between mirrored levels. It's already trained on millions of images and is frozen.

The clone-and-inject recipe

ControlNet's idea: don't retrain the giant U-Net. Instead:

  1. Clone the encoder half of the frozen U-Net to make a trainable adaptor branch.
  2. Feed the control signal (edge map, depth, etc.) into this clone.
  3. Add the adaptor's outputs back into the frozen decoder's corresponding layers — so the control nudges the generation.
Why a frozen base + a small trainable branch? The frozen U-Net already knows how to make realistic images (or music). You don't want to disturb that hard-won knowledge with a small control dataset — you'd risk catastrophic forgetting. The adaptor branch only has to learn the narrow skill of bending the existing generator toward the control. Less data needed, no degradation of base quality. This is why a 41M-param model trained on 1800 hours works.

The zero-convolution: the part that makes it train

How do you connect a freshly-initialized adaptor to a delicately-trained frozen network without wrecking it on step one? ControlNet's answer is the zero convolution Z — a 1×1 conv whose weights and bias are initialized to exactly zero. The control enters one layer like this:

(l)(·) = Zout( f(l)( x(m,l−1) + Zin(c), m, ctext) )

Decode it: f(l) is the l-th block (a copy of the frozen encoder block), x(m,l−1) is the activation flowing in, and c is the control. Zin brings the control in; Zout sends the result back to the frozen network.

The beautiful trick: Because Z starts at zero, at the very first training step the adaptor contributes nothing — the output equals the original frozen model's output exactly. So training begins from a known-good state and the gradient gently "opens up" the zero convs as it learns. No random garbage destroying the base model. The network learns the control as a smooth perturbation from "do nothing."

Frozen U-Net + Adaptor Branch — Click a Component
Click any block to see its role and whether it is frozen or trained.

Gray blocks = frozen pretrained U-Net (encoder → decoder with skip connections). Teal blocks = the trainable adaptor (a clone of the encoder) that receives the control. The orange Z nodes are zero convolutions — initialized to zero so the control starts as a no-op.

Why are the connecting convolutions initialized to zero?

Chapter 4: Adapting to Audio — The Frequency MLP

Now the genuinely novel step. In images, a control like a depth map has the same shape as the image — one value per pixel, on the same W×H grid. You can literally stack it and feed it in. Audio breaks this.

Why you can't just stack the control

The spectrogram has shape [T·fk, B, 1] with B=160 frequency bins. But a control like dynamics is one loudness number per time frame — shape [T·fk, 1, 1]. Its "frequency" dimension is 1, not 160. Melody is 12 pitch classes — frequency dimension 12. The control axes simply don't line up with the spectrogram's frequency axis.

So the paper generalizes the control definition. The time axis always matches the spectrogram (frame-wise correspondence), but the second dimension Bn is free:

C := { c(n) ∈ R(T·fk) × Bn × Dn }n=1..N

where Bn is the number of classes for control n (12 for melody, 1 for dynamics, 2 for rhythm) — not bound to the spectrogram's 160 bins.

The intuition behind decoupling frequency: A "high dynamics" value for one frame doesn't dictate which frequencies are loud — it could be a single booming bass note or a rich chord across many pitches. The model should be free to decide the frequency profile. So the control must NOT be locked to specific frequency bins. It informs time tightly, frequency loosely.

The fix: a learned MLP from control-classes to frequency bins

Music ControlNet inserts a small 1-hidden-layer MLP M that maps the control's Bn classes up to the spectrogram's B bins, learning how control classes relate to frequencies. The injection becomes:

(l)(·) = Zout( f(l)( x(m,l−1) + Zin( M(c(1)) ), m, ctext) )

The only change from Chapter 3's image equation is the new M(·) wrapping the control. For multiple controls, each gets its own MLP M(n), and the results are concatenated along the depth dimension before entering the shared zero-conv Zin.

Data flow, with shapes (the whole point)

StageTensor shapeWhat it is
Melody control in[512, 12, 1]12 pitch classes per frame (one-hot), 512 frames ≈ 6 s
After MLP M(mel)[512, 160, 1]projected onto the 160 Mel bins — now alignable with the spectrogram
Dynamics + its MLP[512,1,1] → [512,160,1]one loudness value → spread across bins
Concatenate (depth)[512, 160, N]all controls stacked, ready for the shared Zin
Through Zin → adaptorU-Net feature shapeadded into the frozen U-Net's activations
The Frequency MLP — Map Control Classes → 160 Mel Bins

Left column = the control's Bn classes (12 / 1 / 2). Right column = the 160 Mel frequency bins of the spectrogram. The MLP M learns the dense mapping between them — e.g. pitch class "C" should light up the bins near C's fundamental and its harmonics. Switch controls to see how few classes fan out to many bins.

Why does Music ControlNet add an MLP M before injecting each control?

Chapter 5: The Three Control Signals (the showcase)

What controls do creators actually want? The paper picks three musically complementary attributes that — crucially — can be extracted directly from any training spectrogram, so you never need a human to annotate anything. This is the data-efficiency masterstroke: every song is automatically a (music, control) training pair.

Melody — the chromagram, argmax'd

cmel ∈ R(T·fk) × 12 × 1. Compute the spectrogram's energy, fold all octaves into 12 pitch classes (C, C#, ..., B) — a chromagram — then keep only the most prominent pitch each frame (argmax → one-hot). Two engineering choices reveal the craft:

Dynamics — energy in decibels, smoothed

cdyn ∈ R(T·fk) × 1 × 1. Sum energy across all frequency bins per frame, convert to decibels (perceptual loudness), then apply a Savitzky-Golay smoothing filter with a 1-second window. Why smooth? Raw energy spikes on every note onset; smoothing gives the slow "musical intensity" envelope a creator would draw as a single rising/falling curve. At inference, you literally draw a line.

Rhythm — beat / downbeat probabilities

crhy ∈ R(T·fk) × 2 × 1. An RNN beat-tracker emits two per-frame probabilities: "is this a beat?" and "is this a downbeat?" (2 classes). The killer feature: because it's frame-level (not a global BPM), a creator can align beats to video scene cuts or any external timing.

Why these three and not, say, "chords"? They are (a) complementary — melody = pitch, dynamics = loudness, rhythm = timing, three orthogonal musical dimensions; (b) extractable with no human labels; and (c) easy for a non-expert to create at inference (draw a contour, draw a curve, pick a beat preset). The Conclusion explicitly flags chords/harmony as future work.

Extract the Three Controls from a Spectrogram — Showcase

Top: a synthetic Mel spectrogram. Toggle each control to overlay what gets extracted: the orange melody contour (most-prominent pitch class), the teal dynamics envelope (smoothed dB), and the purple/green rhythm markers (beats / downbeats). Change song to see all three re-extract from a different clip. Every overlay was computed from the spectrogram alone — no annotation.

python
# Extracting the three controls directly from audio (no labels needed)
import numpy as np, librosa
from scipy.signal import savgol_filter

def melody_control(y, sr, hop=256):
    # high-pass at Middle C so the bass doesn't dominate the argmax
    y_hp = librosa.effects.preemphasis(y)           # (stand-in for biquad HPF @261Hz)
    chroma = librosa.feature.chroma_stft(y=y_hp, sr=sr, hop_length=hop)  # [12, T]
    one_hot = (chroma == chroma.max(0, keepdims=True)).astype(float)
    return one_hot.T                                 # [T, 12]

def dynamics_control(y, sr, hop=256):
    S = np.abs(librosa.stft(y, hop_length=hop))**2  # power spectrogram
    energy = S.sum(0)                              # [T]  energy per frame
    db = librosa.power_to_db(energy)                # perceptual loudness
    return savgol_filter(db, 87, 3)[:, None]    # ~1s window -> [T, 1]

def rhythm_control(beat_p, downbeat_p):
    return np.stack([beat_p, downbeat_p], -1)    # [T, 2] from an RNN beat tracker
Why is a high-pass filter applied before computing the melody chromagram?

Chapter 6: The Masking Strategy

Now the second contribution. We want creators to use any subset of controls, and to specify each control for only part of the timeline. How do you train a single model to handle "melody only, for the first 3 seconds, improvise the rest"?

Step 1: control dropout (from Uni-ControlNet)

To make controls composable / optional, randomly drop entire controls during training. Let the index set be I = {1,...,N}; each step pick a subset I' to zero out:

c(n) = 0  if n ∈ I'   else   c(n)

This is exactly the classifier-free-guidance idea: by sometimes seeing a control and sometimes not, the model learns the correspondence between each subset and the output. At inference you can then provide any combination. (The paper also biases toward "keep all" or "drop all" because it gave perceptually better results.)

Step 2: partial-in-time masking (the new bit)

Dropout makes a control all-or-nothing. The paper's novelty is masking a control partially in time. For each active control, sample a random time span [ta, tb] and zero it out only there:

ct(n) = 0  if t ∈ [ta, tb]   else   ct(n)

At each training step the model flips a coin: use the full-masking scheme (drop whole controls) or the partial scheme (drop a time span). The zeroed span tells the model: "no control here — improvise musically."

What "zero means improvise" really teaches: By seeing controlled and uncontrolled spans side by side during training, the model learns to (a) obey the control where present, and (b) generate coherent music that smoothly bridges into the uncontrolled gaps. The paper reports no "visible borders" between controlled and improvised spans — the seams are inaudible. That seamlessness is the entire reward for this masking design.

Training Masking Schemes — Roll a Training Step

Each row is one control (melody / dynamics / rhythm) across the 6-second timeline. Colored = control supplied; gray = masked (→ improvise). Hit New random masking to draw a fresh training instantiation: sometimes whole controls vanish (full masking), sometimes only a time span (partial masking). The model trains on thousands of these so it handles any pattern at inference.

What does the partial-in-time masking scheme enable that plain control dropout does not?

Chapter 7: The Full Pipeline

Let's assemble everything into the end-to-end system and trace the data, including the often-glossed engineering specifics.

Two training phases

  1. Pretrain the base (frozen-to-be) model. A convolutional U-Net (5 ResNet blocks, [64,64,128,128,256] channels) learns pθ(s | ctext) on ~1800 hours of licensed instrumental music. Genre/mood tags enter via cross-attention in the inner blocks. Output spectrogram: 512×160×1 (512 time frames ≈ 6 s, 160 Mel bins). 41M params, 5 days on 32 A100s. This is the part we freeze.
  2. Finetune the adaptor branch. Freeze the base; train the cloned-encoder adaptor + MLPs + zero-convs to inject melody/dynamics/rhythm, using the masking strategy. Same loss/optimizer, 3 days on 8 A100s. Controls are extracted on-the-fly from the same training audio — no new annotation.
Why freeze, concretely: The control dataset is the same 1800 hours, just paired with auto-extracted controls. If you finetuned the whole U-Net on it, you'd risk overfitting the generator to control-correlated artifacts and degrading general music quality. Freezing guarantees the base's generative quality is preserved; only the "how to obey controls" skill is added. Tables confirm FAD (realism) barely moves as controls are added.

Inference, end to end

1. Creator inputs
Genre+mood tags (ctext) + any subset of drawn/extracted melody, dynamics, rhythm — fully or partially specified.
2. Diffusion denoise
100-step DDIM from noise. Each step: frozen U-Net + adaptor (with controls via MLP→Zin). CFG scale 4 on global style only.
3. Spectrogram out
512×160×1 Mel spectrogram s honoring the controls.
4. Vocoder
DiffWave pφ(w|s) renders the spectrogram to a 22.05 kHz waveform (6-step fast sampling).

A free superpower: length extrapolation

The U-Net is fully convolutional — no fixed-length layers. So even though it trained on 6-second clips, at inference you can feed a longer control and it generates 12 or 24 seconds. Convolutions don't care about sequence length; they slide. The paper measures 2× and 4× durations work, with only a mild rise in background noise (FAD) — a nice example of an architectural choice paying an unplanned dividend.

Inference Pipeline — Watch the Denoise + Control Adherence

Hit Run to denoise from pure noise to a spectrogram. With melody control on, the generated harmonics snap onto the orange target contour; turn it off and the model is free to put energy anywhere (text-only generation). This is the adaptor branch steering the frozen generator.

How can a model trained only on 6-second clips generate 24-second outputs?

Chapter 8: Experiments & Findings

The evaluation answers: does each control actually control its attribute? Do multiple controls coexist? Does it generalize from auto-extracted controls (training) to creator-drawn controls (deployment)?

Metrics, decoded

Finding 1: controls work, and stack cleanly

When a control is enforced, its metric jumps dramatically vs. global-style-only. Melody accuracy goes from 8.5% → 58%; rhythm beat-F1 from 27.8% → ~70%; dynamics correlation from near-0 → ~90%. And when all three are enforced together, the numbers stay essentially as high as single-control — the model handles them simultaneously. Cost: text adherence (CLAP) drops mildly; realism (FAD) is unharmed.

Control Adherence — Toggle Controls On/Off (Table I)

Toggle each control. Bars show the controllability metric (melody acc / dynamics corr / rhythm F1) when that control is enforced (✓) vs excluded (✗), straight from Table I. Notice: enforcing a control sends its metric way up; the others stay low — and the ✓ values barely change whether you enforce one control or all three.

Finding 2: created controls work even BETTER than extracted

Counterintuitive but real: when creators draw simpler controls than the messy auto-extracted ones, controllability improves — melody accuracy 58% → 78%, dynamics corr 89% → 99%. The drawn controls are cleaner targets, so the model hits them more precisely. The catch: FAD worsens, because simple controls steer the model out of its training distribution (it may copy a melody on one bland instrument). The authors are honest about this — and note creators just generate a batch and pick the best.

The generalization that matters: The model trained only on auto-extracted controls, yet handles human-drawn controls it never saw — and handles them better. This is the linchpin of the whole "co-creation" pitch: a creator's hand-drawn squiggle is out-of-domain, and the model still obeys it. Without this, the system would be a lab toy.

What surprising result did the "created vs extracted controls" experiment show?

Chapter 9: Benchmark vs. MusicGen

The flagship comparison. MusicGen is a 1.5-billion-parameter language-model-over-audio-tokens that also accepts a melody. Music ControlNet is 41M params — 35× smaller — trained on 11× less data, and additionally controls dynamics & rhythm. Who follows the melody better?

The numbers (Table V)

SettingModelMelody acc (%)
Extracted melodyOurs47.1
Extracted melodyMusicGen41.3
Created melodyOurs82.6
Created melodyMusicGen55.2

On created melodies — the realistic deployment case — Music ControlNet hits 82.6% vs MusicGen's 55.2%. That's the "49% relatively more faithful" headline: (82.6 − 55.2)/55.2 ≈ 0.49. A model 35× smaller is markedly more obedient to the control you actually care about.

Melody Faithfulness — Ours (41M) vs MusicGen (1.5B)

Melody accuracy, ours vs MusicGen, on created (deployment-realistic) vs extracted melodies. The gap is largest exactly where it counts — on the simple, hand-creatable controls.

The honest caveats

The real lesson of this benchmark: It's not "small beats big." It's that the right inductive bias — pixel-wise spatial control transplanted to time-varying audio — buys precise controllability that brute-force scale and text alone don't. A frozen base + a tiny control adaptor is a remarkably efficient way to add a capability the big model lacks.

What is the headline comparison against MusicGen?

Chapter 10: Connections & Cheat Sheet

Music ControlNet sits at the intersection of two lineages: the diffusion-with-spatial-control line from images, and the controllable-music line from audio. It's the bridge that carried "ControlNet" across the modality gap.

2020
DDPM / DDIM — diffusion generative modeling, fast sampling
2023
ControlNet & Uni-ControlNet — frozen U-Net + zero-conv adaptor for pixel-wise image control
2023
Music ControlNet — transplant to audio: time-varying melody/dynamics/rhythm via a frequency MLP + partial masking
2023+
MusicGen, Stable Audio, MusicLM — the broader text-to-music landscape this competes & composes within

The cheat sheet — every key equation

IdeaEquation / RuleWhat it means
Hierarchical factorizationp(w,s|ctext,C) = pφ(w|s)·pθ(s|ctext,C)diffusion makes the spectrogram s; vocoder makes the waveform w
Diffusion noisingx(m)=√ám x(0)+√(1−ám) εjump to any noise level in one step; network predicts ε
Diffusion lossE‖ε − fθ(x(m),m,ctext,C)‖2train the U-Net to predict the added noise (L1 in this paper)
Control injection (audio)Zout(f(l)(x + Zin(M(c)),m,ctext))M = MLP mapping control classes→160 bins; Z = zero conv (starts at 0)
Control definitionc(n) ∈ R(T·fk)×Bn×Dntime matches spectrogram; Bn classes free (mel=12, dyn=1, rhy=2)
Full masking (dropout)c(n)=0 if n∈I'drop whole controls → composable / optional
Partial maskingct(n)=0 if t∈[ta,tb]drop a time span → "improvise here"

Why this paper matters

The one-paragraph summary you could give on a whiteboard

Music ControlNet adds precise, time-varying control to a frozen text-to-music diffusion model by adapting image ControlNet. It generates a Mel spectrogram (then vocodes to audio), and injects melody / dynamics / rhythm controls through a cloned-encoder adaptor branch wired in via zero convolutions (which start at zero so the base is never disturbed). Because a control's class dimension (12/1/2) doesn't match the spectrogram's 160 frequency bins, a learned MLP maps classes→bins — informing time tightly, frequency loosely. A masking strategy (drop whole controls, or just a time span) makes the controls composable and partially specifiable, with the model improvising the gaps. Controls are auto-extracted from training audio, so no annotation is needed, and the model generalizes to simpler creator-drawn controls — beating MusicGen on melody faithfulness by ~49% at 35× fewer parameters.

"...we sharply focus on improving control methods so as to directly offer musicians more creative agency during the generation process."
— Wu, Donahue, Watanabe & Bryan, Music ControlNet (2023)