Nodes/ComfyUI-AudioMoodAnalyzer/Audio Mood Analyzer
ComfyUI Node

Audio Mood Analyzer

Turn a Song Into a Painterly Image Prompt, Locally — No API Key

By andrea-spoldi·Created 4 months ago·Updated 3 months ago· 0
Audio Mood Analyzer
  • audio
  • mood_json
  • subject_json
  • environment_prompt
  • subject_prompt
  • merge_prompt
  • summary
ollama_urlhttp://localhost:11434/api/generate
modelqwen3:14b
analysis_temperature0.4
prompt_temperature0.8
custom_contextAnalyze the music as pure sound, not lyrics. Translate sonic qualities into emotional visual direction.
lyrics_or_text
focus_fragment
song_title
song_description
song_genre
style_presetpainterly
style_notes
generate_environment_prompttrue
generate_subject_prompttrue
generate_merge_prompttrue

Most "audio to image" tools treat a song like a filename: they read a BPM, maybe a spectrogram, and hand it to a diffusion model as a trigger. This node does the opposite. It listens to the audio the way a music critic does, turns what it hears into a structured mood analysis, and then asks a local LLM to write image-generation prompts from that analysis - all local, through Ollama, no API key anywhere.

Audio Mood Analyzer is the heart of the ComfyUI-AudioMoodAnalyzer pack. It's an experiment, and the author says so plainly: results vary, some outputs surprise you, and that's the point. If you want a deterministic "BPM → image" mapping, this isn't it. If you want a workflow that starts from a song's emotional content and produces prompts worth editing, this is the one you'll actually reach for.

How it works

The pipeline is two-phase. First, it runs the audio through librosa and extracts physical features - tempo, beat count, RMS energy, dynamic range, spectral centroid (brightness), spectral bandwidth, zero-crossing rate, onset strength, and an 8-section energy profile. Those features are serialized into JSON and sent to your local Ollama server with a carefully written prompt: "Analyze only the sonic features… Translate sonic qualities into emotional visual direction." That call returns a structured mood JSON (sonic mood adjectives, energy profile, tension, color palette, lighting, texture, composition cues, and an avoid list).

Phase two takes that JSON and runs up to three separate LLM calls to write prompts, using a higher temperature (0.8 vs. 0.4 for analysis) so the language stays expressive instead of repeating itself. You get an environment-only prompt (no people), a subject-only prompt (from lyrics or text, if you provided any), and a merge prompt that combines both. The two-temperature split is the smart bit: consistency where the structure matters, creativity where it doesn't.

Inputs and outputs that matter

The audio input takes any ComfyUI AUDIO source - a loader, an audio file node, whatever feeds the graph. model defaults to qwen3:14b, which is a sensible default; anything Ollama has installed works, and bigger instruction-tuned models give noticeably better prose. analysis_temperature and prompt_temperature are the two knobs described above - leave them alone until you're chasing a specific feel.

The fields that actually change the output:

  • style_preset - painterly, cinematic, raw, abstract, or custom. These map to real aesthetic targets - painterly references Bacon and Schiele, cinematic references Tarkovsky and Wong Kar-wai - so this one input does a lot of heavy lifting.
  • lyrics_or_text / focus_fragment / song_title / song_description / song_genre - subject analysis only runs if at least one of these is filled in. No lyrics, no subject prompt; that's the single most common "it's broken" complaint, and it isn't broken.
  • custom_context - free-text direction for the analysis phase, defaults to "Analyze the music as pure sound, not lyrics." This is where you'd wire in the CLAP node's output.

The outputs are: mood_json and subject_json (structured analyses), environment_prompt, subject_prompt, merge_prompt (the three image prompts - wire these into CLIPTextEncode), and summary (a short human-readable mood recap). The JSON outputs are the connective tissue of this pack: mood_json feeds Composition Inference, Mood JSON Unpacker, and Prompt Enricher.

Installing it

Install from ComfyUI Manager by searching for AudioMoodAnalyzer, or the manual route:

cd ComfyUI/custom_nodes
git clone https://github.com/andrea-spoldi/ComfyUI-AudioMoodAnalyzer.git
pip install -r ComfyUI-AudioMoodAnalyzer/requirements.txt

Restart ComfyUI; the nodes appear under audio/analysis. You also need Ollama running locally with a model pulled:

ollama pull qwen3:14b

The Python side needs librosa, soundfile, numpy, requests, and transformers>=4.35.0 - the transformers requirement only matters if you use the CLAP node, but the README installs it anyway.

Where people get burned

  • Ollama isn't running or the URL is wrong. The node posts to http://localhost:11434/api/generate by default. If Ollama is elsewhere, that string is your first suspect when calls hang or error.
  • No subject prompt despite lyrics in your head. You have to actually paste the text into lyrics_or_text (or one of the other four subject fields). Empty fields mean no subject analysis, on purpose.
  • Generic, flavorless prompts. That's the model, not the node. Smaller Ollama models default to safe, boring language; a larger instruction-tuned model - or a higher prompt_temperature - is the fix.
  • It's slow. Every run is at least one Ollama call, usually three to five. It's a local LLM doing writing, not a hash function.

Treat the prompts as starting points - the author's own note says they'll need refinement for production use. That's honest, and it's the right expectation to bring.

Categoryaudio/analysis

Inputs (16)

NameTypeDefaultDescription
audioAUDIO
ollama_urlSTRINGhttp://localhost:11434/api/generate
modelSTRINGqwen3:14b
analysis_temperatureFLOAT0.40–1.5
prompt_temperatureFLOAT0.80–1.5
custom_contextSTRINGAnalyze the music as pure sound, not lyrics. Translate sonic qualities into emotional visual direction.
lyrics_or_textSTRING
focus_fragmentSTRING
song_titleSTRING
song_descriptionSTRING
song_genreSTRING
style_presetCOMBOpainterly5 options: painterly, cinematic, raw, abstract, custom
style_notesSTRING
generate_environment_promptBOOLEANtrue
generate_subject_promptBOOLEANtrue
generate_merge_promptBOOLEANtrue

Outputs (6)

NameTypeDescription
mood_jsonSTRING
subject_jsonSTRING
environment_promptSTRING
subject_promptSTRING
merge_promptSTRING
summarySTRING