{"id":26187139,"url":"https://github.com/reelyactive/javascript-dsp-examples","last_synced_at":"2026-04-29T05:07:20.136Z","repository":{"id":277568258,"uuid":"932209502","full_name":"reelyactive/javascript-dsp-examples","owner":"reelyactive","description":"Examples of digital signal processing in pure JavaScript.  We believe in an open Internet of Things.","archived":false,"fork":false,"pushed_at":"2025-03-07T12:06:40.000Z","size":31,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-07T12:24:41.007Z","etag":null,"topics":["dsp","fft","hann-window","javascript","rms","velocity-overall"],"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/reelyactive.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-02-13T14:50:19.000Z","updated_at":"2025-03-07T12:06:42.000Z","dependencies_parsed_at":"2025-02-14T17:22:10.396Z","dependency_job_id":"1166da75-6292-4a2d-a9e9-97371d31cc14","html_url":"https://github.com/reelyactive/javascript-dsp-examples","commit_stats":null,"previous_names":["reelyactive/javascript-dsp-examples"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reelyactive%2Fjavascript-dsp-examples","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reelyactive%2Fjavascript-dsp-examples/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reelyactive%2Fjavascript-dsp-examples/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reelyactive%2Fjavascript-dsp-examples/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/reelyactive","download_url":"https://codeload.github.com/reelyactive/javascript-dsp-examples/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243131023,"owners_count":20241176,"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":["dsp","fft","hann-window","javascript","rms","velocity-overall"],"created_at":"2025-03-11T23:39:23.340Z","updated_at":"2025-12-25T05:34:04.151Z","avatar_url":"https://github.com/reelyactive.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"javascript-dsp-examples\n=======================\n\nExamples of digital signal processing in pure JavaScript.  The code is adapted from [node-fft (fft-js)](https://github.com/vail-systems/node-fft/) and remains intended primarily for _example_ purposes as it is __not__ optimised for efficiency.\n\nThe [lib/dsp.js](lib/dsp.js) file is nonetheless coded with reusability and portability in mind, such that it should be straightforward for developers to use part or all of the library of functions in either Node.js (ex: [advlib-ble-gatt](https://github.com/reelyactive/advlib-ble-gatt)) or in client-side applications.\n\n\nExamples\n--------\n\nExamples are provided in the /bin folder, each of which can be run with the command `npm run exampleName`.  Clone this repository and run the commands from its root folder.\n\n### fft\n\nPerform a Fast Fourier Transform on a time series of audio samples.\n\n    npm run fft\n\nThe example uses a 440Hz sine wave of amplitude 1 sampled at 44.1kHz using 32768 samples and should output the following:\n\n```console\nCompleted in ### ms\nPeak magnitude of 0.9934 at 440.1Hz\n```\n\nEdit the parameters in [bin/fft](bin/fft) to test different scenarios.\n\n### velocityOverall\n\nDetermine the velocity overall from a time series of acceleration samples.\n\n    npm run velocityoverall\n\nThe velocity overall is calculated as follows:\n- Remove any DC offset from the samples\n- Split into (up to 4) non-overlapping time series of at least 256 samples\n- Application of Hann window to each time series using `hannWindow(samples)`\n- Conversion to frequency domain using `fft(samples, samplingRate)`\n- Integration over each frequency bin from 10Hz to 1000Hz to obtain velocities\n- RMS of velocities divided by square root of Hann noise bandwidth\n- Average of the (up to 4) overall velocities\n\nAssuming acceleration samples are in m/s^2 and the samplingRate is in Hz, the velocity overall will be in m/s.  The example uses a 63Hz sine wave of magnitude 1g (9.8m/s^2) sampled at 2560Hz using 4096 samples and should output the following:\n\n```console\nPeak acceleration at 62.5Hz with 4.77m/s2 and 0.0121m/s\nvelocityOverall(Set 0): 0.01751m/s\n\nPeak acceleration at 62.5Hz with 4.77m/s2 and 0.0121m/s\nvelocityOverall(Set 1): 0.01751m/s\n\nPeak acceleration at 62.5Hz with 4.77m/s2 and 0.0121m/s\nvelocityOverall(Set 2): 0.01751m/s\n\nPeak acceleration at 62.5Hz with 4.77m/s2 and 0.0121m/s\nvelocityOverall(Set 3): 0.01751m/s\n\nvelocityOverall(*Avg*): 0.01751m/s\nCompleted in ## ms\n```\n\nEdit the parameters in [bin/velocityoverall](bin/velocityoverall) to test different scenarios.\n\n\ndsp.js\n------\n\nThe [lib/dsp.js](lib/dsp.js) file provides a JavaScript implementation of a Fast Fourier Transform (FFT), Hann window, and root mean square calculation.\n\n### fft(samples, samplingRate)\n\nCompute the Fast Fourier Transform of the given Array of samples captured at the given samplingRate (typically in Hz).  For example, [the original test case](https://github.com/vail-systems/node-fft/tree/master?tab=readme-ov-file#command-line) would be implemented as follows:\n\n```javascript\nconst dsp = require('./lib/dsp.js'); // Edit path as required\n\nlet samples = [ 1, 1, 1, 1, 0, 0, 0, 0 ];\nlet samplingRate = 44100;\n\nconsole.log(dsp.fft(samples, samplingRate));\n// {\n//   magnitudes: [ 4, 2.613125929752753, 0, 1.0823922002923938 ],\n//   frequencies: [ 0, 5512.5, 11025, 16537.5 ],\n//   numberOfBins: 4\n// }\n```\n\n### hannWindow(samples)\n\nCompute the Hann window of the given samples, returning the windowed samples as a new Array.\n\n```javascript\nconst dsp = require('./lib/dsp.js'); // Edit path as required\n\nlet values = [ 1, -1, 1, -1, 1 ];\n\nconsole.log(dsp.hannWindow(values));\n// [ 0, -0.4999999999999999, 1, -0.5000000000000001, 0 ]\n```\n\n\n### rms(values)\n\nCompute the root mean square of the given Array of values, for example:\n\n```javascript\nconst dsp = require('./lib/dsp.js'); // Edit path as required\n\nlet values = [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ];\n\nconsole.log('The calculated RMS is', dsp.rms(values));\n// The calculated RMS is 13.674794331177344\n```\n\n\n### dcOffset(values, offset)\n\nOffset the given values by the given offset.  If no offset is provided, the mean of the values will be used as the offset, effectively removing any DC offset from the values.\n\nThe values can be either an Array of Numbers of an Array of Array.  In the latter case, the function will use self-recursion.\n\n```javascript\nconst dsp = require('./lib/dsp.js'); // Edit path as required\n\nlet values = [ 1, -1, 1, -1, 1 ];\n\nconsole.log(dsp.dcOffset(values, 1));\n// [ 2, 0, 2, 0, 2 ]\n\nvalues = [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ];\n\nconsole.log(dsp.dcOffset(values));\n// [ [ -0.5, 0.5 ], [ -0.5, 0.5 ], [ -0.5, 0.5 ] ]\n```\n\n\n### createPowerOfTwoLengthSubSamples(samples, minLength, maxNumberOfSubs)\n\nSplit the given samples into a set of subsamples, up to the given maximum number of subsamples, each of the given minimum length or a larger power of two, whichever is greater, for example:\n\n```javascript\nconst dsp = require('./lib/dsp.js'); // Edit path as required\n\nlet samples = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ];\n\nconsole.log(dsp.createPowerOfTwoLengthSubSamples(samples, 2, 2));\n// [ [ 0, 1, 2, 3 ], [ 6, 7, 8, 9 ] ]\n\nconsole.log(dsp.createPowerOfTwoLengthSubSamples(samples, 2, 4));\n// [ [ 0, 1 ], [ 3, 4 ], [ 6, 7 ], [ 9, 10 ] ]\n```\n\n\nContributing\n------------\n\nDiscover [how to contribute](CONTRIBUTING.md) to this open source project which upholds a standard [code of conduct](CODE_OF_CONDUCT.md).\n\n\nSecurity\n--------\n\nConsult our [security policy](SECURITY.md) for best practices using this open source software and to report vulnerabilities.\n\n\nLicense\n-------\n\nMIT License\n\nCopyright (c) 2025 [reelyActive](https://www.reelyactive.com)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR \nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, \nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE \nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER \nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN \nTHE SOFTWARE.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freelyactive%2Fjavascript-dsp-examples","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freelyactive%2Fjavascript-dsp-examples","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freelyactive%2Fjavascript-dsp-examples/lists"}