@plotdb/sfx 0.0.0-stage → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +47 -0
- package/LICENSE +21 -0
- package/README.md +225 -2
- package/index.js +3417 -0
- package/index.min.js +1 -0
- package/package.json +1 -6
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Change Logs
|
|
2
|
+
|
|
3
|
+
## v0.0.3
|
|
4
|
+
|
|
5
|
+
- feature: 變化機制 ( 預設不變 )
|
|
6
|
+
- 所有合成聲可加 `vary` ( 0~1 ): 換雜訊、音高與長度微調、音量略小; 同 seed 可重現
|
|
7
|
+
- `S.variants(name, opt, count)`: 一次產生多個變化
|
|
8
|
+
- 時間軸項目的 `sound` 可為陣列 ( 依位置與時間挑一個 ), 項目可加 `vary`; 皆可重現, 離線混音一致
|
|
9
|
+
- `S.play` 可給陣列與 `vary` ( 隨機 )
|
|
10
|
+
- `S.mutate(name, opt, {amount, seed})`: 以目前參數為中心產生變化的參數 ( 數值常態分布、選項隨機挑 )
|
|
11
|
+
- feature: `S.params[name]`: 每種合成聲的參數定義 ( 範圍、預設、選項 ), demo 頁由它產生控制項
|
|
12
|
+
- feature: demo 頁最上面加上全部音效的清單: 點名稱播預設, 點 🎲 播隨機變化; 每張卡片加 `vary` 與 🎲 ( 以目前設定為中心變化 )
|
|
13
|
+
- feature: 樂譜: `S.synth.score({score, instrument, bpm})` 依文字樂譜 ( `C4/4 D4 E4/8. ...` ) 用任何聲音演奏
|
|
14
|
+
( 有 note 參數的合成聲以音高合成, 其他聲音以 base 為準變調 ); `S.score` / `S.score.parse` / `S.score.duration`
|
|
15
|
+
- feature: `synth.melody` 新增 `release` ( 每個音之後的尾音, 預設 0.8 不變 )
|
|
16
|
+
- feature: demo 頁新增五線譜 ( 4/4 拍 4 小節, 鍵盤編輯音長 / 附點 / 休止、拖曳改音高, 與樂譜文字雙向同步, 選樂器或 🎲 隨機 )
|
|
17
|
+
- tweak: demo 頁標題改為「音效清單」與「全部音效:合成細節」; 混音器移到時間軸區
|
|
18
|
+
- tweak: demo 頁資源改用相對路徑, `npm run deploy` 以 @zbryikt/deploy 發佈到 GitHub Pages ( 只帶用到的檔案 )
|
|
19
|
+
- tweak: demo 頁先畫畫面再分批產生聲音, 並在畫好前隱藏, 不再閃出空的模板
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## v0.0.2
|
|
23
|
+
|
|
24
|
+
- feature: 新增合成聲
|
|
25
|
+
- 動作:`slide` `rise` `fall` `count` `snap` `draw` `glitch`,以及通用的 `sweep`
|
|
26
|
+
- 敘事:`reveal` `error` `tension` `heartbeat` `clock`
|
|
27
|
+
- 擬音:`paper` `water` `fire` `steps` `bell` `thunder`
|
|
28
|
+
- 樂器:`marimba` `xylophone` `vibraphone` `glockenspiel` ( 模態合成 )、`guitar` ( 單音或刷和弦 )
|
|
29
|
+
- 人聲與人體:`fingersnap` ( 打響指 ) `huh` ( 蛤? ) `yay` ( 耶! ),人聲以共振峰合成
|
|
30
|
+
- 答題:`correct` ( 叮咚 / 琶音 ) `wrong` ( 噗噗 / 悲傷長號 )
|
|
31
|
+
- 鼓組:`kick` `snare` `hihat` `tom` `clap` `crash` `ride`,以及節奏器 `beat`
|
|
32
|
+
- 擬音與鈸 ( `crash` `ride` `thunder` `steps` `paper` `water` ) 依真實錄音的頻譜與衰減分析調整;`steps` 有 `gait: run`
|
|
33
|
+
- feature: 全部合成聲都可以加 `reverb` / `room` 殘響;另有 `S.reverb(buffer, {mix, room})`
|
|
34
|
+
- feature: `synth.melody` 新增 `instrument`,可以換成任一有 `note` 參數的聲音 ( 預設仍是 `pluck` )
|
|
35
|
+
- tweak: `whoosh` 與 `swell` 改用連續的時變濾波,去掉分段濾波造成的接縫雜音 ( 質感會略有不同 )
|
|
36
|
+
- feature: demo 網站改用專案慣例 ( `web/src/pug` 經 `@zbryikt/template` 建置到 `web/static` ),取代手寫的 `web/index.html`
|
|
37
|
+
- 合成聲:每種聲音以滑桿 / 欄位調參數、範例標籤、波形與播放進度、可複製的程式碼
|
|
38
|
+
- 時間軸:可編輯的場景 ( JSON )、播放 / 暫停 / 拖曳 / 倍速、各項的檔案範圍與擊點、離線混成 wav
|
|
39
|
+
- bus 音量 ( master / music / sfx / voice )
|
|
40
|
+
- bug fix: `synth.pluck` ( 與 `synth.melody` ) 的 `slide: 0` 被當成預設值 0.6,現在可以關掉滑音
|
|
41
|
+
- bug fix: `synth.pluck` 給了 `bright` 時 `slide` 沒有設定,整段變成 NaN ( 無聲 );同一行 `if ... else x; y = ...` 會把後面的設定吞進 else
|
|
42
|
+
- tweak: `./build` 改把 `dist/` 複製到 `web/static/assets/lib/@plotdb/sfx/dev/`
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
## v0.0.1
|
|
46
|
+
|
|
47
|
+
- 從 Shelf 的 shelfSound 抽出的音訊 runtime 與程序化合成
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 zbryikt
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,226 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @plotdb/sfx
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
給確定性動畫 ( 例如 [lotion](https://github.com/plotdb/lotion) ) 用的音訊 runtime:
|
|
4
|
+
|
|
5
|
+
- 時間軸:聲音綁在動畫時間上,播放、暫停、拖曳、倍速都會同步。
|
|
6
|
+
- 指令式播放:互動用,與時間軸無關。
|
|
7
|
+
- 程序化合成:在瀏覽器裡算出 UI 音效、撥弦、環境聲,免費、可重現 ( 同樣的參數永遠是同樣的聲音 )。
|
|
8
|
+
- 離線混音:把時間軸混成一段音訊 ( 輸出影片配音用 )。
|
|
9
|
+
|
|
10
|
+
試玩:`npm install`、`npx fedep`、`npm run build` 後 `npm start` ( 即 `npx server -r web -o true` )。
|
|
11
|
+
線上版:https://plotdb.github.io/sfx/ ( `npm run deploy` 發佈到 gh-pages )。
|
|
12
|
+
頁面原始碼在 `web/src/pug`,建置到 `web/static`:音效清單 ( 點了就播,🎲 隨機變化 )、可編輯的五線譜、每種合成聲的參數試聽,以及可以播放、拖曳、倍速並混成 wav 的時間軸。
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## 安裝與載入
|
|
16
|
+
|
|
17
|
+
npm install github:plotdb/sfx
|
|
18
|
+
|
|
19
|
+
頁面裡在 lotion 之後載入 `dist/index.min.js`,全域變數 `window.sfx`:
|
|
20
|
+
|
|
21
|
+
<script src="/assets/lib/@plotdb/lotion/main/index.min.js"></script>
|
|
22
|
+
<script src="/assets/lib/@plotdb/sfx/main/index.min.js"></script>
|
|
23
|
+
<script>
|
|
24
|
+
const S = window.sfx;
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
頁面上有 `lotion.player` 時會自動攔截它的 play / pause / seek,不用另外接。
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
## 載入聲音
|
|
31
|
+
|
|
32
|
+
S.load({bgm: 'assets/bgm.mp3', pop: S.synth.pop()}).then(() => { ... })
|
|
33
|
+
|
|
34
|
+
- 值可以是網址、`AudioBuffer` ( 例如合成的聲音 ) 或回傳 `AudioBuffer` 的 Promise。
|
|
35
|
+
- 載完再設時間軸,並在 `player.start()` 之前完成。
|
|
36
|
+
- `S.pending`:載入中的數量。`S.errors`:載入或播放的錯誤訊息。
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
## 時間軸
|
|
40
|
+
|
|
41
|
+
S.timeline([
|
|
42
|
+
{t: 0, sound: 'bgm', bus: 'music', gain: 0.35, fadeIn: 1, fadeOut: 2},
|
|
43
|
+
{t: 5.2, sound: 'pop', gain: 0.8}
|
|
44
|
+
])
|
|
45
|
+
|
|
46
|
+
每一項:
|
|
47
|
+
|
|
48
|
+
- `t`:動畫時間 ( 秒 )。
|
|
49
|
+
- `sound`:`S.load` 的名稱。
|
|
50
|
+
- `bus`:`music` | `sfx` ( 預設 ) | `voice`。
|
|
51
|
+
- `gain`、`rate` ( 播放速率 )、`offset` ( 從檔案的第幾秒開始 )、`duration`。
|
|
52
|
+
- `fadeIn`、`fadeOut`:秒。
|
|
53
|
+
- `loop: true` 搭配 `until`:循環到某個時間。
|
|
54
|
+
- `align`:`peak` ( `sfx` 預設,讓聲音的起音點落在 `t` 上 ) | `start` ( 其他 bus 預設,從 `t` 開始播 )。
|
|
55
|
+
|
|
56
|
+
`S.cues(cues)`:把 lotion 的 cues `[{t, sfx, gain}]` 轉成時間軸。
|
|
57
|
+
|
|
58
|
+
### 外部時鐘
|
|
59
|
+
|
|
60
|
+
動畫由外層控制 ( 例如外層頁面經 postMessage 控制 iframe 裡的動畫 ) 時,由外層告知播放狀態:
|
|
61
|
+
|
|
62
|
+
S.transport({playing: true, t: 12.3, rate: 1.5, from: 'host'})
|
|
63
|
+
|
|
64
|
+
- 帶 `from` 之後不再跟隨頁面上的 player。
|
|
65
|
+
- `rate`:倍速。旁白 ( `voice` ) 與配樂 ( `music` ) 用網址載入的會保持音高;合成的聲音與短音效直接變速。
|
|
66
|
+
- 非連續的時間 ( 拖曳 ) 或 `force: true` 時重新排程。
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
## 指令式播放
|
|
70
|
+
|
|
71
|
+
h = S.play('pop', {gain: 0.8, loop: false, fadeIn: 0})
|
|
72
|
+
h.fade(0.2, 0.5) // 0.5 秒內淡到 0.2
|
|
73
|
+
h.stop(0.1) // 0.1 秒淡出後停止
|
|
74
|
+
S.stop('pop') // 停止這個名稱的指令式聲音 ( 不給名稱全停 )
|
|
75
|
+
S.music('bgm', {fade: 1}) // 背景音樂槽: 同時一首, 換曲時交叉淡入淡出; S.music(null) 淡出
|
|
76
|
+
S.volume('music', 0.5) // bus 音量: music | sfx | voice | master
|
|
77
|
+
|
|
78
|
+
瀏覽器的自動播放限制:要在使用者操作後呼叫 `S.resume()` ( `S.play` 會自己呼叫 )。
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
## 合成
|
|
82
|
+
|
|
83
|
+
全部回傳 `AudioBuffer` ( 48kHz 雙聲道 ),可直接 `S.load`。音高參數可以給 Hz 或音名 ( `'A4'`、`'C#5'` )。
|
|
84
|
+
|
|
85
|
+
- `seed`:用到雜訊的聲音 ( click、type、thump、whoosh、swell、pluck、wind、rain ) 換一組雜訊,同樣參數、不同質感。
|
|
86
|
+
- `pan`:-1 左 ~ 1 右,單點的聲音 ( click、tick、pop、toggle、thump、chime、success、notify、pluck、buzz ) 才有;
|
|
87
|
+
whoosh、wind、rain 本身就有左右移動或去相關。
|
|
88
|
+
|
|
89
|
+
| 聲音 | 長度 | 參數 | 用途 |
|
|
90
|
+
| --- | --- | --- | --- |
|
|
91
|
+
| `click` | 0.05s | `freq` | 點擊 |
|
|
92
|
+
| `tick` | 0.06s | `note` / `freq` | 刻度、計數 |
|
|
93
|
+
| `pop` | 0.15s | `from`、`to` ( Hz,音高滑動 ) | 元素出現 |
|
|
94
|
+
| `toggle` | 0.12s | | 開關 |
|
|
95
|
+
| `type` | 0.05s | | 打字 ( 每次 seed 不同較自然 ) |
|
|
96
|
+
| `thump` | 0.35s | | 落地、蓋章 |
|
|
97
|
+
| `snap` | 0.1s | | 吸附、到位 |
|
|
98
|
+
| `chime` | `dur` ( 1.4 ) | `note` ( E6 ) | 鈴聲、完成一步 |
|
|
99
|
+
| `success` | 0.9s | | 成功 ( C-E-G 琶音 ) |
|
|
100
|
+
| `notify` | 0.7s | | 通知 |
|
|
101
|
+
| `error` | 0.5s | `from` ( B3 )、`to` ( F3 ) | 錯誤 |
|
|
102
|
+
| `reveal` | 1.6s | `notes` ( [C6, E6, G6, C7, E7] )、`gap` ( 0.06 ) | 揭曉 ( 預設 `reverb: 0.35` ) |
|
|
103
|
+
| `correct` | 自動 | `style` ( pingpong「叮咚」\| arp 琶音 )、`notes`、`gap` | 答對 |
|
|
104
|
+
| `wrong` | 自動 | `style` ( buzzer「噗噗」\| trombone 悲傷長號 )、`pitch` ( 140 ) | 答錯 |
|
|
105
|
+
| `whoosh` | `dur` ( 0.7 ) | `from` ( 400 )、`peak` ( 2600 )、`to` ( 600 )、`at` ( 0.45 )、`q` ( 1.2 ) | 轉場 |
|
|
106
|
+
| `swell` | `dur` ( 2 ) | | 段落前的醞釀 |
|
|
107
|
+
| `slide` | `dur` ( 0.3 ) | `from` ( 900 )、`to` ( 2600 )、`q` ( 0.9 )、`dir` ( 1 往右,-1 往左 ) | 滑入、滑出 |
|
|
108
|
+
| `rise` / `fall` | `dur` ( 0.6 ) | `from`、`to` ( Hz 或音名;300→900 / 900→250 ) | 數值上升 / 下降 |
|
|
109
|
+
| `count` | `dur` + 0.2 | `n` ( 12 )、`dur` ( 1.2 )、`ease` ( out \| in \| linear )、`climb` ( 7 半音 )、`note` ( C6 ) | 數字滾動 |
|
|
110
|
+
| `draw` | `dur` ( 1 ) | `rough` ( 0~1 )、`pitch` ( 2500 ) | 筆畫 |
|
|
111
|
+
| `glitch` | `dur` ( 0.5 ) | | 故障 |
|
|
112
|
+
| `sweep` | `dur` ( 1 ) | `wave` ( sine \| triangle \| square \| saw \| noise )、`from` ( 200 )、`to` ( 2000 )、`curve` ( exp \| lin )、`q`、`attack`、`release` | 通用掃頻 |
|
|
113
|
+
| `tension` | `dur` ( 6 ) | `note` ( A2 ) | 緊張 |
|
|
114
|
+
| `heartbeat` | `dur` ( 4 ) | `bpm` ( 70 ) | 心跳 |
|
|
115
|
+
| `clock` | `dur` ( 4 ) | `bpm` ( 60 ) | 時鐘 |
|
|
116
|
+
| `fingersnap` | 0.12s | `tone` ( 手掌共鳴 3200Hz ) | 打響指 |
|
|
117
|
+
| `huh` | `dur` ( 0.45 ) | `pitch` ( 200 )、`rise` ( 上揚倍數 1.9 )、`size` | 蛤? |
|
|
118
|
+
| `yay` | `dur` ( 0.5 ) | `pitch` ( 300 )、`size` | 耶! |
|
|
119
|
+
| `paper` | `dur` ( 1.2 ) | `crisp` ( 劈啪聲,0 軟紙 ~ 3 硬紙 )、`flutter` ( 紙張抖動 0~1 ) | 翻頁 |
|
|
120
|
+
| `water` | 自動 | `n` ( 氣泡數,1 為水滴 )、`size` ( 平均半徑 mm,越大越低 )、`rise` ( 音高上升 ) | 水滴、冒泡、溪流 |
|
|
121
|
+
| `fire` | `dur` ( 6 ) | `density` ( 1 ) | 火 |
|
|
122
|
+
| `steps` | 自動 | `surface` ( wood \| concrete \| gravel \| snow \| grass )、`gait` ( walk \| run )、`n` ( 4 )、`pace` ( 走 0.5 / 跑 0.3 ) | 腳步 |
|
|
123
|
+
| `bell` | `dur` ( 5 ) | `note` ( C5 ) | 教堂鐘、管鐘 ( 預設 `reverb: 0.2` ) |
|
|
124
|
+
| `thunder` | `dur` ( 6 ) | `dist` ( 0 近 ~ 1 遠 ) | 雷 |
|
|
125
|
+
| `wind` | `dur` ( 6 ) | `cutoff` ( 900 ) | 風 |
|
|
126
|
+
| `rain` | `dur` ( 6 ) | `density` ( 0.02 ) | 雨 |
|
|
127
|
+
| `buzz` | `dur` ( 1.5 ) | `freq` ( 220 ) | 昆蟲振翅 |
|
|
128
|
+
| `pluck` | `dur` ( 2.5 ) | `note` ( A3 )、`bright` ( 0~1 )、`slide` ( 半音 ) | 撥弦 ( 類古箏 ) |
|
|
129
|
+
| `guitar` | `dur` ( 3 ) | `note` ( E3 ) 或 `chord` ( C D Dm E Em F G A Am ) 或 `notes`、`strum` ( 0.03 )、`dir` ( down \| up )、`bright`、`pos` ( 撥弦位置 0.2 )、`mute` ( 0~1 ) | 吉他 |
|
|
130
|
+
| `marimba` | `dur` ( 1.5 ) | `note` ( C4 )、`hard` ( 槌子硬度 0~1 ) | 馬林巴 |
|
|
131
|
+
| `xylophone` | `dur` ( 0.8 ) | `note` ( C5 )、`hard` | 木琴 |
|
|
132
|
+
| `vibraphone` | `dur` ( 3 ) | `note` ( F4 )、`hard`、`trem` ( 顫音深度 0.35 ) | 鐵琴 |
|
|
133
|
+
| `glockenspiel` | `dur` ( 2 ) | `note` ( C6 )、`hard` | 鐘琴 |
|
|
134
|
+
| `melody` | 自動 | `notes: [[t, note, dur, vel], ...]`、`instrument` ( pluck )、`release` ( 0.8 )、`bright`、`slide` | 旋律 |
|
|
135
|
+
| `score` | 自動 | `score` ( 文字樂譜,見下方 )、`instrument`、`bpm`、`base`、`release` | 照樂譜演奏 |
|
|
136
|
+
| `drone` | `dur` ( 8 ) | `notes` ( [A1, E2, A2] )、`attack`、`release` | 持續低音 |
|
|
137
|
+
| `kick` | 自動 | `tune` ( 50 Hz )、`decay` ( 0.3 )、`punch` ( 0~1 ) | 大鼓 |
|
|
138
|
+
| `snare` | 自動 | `tune` ( 180 Hz )、`decay` ( 0.15 )、`snappy` ( 0~1 ) | 小鼓 |
|
|
139
|
+
| `hihat` | 自動 | `open` ( 0 閉 ~ 1 開 )、`tune` ( 1 ) | hi-hat |
|
|
140
|
+
| `tom` | 自動 | `note` ( A2 )、`decay` ( 0.35 ) | 中鼓 / 落地鼓 |
|
|
141
|
+
| `clap` | 自動 | `decay` ( 0.12 ) | 拍手 |
|
|
142
|
+
| `crash` | 自動 | `decay` ( 尾音倍數,1 約 2 秒 )、`tune` ( 1 ) | 碎音鈸 |
|
|
143
|
+
| `ride` | 自動 | `decay` ( 尾音倍數,1 約 3 秒 )、`bell` ( 0~1,越大越靠近鈸心 )、`tune` ( 1 ) | 疊音鈸 |
|
|
144
|
+
| `beat` | 自動 | `pattern`、`bpm` ( 100 )、`bars` ( 1 )、`swing` ( 0~1 ) | 節奏 |
|
|
145
|
+
|
|
146
|
+
擬音、鈸與人聲 ( `crash` `ride` `thunder` `steps` `paper` `water` `fingersnap` `huh` `yay` ) 依 Wikimedia Commons 上的錄音分析調整過頻譜分布、衰減曲線、音高與共振峰。
|
|
147
|
+
|
|
148
|
+
人聲 ( `huh` `yay` ) 以共振峰合成:聲帶脈衝與氣音經過 4 個會移動的共振峰。`size` 是聲道大小 ( 小孩約 1.15,大人男聲約 0.9 )。聽得出是人聲,但偏卡通,不像真人錄音。
|
|
149
|
+
|
|
150
|
+
全部的合成聲都可以加 `vary` ( 見下方「變化」)、`reverb` ( 0~1,濕聲比例 ) 與 `room` ( 0~1,空間大小 ),聲音會多出殘響的尾巴。
|
|
151
|
+
已經有的 `AudioBuffer` 也可以用 `S.reverb(buffer, {mix, room})` 加殘響。
|
|
152
|
+
|
|
153
|
+
### 樂譜
|
|
154
|
+
|
|
155
|
+
用文字寫樂譜,指定任何聲音照著演奏:
|
|
156
|
+
|
|
157
|
+
S.load({tune: S.synth.score({score: 'C4/4 C4 G4 G4 | A4 A4 G4/2', instrument: 'marimba', bpm: 100})})
|
|
158
|
+
|
|
159
|
+
- 音名 + 八度 ( `C4`、`F#5`、`Bb3` ),`/n` 是音長 ( 1 全音符、2 二分、4 四分、8、16、32、64 ),後面加 `.` 是附點。
|
|
160
|
+
- `-` ( 或 `r` ) 是休止符,`C4+E4+G4` 是和弦,`|` 是小節線 ( 只是方便閱讀 )。音長沒寫就沿用前一個。
|
|
161
|
+
- `instrument`:有 `note` 參數的合成聲 ( pluck、marimba、guitar … ) 以音高合成每個音;
|
|
162
|
+
其他聲音 ( 例如 `pop`、`kick`,或載入的 `AudioBuffer` ) 以 `base` ( 預設 C4 ) 為準變調演奏。
|
|
163
|
+
- `bpm` ( 100 )、`release` ( 每個音之後保留的尾音,預設 0.1 秒 );也可以加 `vary`、`reverb`。
|
|
164
|
+
- `S.score(text, {bpm})`:轉成 `melody` 的 `notes`;`S.score.parse(text)`:解析成 `[{notes, beats}]`;`S.score.duration(text, {bpm})`:秒數。
|
|
165
|
+
|
|
166
|
+
demo 頁的五線譜可以直接編輯並產生這段樂譜文字。
|
|
167
|
+
|
|
168
|
+
### 變化
|
|
169
|
+
|
|
170
|
+
同一個聲音重複出現 ( 腳步、打字、點擊 ) 時,每次略有不同會比較自然。預設不變,要用時再加:
|
|
171
|
+
|
|
172
|
+
- 合成時加 `vary` ( 0~1 ):換一組雜訊,音高與長度微調 ( 1 約 ±1 個半音 ),音量略小。同樣的 `seed` 永遠是同樣的變化。
|
|
173
|
+
|
|
174
|
+
S.synth.pop({vary: 0.5, seed: 3})
|
|
175
|
+
|
|
176
|
+
- `S.variants(name, opt, count)`:一次產生 count 個變化 ( seed 1 ~ count,`vary` 預設 0.5 )。
|
|
177
|
+
|
|
178
|
+
const [a, b, c] = S.variants('steps', {n: 1}, 3)
|
|
179
|
+
S.load({step1: a, step2: b, step3: c})
|
|
180
|
+
|
|
181
|
+
- 時間軸項目的 `sound` 可以是陣列,依項目的位置與時間挑一個;加 `vary` 則每個項目的音高與音量略有不同。
|
|
182
|
+
兩者都可重現:拖曳、重播、離線混音結果都一樣。
|
|
183
|
+
|
|
184
|
+
S.timeline([
|
|
185
|
+
{t: 1.0, sound: ['step1', 'step2', 'step3'], vary: 0.3},
|
|
186
|
+
{t: 1.5, sound: ['step1', 'step2', 'step3'], vary: 0.3}
|
|
187
|
+
])
|
|
188
|
+
|
|
189
|
+
- `S.play(name, {vary})` 與 `S.play([...names])`:互動用,每次隨機 ( 不可重現 )。
|
|
190
|
+
|
|
191
|
+
- `S.mutate(name, opt, {amount, seed})`:以目前的參數 ( 沒給的用預設 ) 為中心,產生一組變化的參數。
|
|
192
|
+
數值依常態分布微調 ( σ = amount × 範圍 × 0.15 ),選項 ( 例如 `style`、`chord`、`surface` ) 以 amount × 2 的機率隨機挑,
|
|
193
|
+
音名移幾個半音,並換 `seed`、加上 `vary`。`amount` 預設 0.5;給 `seed` 就可重現。
|
|
194
|
+
|
|
195
|
+
S.synth.correct(S.mutate('correct')) // 可能是 pingpong 也可能是 arp
|
|
196
|
+
S.synth.whoosh(S.mutate('whoosh', {dur: 0.4}, {amount: 0.3, seed: 7}))
|
|
197
|
+
|
|
198
|
+
- `S.params[name]`:每種合成聲的參數定義 `[{k, type: range | note | select | json, min, max, step, def, options}]`,
|
|
199
|
+
demo 頁的控制項也是由它產生。
|
|
200
|
+
|
|
201
|
+
`melody` 的 `instrument` 可以是任何有 `note` 參數的聲音:`pluck` ( 預設 )、`guitar`、`marimba`、`xylophone`、`vibraphone`、`glockenspiel`、`chime`、`bell`。
|
|
202
|
+
|
|
203
|
+
`beat` 的 `pattern` 一個字元是一格十六分音符:`X` 重音、`x` 一般、`o` 輕,其他字元 ( `.`、`-` ) 是休止,空白與 `|` 忽略。
|
|
204
|
+
|
|
205
|
+
S.synth.beat({bpm: 96, bars: 2, swing: 0.3, pattern: {
|
|
206
|
+
kick: 'x.......x.x.....',
|
|
207
|
+
snare: '....x.......x..o',
|
|
208
|
+
hihat: 'x.x.x.x.x.x.x.x.',
|
|
209
|
+
tom: ['..............x.', {note: 'D3'}] // 也可以給 [pattern, 參數]
|
|
210
|
+
}})
|
|
211
|
+
|
|
212
|
+
名稱可以是 `kick` `snare` `hihat` `ohat` ( 開 hi-hat ) `tom` `ltom` `htom` `clap` `crash` `ride`,或任何合成聲的名稱。
|
|
213
|
+
|
|
214
|
+
`whoosh` 是帶通濾波的雜訊,中心頻率依 `from` → `peak` → `to` 走,在 `at` ( 0~1 ) 處最亮最響:
|
|
215
|
+
|
|
216
|
+
- 短促的掃過:`{dur: 0.35}`;更短更乾淨:`{dur: 0.25, q: 2}`。
|
|
217
|
+
- 往上衝:`{from: 300, peak: 3500, to: 3000, at: 0.8}`;往下沉:`{from: 3000, peak: 3000, to: 300, at: 0.1}`。
|
|
218
|
+
- `q` 小 ( 0.5 ) 像風,大 ( 3 ) 像哨音。
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
## 混音與檢查
|
|
222
|
+
|
|
223
|
+
- 建議音量:配樂 0.3~0.4、音效 0.6~1、旁白 1。
|
|
224
|
+
- `S.report()`:載入的聲音 ( 長度、起音點 )、時間軸數量、播放狀態、AudioContext 狀態、最近的錯誤。
|
|
225
|
+
- `S.peak(buffer)`:起音點 ( 秒 )。
|
|
226
|
+
- `S.render(duration)`:離線混音,回傳 Promise<AudioBuffer>。`S.wav(buffer)`:轉成 16-bit wav Blob。
|