Skip to content

Commit

Permalink
Merge pull request #21 from ununu-p2p/feature/recorded-audio
Browse files Browse the repository at this point in the history
Remove the use of data and add test of recorded audios
  • Loading branch information
shresthagrawal authored Jun 30, 2020
2 parents 234af04 + 365dfd8 commit 1b7f4cb
Show file tree
Hide file tree
Showing 27 changed files with 313 additions and 66 deletions.
4 changes: 2 additions & 2 deletions build/lib/ableton.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ export declare class AbletonParser {
getTracksCount(): {
[index: string]: any;
};
getResourceLocations(): string[];
getResourceLocations(internal?: boolean): string[];
getFilerefs(): unknown[];
private appendReferenceList;
private appendResourceList;
changeResourceLocations(location: string): void;
changeResourceLocations(location: string, internal?: boolean, useData?: boolean, overideFileCheck?: boolean): void;
private changeLocation;
}
41 changes: 28 additions & 13 deletions build/lib/ableton.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,11 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var path_1 = __importDefault(require("path"));
var reader_1 = require("./reader/reader");
var fileref_1 = require("./fileref/fileref");
var utils_1 = require("./utils");
var defaultTracks = ['Reverb Default.adv'];
var AbletonParser = /** @class */ (function () {
function AbletonParser(file) {
this.file = file;
Expand Down Expand Up @@ -72,9 +69,10 @@ var AbletonParser = /** @class */ (function () {
}
return trackCount;
};
AbletonParser.prototype.getResourceLocations = function () {
AbletonParser.prototype.getResourceLocations = function (internal) {
if (internal === void 0) { internal = false; }
var resList = new Set();
utils_1.deepRecurrsion(this.reader.xmlJs, 'FileRef', this.appendResourceList, resList);
utils_1.deepRecurrsion(this.reader.xmlJs, 'FileRef', this.appendResourceList, resList, internal);
return Array.from(resList);
};
AbletonParser.prototype.getFilerefs = function () {
Expand All @@ -85,19 +83,36 @@ var AbletonParser = /** @class */ (function () {
AbletonParser.prototype.appendReferenceList = function (obj, resList) {
resList.add(obj[0]);
};
AbletonParser.prototype.appendResourceList = function (obj, resList) {
AbletonParser.prototype.appendResourceList = function (obj, resList, internal) {
if (internal === void 0) { internal = false; }
var fileref = new fileref_1.Fileref(obj[0]);
resList.add(path_1.default.join('/', fileref.getLocation()));
var fileName = fileref.getFileName();
if (fileName != '' && !defaultTracks.includes(fileName)) {
if (!fileref.isInternal || internal) {
resList.add(fileref.getRelativeLocation());
}
}
};
AbletonParser.prototype.changeResourceLocations = function (location) {
AbletonParser.prototype.changeResourceLocations = function (location, internal, useData, overideFileCheck) {
if (internal === void 0) { internal = false; }
if (useData === void 0) { useData = false; }
if (overideFileCheck === void 0) { overideFileCheck = false; }
// Modify the XmlJ
utils_1.deepRecurrsion(this.reader.xmlJs, 'FileRef', this.changeLocation, location, this.file);
utils_1.deepRecurrsion(this.reader.xmlJs, 'FileRef', this.changeLocation, location, this.file, internal, useData, overideFileCheck);
// Save the Modified reader.xmlJs
this.reader.save(this.file);
};
AbletonParser.prototype.changeLocation = function (obj, resourceFolder, project) {
var fileref = new fileref_1.Fileref(obj[0]);
fileref.changeLocation(resourceFolder, project);
AbletonParser.prototype.changeLocation = function (obj, resourceFolder, project, internal, useData, overideFileCheck) {
if (internal === void 0) { internal = false; }
if (useData === void 0) { useData = false; }
if (overideFileCheck === void 0) { overideFileCheck = false; }
var fileref = new fileref_1.Fileref(obj[0], useData);
var fileName = fileref.getFileName();
if (fileref.getFileName() != '' && !defaultTracks.includes(fileName)) {
if (!fileref.isInternal || internal) {
fileref.changeLocation(resourceFolder, project, overideFileCheck);
}
}
};
return AbletonParser;
}());
Expand Down
11 changes: 8 additions & 3 deletions build/lib/fileref/fileref.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { FilerefData } from "./fileref-data";
export declare class Fileref {
fileref: any;
data: FilerefData;
constructor(fileref: any);
getLocation(): string;
data?: FilerefData;
isInternal: boolean;
useData: boolean;
hasRelativePath: boolean;
pathType: number;
constructor(fileref: any, useData?: boolean);
getRelativeLocation(): string;
getFileName(): string;
changeLocation(resourceFolder: string, project: string, overrideFileCheck?: boolean): void;
}
45 changes: 37 additions & 8 deletions build/lib/fileref/fileref.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,56 @@ var fileref_data_1 = require("./fileref-data");
var path_1 = __importDefault(require("path"));
var utils_1 = require("./../reader/utils");
var Fileref = /** @class */ (function () {
function Fileref(fileref) {
function Fileref(fileref, useData) {
if (useData === void 0) { useData = false; }
this.fileref = fileref;
var hex = fileref.Data[0].replace(/\n/g, '').replace(/\t/g, '').replace(/ /g, '');
this.data = fileref_data_1.unmarshall(hex);
this.pathType = fileref.RelativePathType[0]['$'].Value;
this.hasRelativePath = this.fileref.HasRelativePath[0]['$'].Value === 'true';
/*
Hack: All th tracks which have a live pack name or
do not have relative path define are considered or
has pathType equals 6
as internal resources.
*/
this.isInternal = this.fileref.LivePackName[0]['$'].Value != '' || !this.hasRelativePath || this.pathType == 6;
this.useData = useData;
if (useData) {
var hex = fileref.Data[0].replace(/\n/g, '').replace(/\t/g, '').replace(/ /g, '');
this.data = fileref_data_1.unmarshall(hex);
}
}
Fileref.prototype.getLocation = function () {
return this.data.getLocation('/');
Fileref.prototype.getRelativeLocation = function () {
var relativePathArray = [];
var relativePathElement = this.fileref.RelativePath[0].RelativePathElement;
for (var _i = 0, relativePathElement_1 = relativePathElement; _i < relativePathElement_1.length; _i++) {
var pathEntry = relativePathElement_1[_i];
if (pathEntry['$']['Dir'] == '')
relativePathArray.push('..');
else
relativePathArray.push(pathEntry['$']['Dir']);
}
relativePathArray.push(this.getFileName());
return relativePathArray.join(path_1.default.sep);
};
Fileref.prototype.getFileName = function () {
return this.fileref.Name[0]['$'].Value;
};
Fileref.prototype.changeLocation = function (resourceFolder, project, overrideFileCheck) {
if (overrideFileCheck === void 0) { overrideFileCheck = false; }
// Get the absolute path of the objects
resourceFolder = path_1.default.resolve(resourceFolder);
project = path_1.default.resolve(project);
// Change the Binary Data
var resource = path_1.default.join(resourceFolder, this.data.getFileName());
var resource = path_1.default.join(resourceFolder, this.getFileName());
// Verify if the location Exists
// TODO: Throw Error on resource doesn't exist
if (!utils_1.fileExists(resource) && !overrideFileCheck)
return;
this.data.setLocation(resource);
this.fileref.Data[0] = fileref_data_1.marshall(this.data);
// Only modify the data if needed
if (this.useData && this.data) {
this.data.setLocation(resource);
this.fileref.Data[0] = fileref_data_1.marshall(this.data);
}
// Remove the Path hint
this.fileref.SearchHint[0].PathHint = [];
// Update the Relative path
Expand Down
114 changes: 103 additions & 11 deletions build/test/parser-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,20 @@ var sampleAls = "a.als";
var sampleXml = "a.xml";
// Resource List
var resources = [
"/private/tmp/com.ununu.als-parser/a/d/drum.aif",
"/private/tmp/com.ununu.als-parser/a/d/audio.aif",
"/Users/ama/Downloads/Reverb Default.adv",
"/Users/mak/Library/Application Support/Ableton/Live 10 Core Library/Devices/Audio Effects/Simple Delay/Dotted Eighth Note.adv"
"../../a/d/drum.aif",
"../../a/d/audio.aif",
];
var resourcesInternal = [
"../../a/d/drum.aif",
"../../a/d/audio.aif",
"Devices/Audio Effects/Simple Delay/Dotted Eighth Note.adv"
];
var recordedResources = [
"Samples/Recorded/1-Audio 0001 [2020-06-26 114704].aif",
];
var modifiedResource = [
"/private/tmp/com.ununu.als-parser/b/d/drum.aif",
"/private/tmp/com.ununu.als-parser/b/d/audio.aif",
"/Users/ama/Downloads/Reverb Default.adv",
"/Users/mak/Library/Application Support/Ableton/Live 10 Core Library/Devices/Audio Effects/Simple Delay/Dotted Eighth Note.adv"
"../b/d/drum.aif",
"../b/d/audio.aif",
];
describe("Parser", function () {
describe("Parse File", function () {
Expand Down Expand Up @@ -183,18 +187,32 @@ describe("Parser", function () {
});
});
});
it("Get the list of resourcefiles including internal when als project file is given", function () {
return __awaiter(this, void 0, void 0, function () {
var parser;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, lib_1.parseFile("/foo/project.als")];
case 1:
parser = _a.sent();
parser.getResourceLocations(true).should.eql(resourcesInternal);
return [2 /*return*/];
}
});
});
});
it("Change location of all resourcefiles when als project file is given", function () {
return __awaiter(this, void 0, void 0, function () {
var newLocation, parser, secondParser;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
newLocation = "/private/tmp/com.ununu.als-parser/b/d/";
newLocation = "/b/d";
return [4 /*yield*/, lib_1.parseFile("/foo/project.als")];
case 1:
parser = _a.sent();
parser.changeResourceLocations(newLocation);
return [4 /*yield*/, lib_1.parseFile(path_1.default.join("/foo/project.als"))];
parser.changeResourceLocations(newLocation, undefined, undefined, true);
return [4 /*yield*/, lib_1.parseFile("/foo/project.als")];
case 2:
secondParser = _a.sent();
secondParser.getResourceLocations().should.eql(modifiedResource);
Expand All @@ -204,4 +222,78 @@ describe("Parser", function () {
});
});
});
describe("Recorded", function () {
beforeEach(function () {
return __awaiter(this, void 0, void 0, function () {
var mockVolume;
return __generator(this, function (_a) {
mockVolume = new memfs_1.Volume();
memory_fs_1.mountDirectory(mockVolume, path_1.default.join(__dirname, "res/recorded-audio"), {
dest: path_1.default.join(tmp, "/recorded-audio")
});
memory_fs_1.mountDirectory(mockVolume, path_1.default.join(__dirname, "res/drums"), {
dest: path_1.default.join(tmp, "/drums")
});
memory_fs_1.mountDirectory(mockVolume, path_1.default.join(__dirname, "res/drums-midi"), {
dest: path_1.default.join(tmp, "/drums-midi")
});
this.unpatch = fs_monkey_1.patchFs(mockVolume);
return [2 /*return*/];
});
});
});
afterEach(function () {
if (this.unpatch) {
this.unpatch();
}
});
it("Get the list of resourcefiles when als project with recorded audio is given", function () {
return __awaiter(this, void 0, void 0, function () {
var projectFile, parser;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
projectFile = path_1.default.join(tmp, "/recorded-audio/recorded-audio.als");
return [4 /*yield*/, lib_1.parseFile(projectFile)];
case 1:
parser = _a.sent();
parser.getResourceLocations().should.eql(recordedResources);
return [2 /*return*/];
}
});
});
});
it("Get the list of resourcefiles when als project with recorded drums is given", function () {
return __awaiter(this, void 0, void 0, function () {
var projectFile, parser;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
projectFile = path_1.default.join(tmp, "/drums/drums.als");
return [4 /*yield*/, lib_1.parseFile(projectFile)];
case 1:
parser = _a.sent();
parser.getResourceLocations().should.eql([]);
return [2 /*return*/];
}
});
});
});
it("Get the list of resourcefiles when als project with drums midi is given", function () {
return __awaiter(this, void 0, void 0, function () {
var projectFile, parser;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
projectFile = path_1.default.join(tmp, "/drums-midi/drums-midi.als");
return [4 /*yield*/, lib_1.parseFile(projectFile)];
case 1:
parser = _a.sent();
parser.getResourceLocations().should.eql([]);
return [2 /*return*/];
}
});
});
});
});
});
32 changes: 23 additions & 9 deletions lib/ableton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { Reader } from "./reader/reader";
import { Fileref } from "./fileref/fileref";
import { deepRecurrsion } from "./utils";

