新規記事の投稿を行うことで、非表示にすることが可能です。
2023年04月09日
遅くなるWindowsアプリと高速になるJavaScript
ClipBd電卓という名前でエディタで作業中に数式をクリップボードに入れて計算させるツールを作っていた。高速に応答するようにexeサイズを100kb程度になるように作っていたのだが、昨年PCを購入直後は高速だったのに4か月程経過した今は、時に秒単位の遅れがある時がある。比べてJavaScriptはいつも同じ応答時間。
考えて見ればjavascriptがネイティブコードの1/10だとしても10年前のPCのネイティブコードより早いのだ。
という事は10年前にネイティブコード出来ていたことはJavaScriptで出来て当然。
逆に、なぜネイティブアプリがこんなふうに異様に遅くなのか不思議でしょうがないというのは置いておいて
という事で「簡単に計算式から音が出せるツール」についてはJavaScriptで作る事にした。
問題はJavaScriptをブラウザ上でユーザーに開放するのは出来ないこと。
ダウンロードした後は好きにすればよいが、ブラウザ上では制限しないと悪戯し放題になる。
そこで、以下のような方針と 簡易仕様を考えた。 まずは作ってみる。Audioクラスから WebAudioAPIにするのは、その使い勝手を見てから考える。
仕様(方針)
・JavaScriptのeval機能を使って実現するため悪戯防止の為に機能制限をする
・最初は強く機能制限し、後で緩和する
・追加時は他言語へのコンパイルも意識し他言語に翻訳可能な範囲とする
仕様(最初)
・変数名は英字+数字のみで英字は2文字に制限
・関数はMathの1変数関数に制限
・演算子も3項演算子のような複雑なものや文字列関係を除く
・if文/loop文は無い。 > < は正しいなら1 でなければ0
特殊な変数(定数)
PI 円周率(定数)
no 番号 1-110 no==81の時880H
n0 (no-12)/12 の整数が設定される
n1 0=C 2=D 3=E 4=F となる番号 no == n1 + n0*12+12
sw 呼び出したボタンが押されている間1 離されたら0
f 周波数(平均律で設定されるので必要ならn0,n1から求める)
fs サンプルレート
v0 音量が設定(yの値に後で掛け算されるので参照は不要だが音量に応じた応答をする場合用)
v 実行中に与えられる音量
v1〜v9 ツマミ類の為の予備
y 出力値 y=y0*v とするのがよい(実際の出力時v0が掛け算される)
y0 音量を設定する前の出力値
NZ -1〜+1の乱数
他 tm tA tD vS tR が予約されている n,t,vはユーザー用として使わない方がいい
式 変数 定数 関数 演算子 と()
変数 変数名 [a-zA-Z][a-zA-Z]?\d*
定数 小数点付 10進数のみ
関数 sin() cos() tan() log() log10() exp() abs() sqrt() ceil() randowm() round() trunc()
演算子 + - * / > <
文 変数=式;
実装文 文の集まり
プログラム プログラムは文字列で与えられる。
プログラムの解釈の前に全ての改行と空白タブは除かれる。
初期化部(無ラベルのの実装分)の後 A部 D部 S部 R部が続き文字列が終了する
全体の形は
初期化 実装文;
A:秒:実装文;
D:秒:実装文;
S:量:実装文;
R:秒:実装文;
となる。
秒と量は変数又は数値又は数式で設定する 変数・数式が使われても初期化後の値で固定される
量 最大は1なので 0.6のように設定する
ADSRの実装文は指定秒とSはボタン押し中に繰返し実行される
またv 変数が更新される A: 0->1に大きくなり D:1->v0->S量に小さくなり S:指定量 R: s量->0へと小さくなる
vは直線状に変化するので必要なら加工して独自エンベロープを作ればよい。
基本的にvに従う必要はなく独自の処理をすればよい。
A以外は省略出来る。省略時は秒/量は0となる
DSR各部の実装部を省略した場合A部の実装部が呼ばれる
実装した場合はyを更新する式が一つは必要
全体の処理:キーボードが押されると
初期化部が1回実行されと、ADSRの秒量が計算され記録される
その後AとDが指定秒間、繰返し実行される。
ADが終了してもボタンが押されていればSがボタンが離されるまで繰返し実行される
最後に Rが指定秒実行され終了する
A+D中にボタンが離されてもA+DとRは実行される
考えて見ればjavascriptがネイティブコードの1/10だとしても10年前のPCのネイティブコードより早いのだ。
という事は10年前にネイティブコード出来ていたことはJavaScriptで出来て当然。
逆に、なぜネイティブアプリがこんなふうに異様に遅くなのか不思議でしょうがないというのは置いておいて
という事で「簡単に計算式から音が出せるツール」についてはJavaScriptで作る事にした。
問題はJavaScriptをブラウザ上でユーザーに開放するのは出来ないこと。
ダウンロードした後は好きにすればよいが、ブラウザ上では制限しないと悪戯し放題になる。
そこで、以下のような方針と 簡易仕様を考えた。 まずは作ってみる。Audioクラスから WebAudioAPIにするのは、その使い勝手を見てから考える。
仕様(方針)
・JavaScriptのeval機能を使って実現するため悪戯防止の為に機能制限をする
・最初は強く機能制限し、後で緩和する
・追加時は他言語へのコンパイルも意識し他言語に翻訳可能な範囲とする
仕様(最初)
・変数名は英字+数字のみで英字は2文字に制限
・関数はMathの1変数関数に制限
・演算子も3項演算子のような複雑なものや文字列関係を除く
・if文/loop文は無い。 > < は正しいなら1 でなければ0
特殊な変数(定数)
PI 円周率(定数)
no 番号 1-110 no==81の時880H
n0 (no-12)/12 の整数が設定される
n1 0=C 2=D 3=E 4=F となる番号 no == n1 + n0*12+12
sw 呼び出したボタンが押されている間1 離されたら0
f 周波数(平均律で設定されるので必要ならn0,n1から求める)
fs サンプルレート
v0 音量が設定(yの値に後で掛け算されるので参照は不要だが音量に応じた応答をする場合用)
v 実行中に与えられる音量
v1〜v9 ツマミ類の為の予備
y 出力値 y=y0*v とするのがよい(実際の出力時v0が掛け算される)
y0 音量を設定する前の出力値
NZ -1〜+1の乱数
他 tm tA tD vS tR が予約されている n,t,vはユーザー用として使わない方がいい
式 変数 定数 関数 演算子 と()
変数 変数名 [a-zA-Z][a-zA-Z]?\d*
定数 小数点付 10進数のみ
関数 sin() cos() tan() log() log10() exp() abs() sqrt() ceil() randowm() round() trunc()
演算子 + - * / > <
文 変数=式;
実装文 文の集まり
プログラム プログラムは文字列で与えられる。
プログラムの解釈の前に全ての改行と空白タブは除かれる。
初期化部(無ラベルのの実装分)の後 A部 D部 S部 R部が続き文字列が終了する
全体の形は
初期化 実装文;
A:秒:実装文;
D:秒:実装文;
S:量:実装文;
R:秒:実装文;
となる。
秒と量は変数又は数値又は数式で設定する 変数・数式が使われても初期化後の値で固定される
量 最大は1なので 0.6のように設定する
ADSRの実装文は指定秒とSはボタン押し中に繰返し実行される
またv 変数が更新される A: 0->1に大きくなり D:1->v0->S量に小さくなり S:指定量 R: s量->0へと小さくなる
vは直線状に変化するので必要なら加工して独自エンベロープを作ればよい。
基本的にvに従う必要はなく独自の処理をすればよい。
A以外は省略出来る。省略時は秒/量は0となる
DSR各部の実装部を省略した場合A部の実装部が呼ばれる
実装した場合はyを更新する式が一つは必要
全体の処理:キーボードが押されると
初期化部が1回実行されと、ADSRの秒量が計算され記録される
その後AとDが指定秒間、繰返し実行される。
ADが終了してもボタンが押されていればSがボタンが離されるまで繰返し実行される
最後に Rが指定秒実行され終了する
A+D中にボタンが離されてもA+DとRは実行される
2023年04月06日
JavaScript で Audio() 3音にしたら、だいぶ良い感じ
wavFileでダウンロード
3音分のAudioオブジェクトを確保して順に使ってみました。
同時に音が出るとクリップするので少し音量を下げています。
前回の1音のものと比べてブツブツ切れる感じが減っていると思います。
これで「計算による音作りを楽しんでもらう」という目標の為にはEVALでJavaScriptを直接入れてもらうと達成なような・・・でもそうするとJavaScriptで悪戯も可能なので、何か制限をかけて(簡易言語のような方式で)出来ないか考慮中
あ、画面幅によっては、鍵盤押しに甘い部分があるみたい。修正等あればこちらに修正したソースを
2023年04月04日
JavaScripで音を出す 初めの一歩
wavFileでダウンロード
ボタンを押すと音が出ますから注意して下さい。
マウスを波形の上に持ってゆくと波形がスクロールします。
web Audio APIではなく Audioクラスのplayで音を出しています。
そのためにbase64エンコードが必要なようでFileReader()オブジェクトを使う為に音が出るまで遅延が酷い。
やはりweb Audio APIを調べないといけないようです。
JavaScriptソースを見たい人はこちら
3枚の内歯車
偏芯運動する外歯に回転する内歯車の内側に偏芯しながら回転する内歯車
息抜きに