Spaces:
Runtime error
Runtime error
File size: 5,145 Bytes
fde0931 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Magenta.js Model Loader and Player</title>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@4.11.0"></script>
<script src="https://cdn.jsdelivr.net/npm/@magenta/music"></script>
</head>
<body>
<button onclick="generateAndPlayMusic()">Generate and Play Music</button>
<script>
class MSEWithPositivePressure extends tf.layers.Layer {
constructor() {
super({});
}
call(inputs) {
let y_true = inputs[0];
let y_pred = inputs[1];
let mse = tf.mean(tf.square(tf.sub(y_true, y_pred)));
let positive_pressure = tf.mean(tf.maximum(tf.scalar(0), tf.neg(y_pred)));
return tf.add(mse, positive_pressure);
}
static get className() {
return 'MSEWithPositivePressure';
}
}
// tf.serialization.registerClass(MSEWithPositivePressure);
let model;
async function loadModel() {
tf.serialization.registerClass(MSEWithPositivePressure);
// model = await tf.loadLayersModel('/js_model/model.json');
model = await tf.loadGraphModel('/js_model/model.json');
console.log("Model loaded successfully!");
}
async function generateAndPlayMusic() {
if (!model) {
await loadModel();
}
let inputValues = [60, 0.5, 0.5, 62, 0.5, 0.5, 64, 0.5, 0.5];
let numNotes = inputValues.length / 3;
let inputSequence;
if (numNotes > 25) {
let inputData = new Array(numNotes * 3).fill(0).concat(inputValues);
inputSequence = tf.tensor3d(inputData, [1, numNotes, 3]);
} else {
const padding = new Array((25 - numNotes) * 3).fill(0);
let inputData = padding.concat(inputValues);
inputSequence = tf.tensor3d(inputData, [1, 25, 3]);
}
// inputSequence = inputSequence.bufferSync();
// for (let i = 0; i < inputValues.length; i++) {
// inputSequence.set(inputValues[i], 0, 24 - numNotes + Math.floor(i / 3), i % 3);
// }
// inputSequence = inputSequence.toTensor();
const temperature = 2.0 // 0.5 // 2.0;
const numPredictions = 40; // 120;
let generatedNotes = [];
for (let i = 0; i < numPredictions; i++) {
const predictions = await model.executeAsync(inputSequence);
// const pitchProbs = tf.softmax(predictions[2]);
// const pitch = tf.multinomial(pitchProbs, 1).dataSync()[0];
// const pitchProbs = tf.softmax(predictions[2].dataSync()).div(temperature);
// const pitch = tf.multinomial(pitchProbs, 1).dataSync()[0];
// const pitchLogitsArray = predictions[2].dataSync();
const pitchLogitsArray = predictions[2].dataSync().map(value => value / temperature);
// const pitchLogitsTensor = tf.tensor(pitchLogitsArray).div(temperature);
// const pitchProbs = tf.softmax(pitchLogitsTensor);
const pitchProbs = tf.softmax(pitchLogitsArray);
const pitch = tf.multinomial(pitchProbs, 1).dataSync()[0];
const clippedPitch = Math.min(Math.max(pitch, 21), 108);
const step = Math.max(0, predictions[1].dataSync()[0]);
const duration = Math.max(0, predictions[0].dataSync()[0]);
// console.log('///////////////////')
// console.log(predictions[0].dataSync(),predictions[1].dataSync(),predictions[2].dataSync())
// console.log('/////////////////// //')
// console.log({predictions, pitch, step, duration})
console.log('pitch:', pitch, {pitchLogitsArray, pitchProbs})
generatedNotes.push([clippedPitch, step, duration]);
// 新しいノートを生成
const newNote = tf.tensor3d([[[clippedPitch * 1.0, step, duration]]], [1, 1, 3]);
// 入力シーケンスに新しいノートを追加
inputSequence = inputSequence.slice([0, 1, 0], [-1, -1, -1]).concat(newNote, 1);
}
// 生成されたノートをNoteSequenceに変換
const noteSequence = {
ticksPerQuarter: 220,
totalTime: generatedNotes.length / 2,
timeSignatures: [{ time: 0, numerator: 4, denominator: 4 }],
tempos: [{ time: 0, qpm: 120 }],
notes: generatedNotes.map((note, index) => ({
startTime: index / 2,
endTime: (index + 1) / 2,
pitch: note[0],
velocity: 80
}))
};
// // NoteSequenceを再生する
// const player = new mm.Player();
// player.start(noteSequence);
// Play the note sequence using SoundFontPlayer
const soundfontURL = 'https://storage.googleapis.com/magentadata/js/soundfonts/sgm_plus';
const player = new mm.SoundFontPlayer(soundfontURL);
player.start(noteSequence);
}
</script>
</body>
</html>
|