{"id":13510271,"url":"https://github.com/mikehelland/omg-music","last_synced_at":"2025-03-30T15:31:06.549Z","repository":{"id":216998409,"uuid":"58564800","full_name":"mikehelland/omg-music","owner":"mikehelland","description":"Music making, remixing, and collaborating tools for the web","archived":false,"fork":false,"pushed_at":"2022-05-12T02:02:12.000Z","size":3888,"stargazers_count":77,"open_issues_count":4,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-11-01T10:35:18.569Z","etag":null,"topics":["electronica","gallery","html5-audio","html5-canvas","music","webaudio","webaudio-api","webaudioapi"],"latest_commit_sha":null,"homepage":"https://openmusic.gallery","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mikehelland.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-05-11T17:09:19.000Z","updated_at":"2024-09-11T12:34:59.000Z","dependencies_parsed_at":null,"dependency_job_id":"55f41646-de26-487d-8756-4f6d846dfe74","html_url":"https://github.com/mikehelland/omg-music","commit_stats":null,"previous_names":["mikehelland/omg-music"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikehelland%2Fomg-music","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikehelland%2Fomg-music/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikehelland%2Fomg-music/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikehelland%2Fomg-music/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mikehelland","download_url":"https://codeload.github.com/mikehelland/omg-music/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246338814,"owners_count":20761442,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["electronica","gallery","html5-audio","html5-canvas","music","webaudio","webaudio-api","webaudioapi"],"created_at":"2024-08-01T02:01:31.465Z","updated_at":"2025-03-30T15:31:01.539Z","avatar_url":"https://github.com/mikehelland.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","music"],"sub_categories":[],"readme":"# OMG Music\n\nOMG Music is a \"Music Context\" that wraps the web browser's AudioContext. \n\nMusic created and shared in the OMG Music format contains information like key and time signatures that make the \nmodification and mutation of beats and melodies simple.\n\nIt designed for the advancement of \"open music\", where music is shared in a \"source code\" format that promotes remixing.\n\nThis app supplies the core music functionality for the [OMG Platform](https://github.com/mikehelland/openmedia.gallery)\n\n## OMG Song File Format\n\nThe song and its parts are a JSON file. \n\nAn overview of the file format looks like this:\n\n     let song = {\n          parts: [{name: \"Piano\", ...}],\n          sections: [\n               {\n                    name: \"Verse\",\n                    parts: [{name: \"Piano\", ...}]\n               }\n          ],\n          beatParams: {...},\n          keyParams: {...},\n          name: \"My Song\"\n     }\n\nThe song is separated \"horizontally\" into **parts** (such as piano, drums, guitar) and \"vertically\" into **sections**\n(such as Intro, Verse, Chorus).\n\nThe `song.parts` array is the *part header*, which contains information about how to make sounds from the part. \nThis may contain a list of MP3 or WAV files contained in a **Sound Set**. Or a the part might generate sounds from\nWeb Audio API's built in oscillators, or the [WebAudioFont](https://surikov.github.io/webaudiofont/).\n\nEach section in `song.sections` also has a `parts` array. This contains information about when to play each sound, producing a melody or a beat.\n\nThe `parts` in `song.sections` have either a `notes` array, or a `tracks` array. \n\n### notes Vs tracks\n\nThe `notes` array contains a list of objects that describe what note to play and for how long. Like this:\n\n     notes = [\n          {note: 0, scaledNote: 60, beats: 2.0},\n          {rest: true, beats: 1.0},\n          {note: 1, scaledNote: 62, beats: 1.0}\n     ]\n\nThe `scaledNote` is a MIDI note determined from the key of the song and octave of the instrument\nof the part. In this case a middle C (MIDI note 60) is played for a two beats, then a one beat rest, \nthen the D above it (MIDI note 62) is played for one beat.\n\nThe `tracks` array can contain multiple tracks (think bass drum, snare drum, high-hat). Each track \nis an array that contains an element for each subbeat in the current part. If the value N is a number between 0 and 1,\nthe audio sample for that track is played at volume N. The entire audio sample is played.\n\nUse `notes` when you need to determine how long an audio sample is played (such as in a melody or bassline).\n\n### Classes\n\nTHe main class is `OMusicContext`. This can `load()` songs or parts in the OMG format, or create blanks.\n\nThe `OMGSong` and `OMGSongPart` classes can be thought of as an \"exo-skeleton\" for the data. For example, the following data:\n\n     let songData = {\n          parts: [{name: \"Piano\", ...}],\n          sections: [\n               {\n                    name: \"Verse\",\n                    parts: [{name: \"Piano\", ...}]\n               }\n          ],\n          beatParams: {...},\n          keyParams: {...},\n          name: \"My Song\"\n     }\n\nWhen loaded becomes:\n\n     omgSong = {\n          data: songData,\n          parts: {\n               \"Piano: {data: partHeaderData}\n          }\n          Sections: {\n               \"Verse\": {\n                    data: sectionData,\n                    parts: {\n                         \"Piano\": {data: partDetailData}\n                    }\n               }\n          }\n     }\n\nThe original `songData` still exists as `omgSong.data`. The `parts` and `sections` arrays\nof the data have been turned into objects/dictionaries. This is for easier access to parts and sections\nby name, which is useful when passing data through websockets and other layers.\n\nAll elements of `songData` can be accessed individually through these wrapper objects (`OMGSong` and `OMGSongPart`). \nThe wrapper allows the player, and the context, and the user interfaces to attach temporary things which \ndo not need to saved are cannot be stringified. For example, the GainNode for each part is on the `OMGSongPart` that \nwraps its the parts data.\n\nThese audio nodes needs to be associated with the part, but cannot be stringified, and need to be created for each session.\nSo they go onto the wrapper.\n\n## Examples\n\nHere are some apps where OMG Music is used:\n\n* [OpenMedia.Gallery](https://openmedia.gallery) social networking sites\n* [Dawesome](https://openmedia.gallery/apps/dawesome) [(github)](https://github.com/mikehelland/dawesome)\n* [Techno GAUNTLET](https://openmedia.gallery/apps/gauntlet)\n* [OMG Meme Maker](https://openmedia.gallery/apps/meme/editor.htm)\n* Song Processor\n\n\n# Using the Client: Game Dev Example\n\n## How to: https://www.youtube.com/watch?v=TXpPFBkpXp0\n\n(Note, the video has outdated code)\n\n## When the game is loading:\n\n     import OMusicContext from \"https://openmedia.gallery/apps/music/js/omusic.js\"\n     \n     var music = new OMusicContext()\n     var {song, player} = await music.load(\"http://openmusic.gallery/data/1333\")\n\n## When the game starts:\n\n     game.music.play()\n\n## Increase BPM and key when difficulty increases:\n\n     music.beatParams.bpm += 20\n\n     music.keyParams.rootNote++\n     music.rescaleSong()\n\n## When the game ends:\n\n     music.stop()\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikehelland%2Fomg-music","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmikehelland%2Fomg-music","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikehelland%2Fomg-music/lists"}