質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.53%
Web Audio

Web Audioは、音声を処理・合成するためのWebアプリケーション向けJavaScript APIです。HTML5から導入されました。オーディオソースの選択、エフェクト・ビジュアライゼーションの追加、パンニングなど特殊効果の適用など多くの機能を持ちます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

1回答

130閲覧

Web Audio API オシレーターの使い方 時間コントロールの方法が分からない

xmg

総合スコア19

Web Audio

Web Audioは、音声を処理・合成するためのWebアプリケーション向けJavaScript APIです。HTML5から導入されました。オーディオソースの選択、エフェクト・ビジュアライゼーションの追加、パンニングなど特殊効果の適用など多くの機能を持ちます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2023/11/30 04:41

実現したいこと

Web Audio API を用いて、時間経過に沿って一連の音階を発生させたいが
setInterval() などを使用することは望ましくないため
どうやって、一定の時刻に指定された音階の音を出させたらよいかが分からない

質問の内容  詳細

下記のコードの見本のような方法で、あらかじめ用意しておいた時系列データーの音階を再生させたい

困っている問題

Web Audio API では、指定された秒数のところで、予定どおりの音階を鳴らす設定になっている

ところが、javascript においては、指定された秒数になる前に、4つも 5つも先の音階のノード設定を待たずに実行してしまうため、
setTimeout() などの方法で、無限大の音階設定をいちいち指定しなければならないことになりそうで
LOOP を使う方法も思いつかない

下記の見本を参照してください

該当のソースコード

HTML

1<!DOCTYPE html> 2<html> 3<style> 4body { margin: 60px; } 5button, select { font-size: 20px; } 6</style> 7 8<body> 9<h1>Oscillator test 7</h1> 10<br/> 11<br/> 12<button onclick="Play200()"> 200--1000 Hz </button> &nbsp; &nbsp; &nbsp; 13<br/> 14<br/> 15<br/> 16<br/> 17 18<p>Freq(Hz) &nbsp; &nbsp; 19<span id="freqdisp">**</span> 20</p> 21 22 23<script> 24 25function ToneControl( f ) 26{ 27 osc.type = "Triangle" ; 28 osc.frequency.value = f-0 ; // REAL f 29 30 WriteFreq( f ) ; 31} 32function WriteFreq( f ) { document.getElementById("freqdisp").innerHTML = f ; 33} 34 35function Play200() 36{ 37 var  audioctx = new AudioContext(); 38 var t0 = audioctx.currentTime; 39 40 osc = new OscillatorNode(audioctx); 41 osc.connect(audioctx.destination); 42 43 ToneControl(200) ; 44 45 osc.start(t0 + 1 ); 46 osc.stop (t0 + 1.5); // この行が実行されるのは、 47 // この行を読み込んでから 1.5秒後であるため 48 49 // これより下のコマンドが、上の行の実行開始前にどんどん読み込まれて  50 // 次々と先回りしたノードが生成されてしまうと思われるため 51 // 大量のデーター処理をする場合に、メモリー内部などで 52 // 相当な混乱が起きるのではないかと懸念される 53 54 osc = new OscillatorNode(audioctx); 55 osc.connect(audioctx.destination); 56 ToneControl(300) ; 57 58 osc.start(t0 + 2 ); 59 osc.stop (t0 + 2.5); 60 61 osc = new OscillatorNode(audioctx); 62 osc.connect(audioctx.destination); 63 ToneControl(400) ; 64 65 osc.start(t0 + 3 ); 66 osc.stop (t0 + 3.5); 67 68 69 osc = new OscillatorNode(audioctx); 70 osc.connect(audioctx.destination); 71 ToneControl(500) ; 72 73 osc.start(t0 + 4 ); 74 osc.stop (t0 + 4.5); 75 76 77 osc = new OscillatorNode(audioctx); 78 osc.connect(audioctx.destination); 79 ToneControl(600) ; 80 81 osc.start(t0 + 5 ); 82 osc.stop (t0 + 5.5); 83 84 osc = new OscillatorNode(audioctx); 85 osc.connect(audioctx.destination); 86 ToneControl(700) ; 87 88 osc.start(t0 + 6 ); 89 osc.stop (t0 + 6.5); 90 91 osc = new OscillatorNode(audioctx); 92 osc.connect(audioctx.destination); 93 ToneControl(800) ; 94 95 osc.start(t0 + 7 ); 96 osc.stop (t0 + 7.5); 97} 98 99</script> 100</body> 101</html> 102

参考資料

オシレーターのタイミング制御

https://www.g200kg.com/jp/docs/webaudio/generatesound.html

g200kg > Web Audio API 解説 > 03.オシレーターの使い方

実用的なものを作ろうとした場合、リズムがヨタらない演奏をするには
時刻を指定する事が推奨されます。
というのも
この時刻による制御によらないとすると Javascript の setInterval() などでタイミングを決める事になりますが、
これだと処理が重くなって発音が遅れたりすることが普通に起こります。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

int32_t

2023/11/30 04:58

実際に使いたいオシレータの個数は何個ぐらいなのでしょうか。
xmg

2023/11/30 09:14

特に決めておりません。 今の段階では、とりあえず単音で20-30個程度の単波長の音を鳴らすところから練習を始めたいと思っています。 最終的には、和音を何十小節も再生するところまで、コードを発展させていきたいと思っています。 ありがとうございます。
guest

回答1

0

使うオシレータが数千個程度で有限であるなら、質問文のコードのように AudioContext 生成時に OscillatorNode も一気に数千個生成して時間指定して大丈夫だと思います。

より多数であったり無限個のオシレータが必要なら、MDN の「時刻に合わせた音声の再生」が参考になると思います。やはり setTimeout() setInterval() などを使うのですが、オシレータを動かす時刻に起動するタイマーを設定するのではなく、たとえば「5秒先までのオシレータを登録する」というタスクを1秒毎にタイマーで起動します。

投稿2023/11/30 15:24

int32_t

総合スコア20533

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.53%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問