/* * asap2wav.ppjs - converter of ASAP-supported formats to WAV files * * Copyright (C) 2009 Piotr Fusik * * This file is part of ASAP (Another Slight Atari Player), * see http://asap.sourceforge.net * * ASAP is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2 of the License, * or (at your option) any later version. * * ASAP is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ASAP; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "asap.ppjs" var BinaryFile_cp437ToUnicode = [ 199, 252, 233, 226, 228, 224, 229, 231, 234, 235, 232, 239, 238, 236, 196, 197, 201, 230, 198, 244, 246, 242, 251, 249, 255, 214, 220, 162, 163, 165, 8359, 402, 225, 237, 243, 250, 241, 209, 170, 186, 191, 8976, 172, 189, 188, 161, 171, 187, 9617, 9618, 9619, 9474, 9508, 9569, 9570, 9558, 9557, 9571, 9553, 9559, 9565, 9564, 9563, 9488, 9492, 9524, 9516, 9500, 9472, 9532, 9566, 9567, 9562, 9556, 9577, 9574, 9568, 9552, 9580, 9575, 9576, 9572, 9573, 9561, 9560, 9554, 9555, 9579, 9578, 9496, 9484, 9608, 9604, 9612, 9616, 9600, 945, 223, 915, 960, 931, 963, 181, 964, 934, 920, 937, 948, 8734, 966, 949, 8745, 8801, 177, 8805, 8804, 8992, 8993, 247, 8776, 176, 8729, 183, 8730, 8319, 178, 9632, 160 ]; var BinaryFile_unicodeToCp437 = new Array(9633); for (var c = 0; c < 128; c++) { BinaryFile_unicodeToCp437[c] = c; BinaryFile_unicodeToCp437[BinaryFile_cp437ToUnicode[c]] = 128 + c; } function BinaryFile(filename) { this.filename = filename; this.stream = WScript.CreateObject("ADODB.Stream"); this.stream.Type = 2; this.stream.CharSet = '437'; this.stream.Open(); this.readAll = function() { this.stream.LoadFromFile(this.filename); var unicode = this.stream.ReadText(); this.stream.Close(); var bytes = new Array(unicode.length); for (var i = 0; i < unicode.length; i++) { var c = unicode.charCodeAt(i); bytes[i] = BinaryFile_unicodeToCp437[c]; } return bytes; } this.write = function(bytes, len) { for (var i = 0; i < len; i++) { var c = bytes[i]; if (c >= 128) c = BinaryFile_cp437ToUnicode[c - 128]; this.stream.WriteText(String.fromCharCode(c)); } } this.save = function() { this.stream.SaveToFile(filename, 2); this.stream.Close(); } } var outputFilename = null; var outputHeader = true; var song = -1; var format = ASAP_SampleFormat.S16LE; var duration = -1; var muteMask = 0; function printHelp() { WScript.Echo( "Usage: cscript asap2wav.js [OPTIONS] INPUTFILE...\n" + #ifdef ASAP_ONLY_SAP "INPUTFILEs must be in the SAP format.\n" + #else "Each INPUTFILE must be in a supported format:\n" + "SAP, CMC, CM3, CMR, CMS, DMC, DLT, MPT, MPD, RMT, TMC, TM8 or TM2.\n" + #endif "Options:\n" + "-o FILE --output=FILE Set output file name\n" + "-s SONG --song=SONG Select subsong number (zero-based)\n" + "-t TIME --time=TIME Set output length (MM:SS format)\n" + "-b --byte-samples Output 8-bit samples\n" + "-w --word-samples Output 16-bit samples (default)\n" + " --raw Output raw audio (no WAV header)\n" + "-m CHANNELS --mute=CHANNELS Mute POKEY channels (1-8)\n" + "-h --help Display this information\n" + "-v --version Display version information" ); } function setSong(s) { song = parseInt(s, 10); } function setTime(s) { duration = ASAP_ParseDuration(s); } function setMuteMask(s) { muteMask = 0; for (var i = 0; i < s.length; i++) { var ch = s.charCodeAt(i) - 49; if (ch >= 0 && ch < 8) muteMask |= 1 << ch; } } function processFile(inputFilename) { var module = new BinaryFile(inputFilename).readAll(); var asap = new ASAP(); asap.load(inputFilename, module); var moduleInfo = asap.getModuleInfo(); if (song < 0) song = moduleInfo.default_song; if (duration < 0) { duration = moduleInfo.durations[song]; if (duration < 0) duration = 180 * 1000; } asap.playSong(song, duration); asap.mutePokeyChannels(muteMask); if (outputFilename == null) { var i = inputFilename.lastIndexOf("."); outputFilename = inputFilename.substring(0, i + 1) + (outputHeader ? "wav" : "raw"); } var of = new BinaryFile(outputFilename); var buffer = new Array(8192); if (outputHeader) { asap.getWavHeader(buffer, format); of.write(buffer, ASAP_WAV_HEADER_BYTES); } var nBytes; do { nBytes = asap.generate(buffer, 0, 8192, format); of.write(buffer, nBytes); } while (nBytes == 8192); of.save(); outputFilename = null; song = -1; duration = -1; } var noInputFiles = true; var args = WScript.Arguments; for (var i = 0; i < args.length; i++) { var arg = args(i); if (arg.charAt(0) != "-") { processFile(arg); noInputFiles = false; } else if (arg == "-o") outputFilename = args(++i); else if (arg.substring(0, 9) == "--output=") outputFilename = arg.substring(9, arg.length); else if (arg == "-s") setSong(args(++i)); else if (arg.substring(0, 7) == "--song=") setSong(arg.substring(7, arg.length)); else if (arg == "-t") setTime(args(++i)); else if (arg.substring(0, 7) == "--time=") setTime(arg.substring(7, arg.length)); else if (arg == "-b" || arg == "--byte-samples") format = ASAP_SampleFormat.U8; else if (arg == "-w" || arg == "--word-samples") format = ASAP_SampleFormat.S16_LE; else if (arg == "--raw") outputHeader = false; else if (arg == "-m") setMuteMask(args(++i)); else if (arg.substring(0, 7) == "--mute=") setMuteMask(arg.substring(7, arg.length)); else if (arg == "-h" || arg == "--help") { printHelp(); noInputFiles = false; } else if (arg == "-v" || arg == "--version") { WScript.Echo("ASAP2WAV (JScript) " + ASAP_VERSION); noInputFiles = false; } else throw "unknown option: " + arg; } if (noInputFiles) { printHelp(); WScript.Quit(1); }