Original idea by Alexis Casanova & Antoine Pirog : experiencing music with multiple narratives, multiple paths. A randomized listening experience in a fully composed piece of music.
Easy enough (for now).
The currently launches with a pre-loaded song (V0.1.0 and less). To try other AMstructure files, open the console in your browser of choice and enter the command "app.importURL()" (file must be served).
Not so easy ...
| Control | Target | Action |
|---|---|---|
| Click + Drag | Track node | Move node |
| Click + Drag | Track transport | Move track |
| Click + Drag | Canvas | Drag canvas |
| Shift + click + Drag | Track | Move tracks with same track number |
| Right click | Track | Edit track properties |
| Right click | Link | Edit link properties |
| Right click | Canvas | Edit song properties |
| Ctrl + click + drag | Track | Create link to other track |
| Alt + click | Track | Delete track |
| Alt + click | Link | Delete link |
| Shift + right click | Track | Adjust screeen to track |
| Shift + right click | Link | Adjust screeen to link |
| Shift + right click | Canvas | Reset screen view |
| Mousewheel | Canvas | Adjust zoom |
| Button | Action |
|---|---|
| Add track | Add new track |
| x1.00 | Reset zoom to 1:1. Button name indicates current zoom |
| Import... | Prompts for a JSON file to load an existing AMstrucure |
| Export | Downloads the current AMstructure to .json |
| Property | Description | Expected values |
|---|---|---|
| Song name | Song name | Any string |
| Property | Description | Expected values |
|---|---|---|
| Name | Track ID | Any string |
| Path | Path to audio file (relative, url not tested) | Any string |
| Track number | Or rather "song number" ; What song does the (partial) track belong to ? ( indroduced in AMfs V040, makes things a bit confusing ) | Int |
| Group | Groups allow to constrain random choices to a subset of tracks (if a track from a group has been played, the others will follow) | Any string |
| Show | Is the track visible to the auditor ? | 0 / 1 |
| Property | Description | Expected values |
|---|---|---|
| Weight | Link weight (likelyhood of being chosen) | Int |
Want a bigger canvas ? Open the developer tools in your browser of choice, select style.css in the sources and adjust lines 2 & 3 -screen-width: 500px; -screen-height: 500px; (some internal variables won't update though, planning to make canvas fully resizable).
- Mostly tested under Chrome for now, a bit under firefox, never under IE, Opera.
AM : AugmentedMusic
| File | Descriptions |
|---|---|
| common/AMfilesystem.js | AM File Structure. File created with fs V0.2.0. Previous versions existed in Python. |
| common/AMDisplay.js | AM Display system. Contains the graphical elements of the AM representation. |
| AMMaker/AMMaker.js | AM Maker. Creation Tools. Utilizes AMD |
| AMplayer/AMPlayer.js | AM Player. Utilizes a custom Gapless5 and AMD |
| AMMaker/index.html | Home HTML file for AMM. No versionning as of now. |
| AMPlayer/index.html | Home HTML file for AMP. No versionning as of now. |
| common/style.css | CSS sheet for AMD & Gapless5 |
| common/Jquery-3.3.1.min.js | jquery. The project uses jquery quite a bit. |
Described in ./AMfilesystem.js upwards of V0.2.0
Three classes are used to describe an AM:
- AMstructure, which describes the core aspects of a song.
- AMtrack, which describes a segment of the song.
- AMnext, which describes the links between AMtracks.
| Attribute | Description | Type | Version |
|---|---|---|---|
| title | The title of the Album. | String | V0.5.0+ |
| band | The band name. | String | V0.5.0+ |
| about | Information about the song or file. Has no effect whatsoever. | String | V0.0.0+ |
| fs_version | File structure version. | String | V0.2.0+ |
| tracks | A dictionnary of AMtrack: {"track_id": AMtrack()} | Object | V0.0.0+ |
| numberOfTracks | Total number of tracks in the album. | Int | V0.4.0+ |
| display | Information regarding initial display (scale & position): display.scale, display.pan.x, display.pan.y (floats) | Object | V0.2.0+ |
| Attribute | Description | Type | Version |
|---|---|---|---|
| id | Track identifier | String | V0.0.0+ |
| path | Path to audio file | String | V0.0.0+ |
| draw | Should the track be drawn on the display. (Useful for system or hidden tracks) | Bool | V0.0.0+ |
| position | Spatial coordinates of the track (position.x0, y0, x1, y1) | Object | V0.0.0+ |
| links | An array of AMlink objects describing the links to other AMtracks. Was "next" before V0.5.0 | Array | V0.5.0+ |
| group | Optional. Coherence group the AMtrack belongs in. | String | V0.4.0+ |
| trackNumber | Track number in the augmented album. | Int | V0.4.0+ |
| Attribute | Description | Type | Version |
|---|---|---|---|
| id | The id of the target track | String | V0.0.0+ |
| weight | The weight of the link (the higher the weight, the higher the chance of being chosen) | Int | V0.0.0+ |
Some additional data is required when utilizing the player
"Groups", or "Coherence groups", can be set up to link distant subtracks: If a subtrack from a group is played, the other subtracks in the group will be prioritized in the structure generation. Hence, next subtrack generation is defined by the following algorithm:
A group is considered "active" when at least one subtrack from it is queued in the playlist.
For an AMstructure to be used with the player or the editing tools, it has to be populated with both its attributes and methods, which are heavily used throughout the project. Loading a JSON object to recall a song structure won't suffice. Currently, a new AMstructure object is created, then automatically populated using the editing tools.
( / TODO list, in no particular order, for the recurringly insistent, overly enthusiastic user)
- Snap to grid (AMM)
- Snap to nodes (AMM)
- Coherence groups (AMM & AMP & Asfs) (WIP: TEST ME)
- Free navigation during playback (AMP)
- Transport callbacks (AMP)
- Continuous scrolling in tracks (scrubbing) ( still some bugfixes todo > onLoadedWebAudio scrub)
- Friendly track names for the auditor (AMP & AMfs & AMM)
- Touchscreen compatibility (AMP & AMM)
- Improve touchscreen compatibility: UI size, better multitouch, touch scrub
- Nicer transport bars (AMP)
- Save/recall path presets (AMP)
- Key bindings (playback) (AMP)
- Key binding (navigation) (AMP & AMM)
- Local storage (AMP) aaaaw yeah
- Different themes (AMP & AMM)
- Song format / Album format (Asfs) Replaced by track numbers (still need to integrate in AMP)
- Loaded playlist highlight (AMP)
- Dynamic time display within whole song (AMP)
- Append files (AMM)
- Move whole song (AMM)
- Investigate javascript-generated svg shapes for transports instead of divs (now that's a HUGE one)
- Different modes of playlist creation (AMP) Step by Step / Track by Track / full Album
- Define a way to generate a new tree path for the current track
- Song-specifit themes
- Display song/album metadata
- Autosave
- Bezier links
- Mobile :
- Improve performance on mobile devices (AMM &)
- Adapt display for mobile devices (AMM & AMP)
- Obfuscation:
- "Encrypted" local storage (easy enough)
- Filenames obfuscation
- JSON obfuscation
- Code obfuscation
§ Navigation !
- Added a freeCam mode, to navigate the map during playback
- Added a navigation div in the lower right corner
- Added a "H" (home, until an icon is drawn) button to deactivate freeCam § Touchscreens !
- Added methods to handle touchscreens ! § Scrubbing !
- Added a method to get cursor position on clicked AMgTracks (handleTransports)
- The bulk of scrubbing is handled by AMP & gapless
Tracks now appear as you discover them !
§ Pretty pretty #1
- AMdisplay.animate(): call this before a transform to make it smooth and make sure the transition will play in totality
- AMdisplay.smoothTransitions has a new argument "force" (bool), to override the AMdisplay.animate() lock § Pretty pretty #2
- AMdisplay.focus has a new argument "trackCursor" (bool), that creates a nice panning effect when track is playing. § Pretty pretty #3
- Added a panning background that gives some depth (still a bit rough, with clumsy translate/scale properties)
- Added a bunch of globals to define the z-index of different on-screen elements (not entirely sure if working) § Pretty pretty #4
- Added and "advanced" (todo: consider finding a less presomptuous name) track visibility mode : Track visibility has four modes (INVISIBLE (opacity=0), DISTANT (opacity=0), UNDISCOVERED (1>opacity>0), VISIBLE (opacity=1)) These modes deped on whether the track has already been played, and its position relative to discovered/undiscovered tracks. Now that feels like adventure. ps: Also handles link visibility.
- For good measure, added AMdisplay.focusVisible() method, that adjusts the screen only to visible elements. Feels like even more adventure.
- Oh, and also added a "smooth reveal" for tracks & links, so it's really really nice when it happens. § Pretty pretty #5
- Added random messages in the console on launch to amuse the programmer when he feels stressed (pretty much always).
- Private jokes shamelessly reference Orteil. This guy is too much fun. Highly recommend http://orteil.dashnet.org/cookieclicker/main.js, it's good litterature.
- Massively changed project structure
- AMPlayer and AMMaker now use the same display engine
- Removed pyAMMaker to only use js version
- Changed appearance of unused nodes and links
- Incrased hype (a bit).
- Added song structure representation (with moving cursor)
- Augmented hype.
- Introduced JSON file parsing
- Intruduced playlist generation
- Introduced playback
- Introduced hype
Utilizes Gapless-5 (commit d875325) to allow gapless playback between musical pieces in-browser.
The augmented playlist is stored in a .json file describing the whole song structure. Basically the json describes all possible links between song parts. The player parses the json file and builds a playlist from a randomly chosen path.
TODO:
- document JSON file
- draw song tree
- make the randomness happen during playback
- adapt interface
- program a json generator with graphical interface
A few words about the JSON playlist file:
- Mandatory fields :
.tracks (an object. Each attribute is a track object.) .tracks.init (dummy track object) .tracks.some_track.path (relative path to the corresponding audio track) .tracks.some_track.next (an array of objects {"id":"some_other_track"(mandatory string), "weight":some_weight(optional integer)}. Each object id refers to another track. An empty array indicate a terminal track.)
- Optional fields :
.seed (a string of numbers. Any size will do) .tracks.some_track.next[some_index].weight (An integer. The higher it is the higher the chances of picking this track.)


