From 3f6454c1340c74e5b226442b8345799e66928470 Mon Sep 17 00:00:00 2001 From: grymmjack Date: Tue, 30 May 2023 20:09:23 -0400 Subject: [PATCH] Added QB SOUND keyword with validation and support for additional shapes as provded by the WebAudio API OscillatorNode object. --- .gitignore | 1 + codemirror/qb-lang.js | 2 +- qb.js | 24 ++++++++++++++++++++++++ qb2js.js | 1 + tools/qb2js.bas | 1 + 5 files changed, 28 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index fcf6b59..ed8264e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ tools/qb2js.exe qbjs.zip .vscode/launch.json .vscode/settings.json +.vscode/tasks.json diff --git a/codemirror/qb-lang.js b/codemirror/qb-lang.js index b963150..6aae4df 100644 --- a/codemirror/qb-lang.js +++ b/codemirror/qb-lang.js @@ -54,7 +54,7 @@ CodeMirror.defineMode("qbjs", function(conf, parserConf) { 'lbound', 'left', 'lcase', 'len', 'line', 'locate', 'log', 'ltrim', 'mid', 'mki', 'mkl', 'oct', 'paint', 'point', 'preset', 'print', 'pset', 'right', 'rtrim', 'randomize', 'read', 'restore', 'rnd', - 'screen', 'shared', 'sgn', 'sin', 'sleep', 'space', 'sqr', + 'screen', 'shared', 'sgn', 'sin', 'sleep', 'sound', 'space', 'sqr', 'str', 'swap', 'tan', 'time', 'timer', 'ubound', 'ucase', 'val', 'varptr', 'window', 'mkdir', 'chdir', 'rmdir', 'kill', 'name', 'files', 'open', 'close', 'lof', 'eof', 'put', 'get', 'freefile', diff --git a/qb.js b/qb.js index 7529ddf..5b29654 100644 --- a/qb.js +++ b/qb.js @@ -2815,6 +2815,30 @@ var QB = new function() { } }; + this.sub_Sound = async function(freq, duration, shape) { + if (shape == undefined) { shape = "square"; } + if (!(freq == 0 || (freq >= 32 && freq <= 32767))) { + throw new Error("Frequency invalid - valid: 0 (delay), 32 to 32767"); + } + var valid_shapes = ["sine", "square", "sawtooth", "triangle"]; + if (!valid_shapes.includes(shape.toLowerCase())) { + throw new Error("Shape invalid - valid: " + valid_shapes.join(', ')); + } + if (freq == 0) { + await GX.sleep(duration); + } else { + var context = new AudioContext(); + var oscillator = context.createOscillator(); + oscillator.type = shape; + oscillator.frequency.value = freq; + oscillator.connect(context.destination); + oscillator.start(); + setTimeout(await function () { + oscillator.stop(); + }, duration); + } + }; + this.func_Sqr = function(value) { return Math.sqrt(value); }; diff --git a/qb2js.js b/qb2js.js index cfef177..d95a192 100644 --- a/qb2js.js +++ b/qb2js.js @@ -3366,6 +3366,7 @@ if (QB.halted()) { return; } await sub_AddQBMethod( "FUNCTION" , "Sgn" , False); await sub_AddQBMethod( "FUNCTION" , "Sin" , False); await sub_AddQBMethod( "SUB" , "Sleep" , True); + await sub_AddQBMethod( "SUB" , "Sound" , True); await sub_AddQBMethod( "FUNCTION" , "Space" , False); await sub_AddQBMethod( "FUNCTION" , "String" , False); await sub_AddQBMethod( "FUNCTION" , "Sqr" , False); diff --git a/tools/qb2js.bas b/tools/qb2js.bas index aca947f..c50de78 100644 --- a/tools/qb2js.bas +++ b/tools/qb2js.bas @@ -3581,6 +3581,7 @@ Sub InitQBMethods AddQBMethod "FUNCTION", "Sgn", False AddQBMethod "FUNCTION", "Sin", False AddQBMethod "SUB", "Sleep", True + AddQBMethod "SUB", "Sound", True AddQBMethod "FUNCTION", "Space", False AddQBMethod "FUNCTION", "String", False AddQBMethod "FUNCTION", "Sqr", False