const defaultTracks = ['Reverb Default.adv']

export class AbletonParser {
file: string;
reader: any;
Expand All @@ -24,9 +26,9 @@ export class AbletonParser {
}
return trackCount;
}
getResourceLocations(): string[]{
getResourceLocations(internal=false): string[]{
let resList = new Set<string>();
deepRecurrsion(this.reader.xmlJs, 'FileRef', this.appendResourceList, resList);
deepRecurrsion(this.reader.xmlJs, 'FileRef', this.appendResourceList, resList, internal);
return Array.from(resList);
}
getFilerefs() {
Expand All @@ -37,19 +39,31 @@ export class AbletonParser {
private appendReferenceList(obj: any, resList: Set<any>) {
resList.add(obj[0]);
}
private appendResourceList(obj: any, resList: Set<string>) {
private appendResourceList(obj: any, resList: Set<string>, internal=false) {
let fileref = new Fileref(obj[0]);
resList.add(path.join('/', fileref.getLocation()));
let fileName = fileref.getFileName();
if (fileName != '' && !defaultTracks.includes(fileName)) {
if (!fileref.isInternal || internal) {
resList.add(fileref.getRelativeLocation());
}
}
}
changeResourceLocations(location: string) {
changeResourceLocations(location: string, internal=false, useData=false, overideFileCheck=false) {
// Modify the XmlJ
deepRecurrsion(this.reader.xmlJs, 'FileRef', this.changeLocation, location, this.file);
deepRecurrsion(this.reader.xmlJs, 'FileRef', this.changeLocation, location,
this.file, internal, useData, overideFileCheck);
// Save the Modified reader.xmlJs
this.reader.save(this.file);
}
private changeLocation(obj: any, resourceFolder: string, project: string) {
let fileref = new Fileref(obj[0]);
fileref.changeLocation(resourceFolder, project);
private changeLocation(obj: any, resourceFolder: string, project: string,
internal=false, useData=false, overideFileCheck=false) {
let fileref = new Fileref(obj[0], useData);
let fileName = fileref.getFileName();
if (fileref.getFileName() != '' && !defaultTracks.includes(fileName)) {
if (!fileref.isInternal || internal) {
fileref.changeLocation(resourceFolder, project, overideFileCheck);
}
}
}
}

Loading

0 comments on commit 1b7f4cb

Please sign in to comment.