create a musical melody generator banner

How to create a musical melody generator using HTML, CSS and JavaScript

Do you love music and want to make your own songs? Do you want to learn how to use artificial intelligence (AI) to create melodies that sound amazing and unique? If so, this tutorial is for you!

Introduction

In this tutorial, you will learn how to create a web app that can generate musical melodies using generative AI. Generative AI is a branch of artificial intelligence that can create new content, such as images, text, music, etc., based on some input or parameters. You will use the Web Audio API, which is a JavaScript interface that allows you to manipulate and process audio in the browser. You will also use some HTML and CSS to create a simple user interface for your web app.

What you will need

To follow this tutorial, you will need:

  • A text editor, such as Visual Studio Code, Atom, or Sublime Text
  • A web browser, such as Chrome, Firefox, or Safari
  • A basic knowledge of HTML, CSS and JavaScript

Before we get into it, here's a preview of how our musical melody generator will look:

screenshot of the melody generator

...and now for the fun part.

Step 1: Create the HTML file

First, create a new folder for your project and name it melody-generator. Inside this folder, create a new file and name it index.html. This will be the main HTML file for your app. Open this file in your text editor and add the following code:

HTML
                        
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Melody Generator</title>
    <!-- Link to the CSS file -->
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <h1>Melody Generator</h1>
    <p>This app can generate musical melodies
using generative AI and the Web Audio API.</p>
    <!-- Create a form to get the user input -->
    <form id="melody-form">
        <label for="scale">Scale:</label>
        <select id="scale" name="scale">
            <option value="major">Major</option>
            <option value="minor">Minor</option>
            <option value="pentatonic">Pentatonic</option>
            <option value="blues">Blues</option>
        </select>
        <label id="tempo-label" for="tempo">Tempo:</label>
        <input id="tempo" name="tempo" type="range" min="60" max="180" value="120">
        <label id="length-label" for="length">Length:</label>
        <input id="length" name="length" type="range" min="4" max="16" value="8">
        <button id="generate-button" type="button">Generate</button>
    </form>
    <!-- Create a div to display the generated melody -->
    <div id="melody-display"></div>
    <!-- Link to the JavaScript file -->
    <script src="script.js"></script>
</body>
</html>

This code creates a basic HTML structure for your app, with a title, a paragraph, a form, and a div. The form contains three inputs: a select for the scale, a number for the tempo, and a number for the length.

  • Scale: The scale is the set of notes that the melody will use.
  • Tempo: The tempo is the speed of the melody in beats per minute.
  • Length: The length is the number of notes in the melody.

The form also has a button to generate the melody. The div will be used to display the generated melody as text and play it as audio. The code also links to two external files: a CSS file for the style and a JavaScript file for the logic.

Step 2: Create the CSS file

Next, create a new file in the same folder and name it style.css. This will be the CSS file for your app. Open this file in your text editor and add the following code:

CSS
                        
/* Set the font family and size for the whole document */
* {
  box-sizing: border-box;
  font-family: Arial, sans-serif;
}

body {
  background-color: #f0f0f0;
}

/* Center the title and the paragraph */
h1, p {
  text-align: center;
}

/* Style the form */
#melody-form {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  margin: 10px;
}

/* Style the labels and the inputs */
label {
  font-weight: bold;
  margin: 16px 5px 5px 5px;
  width: 150px;
}

input, select {
  margin: 5px;
  width: 150px;
  width: 150px;
  height: 30px;
  border: 2px solid #4a47a3;
  border-radius: 5px;
  outline: none;
  padding: 5px;
}

/* Style the button */
#generate-button {
  margin: 16px;
  padding: 10px;
  width: 150px;
  background-color: #4a47a3;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}

/* Style the div */
#melody-display {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 20px;
}

This code adds some basic style to your app, such as the font, the colors, the margins, and the alignment. You can modify this code as you like to customize the appearance of your app.

Our melody generator will look like this on smaller screens:

melody generator on small screen

Step 3: Create the JavaScript file

Finally, create a new file in the same folder and name it script.js. This will be the JavaScript file for your app. Open this file in your text editor and add the following code:

JAVASCRIPT
                        
// Get the elements from the HTML file
const scaleSelect = document.getElementById("scale");
const tempoInput = document.getElementById("tempo");
const lengthInput = document.getElementById("length");
const generateButton = document.getElementById("generate-button");
const melodyDisplay = document.getElementById("melody-display");
const tempoLabel = document.getElementById("tempo-label");
const lengthLabel = document.getElementById("length-label");

