Last active
November 21, 2019 13:48
-
-
Save oleics/a4569a39009257a9afbeb26c17c72080 to your computer and use it in GitHub Desktop.
Merge multiple Deluge (Synthstrom) songs into one single song
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div> | |
Deluge Song Merger | |
<div v-if="state.error"> | |
{{state.error}} | |
</div> | |
<div> | |
Song Files (eg SONG000.XML and SONG001.XML) | |
<input type="file" name="files[]" multiple @change="onFileSelect"> | |
</div> | |
<div v-if="state.files.length > 1"> | |
<div v-for="file in state.files"> | |
{{file.name}} | |
{{file.size}} | |
{{file.type}} | |
</div> | |
</div> | |
<div> | |
Merge into (eg SONG000.XML or SONG001.XML) | |
<input type="file" name="mergeinto" @change="onMergeintoSelect"> | |
</div> | |
<button @click="mergeFiles">mergeFiles</button> | |
<div v-if="state.output"> | |
<a :href="state.outputDataURL" :download="state.outputFilename">save to disk</a> | |
<textarea class="small w-100" style="min-height:9rem">{{state.output}}</textarea> | |
</div> | |
<div class="text-muted"> | |
* Works only for files written by firmware 3.0.0 or above | |
* Modern browsers required | |
</div> | |
</div> | |
</template> | |
<script> | |
module.exports = { | |
name: 'deluge-song-merger', | |
data: function() { | |
return { | |
state: { | |
files: [], | |
mergeInto: null, | |
error: null, | |
output: null, | |
outputDataURL: null, | |
outputFilename: null | |
} | |
}; | |
}, | |
methods: { | |
onMergeintoSelect: function($event) { | |
var file = $event.target.files[0]; | |
this.state.error = null; | |
this.state.mergeInto = null; | |
readAndParseXMLFile(file).then((file) => { | |
this.state.mergeInto = file; | |
}).catch((err) => { | |
console.error(err.stack||err); | |
this.state.error = err; | |
}); | |
}, | |
onFileSelect: function($event) { | |
this.state.error = null; | |
this.state.files.splice(0, this.state.files.length); | |
var files = $event.target.files; | |
var promises = []; | |
for(var i = 0, f; f = files[i]; i++) { | |
promises.push(readAndParseXMLFile(f)); | |
} | |
Promise.all(promises).then((files) => { | |
this.state.files.splice.apply(this.state.files, [0, this.state.files.length].concat(files)); | |
}).catch((err) => { | |
console.error(err.stack||err); | |
this.state.error = err; | |
}); | |
}, | |
mergeFiles: function() { | |
var selectorInstrumentChilds = 'song > instruments > sound, song > instruments > kit'; | |
var selectorInstrumentClips = 'song > sessionClips > instrumentClip'; | |
var selectorSessionClips = 'song > sessionClips'; | |
var selectorInstruments = 'song > instruments'; | |
// collect from state.files | |
var instrumentChilds = []; | |
var instrumentClips = []; | |
var files = this.state.files; | |
for(var i = 0, f; f = files[i]; i++) { | |
instrumentChilds.push.apply(instrumentChilds, f.doc.querySelectorAll(selectorInstrumentChilds)); | |
instrumentClips.push.apply(instrumentClips, f.doc.querySelectorAll(selectorInstrumentClips)); | |
} | |
var mergeInto = this.state.mergeInto.doc; | |
var instruments = mergeInto.querySelector(selectorInstruments); | |
var sessionClips = mergeInto.querySelector(selectorSessionClips); | |
while(instruments.childNodes.length) { | |
instruments.removeChild(instruments.firstChild); | |
} | |
while(sessionClips.childNodes.length) { | |
sessionClips.removeChild(sessionClips.firstChild); | |
} | |
for(var i = 0, len = instrumentChilds.length; i < len; i++) { | |
instruments.appendChild(instrumentChilds[i]); | |
} | |
for(var i = 0, len = instrumentClips.length; i < len; i++) { | |
sessionClips.appendChild(instrumentClips[i]); | |
} | |
// Serialize into XML string | |
var serializer = new XMLSerializer(); | |
var output = serializer.serializeToString(mergeInto); | |
this.state.output = output; | |
this.state.outputDataURL = 'data:text/xml;charset=utf-8,' + encodeURIComponent(output); | |
this.state.outputFilename = 'SONG.XML'; | |
}, | |
} | |
} | |
function readAndParseXMLFile(theFile) { | |
return new Promise(function(resolve, reject) { | |
var reader = new FileReader(); | |
reader.onload = (e) => { | |
var content = e.target.result; | |
var parser = new DOMParser(); | |
try { // dunno if this actually throws | |
var doc = parser.parseFromString(content, 'text/xml'); | |
} catch(ex) { | |
return reject(ex); | |
} | |
resolve({ | |
name: theFile.name, | |
size: theFile.size, | |
type: theFile.type, | |
doc: doc, | |
}); | |
}; | |
reader.readAsText(theFile); | |
}); | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Moved to https://github.com/oleics/deluge-song-merger