diff --git a/js/tones/README.md b/js/tones/README.md new file mode 100644 index 0000000..ddd9b6d --- /dev/null +++ b/js/tones/README.md @@ -0,0 +1,14 @@ +# Speaker + +A JavaScript that plays tones using the `ffi` commands. The advantage of the `ffi` commands is that they can run on firmware without requiring a particular module `.fal` file to exist on the Flipper. Thanks to [Freehuntx](https://github.com/Freehuntx) for the various examples of using `ffi`. + +## How to use +Copy the `speaker.js` file and `speaker_api.js` file to your Flipper Zero, typically the `SD Card/app/Scrips` folder. You can then run the script (on your Flipper press `OK` then choose `Apps`, `Scripts`, `speaker.js`). + +NOTE: The script uses the `__dirpath` variable to locate the `speaker_api.js` file. Some frameworks don't support this variable yet, so you may need to adjust the path to the `speaker_api.js` file. For example change the first line of speaker.js to the following: +```js +let Speaker = load("/ext/apps/Scripts/speaker_api.js"); +``` + +For an `ffi` version of script that obtains the same data as `__dirpath` see [this Discord post]( +https://discord.com/channels/1211622338198765599/1220056596638597327) by @Freehuntx. \ No newline at end of file diff --git a/js/tones/speaker.js b/js/tones/speaker.js new file mode 100644 index 0000000..3ba2f25 --- /dev/null +++ b/js/tones/speaker.js @@ -0,0 +1,4 @@ +let Speaker = load(__dirpath + "/speaker_api.js"); + +Speaker.play(440, 1.0, 500); +Speaker.play(880, 1.0, 500); diff --git a/js/tones/speaker_api.js b/js/tones/speaker_api.js new file mode 100644 index 0000000..ef1746e --- /dev/null +++ b/js/tones/speaker_api.js @@ -0,0 +1,37 @@ +({ + _acquired : false, + _acquire : ffi("int furi_hal_speaker_acquire(int)"), + start : ffi("void furi_hal_speaker_start(float, float)"), + stop : ffi("void furi_hal_speaker_stop()"), + _release : ffi("void furi_hal_speaker_release()"), + acquire : function(timeout) { + if (!this._acquired) { + this._acquired = this._acquire(timeout); + } + return this._acquired; + }, + acquired : function() { + return this._acquired; + }, + release : function() { + if (this._acquired) { + this._release(); + this._acquired = false; + } + }, + play : function(frequency, volume, duration) { + let already_acquired = this.acquired(); + if (!already_acquired) { + this.acquire(1000); + }; + if (this.acquired()) { + this.start(frequency, volume); + delay(duration); + this.stop(); + } + if (!already_acquired) { + this.release(); + } + }, + } +)