Skip to content

BasKloosterman/midievol-frontend

Repository files navigation

Midievol

Midievol is a generative music application that consists of a frontend (this repository) and a backend (midievol-api-deno). It generates evolving musical ideas based on evolutionary principles. Starting from an initial melody, the system creates new variations using random mutations and selects the best ones using fitness functions—custom scoring mechanisms that evaluate melodies according to user-defined criteria.

The application continuously loops and plays melodies, updating them each iteration with newly generated variations to simulate a never-ending, evolving composition.


How It Works

Each time a new loop begins, the frontend sends the current melody to the backend, which performs the following steps:

  1. Scoring the Melody
    The original melody is evaluated using a set of fitness functions.

  2. Creating Mutations
    A number of "children" melodies are generated by mutating the original. Mutations can occur at both the note level (pitch, position, length, and volume—though volume is currently ignored by the frontend) and the structural level (e.g., duplicating or deleting sections).

  3. Evaluating Children
    Each child melody is scored using the configured fitness functions. The results are combined using weighted averaging—functions with higher weights have more influence on the final score.

  4. Selecting the Best
    The system selects the highest-scoring melody from the pool of children and the original.

This entire process represents one generation. Multiple generations can be run in sequence during a single backend call, allowing the melody to evolve further with each iteration. The final result is returned to the frontend for playback.


Installation & Running the Application

  1. Run the Backend API
    Make sure the midievol-api-deno is running on http://localhost:8000.

  2. Install and Start the Frontend
    Ensure Node.js is installed (download here).

     # Run this once during setup or whenever new dependencies are added
     npm install
    
     # Start the application
     npm start
  3. Open the Application
    Navigate to http://localhost:1234 in your browser.


Main Page Overview

On launch, you'll see the Main Page, which includes:

  • Score Summary: Displays unnormalized scores from each active fitness function, along with a normalized overall score (between -1 and 1).
  • Voice Range Controls: Two rotary knobs to control three voices—bass, mid, and melody:
    • Max Bass: Sets the upper limit for the bass voice and lower limit for mid.
    • Min Melody: Sets the upper limit for mid and lower limit for melody.
  • Visualization Visualization of the output sent to the MIDI output selected in the Visualisation output select on the Details page

Details Page

Accessed via the gear icon on the Main Page, the Details Page offers fine-grained controls.

Top Section

  • Configure output MIDI device.
  • Set number of children per generation.
  • Set number of generations per evolution cycle.

Second Section

  • Save/load settings and melodies.
  • View melody stats: note count, length (in quarter notes), and score.

Third Section

  • Adjust BPM (tempo).
  • Voice range controls (same as Main Page).

Fitness Function Configuration

  • Assign weights to fitness functions.
  • Choose which voices each function evaluates (bass, mid, melody), represented by 3 checkboxes.
  • Modify each function’s custom parameters.

Historical Performance

  • Visual graphs showing how each fitness function scored melodies across previous generations.

Use the home icon to return to the Main Page.


Fitness Functions

In the backend, fitness functions are called ScoringsFunction; in the frontend, they’re referred to as ModFunc. They have the following signature:

// Actual Note implementation has some methods not relevant for fitness functions
interface Note {
  pitch: number;
  length: number;
  volume: number;
  position: number;
}

export type ParamType = "note" | "float" | "int";
export interface Param {
  name: string;
  value: number;
  range: [number, number]; // min and max setting for this param
  type: ParamType; // Used for display in frontend
}

interface ScoringsFunctionArgs {
  melody: Note[];
  params: Param[];
  voiceSplits: { min: number; max: number };
  voices: [boolean, boolean, boolean];
}

export type score = number | null;
export type ScoringsFunction = (args: ScoringsFunctionArgs) => score;

Each function receives:

  • The melody to evaluate.
  • Voice range splits and selected voices.
  • An array of parameters (unique per function).

Functions return either a number (the score) or null if the melody is not scorable. null values are ignored during score aggregation.


Audio Output

The frontend only produces MIDI output. To hear the results, connect virtual or physical instruments:

  • Set your MIDI output in the Details Page (Output selector).
  • The application sends MIDI on channels 1, 2, and 3, corresponding to the three voices.

Suggested Tools

  • Virtual Synth: OB-Xd (free)
  • DAW: Reaper – (free) great for routing and managing multiple instruments

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages