Skip to content

Commit

Permalink
refactoring and mixer test
Browse files Browse the repository at this point in the history
  • Loading branch information
shreyas-jadhav committed Jun 10, 2023
1 parent e304ce2 commit 9773157
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 104 deletions.
132 changes: 57 additions & 75 deletions src/assetPool.ts
Original file line number Diff line number Diff line change
@@ -1,64 +1,11 @@
import distance from "@turf/distance";
import { union } from "lodash";
import { AssetPriorityType, roundwareDefaultFilterChain } from "./assetFilters";
import { AssetSorter } from "./assetSorter";
import {
InvalidArgumentError,
RoundwareFrameworkError,
} from "./errors/app.errors";
import { InvalidArgumentError } from "./errors/app.errors";
import { PlaylistAudiotrack } from "./playlistAudioTrack";
import { ILookupTable, IMixParams, ITimedAssetData } from "./types";
import { IDecoratedAsset, IAssetData } from "./types/asset";
import { cleanAudioURL, coordsToPoints, debugLogger } from "./utils";

// add new fields to assets after they have been downloaded from the API to be used by rest of the mixing code
// also rewrite .wav as .mp3
export const assetDecorationMapper = (timedAssets: ITimedAssetData[]) => {
const timedAssetLookup = timedAssets.reduce(
(lookupTable: ILookupTable, timedAsset: ITimedAssetData) => ({
...lookupTable,
[timedAsset.asset_id]: timedAsset,
}),
{}
);

return (asset: IAssetData): IDecoratedAsset => {
const {
start_time: activeRegionLowerBound = 0,
end_time: activeRegionUpperBound = 0,
file: assetUrl,
} = asset;

const activeRegionLength = activeRegionUpperBound - activeRegionLowerBound;

// per Halsey we should always use mp3s; also we avoid specifying http/https to avoid mixed-content warnings
if (!assetUrl) console.warn(`assetUrl was undefined!`);
const mp3Url = cleanAudioURL(assetUrl!);

const decoratedAsset: IDecoratedAsset = {
locationPoint: coordsToPoints({
latitude: asset.latitude!,
longitude: asset.longitude!,
}),
playCount: 0,
activeRegionLength,
activeRegionUpperBound,
activeRegionLowerBound,
...asset,
created: asset.created ? new Date(asset.created) : new Date(),
file: mp3Url,
};

const timedAsset = timedAssetLookup[asset.id!];

if (timedAsset) {
decoratedAsset.timedAssetStart = timedAsset.start!;
decoratedAsset.timedAssetEnd = timedAsset.end!;
}

return decoratedAsset;
};
};
import { IAssetData, IDecoratedAsset } from "./types/asset";
import { cleanAudioURL, coordsToPoints } from "./utils";

export class AssetPool {
assetSorter: AssetSorter;
Expand Down Expand Up @@ -86,27 +33,14 @@ export class AssetPool {
sortMethods?: string[];
mixParams?: IMixParams;
}) {
if (!Array.isArray(assets))
throw new InvalidArgumentError(
"assets",
"array of IAssetData",
"instantiation assetPool"
);
if (!Array.isArray(timedAssets))
throw new InvalidArgumentError(
"timedAssets",
"array of ITimedAssetData",
"instantiation assetPool"
);
this.updateAssets(assets, timedAssets);

this.assetSorter = new AssetSorter({
sortMethods,
...mixParams,
});
this.playingTracks = {};
this.mixParams = mixParams;
this.filterChain = filterChain;
this.updateAssets(assets, timedAssets);
this.sortAssets();
}

Expand All @@ -121,11 +55,10 @@ export class AssetPool {

let newAssets = assets.map(assetDecorationMapper(timedAssets));
// preserve the existing properties of assets, add instead of replacing...
if (Array.isArray(this.assets)) {
newAssets.forEach((asset) => {
if (!this.assets.some((a) => a.id === asset.id)) this.add(asset);
});
} else this.assets = newAssets;

newAssets.forEach((asset) => {
if (!this.assets.some((a) => a.id === asset.id)) this.add(asset);
});
}

nextForTrack(
Expand Down Expand Up @@ -219,3 +152,52 @@ export class AssetPool {
}

export default AssetPool;

// add new fields to assets after they have been downloaded from the API to be used by rest of the mixing code
// also rewrite .wav as .mp3
export function assetDecorationMapper(timedAssets: ITimedAssetData[]) {
const timedAssetLookup = timedAssets.reduce(
(lookupTable: ILookupTable, timedAsset: ITimedAssetData) => ({
...lookupTable,
[timedAsset.asset_id]: timedAsset,
}),
{}
);

return (asset: IAssetData): IDecoratedAsset => {
const {
start_time: activeRegionLowerBound = 0,
end_time: activeRegionUpperBound = 0,
file: assetUrl,
} = asset;

const activeRegionLength = activeRegionUpperBound - activeRegionLowerBound;

// per Halsey we should always use mp3s; also we avoid specifying http/https to avoid mixed-content warnings
if (!assetUrl) console.warn(`assetUrl was undefined!`);
const mp3Url = cleanAudioURL(assetUrl!);

const decoratedAsset: IDecoratedAsset = {
locationPoint: coordsToPoints({
latitude: asset.latitude!,
longitude: asset.longitude!,
}),
playCount: 0,
activeRegionLength,
activeRegionUpperBound,
activeRegionLowerBound,
...asset,
created: asset.created ? new Date(asset.created) : new Date(),
file: mp3Url,
};

const timedAsset = timedAssetLookup[asset.id!];

if (timedAsset) {
decoratedAsset.timedAssetStart = timedAsset.start!;
decoratedAsset.timedAssetEnd = timedAsset.end!;
}

return decoratedAsset;
};
}
10 changes: 3 additions & 7 deletions src/mixer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const GeoListenMode: {

export class Mixer {
playing: boolean;
private _windowScope: Window;

private _client: Roundware;
private _prefetchSpeakerAudio: any | boolean;

Expand All @@ -37,14 +37,12 @@ export class Mixer {

constructor({
client,
windowScope,
listenerLocation,
filters,
sortMethods = [],
mixParams = {},
}: {
client: Roundware;
windowScope: Window;
listenerLocation: Coordinates;
filters?: (
asset: IDecoratedAsset,
Expand All @@ -55,7 +53,6 @@ export class Mixer {
}) {
this.playing = false;

this._windowScope = windowScope;
this._client = client;

const assets: IAssetData[] = client.assets();
Expand All @@ -76,7 +73,7 @@ export class Mixer {
sortMethods,
mixParams: this.mixParams,
});
this.audioContext = buildAudioContext(this._windowScope);
this.audioContext = buildAudioContext();
}

updateParams({ listenerLocation, ...params }: IMixParams) {
Expand Down Expand Up @@ -129,7 +126,7 @@ export class Mixer {
const listenerPoint = this.mixParams.listenerPoint;

let selectTrackId: string | number | null = getUrlParam(
this._windowScope.location.toString(),
window.location.toString(),
"rwfSelectTrackId"
);
let audioTracks = this._client.audiotracks();
Expand All @@ -146,7 +143,6 @@ export class Mixer {
listenerPoint,
assetPool: this.assetPool,
audioContext: this.audioContext,
windowScope: this._windowScope,
});

this.initializeSpeakers();
Expand Down
7 changes: 3 additions & 4 deletions src/playlist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ export class Playlist {
client,
audioTracks = [],
listenerPoint,
windowScope,

assetPool,
audioContext,
...playlistTrackOptions
}: {
client: Roundware;
audioTracks?: IAudioTrackData[];
listenerPoint: Feature<Point>;
windowScope: Window;

assetPool: AssetPool;
audioContext: IAudioContext;
}) {
Expand All @@ -46,7 +46,7 @@ export class Playlist {

let elapsedTimeMs = 0;
const timerSecs = getUrlParam(
windowScope.location.toString(),
window.location.toString(),
"rwfTimerSeconds"
);

Expand All @@ -64,7 +64,6 @@ export class Playlist {
const track = new PlaylistAudiotrack({
audioContext,
audioData,
windowScope,
playlist: this,
client: this._client,
});
Expand Down
10 changes: 5 additions & 5 deletions src/playlistAudioTrack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export class PlaylistAudiotrack {
*/
playlist: Playlist;
playing: boolean;
windowScope: Window;

currentAsset: IDecoratedAsset | null;

gainNode: IGainNode<IAudioContext>;
Expand Down Expand Up @@ -158,13 +158,13 @@ export class PlaylistAudiotrack {
isSafeToPlay = false;
constructor({
audioContext,
windowScope,

audioData,
playlist,
client,
}: {
audioContext: IAudioContext;
windowScope: Window;

audioData: IAudioTrackData;
playlist: Playlist;
client: Roundware;
Expand All @@ -173,7 +173,7 @@ export class PlaylistAudiotrack {
this.timedAssetPriority = audioData.timed_asset_priority;
this.playlist = playlist;
this.playing = false;
this.windowScope = windowScope;

this.listenEvents = client.events;
this.currentAsset = null;
this.audioData = audioData;
Expand Down Expand Up @@ -202,7 +202,7 @@ export class PlaylistAudiotrack {
audioElement.addEventListener("ended", () => this.onAudioEnded());

const trackOptions = new TrackOptions(
(param) => getUrlParam(windowScope.location.toString(), param),
(param) => getUrlParam(window.location.toString(), param),
audioData
);

Expand Down
13 changes: 2 additions & 11 deletions src/roundware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ import { ListenHistory } from "./listenHistory";
**/

export class Roundware {
readonly windowScope: Window;
private _serverUrl: string;
private _projectId: number;
private _speakerFilters: ISpeakerFilters = {};
Expand Down Expand Up @@ -119,14 +118,7 @@ export class Roundware {
* @throws Will throw an error if serveUrl or projectId are missing
TODO need to provide a more modern/ES6-aware architecture here vs burdening the constructor with all of these details **/

constructor(windowScope: Window, options: IRoundwareConstructorOptions) {
if (!windowScope)
throw new MissingArgumentError(
`windowScope`,
`instantiating Roundware`,
`window`
);

constructor(options: IRoundwareConstructorOptions) {
if (typeof options !== "object")
throw new MissingArgumentError(
`options`,
Expand Down Expand Up @@ -167,7 +159,6 @@ export class Roundware {
);
}

this.windowScope = windowScope;
this._serverUrl = serverUrl;
this._projectId = projectId;
if (speakerFilters) this._speakerFilters = speakerFilters;
Expand Down Expand Up @@ -232,7 +223,7 @@ export class Roundware {
};
this.mixer = new Mixer({
client: this,
windowScope: this.windowScope,

listenerLocation: this.listenerLocation,
mixParams,
});
Expand Down
4 changes: 2 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,11 @@ function unlockAudioContext(
);
}

export function buildAudioContext(windowScope: Window): IAudioContext {
export function buildAudioContext(): IAudioContext {
const audioContext = new AudioContext();
const {
document: { body },
} = windowScope;
} = window;
unlockAudioContext(body, audioContext);
audioContext.onstatechange = () =>
console.info(`[Audio Context]: ${audioContext.state}`);
Expand Down

0 comments on commit 9773157

Please sign in to comment.