Music discovery features in WordPress or WooCommerce almost always start from metadata. Filter by genre, sort by BPM, bolt on some “customers also bought” logic. It holds up for a while, but none of those fields describe what a track actually sounds like. That is why a “Discover” page built this way reads like a random shuffle rather than something driven by Audio Embeddings.
The big streaming services did not fix this by hiring more librarians. They fixed it by treating audio as a visual problem, running Convolutional Neural Networks (CNNs) over it to produce Audio Embeddings: high-dimensional vectors that encode timbre, rhythm and production style.
Mel-spectrograms: sound as an image
A network cannot work on an MP3 directly. Raw audio is messy time-series data, so it gets converted into a Mel-spectrogram first. The result behaves a bit like a thermal camera for sound: time on the x-axis, frequency on the y-axis scaled to how people actually hear, and color intensity standing in for energy.
Once it is an image, the CNN does the thing it is good at and finds patterns. A sharp vertical line is a snare hit. A horizontal band is a sustained vocal note. Feed it enough of these and the model builds up Audio Embeddings without ever reading an ID3 tag.
How contrastive learning shapes audio embeddings
The part that trips people up is that the model learns without labels. Nobody tells it “this is Jazz” or “this is Lo-fi.” Training uses contrastive learning, with InfoNCE loss doing the work.
You take one song, make two slightly different views of it by adding a little noise, then tell the model those two belong close together in the embedding space while everything else in the batch belongs far away. The network learns to ignore the noise and hold on to the musical texture.
/**
* Naive implementation of a similarity check.
* In a real production environment, you wouldn't run
* the inference in PHP. You'd hit an external API.
*/
function bbioon_check_audio_similarity( $embedding_a, $embedding_b ) {
$dot_product = 0;
foreach ( $embedding_a as $i => $val ) {
$dot_product += $val * $embedding_b[$i];
}
return $dot_product; // Returns cosine similarity for normalized vectors
}
Where this should run, and where it should not
I have watched several developers try to shove a Python model into a WordPress plugin. Do not. The PHP worker times out before the Mel-spectrogram has even finished generating. A music recommender for a client needs to be decoupled: a microservice on AWS Lambda runs the inference and hands the Audio Embeddings back to WordPress over a REST API.
If you want those relationships visible on the front end, tying some Ambient Animation to the similarity scores works well. It gives the user something to read instead of a black box.
Checking the geometry with PCA and t-SNE
Judging whether your Audio Embeddings are any good means reducing the dimensions and looking at the result. PCA (Principal Component Analysis) shows you whether the global structure holds together, so you can confirm the heavy metal is not sitting on top of the lullabies. t-SNE is better for local clusters, where you find out which specific tracks the model thinks are twins.
A PCA plot that comes out as one big blob usually means the model has not learned enough features. That is the cue to rework your convolution layers or raise the batch size so the gradient updates settle down.
If this audio embeddings work is eating your dev hours, I can take it on. I have been working with WordPress since the 4.x days.
Hybrids beat either half alone
The systems that hold up are hybrids rather than pure AI. Use Audio Embeddings to find tracks that sound alike, then layer collaborative filtering on top so you keep the signal from what other listeners actually played. Sound plus behavior gets closer to a listener’s own pick than either input does by itself.