{"analyzedAt":"2022-06-28T22:47:44.779Z","collected":{"metadata":{"name":"web-audio-scheduler","scope":"unscoped","version":"1.4.0","description":"Event Scheduler for Web Audio API","keywords":["WebAudioAPI","event","scheduler","timeline"],"date":"2016-12-22T04:45:31.934Z","author":{"name":"Nao Yonamine","email":"mohayonao@gmail.com","username":"mohayonao"},"publisher":{"username":"mohayonao","email":"mohayonao@gmail.com"},"maintainers":[{"username":"mohayonao","email":"mohayonao@gmail.com"}],"repository":{"type":"git","url":"git+https://github.com/mohayonao/web-audio-scheduler.git"},"links":{"npm":"https://www.npmjs.com/package/web-audio-scheduler","homepage":"https://github.com/mohayonao/web-audio-scheduler/","repository":"https://github.com/mohayonao/web-audio-scheduler","bugs":"https://github.com/mohayonao/web-audio-scheduler/issues"},"license":"MIT","devDependencies":{"babel-cli":"^6.18.0","babel-preset-es2015":"^6.18.0","babel-preset-power-assert":"^1.0.0","babel-register":"^6.18.0","babelify":"^7.3.0","browserify":"^13.1.1","eslint":"^3.12.2","mocha":"^3.2.0","npm-run-all":"^3.1.2","nyc":"^10.0.0","power-assert":"^1.4.2","run-with-mocha":"^1.1.0","sinon":"^1.17.6","tickable-timer":"^1.0.0","uglify-js":"^2.7.5","web-audio-test-api":"^0.5.2","which":"^1.2.12"},"releases":[{"from":"2022-05-29T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":0},{"from":"2022-03-30T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":0},{"from":"2021-12-30T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":0},{"from":"2021-06-28T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":0},{"from":"2020-06-28T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":0}],"hasTestScript":true,"hasSelectiveFiles":true,"readme":"# web-audio-scheduler\n[![Build Status](https://img.shields.io/travis/mohayonao/web-audio-scheduler.svg?style=flat-square)](https://travis-ci.org/mohayonao/web-audio-scheduler)\n[![NPM Version](https://img.shields.io/npm/v/web-audio-scheduler.svg?style=flat-square)](https://www.npmjs.org/package/web-audio-scheduler)\n[![License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](https://mohayonao.mit-license.org/)\n\n> Event Scheduler for Web Audio API\n\nThis module is developed based on the idea of this article.\n\n - https://www.html5rocks.com/en/tutorials/audio/scheduling/\n\n## Installation\n\n###### npm\n\n```\nnpm install web-audio-scheduler\n```\n\n###### downloads\n\n- [web-audio-scheduler.js](https://raw.githubusercontent.com/mohayonao/web-audio-scheduler/master/build/web-audio-scheduler.js)\n- [web-audio-scheduler.min.js](https://raw.githubusercontent.com/mohayonao/web-audio-scheduler/master/build/web-audio-scheduler.min.js)\n\n## Examples\n\n[metronome](https://mohayonao.github.io/web-audio-scheduler/)\n\n```js\nconst audioContext = new AudioContext();\nconst sched = new WebAudioScheduler({ context: audioContext });\nlet masterGain = null;\n\nfunction metronome(e) {\n  const t0 = e.playbackTime;\n\n  sched.insert(t0 + 0.000, ticktack, { frequency: 880, duration: 1.0 });\n  sched.insert(t0 + 0.500, ticktack, { frequency: 440, duration: 0.1 });\n  sched.insert(t0 + 1.000, ticktack, { frequency: 440, duration: 0.1 });\n  sched.insert(t0 + 1.500, ticktack, { frequency: 440, duration: 0.1 });\n  sched.insert(t0 + 2.000, metronome);\n}\n\nfunction ticktack(e) {\n  const t0 = e.playbackTime;\n  const t1 = t0 + e.args.duration;\n  const osc = audioContext.createOscillator();\n  const amp = audioContext.createGain();\n\n  osc.frequency.value = e.args.frequency;\n  osc.start(t0);\n  osc.stop(t1);\n  osc.connect(amp);\n\n  amp.gain.setValueAtTime(0.5, t0);\n  amp.gain.exponentialRampToValueAtTime(1e-6, t1);\n  amp.connect(masterGain);\n\n  sched.nextTick(t1, () => {\n    osc.disconnect();\n    amp.disconnect();\n  });\n}\n\nsched.on(\"start\", () => {\n  masterGain = audioContext.createGain();\n  masterGain.connect(audioContext.destination);\n});\n\nsched.on(\"stop\", () => {\n  masterGain.disconnect();\n  masterGain = null;\n});\n\ndocument.addEventListener(\"visibilitychange\", () => {\n  if (document.visibilityState === \"visible\") {\n    sched.aheadTime = 0.1;\n  } else {\n    sched.aheadTime = 1.0;\n    sched.process();\n  }\n});\n\ndocument.getElementById(\"start-button\").addEventListener(\"click\", () => {\n  sched.start(metronome);  \n});\n\ndocument.getElementById(\"stop-button\").addEventListener(\"click\", () => {\n  sched.stop(true);\n});\n```\n\n## API\n### WebAudioScheduler\n- `WebAudioScheduler(opts = {})`\n  - `context: AudioContext`\n  - `interval: number` _default: **0.025** (25ms)_\n  - `aheadTime: number` _default: **0.1** (100ms)_\n  - `timerAPI: object` _default: `window || global`_\n\n#### Instance properties\n- `context: AudioContext`\n- `interval: number`\n- `aheadTime: number`\n- `timerAPI: object`\n- `playbackTime: number`\n- `currentTime: number`\n- `state: string`\n- `events: object[]`\n\n#### Instance methods\n- `start([ callback: function, args: any ]): self`\n  - Start the timeline.\n  - The `callback` is inserted in the head of the event list if given.\n- `stop([ reset = true: boolean ]): self`\n  - Stop the timeline.\n  - The event list is cleared if `reset` is truthy.\n- `insert(time: number, callback: function, [ args: any ]): number`\n  - Insert the `callback` into the event list.\n  - The return value is `schedId`. It is used to `.remove()` the callback.\n- `nextTick([ time: number ], callback: function, [ args: any ]): number`\n  - Same as `.insert()`, but this callback is called at next tick.\n  - This method is used to disconnect an audio node at the proper timing.\n- `remove(schedId: number): number`\n  - Remove a callback function from the event list.\n- `removeAll(): void`\n  - Remove all callback functions from the event list.\n- `process(): void`\n  - process events immediately (this is useful when transition to background tabs)\n\n#### Events\n- `\"start\"`\n  - emitted when the scheduler started.\n- `\"stop\"`\n  - emitted when the scheduler stopped.\n- `\"process\"`\n  - emitted before each scheduler process.\n- `\"processed\"`\n  - emitted after each scheduler process.\n\n#### Callback\nA callback function receives a schedule event and given arguments at `.insert()`.\n\nA schedule event has two parameters.\n\n  - `playbackTime: number`\n  - `args: any`\n\n```js\nsched.insert(0, callback, [ 1, 2 ]);\n\nfunction callback(e) {\n  assert(e.playbackTime === 0);\n  assert(e.args[0] === 1);\n  assert(e.args[1] === 2);\n}\n```\n\n## Customize\n\n### timeline\n\n```\ntime(ms) 0----25---50---75---100--125--150--175--200---->\n         =====|====|====|====|    |    |    |    |\n         |    =====|====|====|====|    |    |    |\n         |    |    =====|====|====|====|    |    |\n         |    |    |    | ===|====|====|====|==  |\n         |    |    |    |    | ===|====|====|====|==\n         :    :    :    :    :    :    :    :    :\n         |<-->|    :    :      |<------------------>|\n         interval (25ms)       aheadTime (100ms)\n                             = range of execution to events\n```\n\nThe below example is the same configuration as defaults.\n\n```js\nconst sched = new WebAudioScheduler({ interval: 0.025, aheadTime: 0.1 });\n```\n\n### timerAPI\n\nTimerAPI is used instead of the native timer API. TimerAPI should have two functions, `setInterval` and `clearInterval`.\n\n- [mohayonao/worker-timer](https://github.com/mohayonao/worker-timer)\n  - A timer that is stable in any situation. e.g. tabs in background, the invisible state page.\n- [mohayonao/tickable-timer](https://github.com/mohayonao/tickable-timer)\n  - Manual ticking `setTimeout` / `setInterval` (for test CI)\n\nThe below example uses stable-timer instead of the native timer API.\n\n```js\nconst WorkerTimer = require(\"worker-timer\");\nconst sched = new WebAudioScheduler({ timerAPI: WorkerTimer });\n```\n\n## License\n\nMIT"},"npm":{"downloads":[{"from":"2022-06-27T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":3},{"from":"2022-06-21T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":23},{"from":"2022-05-29T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":171},{"from":"2022-03-30T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":522},{"from":"2021-12-30T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":809},{"from":"2021-06-28T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":1727}],"starsCount":1},"github":{"homepage":"http://mohayonao.github.io/web-audio-scheduler/","starsCount":85,"forksCount":11,"subscribersCount":3,"issues":{"count":13,"openCount":1,"distribution":{"3600":8,"10800":2,"32400":0,"97200":1,"291600":0,"874800":1,"2624400":0,"7873200":0,"23619600":0,"70858800":0,"212576400":1},"isDisabled":false},"contributors":[{"username":"mohayonao","commitsCount":57}],"commits":[{"from":"2022-06-21T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":0},{"from":"2022-05-29T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":0},{"from":"2022-03-30T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":0},{"from":"2021-12-30T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":0},{"from":"2021-06-28T00:00:00.000Z","to":"2022-06-28T00:00:00.000Z","count":0}],"statuses":[{"context":"continuous-integration/travis-ci/push","state":"success"},{"context":"github/pages","state":"success"}]},"source":{"files":{"readmeSize":5961,"testsSize":14752},"badges":[{"urls":{"original":"https://img.shields.io/travis/mohayonao/web-audio-scheduler.svg?style=flat-square","service":"https://api.travis-ci.org/mohayonao/web-audio-scheduler.svg","shields":"https://img.shields.io/travis/mohayonao/web-audio-scheduler.svg","content":"https://img.shields.io/travis/mohayonao/web-audio-scheduler.json"},"info":{"service":"travis","type":"build"}},{"urls":{"original":"https://img.shields.io/npm/v/web-audio-scheduler.svg?style=flat-square","shields":"https://img.shields.io/npm/v/web-audio-scheduler.svg","content":"https://img.shields.io/npm/v/web-audio-scheduler.json"},"info":{"service":"npm","type":"version","modifiers":{"type":"v"}}}],"linters":["eslint"]}},"evaluation":{"quality":{"carefulness":0.9199999999999999,"tests":0.85,"health":1,"branding":0.3},"popularity":{"communityInterest":101,"downloadsCount":174,"downloadsAcceleration":0.18285768645357692,"dependentsCount":0},"maintenance":{"releasesFrequency":0.9,"commitsFrequency":0.9,"openIssues":1,"issuesDistribution":0.9}},"score":{"final":0.6732048970507245,"detail":{"quality":0.9659558362717634,"popularity":0.09557403431875788,"maintenance":0.9999063833075152}}}