{"id":25961782,"url":"https://github.com/pudretediablo/muses","last_synced_at":"2025-10-19T00:15:46.903Z","repository":{"id":57305544,"uuid":"438514222","full_name":"pudretediablo/muses","owner":"pudretediablo","description":"🎛️ JavaScript Audio Mixing Console 🔊","archived":false,"fork":false,"pushed_at":"2022-06-24T14:41:23.000Z","size":456,"stargazers_count":3,"open_issues_count":1,"forks_count":4,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-03-03T04:33:19.222Z","etag":null,"topics":["audio","audiocontext","javascript","module","nodejs"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pudretediablo.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}},"created_at":"2021-12-15T06:04:37.000Z","updated_at":"2024-09-11T14:37:49.000Z","dependencies_parsed_at":"2022-08-28T21:11:41.155Z","dependency_job_id":null,"html_url":"https://github.com/pudretediablo/muses","commit_stats":null,"previous_names":["samuraicorpse/muses"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pudretediablo%2Fmuses","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pudretediablo%2Fmuses/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pudretediablo%2Fmuses/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pudretediablo%2Fmuses/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pudretediablo","download_url":"https://codeload.github.com/pudretediablo/muses/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241913781,"owners_count":20041461,"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":["audio","audiocontext","javascript","module","nodejs"],"created_at":"2025-03-04T19:49:41.891Z","updated_at":"2025-10-19T00:15:46.815Z","avatar_url":"https://github.com/pudretediablo.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eMuses - Audio Mixing Module\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://img.shields.io/badge/ES6-Supported-F7DF1E\"/\u003e\n\u003cimg src=\"https://img.shields.io/badge/CommonJS-Supported-F7DF1E\"/\u003e\n\u003c!--img src=\"https://img.shields.io/node/v/muses-mixer\"/--\u003e\n\u003cimg src=\"https://img.shields.io/badge/Typescript-\u003e=4.5.4-blue\"/\u003e\n\u003cimg src=\"https://packagephobia.com/badge?p=muses-mixer\"/\u003e\n\u003cimg src=\"https://badge.fury.io/js/muses-mixer.svg\"/\u003e\n\u003cimg src=\"https://img.shields.io/npm/dm/muses-mixer\"/\u003e\n\u003cimg src=\"https://img.shields.io/librariesio/release/npm/muses-mixer\"/\u003e\n\u003c!--img src=\"https://img.shields.io/librariesio/dependent-repos/npm/muses-mixer\"/--\u003e\n\u003c!--img src=\"https://img.shields.io/github/last-commit/samuraicorpse/muses\"/--\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\nCreate \u003cb\u003eaudio mixers\u003c/b\u003e to group your audio sources into channels with basic controllers like \u003ci\u003eVolume\u003c/i\u003e, \u003ci\u003ePanning\u003c/i\u003e and \u003ci\u003eBasic EQ\u003c/i\u003e.\n\u003c/p\u003e\n\n## Table of Contents\n\n- [Browsers Support](#browsers-support)\n- [Live Test](#live-test)\n- [Installation](#installation)\n  * [CDN](#cdn)\n  * [NPM](#npm)\n  * [YARN](#yarn)\n- [Autoplay Policy](#autoplay-policy)\n- [Creating an AudioMixer](#creating-an-audiomixer)\n  * [Standard JavaScript](#standard-javascript)\n  * [Module Import](#module-import)\n- [Using Controllers](#using-controllers)\n- [Connecting A Microphone or Any Other StreamSource](#connecting-a-microphone-or-any-other-streamsource)\n- [Connecting *External Sounds*](#connecting-external-sounds)\n- [Adding Custom Effects and AudioNodes](#adding-custom-effects-and-audionodes)\n  * [Manual Connection](#manual-connection)\n  * [Using *Module-Solution*](#using-module-solution)\n- [Documentation](#documentation)\n\n***\n\n## Browsers Support\n\nThis module uses `AudioContext` feature to work properly. No need to worry, most modern browsers have support of this functionality. Also, remember that [electron](https://www.electronjs.org/) uses *Chromium* technology, so you can also use this package to develop your desktop apps.\n\nPlease see [this table](https://caniuse.com/?search=AudioContext) if you have any doubts about the support in the different browsers.\n\n***\n\n## Live Test\n\nSee [this basic example of usage](https://rawcdn.githack.com/samuraicorpse/muses/main/test.html) to test the module in your current browser by loading local files from your device and creating multiple channels.\n\n***\n\n## Installation\n\nThis package was designed to be supported in different frameworks (like [Webpack](https://webpack.js.org/) or any other module bundlers), but you can also just import it in your *HTML* file to start using it. \n\n### CDN\n\n```html\n\u003cscript src=\"//unpkg.com/muses-mixer/dist/muses.min.js\"\u003e\u003c/script\u003e\n```\n\nYou can also download the full library from the [GitHub Repository](https://github.com/samuraicorpse/muses/tree/main/dist) and then import it with the `\u003cscript\u003e` tag in your project.\n\n### NPM\n\n```sh\nnpm install --save muses-mixer\n```\n\n### YARN\n\n```sh\nyarn add muses-mixer\n```\n\n***\n\n## Autoplay Policy\n\nDue to the constant change in web security, in some browsers, it's necessary to wait for the user to perform an action within the website in order to execute the *AudioContext* correctly.\n\nThere are two solutions to prevent the problem:\n\n1. Don't create a [new mixer](#creating-an-audiomixer) automatically on page load.\n2. Or, just call [.resumeContext()](https://samuraicorpse.github.io/muses/classes/AudioMixer.html#resumeContext) method before any *play-audio* function.\n\n**Note:** This problem is common in *Chromium*-based browsers. However, it is important to take into account that it is a problem that can occur in other environments such as applications created in *Electron* or mobile applications.\n\n***\n\n## Creating an AudioMixer\n\nLet's import the library to connect an audio element to the *AudioMixer*.\n\n### Standard JavaScript\n\n```javascript\n// You can use this example if you have imported the library via \u003cscript\u003e tag.\n\n// Create the mixer...\nconst mixer = muses.createAudioMixer( ) ;\n\n// Add a channel with an optional ID...\nconst channel = mixer.addChannel( \"main\" ) ;\n\n// Add an audio source from an existing HTMLAudioElement...\nconst audioElement = document.querySelector( \"audio\" ) ;\nconst track = channel.input( audioElement ) ;\n\n// Create a new audio element automatically by providing an URL...\nconst track2 = channel.input( \"./my-file.mp3\" ) ;\n```\n\n### Module Import\n\n```javascript\nimport { AudioMixer, createAudioMixer } from \"muses-mixer\" ;\n\nconst mixer = new AudioMixer( ) ;\n// or\nconst mixer = createAudioMixer( ) ;\n\n// Then you can just use the previous \"Standard JavaScript\" example.\n```\n\n## Using Controllers\n\nIs pretty easy to use the *mixer*, but you need to understand that *channels* are the «real players», the *mixer* is just a way to keep all *channels* grouped for better organization, to send a final audio-signal to the speakers.\n\nLike a basic AudioMixer in the real life, all channels have a few controllers to modify the audio signal: *Gain*, *Panning* and *Basic Equalization (Low, Mid and High)*\n\n```javascript\n// All connected audio-sources to the channel will be affected by the parameters in each controller.\n\nchannel.volume = 0.5 ; // \u003c= 0 Silence, 1 Max Volume.\n\nchannel.panning = -1 ; // \u003c= -1 Left, 1 Right, 0 Center.\n\n// All equalization controllers can be changed between -40dB and 36dB (don't include \"dB\" string).\n// WARNING: You can actually set a higher number, but it will only cause an annoying and distorted sound.\nchannel.lowEQ = 20 ; // \u003c= Increase Low frequencies.\nchannel.midEQ = 0 ; // \u003c= Reset Mid frequencies.\nchannel.highEQ = -40 ; // \u003c= Remove High frequencies.\n```\n\n```javascript\n// you can also modify the AudioMixer volume.\nmixer.volume = 0.2 ;\n```\n\n***\n\n## Connecting A Microphone or Any Other StreamSource\n\nRemember, this module uses `AudioContext` to work, so is really easy to connect any other audio source like a microphone input.\n\n```javascript\n// Prepare our mixer and channels first.\nconst mixer = muses.createAudioMixer( ) ;\nconst channel = mixer.addChannel( \"mic\" ) ;\n\n// Now, let's request the microphone input with the getUserMedia API.\nnavigator\n  .mediaDevices\n  .getUserMedia( { video : false, audio : true } )\n  .then( function( stream ) {\n    // Using the audio-context from our mixer just to prevent any error.\n    mic = mixer.ctx.createMediaStreamSource( stream ) ;\n    // Connect to the channel.\n    channel.input( mic ) ;\n    // or\n    mic.connect( channel.inputNode ) ;\n  } )\n  .catch( err =\u003e {\n    console.error( \"GET_MIC_STREAM_ERROR ~\u003e\", err ) ;\n  } ) ;\n```\n\nWe have included a little *async-function* just to get microphone stream-node quickly (basically the process of the previous example, just adding it into a `Promise`).\n\n```javascript\nmuses\n  .getMicStreamNode( )\n  .then( streamNode =\u003e {\n    channel.input( streamNode ) ;\n  } )\n  .catch( err =\u003e {\n    console.error( \"GET_MIC_STREAM_ERROR ~\u003e\", err ) ;\n  } ) ;\n```\n\nYou can try this feature in the [Live Test](#live-test) example.\n\n***\n\n## Connecting *External Sounds*\n\nMany *audio-related* packages use the same structure, creating *AudioNodes* from the *AudioContext* and making connections to get an output signal. So, if the package provide a audio-node connection method, you can just use **channel.inputNode** property as an input for that connection method.\n\nLet's see an example with [PizzicatoJS](https://www.npmjs.com/package/pizzicato) package.\n```javascript\n// First, import both pacakages (Muses and Pizzicato) only if you're using modules instead \u003cscript\u003e tags in html.\nimport { createAudioMixer } from \"muses-mixer\" ;\nimport Pizzicato from \"pizzicato\" ;\n\n// Create a mixer and a channel.\nconst mixer = muses.createAudioMixer( ) ;\nconst channel = mixer.addChannel( \"main-channel\" ) ;\n\n// Create a sound from Pizzicato\nvar sound = new Pizzicato.Sound( { \n    source : 'file' ,\n    options: { path: './audio/sound.wav' }\n} , function( ) {\n    console.log('sound file loaded!');\n} ) ;\n\n// Finally, connect the previous sound to the channel.\nsound.connect( channel.inputNode ) ;\n\n```\n\n***\n\n## Adding Custom Effects and AudioNodes\n\nIt is very easy to add new effects and nodes to the channels of our mixer, you just need to understand the connection structure between the channel and the mixer itself.\n\n```\n                      Channel                                         Mixer\n┌──────────────────────────────────────────────────┐            ┌──────────────┐\n│                                                  │            │              │\n  ┌─────────┐   ┌────────────────┐    ┌──────────┐   ┌─────────┐   ┌─────────┐\n  │inputNode├──►│BasicControllers├───►│outputNode├──►│delayNode├──►│inputNode│\n  └─────────┘   │      Nodes     │    └──────────┘   └────▲────┘   └─────────┘\n                └────────────────┘                        │\n                                                     CustomEffect\n```\n\nAs you can see, what is really important is the channel's `outputNode` and the mixer's `inputNode`. Just break the link between these two elements to introduce new `AudioNodes` between them.\n\n**Tip:** If you're looking for *basic-effects* like **delay**, **distortion**, **compressor**, etc. I recommend to use [PizzicatoJS](https://www.npmjs.com/package/pizzicato), then, just connect the sounds to the mixer just like [this](#connecting-external-sounds)\n\n### Manual Connection\n\n```javascript\n// [!] Rememeber to create your mixer and channels first.\n// Create our delayNode from audio-context.\nconst delayNode = muses.getAudioContext( ).createDelay( 0.5 ) ;\n\n// Disconnect channel-output from all receivers (eg. the mixer).\nchannel.outputNode.disconnect( ) ;\n// Connect output to delayNode and delayNode's output to mixer's input.\nchannel.outputNode.connect( delayNode ) ;\ndelayNode.connect( mixer.inputNode ) ;\n\n// Removing the node.\nchannel.outputNode.disconnect( delayNode ) ;\nchannel.outputNode.connect( mixer.inputNode ) ;\n```\n\n### Using *Module-Solution*\n\n```javascript\n// Just call one method in your channel instance.\nchannel.addNode( delayNode ) ;\n// By default, the channel will re-connect all custom nodes for safety. But you can reset the nodes-connection with...\nchannel.reconnectNodes( ) ;\n\n// Remove one custom-node ;\nchannel.removeNode( delayNode ) ;\n// or\nchannel.removeAllNodes( ) ;\n```\n\n***\n\n## Documentation\n\nTo see the full documentation *(all classes, properties and methods)*, please visit the [official website](https://samuraicorpse.github.io/muses).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpudretediablo%2Fmuses","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpudretediablo%2Fmuses","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpudretediablo%2Fmuses/lists"}