// Set the initial values for the range sliders
tempoLabel.innerHTML = "Tempo: " + tempoInput.value;
lengthLabel.innerHTML = "Length: " + lengthInput.value;

// Define some constants for the notes and the frequencies
const NOTES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
const FREQUENCIES = [261.63, 277.18, 293.66, 311.13, 329.63, 349.23, 369.99, 392.00, 415.30, 440.00, 466.16, 493.88];

// Define some constants for the scales and the intervals
const SCALES = {
  major: [0, 2, 4, 5, 7, 9, 11],
  minor: [0, 2, 3, 5, 7, 8, 10],
  pentatonic: [0, 2, 4, 7, 9],
  blues: [0, 3, 5, 6, 7, 10]
};

// Define a constant for the duration of each note in seconds
const DURATION = 0.5;

// Create a new AudioContext object to use the Web Audio API
const audioContext = new AudioContext();

// Define a function to generate a random integer between a min and a max value
function randomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1) + min);
}

// Define a function to generate a random melody based on the user input
function generateMelody() {
  // Get the user input from the form
  const scale = scaleSelect.value;
  const tempo = tempoInput.value;
  const length = lengthInput.value;

  // Initialize an empty array to store the melody
  const melody = [];

  // Loop for the number of notes in the melody
  for (let i = 0; i < length; i++) {
    // Generate a random index from the scale
    const index = randomInt(0, SCALES[scale].length - 1);

    // Get the note and the frequency from the index
    const note = NOTES[SCALES[scale][index]];
    const frequency = FREQUENCIES[SCALES[scale][index]];

    // Push the note and the frequency to the melody array
    melody.push({note, frequency});
  }

  // Return the melody array
  return melody;
}

// Define a function to display the melody as text and play it as audio
function displayMelody(melody) {
  // Initialize an empty string to store the melody as text
  let melodyText = "";

  // Loop through the melody array
  for (let i = 0; i < melody.length; i++) {
    // Get the note and the frequency from the array
    const note = melody[i].note;
    const frequency = melody[i].frequency;

    // Append the note to the melody text
    melodyText += note + " ";

    // Create a new OscillatorNode object to generate a sound wave
    const oscillator = audioContext.createOscillator();

    // Set the type and the frequency of the oscillator
    oscillator.type = "sine";
    oscillator.frequency.value = frequency;

    // Connect the oscillator to the destination (the speakers)
    oscillator.connect(audioContext.destination);

    // Start the oscillator at the current time plus the duration times the index
    oscillator.start(audioContext.currentTime + DURATION * i);

    // Stop the oscillator at the current time plus the duration times the index plus one
    oscillator.stop(audioContext.currentTime + DURATION * (i + 1));
  }

  // Set the innerHTML of the melody display element to the melody text
  melodyDisplay.innerHTML = melodyText;
}

// Add an event listener to the generate button to call the generate and display functions
generateButton.addEventListener("click", function() {
  // Generate a random melody
  const melody = generateMelody();

  // Display the melody
  displayMelody(melody);
});

// Add an event listener to the tempo range slider and display the chosen value on the label
tempoInput.addEventListener("change", ()=>{
  tempoLabel.innerHTML = "Tempo: " + tempoInput.value;
});

// Add an event listener to the length slider and display the length of the melody on the label
lengthInput.addEventListener("change", ()=>{
  lengthLabel.innerHTML = "Length: " + lengthInput.value;
});

This code adds the logic to your app, using the Web Audio API and some generative AI techniques. The code first gets the elements from the HTML file and defines some constants for the notes, the frequencies, the scales, and the duration. Then, it defines a function to generate a random melody based on the user input, using a random integer function and an array of intervals for each scale.

Conclusion

In this tutorial, you have learned how to create a musical melody generator using HTML, CSS, and JavaScript. You have used the Web Audio API to manipulate audio in the browser, and you have also explored some aspects of generative AI, such as randomness and creativity. You have also created a simple and responsive user interface for your project using HTML and CSS.

You can further improve your project by adding more features, such as:

  • Allowing the user to choose different types of sounds, such as piano, guitar, or synth.
  • Allowing the user to save, download, or share their melodies.
  • Applying some music theory rules or patterns to generate more harmonious or interesting melodies.

You might also want check out our tutorial on how to create a music player, which focuses more on how to use the audio element to play audio files.

We hope you have enjoyed this tutorial and learned something helpful.