Tutorial: Converting a Standard Song to Infinite Stream

In this tutorial, we are going to take a 3 minute J.S Bach piano fugue and convert it into a Celody infinite music stream. If you're unfamiliar with how Celody works, see here for the basics and here for the documentation.

Celody Services:

Celody offers two paid services for "song to infinite stream" conversion (SEE SUBMIT). You can upload a song and Celody will convert it and then host the stream for you. This is the full service option. Or you can convert the song yourself and Celody will just host the stream. This is the self service option. Note that it's always possible to self-host and convert the music yourself. Celody is MIT licensed open source software.

Starting Song - Not Infinite, Not Random:

The song we are converting has a waveform shown below. It's only a single instrument (piano) which will make this tutorial easy to explain. You can build complexity if your song has more instruments and if you have access to individual tracks. You'll just need to extrapolate the logic.

Starting Song

Breaking into Parts:

The first step is to split the song into parts. Each of these parts acts as a separate unit for Celody to apply its magic. So the bigger the part size (like choosing an entire verse vs. choosing a single note), the less fine-tuned control you have. Think of the part size like a shell that prevents randomness from entering.

Breaking Parts

Time stretching:

Now that we have our parts, we start the grouping process. We can group parts together so that Celody can randomly choose a part from within a group. In order to make this swapping process smooth, we time stretch similar parts to the same length.

Breaking Parts

Fading Parts:

We are going to be randomly swapping parts into the stream during the generation process. When Celody randomly chooses a part to play, we want the transition to be smooth. So we next add fade-ins and fade-outs. This will make the stream seamless.

Breaking Parts

Grouping Parts:

We've now got a bunch of time-stretched, faded parts. It's time to set up the loop using groups. We'll create 2 main tracks for Celody. At any point in the stream, Celody will choose to play either a part from Track 1 or Track 2. Other effects get added to the selected part per the stream file (discussed below).

Breaking Parts

Connecting Parts:

We have a basic version of the Celody loop setup, but we still need to make sure the transitions are smooth. So for each transition point, we carefully determine the best starting point for each part. To make this clear, we split Track 1 and Track 2 into subcomponents. Most of the time there will be a slight overlap between two parts.

Connecting Parts

Base Start:

Once we have the positions of the parts in place, we can translate it to the "base start" parameter. This is used in the stream file (discussed next). The base start is calculated by dividing the starting bar position by the total bars. It's just a percentage of where to start the part in the loop.

Base Start

Stream File:

Next we create the stream file that contains the generator settings and sound parts. The key field to highlight is "variety". We are setting "variety" to 0 to prevent multiple parts from playing at the same time. This may be an effect you are after, but for this tutorial we are staying non-experimental.

{ "streamId": "", "streamName": "Bach Fugue", "artist": "J.S. Bach", "createDate": "06-11-2019", "tokens": ["IOTA"], "tokenAddresses": ["DET9OJE9SV9Q9MCUJSSDVCUWPTIOJWLKILMWCQMLUSHZNWTSB9LIJYKLTCKWXJLBHCVCPEFAGETJDFFTDWLZJKKVOD"], "playSpeed": 1.0, "module": "core", "tempo": 120, "beatsPerBar": 4, "bars": 84, "baseUnit": 128, "backgroundLevel": 0.2, "dynamics": 0.05, "density": 1.0, "variety": 0.0, "spread": 0.35, "spice": 0.1, "instruments": { "0": [ { "instrument": "piano", "type": ["primary","1"], "color": "rgb(55,132,203)", "fileSource": [ "https://celody.com/sounds/bach/c1.mp3","https://celody.com/sounds/bach/c2.mp3","https://celody.com/sounds/bach/c3.mp3","https://celody.com/sounds/bach/c4.mp3","https://celody.com/sounds/bach/c5.mp3","https://celody.com/sounds/bach/c6.mp3","https://celody.com/sounds/bach/c7.mp3","https://celody.com/sounds/bach/c8.mp3","https://celody.com/sounds/bach/c9.mp3","https://celody.com/sounds/bach/c10.mp3","https://celody.com/sounds/bach/c11.mp3","https://celody.com/sounds/bach/c12.mp3","https://celody.com/sounds/bach/c13.mp3","https://celody.com/sounds/bach/c14.mp3","https://celody.com/sounds/bach/c15.mp3","https://celody.com/sounds/bach/c16.mp3","https://celody.com/sounds/bach/c17.mp3","https://celody.com/sounds/bach/c18.mp3","https://celody.com/sounds/bach/c19.mp3","https://celody.com/sounds/bach/c20.mp3","https://celody.com/sounds/bach/c21.mp3","https://celody.com/sounds/bach/c8a.mp3"], "basePhrase": [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21], "baseStart": [0.001,0.0299,0.0578,0.0874,0.1150,0.1428,0.1727,0.2007,0.2586,0.3160,0.3738,0.4014,0.4863,0.5439,0.6012,0.6286,0.6862,0.7136,0.7699,0.8269,0.8840,0.9395], "volumeStart": [0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8], "fxFla": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], "fxLow": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], "fxAtt": [0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4], "fxRel": [0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5], "fxPan": [0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3] } ], "1": [ { "instrument": "piano", "type": ["secondary"], "color": "rgb(25,132,203)", "fileSource": [ "https://celody.com/sounds/bach/c1.mp3","https://celody.com/sounds/bach/c1.mp3","https://celody.com/sounds/bach/c3.mp3","https://celody.com/sounds/bach/c2.mp3","https://celody.com/sounds/bach/c4.mp3","https://celody.com/sounds/bach/c5.mp3","https://celody.com/sounds/bach/c7.mp3","https://celody.com/sounds/bach/c8.mp3","https://celody.com/sounds/bach/c9.mp3","https://celody.com/sounds/bach/c9.mp3","https://celody.com/sounds/bach/c11.mp3","https://celody.com/sounds/bach/c12.mp3","https://celody.com/sounds/bach/c14.mp3","https://celody.com/sounds/bach/c14.mp3","https://celody.com/sounds/bach/c17.mp3","https://celody.com/sounds/bach/c16.mp3","https://celody.com/sounds/bach/c17.mp3","https://celody.com/sounds/bach/c16.mp3","https://celody.com/sounds/bach/c19.mp3","https://celody.com/sounds/bach/c20.mp3","https://celody.com/sounds/bach/c21.mp3","https://celody.com/sounds/bach/c22a.mp3"], "basePhrase": [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21], "baseStart": [0.001,0.0299,0.0578,0.0875,0.1149,0.1427,0.1727,0.2007,0.2586,0.3160,0.3738,0.4014,0.4863,0.5439,0.6012,0.6286,0.6862,0.7136,0.7699,0.8269,0.8840,0.9395], "volumeStart": [0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8], "fxFla": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], "fxLow": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], "fxAtt": [0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4,0.4], "fxRel": [0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5], "fxPan": [0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7] } ] } }

Final Stream:

Once we have the stream file and all the sound files hosted on a webserver, the infinite stream is ready to play. You can hear the Bach infinite stream on celody.com. Just search for "Bach Fugue" in the search box on the homepage. It will sound different on every listen and generate forever.