UNPKG

maia-markov

Version:

Markov analysis and generation functions supporting various applications by Music Artificial Intelligence Algorithms, Inc.

117 lines (106 loc) 3.66 kB
// Copyright Tom Collins, 3.3.2020 // Generating chords excerpts in 4-4 time for AI Eurovision 2020 project. // Individual user paths. const mainPaths = { "tom": { "stm": __dirname + "/stm/aiev2020_data_chords.js", "initial": __dirname + "/stm/aiev2020_data_chords_initial.js", "outputDir": __dirname + "/out/aiev_data_chords/" }, "anotherUser": { "stm": "", "initial": "", "outputDir": "" } } // Requires. const fs = require("fs") const sr = require('seed-random') const { Midi } = require('@tonejs/midi') const gn = require("./generate") // Set up parameters. let seeds = ["Alligator", "Armadillo", "Bee", "Butterfly", "Cat", "Chameleon", "Dove", "Dragonfly", "Elephant", "Firefly", "Gopher", "Hippopotamus", "Hummingbird", "Iguana", "Jay", "Leopard", "Lion", "Lynx", "Magpie", "Mosquito", "Nightingale", "Orangutan", "Orca", "Peacock", "Slug", "Tiger", "Toad", "Tortoise", "Whale", "Zebra"] let param = { "stateType": "beat_rel_sq_MNN_state", "pointReconstruction": "rel_sq_MNN", "timeSignatures": [ {"barNo": 1, "topNo": 4, "bottomNo": 4, "ontime": 0} ], "stm": null, "initial": null, "nosConsecutives": 4, "ontimeUpperLimit": 16, "squashRangeMidiMorph": [12, 7], "indices": { "ontime": 0, "MNN": 1, "MPN": 2, "duration": 3, "channel": 4, "velocity": 5 }, "randCount": 0 } // Grab user name from command line to set path to data. let nextU = false let pathsEtc; process.argv.forEach(function(arg, ind){ if (arg === "-u"){ nextU = true } else if (nextU){ pathsEtc = mainPaths[arg] nextU = false } }) // fs.mkdir(outdir); const stmStr = fs.readFileSync(pathsEtc.stm); param.stm = JSON.parse(stmStr); const initialStr = fs.readFileSync(pathsEtc.initial); param.initial = JSON.parse(initialStr); // console.log("stm:", stm) // Seed random number generation. // sr('christianeriksen', {global: true}); // Overrides global Math.random. // var numA = Math.random(); // console.log(numA); // sr.resetGlobal();// Reset to default Math.random. seeds.map(function(seed){ // Seed random number generation. sr(seed, {global: true}) // Reset randCount, then generate states and points. param.randCount = 0 console.log("randCount before get_abs_suggestion:", param.randCount) var gendOutput = gn.get_suggestion(param) console.log("randCount after get_abs_suggestion:", gendOutput.randCount) // console.log("gendOutput.points:", gendOutput.points) // Convert points to a key according to the initial state. gendOutput.points = gendOutput.points.map(function(p){ p[param.indices.MNN] += gendOutput.stateContextPairs[0].context .tonic_pitch_closest[0] //60 p[param.indices.MPN] += gendOutput.stateContextPairs[0].context .tonic_pitch_closest[1] //60 return p }) // Save points as a MIDI file and state-context pairs as a text file. let midi = new Midi() console.log("midi.header:", midi.header) let track = midi.addTrack() gendOutput.points.map(function(p){ track.addNote({ midi: p[param.indices.MNN], time: p[param.indices.ontime], duration: p[param.indices.duration], velocity: p[param.indices.velocity] }) }) fs.writeFileSync( pathsEtc.outputDir + "chords_" + seed + ".mid", new Buffer(midi.toArray()) ) // track.notes = track.notes.map(function(n){ // n.time *= 0.5 // n.duration *= 0.5 // return n // }) // fs.writeFileSync( // pathsEtc.outputDir + "chords_" + seed + "_ableton.mid", // new Buffer(midi.toArray()) // ) fs.writeFileSync( pathsEtc.outputDir + "chords_" + seed + ".txt", JSON.stringify(gendOutput.stateContextPairs, null, 2) ) })