回答編集履歴

3

動作説明追記

2022/11/01 11:15

投稿

nobonobo
nobonobo

スコア3367

test CHANGED
@@ -124,3 +124,7 @@
124
124
  select {}
125
125
  }
126
126
  ```
127
+
128
+ 動作例:
129
+ ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-11-01/e4998b38-056b-45e0-9e0f-9cc1d6127ace.png)
130
+ ボタンクリックで「ミ->レ->ド」を3回繰り返します。

2

JS版の最小サンプルを追記

2022/11/01 11:12

投稿

nobonobo
nobonobo

スコア3367

test CHANGED
@@ -19,3 +19,108 @@
19
19
 
20
20
  もしくは「やりたいこと」はどういうことなのかをもう少し具体的に示してください。
21
21
 
22
+ ## 追記
23
+
24
+ 質問の意味を取り違えていました。
25
+ スクリプトエンジンを使って書いたシナリオに基づき音を鳴らしたいという事でした。
26
+
27
+ 下記に「JSスクリプトエンジン」を使ってシナリオプログラムを記述しそれに基づいて音楽を鳴らす最小のサンプルを示します。
28
+ ここからMonkeyに移植するなどしてもらえば実現できそうですね。
29
+
30
+
31
+ https://go.dev/play/p/4LW0Jjzr5mO
32
+ ```go
33
+ package main
34
+
35
+ import (
36
+ "math"
37
+ "syscall/js"
38
+ )
39
+
40
+ var (
41
+ window = js.Global()
42
+ document = window.Get("document")
43
+
44
+ AudioContext = js.Global().Get("AudioContext")
45
+ OscillatorNode = js.Global().Get("OscillatorNode")
46
+ GainNode = js.Global().Get("GainNode")
47
+
48
+ note2freq = []float64{}
49
+ )
50
+
51
+ func init() {
52
+ for i := 0; i < 128; i++ {
53
+ note2freq = append(note2freq, 440*math.Pow(2, float64(i-69)/12))
54
+ }
55
+ }
56
+
57
+ type Note struct {
58
+ Number int
59
+ Duration float64
60
+ }
61
+
62
+ type MusicBox struct {
63
+ ctx js.Value
64
+ osc js.Value
65
+ gain js.Value
66
+ current float64
67
+ }
68
+
69
+ func NewMusicBox() *MusicBox {
70
+ ctx := AudioContext.New()
71
+ osc := OscillatorNode.New(ctx)
72
+ gain := GainNode.New(ctx)
73
+ osc.Call("connect", gain)
74
+ osc.Get("frequency").Set("value", 0)
75
+ gain.Call("connect", ctx.Get("destination"))
76
+ gain.Get("gain").Set("value", 0)
77
+ osc.Call("start")
78
+ return &MusicBox{
79
+ ctx: ctx,
80
+ osc: osc,
81
+ gain: gain,
82
+ current: ctx.Get("currentTime").Float(),
83
+ }
84
+ }
85
+
86
+ func (mb *MusicBox) Play(note Note) {
87
+ mb.osc.Get("frequency").Call("setValueAtTime", note2freq[note.Number], mb.current)
88
+ mb.gain.Get("gain").Call("setValueAtTime", 0.3, mb.current)
89
+ mb.gain.Get("gain").Call("setValueAtTime", 0.0, mb.current+note.Duration)
90
+ mb.current += note.Duration
91
+ }
92
+
93
+ const sample = `for (let i=0; i< 3; i++) {
94
+ play(64, 0.2)
95
+ play(0, 0.1)
96
+ play(62, 0.2)
97
+ play(0, 0.1)
98
+ play(60, 0.2)
99
+ play(0, 0.1)
100
+ }
101
+ `
102
+
103
+ func main() {
104
+ code := document.Call("createElement", "textarea")
105
+ code.Set("id", "code")
106
+ code.Set("value", sample)
107
+ code.Get("style").Set("width", "50%")
108
+ code.Get("style").Set("height", "20em")
109
+ document.Get("body").Call("appendChild", code)
110
+ btn := document.Call("createElement", "button")
111
+ btn.Set("textContent", "music start!")
112
+ btn.Call("addEventListener", "click", js.FuncOf(func(js.Value, []js.Value) interface{} {
113
+ mb := NewMusicBox()
114
+ window.Set("play", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
115
+ mb.Play(Note{args[0].Int(), args[1].Float()})
116
+ return nil
117
+ }))
118
+ code := document.Call("getElementById", "code")
119
+ src := code.Get("value")
120
+ window.Call("eval", src)
121
+ return nil
122
+ }))
123
+ document.Get("body").Call("appendChild", btn)
124
+ select {}
125
+ }
126
+ ```

1

回答の方針を追記

2022/11/01 05:39

投稿

nobonobo
nobonobo

スコア3367

test CHANGED
@@ -1,3 +1,7 @@
1
+ 「標準入力」という概念はコマンドラインのプログラムのための仕組みなのでブラウザにはありません。
2
+ ノート番号を引数に渡して音を鳴らす関数を作成することはもちろんできるはずです。
3
+ その引数にインタラクティブに渡す手段を質問されているという仮定で回答します。
4
+
1
5
  「調べてでてきたもの」でなにか不都合はありますか?
2
6
  ブラウザのフォームに番号を入力したものを読み取って動くというのはどうでしょうか?
3
7
 
@@ -13,6 +17,5 @@
13
17
 
14
18
  というのではどうでしょうか。
15
19
 
16
- もしくは「やりたいこと」はどういうことなのかを具体的に示してください。
20
+ もしくは「やりたいこと」はどういうことなのかをもう少し具体的に示してください。
17
21
 
18
- 「標準入力」という概念はコマンドラインのプログラムのための仕組みなのでブラウザにはありません。