├── .gitignore ├── .jshintrc ├── .travis.yml ├── Gruntfile.js ├── LICENSE ├── README.md ├── README.org ├── bower.json ├── bundle └── SAME.js ├── etc ├── generate-lib-fixtures.js └── generate-test-fixtures.js ├── examples ├── client.js ├── client │ ├── index.html │ └── js │ │ ├── index.js │ │ └── lib └── server.js ├── index.js ├── lib ├── fixtures │ ├── county.json │ ├── same.js │ └── state.json ├── same-validator.js ├── same.js ├── util.js ├── wav.js ├── writer.js └── writers │ ├── browser.js │ └── node.js ├── node_modules └── lib ├── package.json └── test ├── fixtures ├── renderTone.gz ├── render_complete.gz └── render_empty.gz ├── lib ├── fixtures.js └── mocks.js └── unit ├── lib └── fixtures.spec.js ├── same-validator.spec.js ├── same.spec.js ├── util.spec.js └── wav.spec.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | test/reports/ 3 | .hg/ 4 | .hgignore 5 | .hgtags 6 | *.wav -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "laxbreak": true, 3 | "laxcomma": true, 4 | "loopfunc": true, 5 | "eqeqeq": true, 6 | "globals": { 7 | "global": false, 8 | "window": false 9 | } 10 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | 3 | language: node_js 4 | 5 | node_js: 6 | - "node" 7 | 8 | before_install: 9 | - npm install -g npm 10 | 11 | before_script: 12 | - npm install -g grunt-cli 13 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | var grunt = require('grunt'); 2 | 3 | module.exports = function(grunt) { 4 | grunt.loadNpmTasks('grunt-shell'); 5 | grunt.loadNpmTasks('grunt-mocha-istanbul'); 6 | 7 | grunt.initConfig({ 8 | shell: { 9 | serverDemo: { 10 | command: 'node examples/server.js' 11 | }, 12 | 13 | clientDemo: { 14 | command: 'node examples/client.js' 15 | }, 16 | 17 | testUnit: { 18 | command: 'node_modules/.bin/mocha test/unit/*.spec.js test/unit/**/*.spec.js' 19 | }, 20 | 21 | jshint: { 22 | command: 'find lib test -not -path \'test/reports/*\' -name \'*.js\' | xargs jshint' 23 | }, 24 | 25 | browserify: { 26 | command: 'browserify index.js -s SAME -o bundle/SAME.js' 27 | } 28 | }, 29 | 30 | mocha_istanbul: { 31 | coverage: { 32 | src: 'test/unit', 33 | options: { 34 | coverageFolder: 'test/reports/', 35 | mask: '*.spec.js' 36 | } 37 | } 38 | } 39 | }); 40 | 41 | grunt.registerTask('browserify', 'Bundle the library for browsers', 42 | ['shell:browserify']); 43 | 44 | grunt.registerTask('demo:client', 'Run the client-side demo server', 45 | ['browserify', 'shell:clientDemo']); 46 | grunt.registerTask('demo:server', 'Run the server-side demo', 47 | ['shell:serverDemo']); 48 | 49 | grunt.registerTask('jshint', 'Run jshint check', 50 | ['shell:jshint']); 51 | grunt.registerTask('test', 'Run unit tests', 52 | ['shell:testUnit']); 53 | grunt.registerTask('cover', 'Run unit tests + coverage report', 54 | ['mocha_istanbul:coverage']); 55 | grunt.registerTask('validate', 'Run all checks and generate coverage', 56 | ['shell:jshint', 57 | 'mocha_istanbul:coverage']); 58 | }; 59 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Aaron Miller 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # same-encoder: Isomorphic SAME header and footer encoding 2 | 3 | 4 | 5 | 6 | 7 | # What? 8 | 9 | Wikipedia: "[Specific Area Message Encoding](https://en.wikipedia.org/wiki/Specific_Area_Message_Encoding) is the protocol used to encode the [Emergency Alert System](https://en.wikipedia.org/wiki/Emergency_Alert_System) (EAS) and [NOAA Weather Radio](https://en.wikipedia.org/wiki/NOAA_Weather_Radio_All_Hazards) (NWR) in the U.S. and [Weatheradio Canada](https://en.wikipedia.org/wiki/Weatheradio_Canada) in Canada." 10 | 11 | In EAS and NWR transmissions, SAME-encoded data is presented as a pair of AFSK data bursts, one a message header encoding the essentials of the alert, the other a message footer which indicates only the end of the transmission. This library encodes EAS header and footer message bursts as LPCM audio data in a RIFF WAVE container. Also provided are output modules for Node.js (emitting a .wav file) and browser environments (emitting an