parent
98a235e0f4
commit
80760bc534
|
@ -161,24 +161,37 @@ public class AudioExtractor {
|
||||||
if(args.length == 0) { // no arguments provided
|
if(args.length == 0) { // no arguments provided
|
||||||
|
|
||||||
switch(operation) {
|
switch(operation) {
|
||||||
case "identify":
|
|
||||||
|
case "identify": {
|
||||||
File unknownFile = retrieveFile(reader, "Please enter the path of a file: " + ANSI_BEIGE);
|
File unknownFile = retrieveFile(reader, "Please enter the path of a file: " + ANSI_BEIGE);
|
||||||
identify(unknownFile);
|
identify(unknownFile);
|
||||||
break;
|
break;
|
||||||
case "extract": // extract
|
}
|
||||||
// Determine package directory
|
|
||||||
File currentDir = new File(new File(AudioExtractor.class.getProtectionDomain().getCodeSource().getLocation().toURI())
|
case "extract": {
|
||||||
.getParent());
|
File packageFile = retrievePackage(reader);
|
||||||
boolean packDirFound = false;
|
if(packageFile.isFile())
|
||||||
do {
|
extract(packageFile);
|
||||||
System.out.println(Ansi.colorize("\nPackage Directory:", Attribute.BOLD(), Attribute.CYAN_TEXT()));
|
else { // packageFile is a folder
|
||||||
System.out.println("- " + Ansi.colorize("Current", Attribute.BRIGHT_RED_TEXT()) + " directory:\t"
|
File[] packages = packageFile.listFiles(new FilenameFilter() {
|
||||||
+ Ansi.colorize(currentDir.getPath(), Attribute.BRIGHT_CYAN_TEXT()));
|
public boolean accept(File dir, String name) {
|
||||||
|
return name.toLowerCase().endsWith(".bin");
|
||||||
} while(!packDirFound);
|
}
|
||||||
|
});
|
||||||
|
for(File pack : packages) {
|
||||||
|
extract(pack);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "package": // pack
|
}
|
||||||
|
|
||||||
|
case "convert": {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
case "package": {// pack
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case "patch": // patch
|
case "patch": // patch
|
||||||
File waveFile = retrieveWave(reader);
|
File waveFile = retrieveWave(reader);
|
||||||
patch(waveFile);
|
patch(waveFile);
|
||||||
|
@ -195,6 +208,9 @@ public class AudioExtractor {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
System.out.println("Press Enter to continue...");
|
||||||
|
try { reader.readLine(); } catch (Exception e) {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +296,281 @@ public class AudioExtractor {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts audio tracks from the given package file.
|
||||||
|
*
|
||||||
|
* @param packageFile
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
*/
|
||||||
|
private static void extract(File packageFile) {
|
||||||
|
|
||||||
|
System.out.println("Name:\t" + packageFile.getName());
|
||||||
|
System.out.println("Size:\t" + packageFile.length() + " (" + convertBytes(packageFile.length()) + ")\n");
|
||||||
|
|
||||||
|
try {
|
||||||
|
RandomAccessFile file = new RandomAccessFile(packageFile, "r");
|
||||||
|
LinkedHashMap<Integer, Integer> tracklist = findAudioTracks(file);
|
||||||
|
|
||||||
|
File dir = new File(packageFile.getAbsoluteFile().getParentFile().toPath() + "/" + FilenameUtils.removeExtension(packageFile.getName()));
|
||||||
|
if(!dir.exists())
|
||||||
|
dir.mkdir();
|
||||||
|
|
||||||
|
System.out.println("Extracting " + tracklist.size() + " tracks...");
|
||||||
|
|
||||||
|
int digits = (int) Math.ceil(Math.log10(tracklist.size() + 1));
|
||||||
|
int extracted = 0;
|
||||||
|
Set<Integer> keys = tracklist.keySet();
|
||||||
|
for(Integer address : keys) {
|
||||||
|
int length = tracklist.get(address);
|
||||||
|
|
||||||
|
if(CMD_MODE)
|
||||||
|
printProgressBar(extracted, keys.size());
|
||||||
|
|
||||||
|
String extension;
|
||||||
|
byte[] bytes = new byte[2];
|
||||||
|
file.seek(address + 0x14);
|
||||||
|
file.read(bytes);
|
||||||
|
int encoding = littleEndianToInt(bytes);
|
||||||
|
switch(encoding) {
|
||||||
|
case 0x0165: extension = "xma"; break;
|
||||||
|
case 0x0001: extension = "wav"; break;
|
||||||
|
default: extension = "bin"; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
File trackFile = new File(dir.toPath() + "/track" + String.format("%0" + digits + "d", extracted + 1) + "." + extension);
|
||||||
|
|
||||||
|
try (
|
||||||
|
FileInputStream in = new FileInputStream(packageFile);
|
||||||
|
FileOutputStream out = new FileOutputStream(trackFile);
|
||||||
|
) {
|
||||||
|
in.skipNBytes(address.intValue());
|
||||||
|
bytes = new byte[length];
|
||||||
|
int readBytes = in.read(bytes);
|
||||||
|
out.write(bytes, 0, readBytes);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
extracted++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(CMD_MODE)
|
||||||
|
printProgressBar(extracted, keys.size());
|
||||||
|
|
||||||
|
} catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Finished.\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void printProgressBar(int current, int total) {
|
||||||
|
int done = 50 * current / total;
|
||||||
|
int todo = 50 - done;
|
||||||
|
String doneStr = ""; // String.format("%" + done + "s", '█');
|
||||||
|
for(int i = 0; i < done; i++)
|
||||||
|
doneStr += '█';
|
||||||
|
String todoStr = ""; // String.format("%" + todo + "s", '_');
|
||||||
|
for(int i = 0; i < todo; i++)
|
||||||
|
doneStr += '_';
|
||||||
|
System.out.println(ANSI_BACKLINE + "Progress: |" + doneStr + todoStr + "| (" + current + "/" + total + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts audio files to the extract directory from package files located at the package directory.
|
||||||
|
* Also supports FLAC conversion for BGM files.
|
||||||
|
*
|
||||||
|
* @param packDirectory
|
||||||
|
* @param extractDirectory
|
||||||
|
* @param compressBGM
|
||||||
|
*/
|
||||||
|
public static void extract(File packDirectory, File extractDirectory, boolean compressBGM) {
|
||||||
|
|
||||||
|
// TODO Delete
|
||||||
|
System.out.println("packDirectory:\t" + packDirectory);
|
||||||
|
System.out.println("extractDirectory:\t" + extractDirectory);
|
||||||
|
|
||||||
|
// Identify target binary files
|
||||||
|
File[] packages = new File(packDirectory.toString()).listFiles(new FilenameFilter() {
|
||||||
|
public boolean accept(File dir, String name) {
|
||||||
|
return name.toLowerCase().endsWith(".bin");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Identify and extract audio within binary files
|
||||||
|
for(int i = 0; i < packages.length; i++) {
|
||||||
|
|
||||||
|
RandomAccessFile source;
|
||||||
|
LinkedHashMap<Integer, Integer> tracklist = null;
|
||||||
|
try {
|
||||||
|
source = new RandomAccessFile(packages[i], "r");
|
||||||
|
tracklist = findAudioTracks(source);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
System.out.println("Binary file:\t" + packages[i] + "\n was not found. File skipped.");
|
||||||
|
continue;
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("Binary file:\t" + packages[i] + "\n could not be read. File skipped.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO Delete
|
||||||
|
System.out.println("packages[" + i + "]:\t" + packages[i]);
|
||||||
|
|
||||||
|
File dir = new File(extractDirectory.getPath() + "/" + FilenameUtils.removeExtension(packages[i].getName()));
|
||||||
|
if(!dir.exists())
|
||||||
|
dir.mkdir();
|
||||||
|
|
||||||
|
// Extract and write WAV files in directory
|
||||||
|
Set<Integer> keys = tracklist.keySet();
|
||||||
|
int track = 1;
|
||||||
|
|
||||||
|
for(Integer key : keys) {
|
||||||
|
|
||||||
|
String name = String.format("track%04d", track);
|
||||||
|
{ // Extract WAV files
|
||||||
|
File wav = null;
|
||||||
|
try {
|
||||||
|
|
||||||
|
// create file for storing WAV data
|
||||||
|
wav = new File(dir.getPath() + "/" + name + ".wav");
|
||||||
|
if(!wav.exists())
|
||||||
|
wav.createNewFile();
|
||||||
|
|
||||||
|
//TODO Delete
|
||||||
|
System.out.println("Saving track " + String.format("%d (@0x%08X)", track, key) + " to " + wav + String.format(" (%d bytes)", tracklist.get(key)));
|
||||||
|
|
||||||
|
// write selection to file
|
||||||
|
try (
|
||||||
|
FileInputStream inStream = new FileInputStream(packages[i]);
|
||||||
|
FileOutputStream outStream = new FileOutputStream(wav)
|
||||||
|
) {
|
||||||
|
inStream.skipNBytes(key.intValue());
|
||||||
|
byte[] trackBytes = new byte[tracklist.get(key)];
|
||||||
|
int readBytes = inStream.read(trackBytes);
|
||||||
|
outStream.write(trackBytes, 0, readBytes);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.exit(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("An error occurred when attempting to write " + name + " to file:\t" + wav);
|
||||||
|
e.printStackTrace();
|
||||||
|
System.exit(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
track++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(compressBGM && packages[i].getName().equals("pack_bgm.bin")) {
|
||||||
|
|
||||||
|
// find WAV files
|
||||||
|
File[] WAV_Files = dir.listFiles(new FilenameFilter() {
|
||||||
|
public boolean accept(File dir, String name) {
|
||||||
|
return name.toLowerCase().endsWith(".wav");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// convert WAV files to FLAC
|
||||||
|
FLAC_FileEncoder ffe = new FLAC_FileEncoder();
|
||||||
|
|
||||||
|
for(File wav : WAV_Files) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
File flac = new File(dir.getPath() + "/" + FilenameUtils.removeExtension(wav.getName()) + ".flac");
|
||||||
|
if(!flac.exists())
|
||||||
|
flac.createNewFile();
|
||||||
|
|
||||||
|
//TODO Delete
|
||||||
|
System.out.println("Compressing WAV to FLAC:\t" + flac);
|
||||||
|
|
||||||
|
ffe.encode(wav, flac);
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("An error occurred when attempting to write file.");
|
||||||
|
e.printStackTrace();
|
||||||
|
System.exit(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.print("Deleting WAV files");
|
||||||
|
// delete WAV files
|
||||||
|
for(File wav : WAV_Files) {
|
||||||
|
boolean deleted = false;
|
||||||
|
while(!deleted) {
|
||||||
|
try {
|
||||||
|
Files.delete(wav.toPath());
|
||||||
|
deleted = true;
|
||||||
|
} catch(Exception e) {
|
||||||
|
System.out.print('.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to prompt user to select a package file, or folder containing one or more packages.
|
||||||
|
*
|
||||||
|
* @param reader
|
||||||
|
* @return file
|
||||||
|
*/
|
||||||
|
private static File retrievePackage(BufferedReader reader) {
|
||||||
|
|
||||||
|
String prompt = "Please enter the path of a package: " + ANSI_BEIGE;
|
||||||
|
|
||||||
|
File packageFile = null;
|
||||||
|
boolean valid = false;
|
||||||
|
do {
|
||||||
|
|
||||||
|
// Retrieve an audio file
|
||||||
|
packageFile = retrieveFileOrFolder(reader, prompt);
|
||||||
|
|
||||||
|
if(packageFile.isFile()) {
|
||||||
|
// File must have .bin extension
|
||||||
|
String name = packageFile.getName();
|
||||||
|
int extIndex = name.lastIndexOf('.');
|
||||||
|
String extension = null;
|
||||||
|
if(extIndex > 0 && extIndex < name.length() - 1)
|
||||||
|
extension = name.substring(extIndex + 1);
|
||||||
|
if(extension != null && extension.equalsIgnoreCase("bin"))
|
||||||
|
valid = true;
|
||||||
|
} else { // packageFile is folder
|
||||||
|
; // Folder should have a .bin file
|
||||||
|
File[] contents = packageFile.listFiles();
|
||||||
|
for(File file : contents) {
|
||||||
|
String name = file.getName();
|
||||||
|
int extIndex = name.lastIndexOf('.');
|
||||||
|
String extension = null;
|
||||||
|
if(extIndex > 0 && extIndex < name.length() - 1)
|
||||||
|
extension = name.substring(extIndex + 1);
|
||||||
|
if(extension != null && extension.equalsIgnoreCase("bin")) {
|
||||||
|
valid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!valid) {
|
||||||
|
if(packageFile.isFile())
|
||||||
|
System.out.println("File does not have a .BIN file extension.");
|
||||||
|
else System.out.println("Directory does not contain a .BIN file.");
|
||||||
|
}
|
||||||
|
|
||||||
|
} while(!valid);
|
||||||
|
|
||||||
|
return packageFile;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to prompt user to select a program task.
|
* Helper function to prompt user to select a program task.
|
||||||
*
|
*
|
||||||
|
@ -350,15 +640,15 @@ public class AudioExtractor {
|
||||||
/**
|
/**
|
||||||
* Examines a given file and reads some of its properties.
|
* Examines a given file and reads some of its properties.
|
||||||
*
|
*
|
||||||
* @param unknownFile
|
* @param givenFile
|
||||||
*/
|
*/
|
||||||
public static void identify(File unknownFile) {
|
public static void identify(File givenFile) {
|
||||||
|
|
||||||
// TODO check for characteristics of BIN or WAV files
|
// TODO check for characteristics of BIN or WAV files
|
||||||
String name = unknownFile.getName();
|
String name = givenFile.getName();
|
||||||
System.out.println("Name:\t" + name);
|
System.out.println("Name:\t" + name);
|
||||||
|
|
||||||
long size = unknownFile.length();
|
long size = givenFile.length();
|
||||||
System.out.println("Size:\t" + size + " Bytes" + (size > 1024 ? " (" + convertBytes(size) + ")" : "") + "\n");
|
System.out.println("Size:\t" + size + " Bytes" + (size > 1024 ? " (" + convertBytes(size) + ")" : "") + "\n");
|
||||||
|
|
||||||
// file extension
|
// file extension
|
||||||
|
@ -368,14 +658,13 @@ public class AudioExtractor {
|
||||||
extension = name.substring(extIndex + 1);
|
extension = name.substring(extIndex + 1);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
RandomAccessFile file = new RandomAccessFile(unknownFile, "r");
|
RandomAccessFile file = new RandomAccessFile(givenFile, "r");
|
||||||
switch(extension.toLowerCase()) {
|
switch(extension.toLowerCase()) {
|
||||||
case "bin": {
|
case "bin": {
|
||||||
|
LinkedHashMap<Integer, Integer> tracklist = findAudioTracks(file);
|
||||||
break;
|
System.out.println(tracklist.size() + " Tracks (" + convertBytes(size / tracklist.size()) + " avg size)\n");
|
||||||
}
|
System.out.println("Format Info");
|
||||||
case "flac": {
|
readFormatChunk(file, 0x0C);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "wav":
|
case "wav":
|
||||||
|
@ -402,15 +691,15 @@ public class AudioExtractor {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ASCII_ALIG: {
|
case ASCII_ALIG: {
|
||||||
readAlignmentChunk(file, (int) i);
|
i = readAlignmentChunk(file, (int) i) - 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ASCII_seek: {
|
case ASCII_seek: {
|
||||||
readx2stChunk(file, (int) i);
|
i = readx2stChunk(file, (int) i) - 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ASCII_x2st: {
|
case ASCII_x2st: {
|
||||||
readx2stChunk(file, (int) i);
|
i = readx2stChunk(file, (int) i) - 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -572,8 +861,7 @@ public class AudioExtractor {
|
||||||
System.out.println(formatAddress(offset + 0x04, file.length()) + ":\t" + size + " Bytes" + (size > 1024 ? " (" + convertBytes(size) + ")" : ""));
|
System.out.println(formatAddress(offset + 0x04, file.length()) + ":\t" + size + " Bytes" + (size > 1024 ? " (" + convertBytes(size) + ")" : ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x08 4B manufacturer code
|
// 0x08 4 bytes manufacturer code
|
||||||
// parseField(file, offset + 0x08, 4, " manufacturer code");
|
|
||||||
byte[] bytes = new byte[4];
|
byte[] bytes = new byte[4];
|
||||||
file.seek(offset + 0x08);
|
file.seek(offset + 0x08);
|
||||||
file.read(bytes);
|
file.read(bytes);
|
||||||
|
@ -582,9 +870,7 @@ public class AudioExtractor {
|
||||||
if(relevantBytes == 3)
|
if(relevantBytes == 3)
|
||||||
code = String.format("%02XH %02XH %02XH", bytes[1], bytes[2], bytes[3]);
|
code = String.format("%02XH %02XH %02XH", bytes[1], bytes[2], bytes[3]);
|
||||||
else code = String.format("%02XH", bytes[3]);
|
else code = String.format("%02XH", bytes[3]);
|
||||||
|
|
||||||
System.out.print(formatAddress(offset + 0x08, file.length()) + ":\t");
|
System.out.print(formatAddress(offset + 0x08, file.length()) + ":\t");
|
||||||
|
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
InputStream filestream = AudioExtractor.class.getResourceAsStream("/manufacturer.csv");
|
InputStream filestream = AudioExtractor.class.getResourceAsStream("/manufacturer.csv");
|
||||||
InputStreamReader streamReader = new InputStreamReader(filestream);
|
InputStreamReader streamReader = new InputStreamReader(filestream);
|
||||||
|
@ -603,8 +889,7 @@ public class AudioExtractor {
|
||||||
if(!found)
|
if(!found)
|
||||||
System.out.print("Unknown (" + code + ")");
|
System.out.print("Unknown (" + code + ")");
|
||||||
System.out.println(" manufacturer");
|
System.out.println(" manufacturer");
|
||||||
|
|
||||||
// 0x0C 4B product code
|
|
||||||
parseField(file, offset + 0x0C, 4, " product code");
|
parseField(file, offset + 0x0C, 4, " product code");
|
||||||
parseField(file, offset + 0x10, 4, "-nanosecond sample period");
|
parseField(file, offset + 0x10, 4, "-nanosecond sample period");
|
||||||
parseField(file, offset + 0x14, 4, " MIDI unity note");
|
parseField(file, offset + 0x14, 4, " MIDI unity note");
|
||||||
|
@ -652,7 +937,14 @@ public class AudioExtractor {
|
||||||
System.out.println(formatAddress(loopOffset + 0x08, file.length()) + ":\tLoop end @ sample " + loopEnd);
|
System.out.println(formatAddress(loopOffset + 0x08, file.length()) + ":\tLoop end @ sample " + loopEnd);
|
||||||
|
|
||||||
parseField(file, loopOffset + 0x10, 4, " loop fraction");
|
parseField(file, loopOffset + 0x10, 4, " loop fraction");
|
||||||
parseField(file, loopOffset + 0x14, 4, " repeat count");
|
|
||||||
|
file.seek(loopOffset + 0x14);
|
||||||
|
file.read(bytes);
|
||||||
|
int repeat = littleEndianToInt(bytes);
|
||||||
|
if(repeat == 0)
|
||||||
|
System.out.println(formatAddress(loopOffset + 0x14, file.length()) + ":\tRepeat indefinitely");
|
||||||
|
else System.out.println(formatAddress(loopOffset + 0x14, file.length()) + ":\t" + repeat + "repeat count");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println();
|
System.out.println();
|
||||||
|
@ -752,145 +1044,6 @@ public class AudioExtractor {
|
||||||
// else return String.format("%04X", address);
|
// else return String.format("%04X", address);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts audio files to the extract directory from package files located at the package directory.
|
|
||||||
* Also supports FLAC conversion for BGM files.
|
|
||||||
*
|
|
||||||
* @param packDirectory
|
|
||||||
* @param extractDirectory
|
|
||||||
* @param compressBGM
|
|
||||||
*/
|
|
||||||
public static void extract(File packDirectory, File extractDirectory, boolean compressBGM) {
|
|
||||||
|
|
||||||
// TODO Delete
|
|
||||||
System.out.println("packDirectory:\t" + packDirectory);
|
|
||||||
System.out.println("extractDirectory:\t" + extractDirectory);
|
|
||||||
|
|
||||||
// Identify target binary files
|
|
||||||
File[] packages = new File(packDirectory.toString()).listFiles(new FilenameFilter() {
|
|
||||||
public boolean accept(File dir, String name) {
|
|
||||||
return name.toLowerCase().endsWith(".bin");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Identify and extract audio within binary files
|
|
||||||
for(int i = 0; i < packages.length; i++) {
|
|
||||||
|
|
||||||
RandomAccessFile source;
|
|
||||||
LinkedHashMap<Integer, Integer> tracklist = null;
|
|
||||||
try {
|
|
||||||
source = new RandomAccessFile(packages[i], "r");
|
|
||||||
tracklist = findAudioTracks(source);
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
System.out.println("Binary file:\t" + packages[i] + "\n was not found. File skipped.");
|
|
||||||
continue;
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.out.println("Binary file:\t" + packages[i] + "\n could not be read. File skipped.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO Delete
|
|
||||||
System.out.println("packages[" + i + "]:\t" + packages[i]);
|
|
||||||
|
|
||||||
File dir = new File(extractDirectory.getPath() + "/" + FilenameUtils.removeExtension(packages[i].getName()));
|
|
||||||
if(!dir.exists())
|
|
||||||
dir.mkdir();
|
|
||||||
|
|
||||||
// Extract and write WAV files in directory
|
|
||||||
Set<Integer> keys = tracklist.keySet();
|
|
||||||
int track = 1;
|
|
||||||
|
|
||||||
for(Integer key : keys) {
|
|
||||||
|
|
||||||
String name = String.format("track%04d", track);
|
|
||||||
{ // Extract WAV files
|
|
||||||
File wav = null;
|
|
||||||
try {
|
|
||||||
|
|
||||||
// create file for storing WAV data
|
|
||||||
wav = new File(dir.getPath() + "/" + name + ".wav");
|
|
||||||
if(!wav.exists())
|
|
||||||
wav.createNewFile();
|
|
||||||
|
|
||||||
//TODO Delete
|
|
||||||
System.out.println("Saving track " + String.format("%d (@0x%08X)", track, key) + " to " + wav + String.format(" (%d bytes)", tracklist.get(key)));
|
|
||||||
|
|
||||||
// write selection to file
|
|
||||||
try (
|
|
||||||
FileInputStream inStream = new FileInputStream(packages[i]);
|
|
||||||
FileOutputStream outStream = new FileOutputStream(wav)
|
|
||||||
) {
|
|
||||||
inStream.skipNBytes(key.intValue());
|
|
||||||
byte[] trackBytes = new byte[tracklist.get(key)];
|
|
||||||
int readBytes = inStream.read(trackBytes);
|
|
||||||
outStream.write(trackBytes, 0, readBytes);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
System.exit(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.out.println("An error occurred when attempting to write " + name + " to file:\t" + wav);
|
|
||||||
e.printStackTrace();
|
|
||||||
System.exit(3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
track++;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if(compressBGM && packages[i].getName().equals("pack_bgm.bin")) {
|
|
||||||
|
|
||||||
// find WAV files
|
|
||||||
File[] WAV_Files = dir.listFiles(new FilenameFilter() {
|
|
||||||
public boolean accept(File dir, String name) {
|
|
||||||
return name.toLowerCase().endsWith(".wav");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// convert WAV files to FLAC
|
|
||||||
FLAC_FileEncoder ffe = new FLAC_FileEncoder();
|
|
||||||
|
|
||||||
for(File wav : WAV_Files) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
File flac = new File(dir.getPath() + "/" + FilenameUtils.removeExtension(wav.getName()) + ".flac");
|
|
||||||
if(!flac.exists())
|
|
||||||
flac.createNewFile();
|
|
||||||
|
|
||||||
//TODO Delete
|
|
||||||
System.out.println("Compressing WAV to FLAC:\t" + flac);
|
|
||||||
|
|
||||||
ffe.encode(wav, flac);
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.out.println("An error occurred when attempting to write file.");
|
|
||||||
e.printStackTrace();
|
|
||||||
System.exit(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.print("Deleting WAV files");
|
|
||||||
// delete WAV files
|
|
||||||
for(File wav : WAV_Files) {
|
|
||||||
boolean deleted = false;
|
|
||||||
while(!deleted) {
|
|
||||||
try {
|
|
||||||
Files.delete(wav.toPath());
|
|
||||||
deleted = true;
|
|
||||||
} catch(Exception e) {
|
|
||||||
System.out.print('.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1076,6 +1229,39 @@ public class AudioExtractor {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to prompt user to select a file or folder.
|
||||||
|
*
|
||||||
|
* @param reader
|
||||||
|
* @return file or folder
|
||||||
|
*/
|
||||||
|
private static File retrieveFileOrFolder(BufferedReader reader, String prompt) {
|
||||||
|
|
||||||
|
File file = null;
|
||||||
|
|
||||||
|
String input = null;
|
||||||
|
boolean valid = false;
|
||||||
|
do {
|
||||||
|
System.out.print(prompt);
|
||||||
|
try {
|
||||||
|
input = reader.readLine();
|
||||||
|
if(input == null)
|
||||||
|
throw new IOException("Invalid file.");
|
||||||
|
file = new File(input);
|
||||||
|
if(file.exists()) {
|
||||||
|
valid = true;
|
||||||
|
} else System.out.println(Ansi.colorize("File does not exist."));
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println(Ansi.colorize("Invalid file."));
|
||||||
|
}
|
||||||
|
} while(!valid);
|
||||||
|
|
||||||
|
System.out.print(Ansi.colorize("\n"));
|
||||||
|
|
||||||
|
return file;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to prompt user to select a file.
|
* Helper function to prompt user to select a file.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue