├── .gitignore ├── README.md ├── html ├── static │ ├── css │ │ ├── audio-annotator.css │ │ └── materialize.min.css │ ├── fonts │ │ └── roboto │ │ │ ├── Roboto-Bold.eot │ │ │ ├── Roboto-Bold.ttf │ │ │ ├── Roboto-Bold.woff │ │ │ ├── Roboto-Bold.woff2 │ │ │ ├── Roboto-Light.eot │ │ │ ├── Roboto-Light.ttf │ │ │ ├── Roboto-Light.woff │ │ │ ├── Roboto-Light.woff2 │ │ │ ├── Roboto-Medium.eot │ │ │ ├── Roboto-Medium.ttf │ │ │ ├── Roboto-Medium.woff │ │ │ ├── Roboto-Medium.woff2 │ │ │ ├── Roboto-Regular.eot │ │ │ ├── Roboto-Regular.ttf │ │ │ ├── Roboto-Regular.woff │ │ │ ├── Roboto-Regular.woff2 │ │ │ ├── Roboto-Thin.eot │ │ │ ├── Roboto-Thin.ttf │ │ │ ├── Roboto-Thin.woff │ │ │ └── Roboto-Thin.woff2 │ ├── img │ │ ├── paris.jpg │ │ └── task-interface.png │ ├── js │ │ ├── colormap │ │ │ ├── colormap.min.js │ │ │ ├── gen_colormap.js │ │ │ └── gen_colormap.sh │ │ ├── lib │ │ │ ├── jquery-2.2.3.min.js │ │ │ ├── materialize.min.js │ │ │ ├── wavesurfer.min.js │ │ │ ├── wavesurfer.min.js.map │ │ │ └── wavesurfer.spectrogram.min.js │ │ └── src │ │ │ ├── annotation_stages.js │ │ │ ├── components.js │ │ │ ├── hidden_image.js │ │ │ ├── main.js │ │ │ ├── message.js │ │ │ ├── wavesurfer.drawer.extended.js │ │ │ ├── wavesurfer.labels.js │ │ │ └── wavesurfer.regions.js │ └── json │ │ ├── paris.json │ │ ├── sample_curiosity_data.json │ │ └── sample_data.json └── templates │ └── index.html ├── pyinstaller.sh ├── release ├── audio-annotator-mac-v1.0.zip ├── audio-annotator-mac-v1.1.zip ├── audio-annotator-mac-v1.2.zip ├── audio-annotator-win-v1.0.zip ├── audio-annotator-win-v1.1.zip └── audio-annotator-win-v1.2.zip ├── run.py ├── run_pyinstaller.spec ├── server ├── __init__.py ├── base.py ├── file_utils.py ├── get_task.py └── post_ret.py └── wavs └── test ├── d815927106414d5693f4c0a2c292c546.wav └── paris.wav /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | 3 | # C extensions 4 | *.so 5 | 6 | # Packages 7 | *.egg 8 | *.egg-info 9 | dist 10 | build 11 | eggs 12 | parts 13 | bin 14 | var 15 | sdist 16 | develop-eggs 17 | .installed.cfg 18 | lib 19 | lib64 20 | __pycache__ 21 | 22 | # Installer logs 23 | pip-log.txt 24 | 25 | # Unit test / coverage reports 26 | .coverage 27 | .tox 28 | nosetests.xml 29 | 30 | # Translations 31 | *.mo 32 | 33 | # Mr Developer 34 | .mr.developer.cfg 35 | .project 36 | .pydevproject 37 | .idea 38 | .DS_Store 39 | logs 40 | tmp_dir 41 | .vscode 42 | ~$* 43 | out 44 | w2v 45 | train 46 | scripts 47 | dataset 48 | result 49 | *.log* -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 音频分片打标签工具 2 | 3 | 代码在:[https://github.com/vell001/audio-annotator](https://github.com/vell001/audio-annotator) 4 | 5 | > web端代码基于:[https://github.com/CrowdCurio/audio-annotator](https://github.com/CrowdCurio/audio-annotator),进行汉化、按VAD需求调整标注方式以及根据server调整了一些逻辑 6 | > server端基于tornado实现 7 | 8 | # 原理 9 | 10 | 采用B/S(Browser/Server)架构,所有音频标注操作都是基于web端的wavesurfer框架,web端通过RESTful API从server端获取标注任务以及提交标注结果 11 | 12 | # 使用方式 13 | 14 | ## 一、开启标注服务【Server】 15 | 16 | ### 通过打包好的可执行文件部署 17 | 18 | 可执行文件见:[github release文件夹](https://github.com/vell001/audio-annotator/releases) 19 | 20 | 解压对应操作系统的可执行文件,然后在文件夹内找到 `run` 的可执行文件,可执行文件后可带参数: 21 | 22 | ``` 23 | optional arguments: 24 | -h, --help show this help message and exit 25 | --host HOST host, 0.0.0.0 代表外网可以访问 26 | -p PORT, --port PORT port 27 | -d DEBUG, --debug DEBUG 28 | debug 29 | -l LOG_CONFIG_FILE, --log_config_file LOG_CONFIG_FILE 30 | log config file, json 31 | --wav_dir WAV_DIR, -w WAV_DIR 32 | 待标注的wav文件夹 33 | ``` 34 | 35 | 主要注意,`-w` 这个参数可以指定你要标注的wav文件所在的文件夹,如果不指定,默认是在 `run` 的同级目录下的 `wavs` 文件夹 36 | 37 | ![](https://ask.qcloudimg.com/draft/1420883/dynuke9yy5.png) 38 | 39 | ### 源码部署 40 | 41 | 直接执行 `run.py` 文件,参数也和可执行文件部署一样 42 | 43 | ## 二、在浏览器里进行标注【Browser】 44 | 45 | 没有指定 `--host` 的话,默认地址就是:[http://127.0.0.1:8282](http://127.0.0.1:8282),在任意浏览器打开这个链接,尽量使用chrome 46 | v1.1版本增加了review功能,默认地址是:[http://127.0.0.1:8282/?review=true](http://127.0.0.1:8282/?review=true) 47 | v1.2版本增加了指定wav_name功能,样例地址:[http://127.0.0.1:8282/?review=true&wav_name=82c75.wav](http://127.0.0.1:8282/?review=true&wav_name=82c75.wav) 48 | 标注界面如下: 49 | 50 | ![](https://ask.qcloudimg.com/draft/1420883/nh7nnrmkly.png) 51 | 52 | ## 三、标注结果 53 | 54 | 标注结果保存在 `wavs`里,以`[wav_name].json`命名,json格式 55 | 56 | ![](https://ask.qcloudimg.com/draft/1420883/lwrd861ue2.png) 57 | 58 | 需要关注的字段如下: 59 | 60 | ![](https://ask.qcloudimg.com/draft/1420883/xk2s6nih6l.png) -------------------------------------------------------------------------------- /html/static/css/audio-annotator.css: -------------------------------------------------------------------------------- 1 | .audio_visual, 2 | .labels, 3 | .play_bar, 4 | .submit_container, 5 | .annotation, 6 | .creation_stage_container, 7 | .hidden_img { 8 | width: 97%; 9 | margin: auto; 10 | } 11 | 12 | .scroll_div { 13 | width: auto; 14 | overflow-x: auto; 15 | white-space: nowrap; 16 | } 17 | 18 | .btn { 19 | height: 30px; 20 | line-height: 30px; 21 | } 22 | 23 | .audio_visual wave { 24 | height: 276px !important; 25 | } 26 | 27 | .audio_visual > wave { 28 | cursor: crosshair; 29 | } 30 | 31 | .audio_visual > wave > canvas { 32 | background-color: #EAEAEA; 33 | width: 0px; 34 | } 35 | 36 | .audio_visual wave canvas { 37 | position: relative; 38 | top: 10px !important; 39 | } 40 | 41 | .annotation { 42 | margin: 0px auto; 43 | position: relative; 44 | } 45 | 46 | .play_bar { 47 | margin: 0px auto; 48 | position: relative; 49 | } 50 | 51 | .timer { 52 | position: absolute; 53 | right: 0px; 54 | font-weight: normal; 55 | } 56 | 57 | .play_audio.fa { 58 | font-size: 40px; 59 | color: #000080; 60 | } 61 | 62 | .creation_stage_container { 63 | text-align: center; 64 | min-height: 50px; 65 | position: relative; 66 | } 67 | 68 | .annotation .btn_stop, 69 | .annotation .btn_start { 70 | color: #fff !important; 71 | min-width: 300px; 72 | font-weight: bold; 73 | } 74 | 75 | .annotation .btn_replay { 76 | color: #fff !important; 77 | font-weight: bold; 78 | } 79 | 80 | .btn_replay { 81 | background-color: #910093 !important; 82 | } 83 | 84 | .btn_replay:hover { 85 | background-color: #5D005E !important; 86 | } 87 | 88 | .btn_start { 89 | background-color: #18C501; 90 | } 91 | 92 | .btn_start:enabled:hover { 93 | background-color: #118C01; 94 | } 95 | 96 | .btn_stop { 97 | background-color: #B90042; 98 | } 99 | 100 | .btn_stop:hover { 101 | background-color: #6E0027; 102 | } 103 | 104 | .time_segment input { 105 | margin: 0px 8px; 106 | width: 90px !important; 107 | display: inline-block; 108 | font-weight: normal; 109 | } 110 | 111 | .time_segment span { 112 | margin: 0px 8px; 113 | color: gray; 114 | font-style: italic; 115 | font-weight: normal; 116 | } 117 | 118 | .tag_container { 119 | text-align: left; 120 | margin-top: 25px; 121 | } 122 | 123 | .stage_3_label { 124 | min-width: 150px; 125 | display: inline-block; 126 | } 127 | 128 | .stage_3_message { 129 | text-align: center; 130 | font-style: italic; 131 | color: gray; 132 | } 133 | 134 | .proximity_tags, 135 | .annotation_tags { 136 | display: inline-block; 137 | width: 80%; 138 | vertical-align: top; 139 | font-size: 14px; 140 | } 141 | 142 | .proximity_tag, 143 | .annotation_tag { 144 | margin: 0px 10px 10px 10px !important; 145 | height: 30px; 146 | line-height: 30px; 147 | text-transform: uppercase; 148 | } 149 | 150 | .annotation_tag { 151 | background-color: #fff; 152 | color: #00B1B9 !important; 153 | } 154 | 155 | .annotation_tag:hover, 156 | .annotation_tag.selected { 157 | color: #fff !important; 158 | background-color: #00B1B9; 159 | } 160 | 161 | .proximity_tag { 162 | background-color: #fff; 163 | color: #006079 !important; 164 | } 165 | 166 | .proximity_tag:hover, 167 | .proximity_tag.selected { 168 | color: #fff !important; 169 | background-color: #006079; 170 | } 171 | .btn:focus { 172 | outline: none !important; 173 | } 174 | 175 | .exit { 176 | color: #fff !important; 177 | margin-left: 25px; 178 | font-weight: bold; 179 | height: 30px; 180 | line-height: 30px; 181 | } 182 | 183 | .submit_container { 184 | text-align: center; 185 | } 186 | 187 | .submit_container .btn, 188 | .exit { 189 | color: #fff !important; 190 | font-weight: bold; 191 | background-color: #000080; 192 | } 193 | 194 | .submit_container .btn:hover:enabled, 195 | .exit:hover { 196 | background-color: #000040; 197 | } 198 | 199 | .current_region { 200 | z-index: 5000 !important; 201 | border: 2px solid rgba(0, 177, 185, 0.85); 202 | } 203 | 204 | tag.current_label { 205 | z-index: 5000 !important; 206 | background-color: #00B1B9 !important; 207 | } 208 | 209 | .hint { 210 | color: gray; 211 | font-style: italic; 212 | font-weight: normal; 213 | } 214 | 215 | .fa.fa-exclamation-triangle, 216 | .fa.fa-frown-o, 217 | .fa.fa-thumbs-up, 218 | .fa.fa-lightbulb-o { 219 | margin-right: 10px; 220 | } 221 | 222 | .toastHint { 223 | color: #555; 224 | background-color: #fff59d; 225 | } 226 | 227 | /* START: CSS to override curio defaults */ 228 | .row .subtitle { 229 | display: none; 230 | } 231 | 232 | #task-container { 233 | width: 1500px !important; 234 | } 235 | 236 | html, body { 237 | background-color: #fff; 238 | } 239 | 240 | hr { 241 | margin: 5px; 242 | } 243 | 244 | nav { 245 | z-index: 10000; 246 | } 247 | 248 | input[type=text][readonly="readonly"] { 249 | color: rgba(0, 0, 0, 0.5); 250 | border-bottom: 1px dotted rgba(0, 0, 0, 0.5); 251 | } 252 | 253 | i.fa { 254 | vertical-align: inherit; 255 | } 256 | 257 | h6.instruction { 258 | margin-top: 0px; 259 | margin-bottom: 10px; 260 | } 261 | 262 | .videowrapper { 263 | float: none; 264 | clear: both; 265 | width: 100%; 266 | position: relative; 267 | padding-bottom: 56.25%; 268 | padding-top: 25px; 269 | height: 0; 270 | } 271 | 272 | .videowrapper iframe { 273 | position: absolute; 274 | top: 0; 275 | left: 0; 276 | width: 100%; 277 | height: 100%; 278 | } 279 | 280 | #instructions-modal{ 281 | z-index: 10000 !important; 282 | } 283 | 284 | input.form-control.start, 285 | input.form-control.end, 286 | input.form-control.duration { 287 | border-bottom-width: 0px; 288 | } 289 | 290 | #instructions-container { 291 | padding-top: 20px; 292 | padding-bottom: 20px; 293 | } 294 | 295 | .time { 296 | color: #999; 297 | font-style: italic; 298 | } -------------------------------------------------------------------------------- /html/static/fonts/roboto/Roboto-Bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/fonts/roboto/Roboto-Bold.eot -------------------------------------------------------------------------------- /html/static/fonts/roboto/Roboto-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/fonts/roboto/Roboto-Bold.ttf -------------------------------------------------------------------------------- /html/static/fonts/roboto/Roboto-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/fonts/roboto/Roboto-Bold.woff -------------------------------------------------------------------------------- /html/static/fonts/roboto/Roboto-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/fonts/roboto/Roboto-Bold.woff2 -------------------------------------------------------------------------------- /html/static/fonts/roboto/Roboto-Light.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/fonts/roboto/Roboto-Light.eot -------------------------------------------------------------------------------- /html/static/fonts/roboto/Roboto-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/fonts/roboto/Roboto-Light.ttf -------------------------------------------------------------------------------- /html/static/fonts/roboto/Roboto-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/fonts/roboto/Roboto-Light.woff -------------------------------------------------------------------------------- /html/static/fonts/roboto/Roboto-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/fonts/roboto/Roboto-Light.woff2 -------------------------------------------------------------------------------- /html/static/fonts/roboto/Roboto-Medium.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/fonts/roboto/Roboto-Medium.eot -------------------------------------------------------------------------------- /html/static/fonts/roboto/Roboto-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/fonts/roboto/Roboto-Medium.ttf -------------------------------------------------------------------------------- /html/static/fonts/roboto/Roboto-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/fonts/roboto/Roboto-Medium.woff -------------------------------------------------------------------------------- /html/static/fonts/roboto/Roboto-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/fonts/roboto/Roboto-Medium.woff2 -------------------------------------------------------------------------------- /html/static/fonts/roboto/Roboto-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/fonts/roboto/Roboto-Regular.eot -------------------------------------------------------------------------------- /html/static/fonts/roboto/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/fonts/roboto/Roboto-Regular.ttf -------------------------------------------------------------------------------- /html/static/fonts/roboto/Roboto-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/fonts/roboto/Roboto-Regular.woff -------------------------------------------------------------------------------- /html/static/fonts/roboto/Roboto-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/fonts/roboto/Roboto-Regular.woff2 -------------------------------------------------------------------------------- /html/static/fonts/roboto/Roboto-Thin.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/fonts/roboto/Roboto-Thin.eot -------------------------------------------------------------------------------- /html/static/fonts/roboto/Roboto-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/fonts/roboto/Roboto-Thin.ttf -------------------------------------------------------------------------------- /html/static/fonts/roboto/Roboto-Thin.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/fonts/roboto/Roboto-Thin.woff -------------------------------------------------------------------------------- /html/static/fonts/roboto/Roboto-Thin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/fonts/roboto/Roboto-Thin.woff2 -------------------------------------------------------------------------------- /html/static/img/paris.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/img/paris.jpg -------------------------------------------------------------------------------- /html/static/img/task-interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vell001/audio-annotator/b9818feeeca391839daf36ff40b54014094ee84a/html/static/img/task-interface.png -------------------------------------------------------------------------------- /html/static/js/colormap/gen_colormap.js: -------------------------------------------------------------------------------- 1 | /* 2 | * If modifiying this file make sure to run "sh gen_colormap.sh" in this directory 3 | * once you save to generate the colormap.min.js with the node modules browserified 4 | */ 5 | window.colormap = require('colormap'); 6 | 7 | window.magma = [{"index":0,"rgb":[0,0,4]},{"index":0.0039,"rgb":[1,0,5]},{"index":0.0078,"rgb":[1,1,6]},{"index":0.0118,"rgb":[1,1,8]},{"index":0.0157,"rgb":[2,1,9]},{"index":0.0196,"rgb":[2,2,11]},{"index":0.0235,"rgb":[2,2,13]},{"index":0.0275,"rgb":[3,3,15]},{"index":0.0314,"rgb":[3,3,18]},{"index":0.0353,"rgb":[4,4,20]},{"index":0.0392,"rgb":[5,4,22]},{"index":0.0431,"rgb":[6,5,24]},{"index":0.0471,"rgb":[6,5,26]},{"index":0.051,"rgb":[7,6,28]},{"index":0.0549,"rgb":[8,7,30]},{"index":0.0588,"rgb":[9,7,32]},{"index":0.0627,"rgb":[10,8,34]},{"index":0.0667,"rgb":[11,9,36]},{"index":0.0706,"rgb":[12,9,38]},{"index":0.0745,"rgb":[13,10,41]},{"index":0.0784,"rgb":[14,11,43]},{"index":0.0824,"rgb":[16,11,45]},{"index":0.0863,"rgb":[17,12,47]},{"index":0.0902,"rgb":[18,13,49]},{"index":0.0941,"rgb":[19,13,52]},{"index":0.098,"rgb":[20,14,54]},{"index":0.102,"rgb":[21,14,56]},{"index":0.1059,"rgb":[22,15,59]},{"index":0.1098,"rgb":[24,15,61]},{"index":0.1137,"rgb":[25,16,63]},{"index":0.1176,"rgb":[26,16,66]},{"index":0.1216,"rgb":[28,16,68]},{"index":0.1255,"rgb":[29,17,71]},{"index":0.1294,"rgb":[30,17,73]},{"index":0.1333,"rgb":[32,17,75]},{"index":0.1373,"rgb":[33,17,78]},{"index":0.1412,"rgb":[34,17,80]},{"index":0.1451,"rgb":[36,18,83]},{"index":0.149,"rgb":[37,18,85]},{"index":0.1529,"rgb":[39,18,88]},{"index":0.1569,"rgb":[41,17,90]},{"index":0.1608,"rgb":[42,17,92]},{"index":0.1647,"rgb":[44,17,95]},{"index":0.1686,"rgb":[45,17,97]},{"index":0.1725,"rgb":[47,17,99]},{"index":0.1765,"rgb":[49,17,101]},{"index":0.1804,"rgb":[51,16,103]},{"index":0.1843,"rgb":[52,16,105]},{"index":0.1882,"rgb":[54,16,107]},{"index":0.1922,"rgb":[56,16,108]},{"index":0.1961,"rgb":[57,15,110]},{"index":0.2,"rgb":[59,15,112]},{"index":0.2039,"rgb":[61,15,113]},{"index":0.2078,"rgb":[63,15,114]},{"index":0.2118,"rgb":[64,15,116]},{"index":0.2157,"rgb":[66,15,117]},{"index":0.2196,"rgb":[68,15,118]},{"index":0.2235,"rgb":[69,16,119]},{"index":0.2275,"rgb":[71,16,120]},{"index":0.2314,"rgb":[73,16,120]},{"index":0.2353,"rgb":[74,16,121]},{"index":0.2392,"rgb":[76,17,122]},{"index":0.2431,"rgb":[78,17,123]},{"index":0.2471,"rgb":[79,18,123]},{"index":0.251,"rgb":[81,18,124]},{"index":0.2549,"rgb":[82,19,124]},{"index":0.2588,"rgb":[84,19,125]},{"index":0.2627,"rgb":[86,20,125]},{"index":0.2667,"rgb":[87,21,126]},{"index":0.2706,"rgb":[89,21,126]},{"index":0.2745,"rgb":[90,22,126]},{"index":0.2784,"rgb":[92,22,127]},{"index":0.2824,"rgb":[93,23,127]},{"index":0.2863,"rgb":[95,24,127]},{"index":0.2902,"rgb":[96,24,128]},{"index":0.2941,"rgb":[98,25,128]},{"index":0.298,"rgb":[100,26,128]},{"index":0.302,"rgb":[101,26,128]},{"index":0.3059,"rgb":[103,27,128]},{"index":0.3098,"rgb":[104,28,129]},{"index":0.3137,"rgb":[106,28,129]},{"index":0.3176,"rgb":[107,29,129]},{"index":0.3216,"rgb":[109,29,129]},{"index":0.3255,"rgb":[110,30,129]},{"index":0.3294,"rgb":[112,31,129]},{"index":0.3333,"rgb":[114,31,129]},{"index":0.3373,"rgb":[115,32,129]},{"index":0.3412,"rgb":[117,33,129]},{"index":0.3451,"rgb":[118,33,129]},{"index":0.349,"rgb":[120,34,129]},{"index":0.3529,"rgb":[121,34,130]},{"index":0.3569,"rgb":[123,35,130]},{"index":0.3608,"rgb":[124,35,130]},{"index":0.3647,"rgb":[126,36,130]},{"index":0.3686,"rgb":[128,37,130]},{"index":0.3725,"rgb":[129,37,129]},{"index":0.3765,"rgb":[131,38,129]},{"index":0.3804,"rgb":[132,38,129]},{"index":0.3843,"rgb":[134,39,129]},{"index":0.3882,"rgb":[136,39,129]},{"index":0.3922,"rgb":[137,40,129]},{"index":0.3961,"rgb":[139,41,129]},{"index":0.4,"rgb":[140,41,129]},{"index":0.4039,"rgb":[142,42,129]},{"index":0.4078,"rgb":[144,42,129]},{"index":0.4118,"rgb":[145,43,129]},{"index":0.4157,"rgb":[147,43,128]},{"index":0.4196,"rgb":[148,44,128]},{"index":0.4235,"rgb":[150,44,128]},{"index":0.4275,"rgb":[152,45,128]},{"index":0.4314,"rgb":[153,45,128]},{"index":0.4353,"rgb":[155,46,127]},{"index":0.4392,"rgb":[156,46,127]},{"index":0.4431,"rgb":[158,47,127]},{"index":0.4471,"rgb":[160,47,127]},{"index":0.451,"rgb":[161,48,126]},{"index":0.4549,"rgb":[163,48,126]},{"index":0.4588,"rgb":[165,49,126]},{"index":0.4627,"rgb":[166,49,125]},{"index":0.4667,"rgb":[168,50,125]},{"index":0.4706,"rgb":[170,51,125]},{"index":0.4745,"rgb":[171,51,124]},{"index":0.4784,"rgb":[173,52,124]},{"index":0.4824,"rgb":[174,52,123]},{"index":0.4863,"rgb":[176,53,123]},{"index":0.4902,"rgb":[178,53,123]},{"index":0.4941,"rgb":[179,54,122]},{"index":0.498,"rgb":[181,54,122]},{"index":0.502,"rgb":[183,55,121]},{"index":0.5059,"rgb":[184,55,121]},{"index":0.5098,"rgb":[186,56,120]},{"index":0.5137,"rgb":[188,57,120]},{"index":0.5176,"rgb":[189,57,119]},{"index":0.5216,"rgb":[191,58,119]},{"index":0.5255,"rgb":[192,58,118]},{"index":0.5294,"rgb":[194,59,117]},{"index":0.5333,"rgb":[196,60,117]},{"index":0.5373,"rgb":[197,60,116]},{"index":0.5412,"rgb":[199,61,115]},{"index":0.5451,"rgb":[200,62,115]},{"index":0.549,"rgb":[202,62,114]},{"index":0.5529,"rgb":[204,63,113]},{"index":0.5569,"rgb":[205,64,113]},{"index":0.5608,"rgb":[207,64,112]},{"index":0.5647,"rgb":[208,65,111]},{"index":0.5686,"rgb":[210,66,111]},{"index":0.5725,"rgb":[211,67,110]},{"index":0.5765,"rgb":[213,68,109]},{"index":0.5804,"rgb":[214,69,108]},{"index":0.5843,"rgb":[216,69,108]},{"index":0.5882,"rgb":[217,70,107]},{"index":0.5922,"rgb":[219,71,106]},{"index":0.5961,"rgb":[220,72,105]},{"index":0.6,"rgb":[222,73,104]},{"index":0.6039,"rgb":[223,74,104]},{"index":0.6078,"rgb":[224,76,103]},{"index":0.6118,"rgb":[226,77,102]},{"index":0.6157,"rgb":[227,78,101]},{"index":0.6196,"rgb":[228,79,100]},{"index":0.6235,"rgb":[229,80,100]},{"index":0.6275,"rgb":[231,82,99]},{"index":0.6314,"rgb":[232,83,98]},{"index":0.6353,"rgb":[233,84,98]},{"index":0.6392,"rgb":[234,86,97]},{"index":0.6431,"rgb":[235,87,96]},{"index":0.6471,"rgb":[236,88,96]},{"index":0.651,"rgb":[237,90,95]},{"index":0.6549,"rgb":[238,91,94]},{"index":0.6588,"rgb":[239,93,94]},{"index":0.6627,"rgb":[240,95,94]},{"index":0.6667,"rgb":[241,96,93]},{"index":0.6706,"rgb":[242,98,93]},{"index":0.6745,"rgb":[242,100,92]},{"index":0.6784,"rgb":[243,101,92]},{"index":0.6824,"rgb":[244,103,92]},{"index":0.6863,"rgb":[244,105,92]},{"index":0.6902,"rgb":[245,107,92]},{"index":0.6941,"rgb":[246,108,92]},{"index":0.698,"rgb":[246,110,92]},{"index":0.702,"rgb":[247,112,92]},{"index":0.7059,"rgb":[247,114,92]},{"index":0.7098,"rgb":[248,116,92]},{"index":0.7137,"rgb":[248,118,92]},{"index":0.7176,"rgb":[249,120,93]},{"index":0.7216,"rgb":[249,121,93]},{"index":0.7255,"rgb":[249,123,93]},{"index":0.7294,"rgb":[250,125,94]},{"index":0.7333,"rgb":[250,127,94]},{"index":0.7373,"rgb":[250,129,95]},{"index":0.7412,"rgb":[251,131,95]},{"index":0.7451,"rgb":[251,133,96]},{"index":0.749,"rgb":[251,135,97]},{"index":0.7529,"rgb":[252,137,97]},{"index":0.7569,"rgb":[252,138,98]},{"index":0.7608,"rgb":[252,140,99]},{"index":0.7647,"rgb":[252,142,100]},{"index":0.7686,"rgb":[252,144,101]},{"index":0.7725,"rgb":[253,146,102]},{"index":0.7765,"rgb":[253,148,103]},{"index":0.7804,"rgb":[253,150,104]},{"index":0.7843,"rgb":[253,152,105]},{"index":0.7882,"rgb":[253,154,106]},{"index":0.7922,"rgb":[253,155,107]},{"index":0.7961,"rgb":[254,157,108]},{"index":0.8,"rgb":[254,159,109]},{"index":0.8039,"rgb":[254,161,110]},{"index":0.8078,"rgb":[254,163,111]},{"index":0.8118,"rgb":[254,165,113]},{"index":0.8157,"rgb":[254,167,114]},{"index":0.8196,"rgb":[254,169,115]},{"index":0.8235,"rgb":[254,170,116]},{"index":0.8275,"rgb":[254,172,118]},{"index":0.8314,"rgb":[254,174,119]},{"index":0.8353,"rgb":[254,176,120]},{"index":0.8392,"rgb":[254,178,122]},{"index":0.8431,"rgb":[254,180,123]},{"index":0.8471,"rgb":[254,182,124]},{"index":0.851,"rgb":[254,183,126]},{"index":0.8549,"rgb":[254,185,127]},{"index":0.8588,"rgb":[254,187,129]},{"index":0.8627,"rgb":[254,189,130]},{"index":0.8667,"rgb":[254,191,132]},{"index":0.8706,"rgb":[254,193,133]},{"index":0.8745,"rgb":[254,194,135]},{"index":0.8784,"rgb":[254,196,136]},{"index":0.8824,"rgb":[254,198,138]},{"index":0.8863,"rgb":[254,200,140]},{"index":0.8902,"rgb":[254,202,141]},{"index":0.8941,"rgb":[254,204,143]},{"index":0.898,"rgb":[254,205,144]},{"index":0.902,"rgb":[254,207,146]},{"index":0.9059,"rgb":[254,209,148]},{"index":0.9098,"rgb":[254,211,149]},{"index":0.9137,"rgb":[254,213,151]},{"index":0.9176,"rgb":[254,215,153]},{"index":0.9216,"rgb":[254,216,154]},{"index":0.9255,"rgb":[253,218,156]},{"index":0.9294,"rgb":[253,220,158]},{"index":0.9333,"rgb":[253,222,160]},{"index":0.9373,"rgb":[253,224,161]},{"index":0.9412,"rgb":[253,226,163]},{"index":0.9451,"rgb":[253,227,165]},{"index":0.949,"rgb":[253,229,167]},{"index":0.9529,"rgb":[253,231,169]},{"index":0.9569,"rgb":[253,233,170]},{"index":0.9608,"rgb":[253,235,172]},{"index":0.9647,"rgb":[252,236,174]},{"index":0.9686,"rgb":[252,238,176]},{"index":0.9725,"rgb":[252,240,178]},{"index":0.9765,"rgb":[252,242,180]},{"index":0.9804,"rgb":[252,244,182]},{"index":0.9843,"rgb":[252,246,184]},{"index":0.9882,"rgb":[252,247,185]},{"index":0.9922,"rgb":[252,249,187]},{"index":0.9961,"rgb":[252,251,189]},{"index":1,"rgb":[252,253,191]}]; 8 | -------------------------------------------------------------------------------- /html/static/js/colormap/gen_colormap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | GENERATING_FILE="gen_colormap.js" 4 | TMP_FILE="colormap.js" 5 | GENERATED_FILE="colormap.min.js" 6 | 7 | if npm -v > /dev/null; then 8 | echo 'npm found!' 9 | else 10 | echo 'npm not found, please download node and npm' 11 | exit 3 12 | fi 13 | 14 | if npm list colormap | grep colormap > /dev/null; then 15 | echo 'colormap found!' 16 | else 17 | echo 'colormap module not found, installing locally' 18 | npm install colormap 19 | fi 20 | 21 | if npm list -g browserify | grep browserify > /dev/null; then 22 | echo 'browserify found!' 23 | else 24 | echo 'browserify module not found, installing globally' 25 | sudo npm install -g browserify 26 | fi 27 | 28 | if npm list -g uglifyjs | grep uglifyjs > /dev/null; then 29 | echo 'uglifyjs found!' 30 | else 31 | echo 'uglifyjs module not found, installing globally' 32 | sudo npm install -g uglifyjs 33 | fi 34 | 35 | 36 | if browserify $GENERATING_FILE -o $TMP_FILE; then 37 | uglifyjs $TMP_FILE -o $GENERATED_FILE --comments "/license|License/" 38 | rm $TMP_FILE 39 | echo 'generated colormap.min.js' 40 | else 41 | echo 'failed to generate colormap.js' 42 | fi 43 | -------------------------------------------------------------------------------- /html/static/js/lib/wavesurfer.min.js: -------------------------------------------------------------------------------- 1 | /*! wavesurfer.js 1.1.1 (Mon, 04 Apr 2016 09:49:47 GMT) 2 | * https://github.com/katspaugh/wavesurfer.js 3 | * @license CC-BY-3.0 */ 4 | !function(a,b){"function"==typeof define&&define.amd?define("wavesurfer",[],function(){return a.WaveSurfer=b()}):"object"==typeof exports?module.exports=b():a.WaveSurfer=b()}(this,function(){"use strict";var a={defaultParams:{height:128,waveColor:"#999",progressColor:"#555",cursorColor:"#333",cursorWidth:1,skipLength:2,minPxPerSec:20,pixelRatio:window.devicePixelRatio||screen.deviceXDPI/screen.logicalXDPI,fillParent:!0,scrollParent:!1,hideScrollbar:!1,normalize:!1,audioContext:null,container:null,dragSelection:!0,loopSelection:!0,audioRate:1,interact:!0,splitChannels:!1,channel:-1,mediaContainer:null,mediaControls:!1,renderer:"Canvas",backend:"WebAudio",mediaType:"audio",autoCenter:!0},init:function(b){if(this.params=a.util.extend({},this.defaultParams,b),this.container="string"==typeof b.container?document.querySelector(this.params.container):this.params.container,!this.container)throw new Error("Container element not found");if(null==this.params.mediaContainer?this.mediaContainer=this.container:"string"==typeof this.params.mediaContainer?this.mediaContainer=document.querySelector(this.params.mediaContainer):this.mediaContainer=this.params.mediaContainer,!this.mediaContainer)throw new Error("Media Container element not found");this.savedVolume=0,this.isMuted=!1,this.tmpEvents=[],this.currentAjax=null,this.createDrawer(),this.createBackend()},createDrawer:function(){var b=this;this.drawer=Object.create(a.Drawer[this.params.renderer]),this.drawer.init(this.container,this.params),this.drawer.on("redraw",function(){b.drawBuffer(),b.drawer.progress(b.backend.getPlayedPercents())}),this.drawer.on("click",function(a,c){setTimeout(function(){b.seekTo(c)},0)}),this.drawer.on("scroll",function(a){b.fireEvent("scroll",a)})},createBackend:function(){var b=this;this.backend&&this.backend.destroy(),"AudioElement"==this.params.backend&&(this.params.backend="MediaElement"),"WebAudio"!=this.params.backend||a.WebAudio.supportsWebAudio()||(this.params.backend="MediaElement"),this.backend=Object.create(a[this.params.backend]),this.backend.init(this.params),this.backend.on("finish",function(){b.fireEvent("finish")}),this.backend.on("play",function(){b.fireEvent("play")}),this.backend.on("pause",function(){b.fireEvent("pause")}),this.backend.on("audioprocess",function(a){b.fireEvent("audioprocess",a)})},startAnimationLoop:function(){var a=this,b=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame,c=function(){if(!a.backend.isPaused()){var d=a.backend.getPlayedPercents();a.drawer.progress(d),a.fireEvent("audioprocess",a.getCurrentTime()),b(c)}};c()},getDuration:function(){return this.backend.getDuration()},getCurrentTime:function(){return this.backend.getCurrentTime()},play:function(a,b){this.backend.play(a,b),this.startAnimationLoop()},pause:function(){this.backend.pause()},playPause:function(){this.backend.isPaused()?this.play():this.pause()},isPlaying:function(){return!this.backend.isPaused()},skipBackward:function(a){this.skip(-a||-this.params.skipLength)},skipForward:function(a){this.skip(a||this.params.skipLength)},skip:function(a){var b=this.getCurrentTime()||0,c=this.getDuration()||1;b=Math.max(0,Math.min(c,b+(a||0))),this.seekAndCenter(b/c)},seekAndCenter:function(a){this.seekTo(a),this.drawer.recenter(a)},seekTo:function(a){var b=this.backend.isPaused(),c=this.params.scrollParent;b&&(this.params.scrollParent=!1),this.backend.seekTo(a*this.getDuration()),this.drawer.progress(this.backend.getPlayedPercents()),b||(this.backend.pause(),this.backend.play()),this.params.scrollParent=c,this.fireEvent("seek",a)},stop:function(){this.pause(),this.seekTo(0),this.drawer.progress(0)},setVolume:function(a){this.backend.setVolume(a)},setPlaybackRate:function(a){this.backend.setPlaybackRate(a)},toggleMute:function(){this.isMuted?(this.backend.setVolume(this.savedVolume),this.isMuted=!1):(this.savedVolume=this.backend.getVolume(),this.backend.setVolume(0),this.isMuted=!0)},toggleScroll:function(){this.params.scrollParent=!this.params.scrollParent,this.drawBuffer()},toggleInteraction:function(){this.params.interact=!this.params.interact},drawBuffer:function(){var a=Math.round(this.getDuration()*this.params.minPxPerSec*this.params.pixelRatio),b=this.drawer.getWidth(),c=a;this.params.fillParent&&(!this.params.scrollParent||b>a)&&(c=b);var d=this.backend.getPeaks(c);this.drawer.drawPeaks(d,c),this.fireEvent("redraw",d,c)},zoom:function(a){this.params.minPxPerSec=a,this.params.scrollParent=!0,this.drawBuffer(),this.seekAndCenter(this.getCurrentTime()/this.getDuration()),this.fireEvent("zoom",a)},setChannel:function(a){this.params.channel=a,this.drawer.clearWave(),this.drawBuffer(),this.backend.setChannel(a)},loadArrayBuffer:function(a){this.decodeArrayBuffer(a,function(a){this.loadDecodedBuffer(a)}.bind(this))},loadDecodedBuffer:function(a){this.backend.load(a),this.drawBuffer(),this.fireEvent("ready")},loadBlob:function(a){var b=this,c=new FileReader;c.addEventListener("progress",function(a){b.onProgress(a)}),c.addEventListener("load",function(a){b.loadArrayBuffer(a.target.result)}),c.addEventListener("error",function(){b.fireEvent("error","Error reading file")}),c.readAsArrayBuffer(a),this.empty()},load:function(a,b){switch(this.params.backend){case"WebAudio":return this.loadBuffer(a);case"MediaElement":return this.loadMediaElement(a,b)}},loadBuffer:function(a){return this.empty(),this.getArrayBuffer(a,this.loadArrayBuffer.bind(this))},loadMediaElement:function(a,b){this.empty(),this.backend.load(a,this.mediaContainer,b),this.tmpEvents.push(this.backend.once("canplay",function(){this.drawBuffer(),this.fireEvent("ready")}.bind(this)),this.backend.once("error",function(a){this.fireEvent("error",a)}.bind(this))),!b&&this.backend.supportsWebAudio()&&this.getArrayBuffer(a,function(a){this.decodeArrayBuffer(a,function(a){this.backend.buffer=a,this.drawBuffer()}.bind(this))}.bind(this))},decodeArrayBuffer:function(a,b){this.backend.decodeArrayBuffer(a,this.fireEvent.bind(this,"decoded"),this.fireEvent.bind(this,"error","Error decoding audiobuffer")),this.tmpEvents.push(this.once("decoded",b))},getArrayBuffer:function(b,c){var d=this,e=a.util.ajax({url:b,responseType:"arraybuffer"});return this.currentAjax=e,this.tmpEvents.push(e.on("progress",function(a){d.onProgress(a)}),e.on("success",function(a,b){c(a),d.currentAjax=null}),e.on("error",function(a){d.fireEvent("error","XHR error: "+a.target.statusText),d.currentAjax=null})),e},onProgress:function(a){if(a.lengthComputable)var b=a.loaded/a.total;else b=a.loaded/(a.loaded+1e6);this.fireEvent("loading",Math.round(100*b),a.target)},exportPCM:function(a,b,c){a=a||1024,b=b||1e4,c=c||!1;var d=this.backend.getPeaks(a,b),e=[].map.call(d,function(a){return Math.round(a*b)/b}),f=JSON.stringify(e);return c||window.open("data:application/json;charset=utf-8,"+encodeURIComponent(f)),f},cancelAjax:function(){this.currentAjax&&(this.currentAjax.xhr.abort(),this.currentAjax=null)},clearTmpEvents:function(){this.tmpEvents.forEach(function(a){a.un()})},empty:function(){this.backend.isPaused()||(this.stop(),this.backend.disconnectSource()),this.cancelAjax(),this.clearTmpEvents(),this.drawer.progress(0),this.drawer.setWidth(0),this.drawer.drawPeaks({length:this.drawer.getWidth()},0)},destroy:function(){this.fireEvent("destroy"),this.cancelAjax(),this.clearTmpEvents(),this.unAll(),this.backend.destroy(),this.drawer.destroy()}};return a.create=function(b){var c=Object.create(a);return c.init(b),c},a.util={extend:function(a){var b=Array.prototype.slice.call(arguments,1);return b.forEach(function(b){Object.keys(b).forEach(function(c){a[c]=b[c]})}),a},min:function(a){var b=+(1/0);for(var c in a)a[c]b&&(b=a[c]);return b},getId:function(){return"wavesurfer_"+Math.random().toString(32).substring(2)},ajax:function(b){var c=Object.create(a.Observer),d=new XMLHttpRequest,e=!1;return d.open(b.method||"GET",b.url,!0),d.responseType=b.responseType||"json",d.addEventListener("progress",function(a){c.fireEvent("progress",a),a.lengthComputable&&a.loaded==a.total&&(e=!0)}),d.addEventListener("load",function(a){e||c.fireEvent("progress",a),c.fireEvent("load",a),200==d.status||206==d.status?c.fireEvent("success",d.response,a):c.fireEvent("error",a)}),d.addEventListener("error",function(a){c.fireEvent("error",a)}),d.send(),c.xhr=d,c}},a.Observer={on:function(a,b){this.handlers||(this.handlers={});var c=this.handlers[a];return c||(c=this.handlers[a]=[]),c.push(b),{name:a,callback:b,un:this.un.bind(this,a,b)}},un:function(a,b){if(this.handlers){var c=this.handlers[a];if(c)if(b)for(var d=c.length-1;d>=0;d--)c[d]==b&&c.splice(d,1);else c.length=0}},unAll:function(){this.handlers=null},once:function(a,b){var c=this,d=function(){b.apply(this,arguments),setTimeout(function(){c.un(a,d)},0)};return this.on(a,d)},fireEvent:function(a){if(this.handlers){var b=this.handlers[a],c=Array.prototype.slice.call(arguments,1);b&&b.forEach(function(a){a.apply(null,c)})}}},a.util.extend(a,a.Observer),a.WebAudio={scriptBufferSize:256,PLAYING_STATE:0,PAUSED_STATE:1,FINISHED_STATE:2,supportsWebAudio:function(){return!(!window.AudioContext&&!window.webkitAudioContext)},getAudioContext:function(){return a.WebAudio.audioContext||(a.WebAudio.audioContext=new(window.AudioContext||window.webkitAudioContext)),a.WebAudio.audioContext},getOfflineAudioContext:function(b){return a.WebAudio.offlineAudioContext||(a.WebAudio.offlineAudioContext=new(window.OfflineAudioContext||window.webkitOfflineAudioContext)(1,2,b)),a.WebAudio.offlineAudioContext},init:function(b){this.params=b,this.ac=b.audioContext||this.getAudioContext(),this.lastPlay=this.ac.currentTime,this.startPosition=0,this.scheduledPause=null,this.states=[Object.create(a.WebAudio.state.playing),Object.create(a.WebAudio.state.paused),Object.create(a.WebAudio.state.finished)],this.createVolumeNode(),this.createScriptNode(),this.createAnalyserNode(),this.setState(this.PAUSED_STATE),this.setPlaybackRate(this.params.audioRate)},disconnectFilters:function(){this.filters&&(this.filters.forEach(function(a){a&&a.disconnect()}),this.filters=null,this.analyser.connect(this.splitter))},setState:function(a){this.state!==this.states[a]&&(this.state=this.states[a],this.state.init.call(this))},setFilter:function(){this.setFilters([].slice.call(arguments))},setFilters:function(a){this.disconnectFilters(),a&&a.length&&(this.filters=a,this.analyser.disconnect(),a.reduce(function(a,b){return a.connect(b),b},this.analyser).connect(this.splitter))},createScriptNode:function(){this.ac.createScriptProcessor?this.scriptNode=this.ac.createScriptProcessor(this.scriptBufferSize):this.scriptNode=this.ac.createJavaScriptNode(this.scriptBufferSize),this.scriptNode.connect(this.ac.destination)},addOnAudioProcess:function(){var a=this;this.scriptNode.onaudioprocess=function(){var b=a.getCurrentTime();b>=a.getDuration()?(a.setState(a.FINISHED_STATE),a.fireEvent("pause")):b>=a.scheduledPause?(a.setState(a.PAUSED_STATE),a.fireEvent("pause")):a.state===a.states[a.PLAYING_STATE]&&a.fireEvent("audioprocess",b)}},removeOnAudioProcess:function(){this.scriptNode.onaudioprocess=null},createChannelNodes:function(){var a=this.buffer.numberOfChannels;this.splitter=this.ac.createChannelSplitter(a),this.merger=this.ac.createChannelMerger(a),this.setChannel(this.params.channel),this.analyser.disconnect(),this.analyser.connect(this.splitter),this.merger.connect(this.gainNode)},setChannel:function(a){var b=this.buffer.numberOfChannels;this.splitter.disconnect();for(var c=0;b>c;c++)this.splitter.connect(this.merger,-1===a?c:a,c)},createAnalyserNode:function(){this.analyser=this.ac.createAnalyser(),this.analyser.connect(this.gainNode)},createVolumeNode:function(){this.ac.createGain?this.gainNode=this.ac.createGain():this.gainNode=this.ac.createGainNode(),this.gainNode.connect(this.ac.destination)},setVolume:function(a){this.gainNode.gain.value=a},getVolume:function(){return this.gainNode.gain.value},decodeArrayBuffer:function(a,b,c){this.offlineAc||(this.offlineAc=this.getOfflineAudioContext(this.ac?this.ac.sampleRate:44100)),this.offlineAc.decodeAudioData(a,function(a){b(a)}.bind(this),c)},getPeaks:function(a){for(var b=this.buffer.length/a,c=~~(b/10)||1,d=this.buffer.numberOfChannels,e=[],f=[],g=0;d>g;g++)for(var h=e[g]=[],i=this.buffer.getChannelData(g),j=0;a>j;j++){for(var k=~~(j*b),l=~~(k+b),m=0,n=0,o=k;l>o;o+=c){var p=i[o];p>n&&(n=p),m>p&&(m=p)}h[2*j]=n,h[2*j+1]=m,(0==g||n>f[2*j])&&(f[2*j]=n),(0==g||m-1?e:f},getPlayedPercents:function(){return this.state.getPlayedPercents.call(this)},disconnectSource:function(){this.source&&this.source.disconnect()},destroy:function(){this.isPaused()||this.pause(),this.unAll(),this.buffer=null,this.disconnectFilters(),this.disconnectSource(),this.gainNode.disconnect(),this.scriptNode.disconnect(),this.merger.disconnect(),this.splitter.disconnect(),this.analyser.disconnect()},load:function(a){this.startPosition=0,this.lastPlay=this.ac.currentTime,this.buffer=a,this.createSource(),this.createChannelNodes()},createSource:function(){this.disconnectSource(),this.source=this.ac.createBufferSource(),this.source.start=this.source.start||this.source.noteGrainOn,this.source.stop=this.source.stop||this.source.noteOff,this.source.playbackRate.value=this.playbackRate,this.source.buffer=this.buffer,this.source.connect(this.analyser)},isPaused:function(){return this.state!==this.states[this.PLAYING_STATE]},getDuration:function(){return this.buffer?this.buffer.duration:0},seekTo:function(a,b){return this.scheduledPause=null,null==a&&(a=this.getCurrentTime(),a>=this.getDuration()&&(a=0)),null==b&&(b=this.getDuration()),this.startPosition=a,this.lastPlay=this.ac.currentTime,this.state===this.states[this.FINISHED_STATE]&&this.setState(this.PAUSED_STATE),{start:a,end:b}},getPlayedTime:function(){return(this.ac.currentTime-this.lastPlay)*this.playbackRate},play:function(a,b){this.createSource();var c=this.seekTo(a,b);a=c.start,b=c.end,this.scheduledPause=b,this.source.start(0,a,b-a),this.setState(this.PLAYING_STATE),this.fireEvent("play")},pause:function(){this.scheduledPause=null,this.startPosition+=this.getPlayedTime(),this.source&&this.source.stop(0),this.setState(this.PAUSED_STATE),this.fireEvent("pause")},getCurrentTime:function(){return this.state.getCurrentTime.call(this)},setPlaybackRate:function(a){a=a||1,this.isPaused()?this.playbackRate=a:(this.pause(),this.playbackRate=a,this.play())}},a.WebAudio.state={},a.WebAudio.state.playing={init:function(){this.addOnAudioProcess()},getPlayedPercents:function(){var a=this.getDuration();return this.getCurrentTime()/a||0},getCurrentTime:function(){return this.startPosition+this.getPlayedTime()}},a.WebAudio.state.paused={init:function(){this.removeOnAudioProcess()},getPlayedPercents:function(){var a=this.getDuration();return this.getCurrentTime()/a||0},getCurrentTime:function(){return this.startPosition}},a.WebAudio.state.finished={init:function(){this.removeOnAudioProcess(),this.fireEvent("finish")},getPlayedPercents:function(){return 1},getCurrentTime:function(){return this.getDuration()}},a.util.extend(a.WebAudio,a.Observer),a.MediaElement=Object.create(a.WebAudio),a.util.extend(a.MediaElement,{init:function(a){this.params=a,this.media={currentTime:0,duration:0,paused:!0,playbackRate:1,play:function(){},pause:function(){}},this.mediaType=a.mediaType.toLowerCase(),this.elementPosition=a.elementPosition,this.setPlaybackRate(this.params.audioRate)},load:function(a,b,c){var d=this,e=document.createElement(this.mediaType);e.controls=this.params.mediaControls,e.autoplay=this.params.autoplay||!1,e.preload="auto",e.src=a,e.style.width="100%",e.addEventListener("error",function(){d.fireEvent("error","Error loading media element")}),e.addEventListener("canplay",function(){d.fireEvent("canplay")}),e.addEventListener("ended",function(){d.fireEvent("finish")}),e.addEventListener("timeupdate",function(){d.fireEvent("audioprocess",d.getCurrentTime())});var f=b.querySelector(this.mediaType);f&&b.removeChild(f),b.appendChild(e),this.media=e,this.peaks=c,this.onPlayEnd=null,this.buffer=null,this.setPlaybackRate(this.playbackRate)},isPaused:function(){return!this.media||this.media.paused},getDuration:function(){var a=this.media.duration;return a>=1/0&&(a=this.media.seekable.end()),a},getCurrentTime:function(){return this.media&&this.media.currentTime},getPlayedPercents:function(){return this.getCurrentTime()/this.getDuration()||0},setPlaybackRate:function(a){this.playbackRate=a||1,this.media.playbackRate=this.playbackRate},seekTo:function(a){null!=a&&(this.media.currentTime=a),this.clearPlayEnd()},play:function(a,b){this.seekTo(a),this.media.play(),b&&this.setPlayEnd(b),this.fireEvent("play")},pause:function(){this.media&&this.media.pause(),this.clearPlayEnd(),this.fireEvent("pause")},setPlayEnd:function(a){var b=this;this.onPlayEnd=function(c){c>=a&&(b.pause(),b.seekTo(a))},this.on("audioprocess",this.onPlayEnd)},clearPlayEnd:function(){this.onPlayEnd&&(this.un("audioprocess",this.onPlayEnd),this.onPlayEnd=null)},getPeaks:function(b){return this.buffer?a.WebAudio.getPeaks.call(this,b):this.peaks||[]},getVolume:function(){return this.media.volume},setVolume:function(a){this.media.volume=a},destroy:function(){this.pause(),this.unAll(),this.media&&this.media.parentNode&&this.media.parentNode.removeChild(this.media),this.media=null}}),a.AudioElement=a.MediaElement,a.Drawer={init:function(a,b){this.container=a,this.params=b,this.width=0,this.height=b.height*this.params.pixelRatio,this.lastPos=0,this.initDrawer(b),this.createWrapper(),this.createElements()},createWrapper:function(){this.wrapper=this.container.appendChild(document.createElement("wave")),this.style(this.wrapper,{display:"block",position:"relative",userSelect:"none",webkitUserSelect:"none",height:this.params.height+"px"}),(this.params.fillParent||this.params.scrollParent)&&this.style(this.wrapper,{width:"100%",overflowX:this.params.hideScrollbar?"hidden":"auto",overflowY:"hidden"}),this.setupWrapperEvents()},handleEvent:function(a){a.preventDefault();var b,c=this.wrapper.getBoundingClientRect(),d=this.width,e=this.getWidth();return!this.params.fillParent&&e>d?(b=(a.clientX-c.left)*this.params.pixelRatio/d||0,b>1&&(b=1)):b=(a.clientX-c.left+this.wrapper.scrollLeft)/this.wrapper.scrollWidth||0,b},setupWrapperEvents:function(){var a=this;this.wrapper.addEventListener("click",function(b){var c=a.wrapper.offsetHeight-a.wrapper.clientHeight;if(0!=c){var d=a.wrapper.getBoundingClientRect();if(b.clientY>=d.bottom-c)return}a.params.interact&&a.fireEvent("click",b,a.handleEvent(b))}),this.wrapper.addEventListener("scroll",function(b){a.fireEvent("scroll",b)})},drawPeaks:function(a,b){this.resetScroll(),this.setWidth(b),this.params.barWidth?this.drawBars(a):this.drawWave(a)},style:function(a,b){return Object.keys(b).forEach(function(c){a.style[c]!==b[c]&&(a.style[c]=b[c])}),a},resetScroll:function(){null!==this.wrapper&&(this.wrapper.scrollLeft=0)},recenter:function(a){var b=this.wrapper.scrollWidth*a;this.recenterOnPosition(b,!0)},recenterOnPosition:function(a,b){var c=this.wrapper.scrollLeft,d=~~(this.wrapper.clientWidth/2),e=a-d,f=e-c,g=this.wrapper.scrollWidth-this.wrapper.clientWidth;if(0!=g){if(!b&&f>=-d&&d>f){var h=5;f=Math.max(-h,Math.min(h,f)),e=c+f}e=Math.max(0,Math.min(g,e)),e!=c&&(this.wrapper.scrollLeft=e)}},getWidth:function(){return Math.round(this.container.clientWidth*this.params.pixelRatio)},setWidth:function(a){a!=this.width&&(this.width=a,this.params.fillParent||this.params.scrollParent?this.style(this.wrapper,{width:""}):this.style(this.wrapper,{width:~~(this.width/this.params.pixelRatio)+"px"}),this.updateSize())},setHeight:function(a){a!=this.height&&(this.height=a,this.style(this.wrapper,{height:~~(this.height/this.params.pixelRatio)+"px"}),this.updateSize())},progress:function(a){var b=1/this.params.pixelRatio,c=Math.round(a*this.width)*b;if(c=b){if(this.lastPos=c,this.params.scrollParent&&this.params.autoCenter){var d=~~(this.wrapper.scrollWidth*a);this.recenterOnPosition(d)}this.updateProgress(a)}},destroy:function(){this.unAll(),this.wrapper&&(this.container.removeChild(this.wrapper),this.wrapper=null)},initDrawer:function(){},createElements:function(){},updateSize:function(){},drawWave:function(a,b){},clearWave:function(){},updateProgress:function(a){}},a.util.extend(a.Drawer,a.Observer),a.Drawer.Canvas=Object.create(a.Drawer),a.util.extend(a.Drawer.Canvas,{createElements:function(){var a=this.wrapper.appendChild(this.style(document.createElement("canvas"),{position:"absolute",zIndex:1,left:0,top:0,bottom:0}));if(this.waveCc=a.getContext("2d"),this.progressWave=this.wrapper.appendChild(this.style(document.createElement("wave"),{position:"absolute",zIndex:2,left:0,top:0,bottom:0,overflow:"hidden",width:"0",display:"none",boxSizing:"border-box",borderRightStyle:"solid",borderRightWidth:this.params.cursorWidth+"px",borderRightColor:this.params.cursorColor})),this.params.waveColor!=this.params.progressColor){var b=this.progressWave.appendChild(document.createElement("canvas"));this.progressCc=b.getContext("2d")}},updateSize:function(){var a=Math.round(this.width/this.params.pixelRatio);this.waveCc.canvas.width=this.width,this.waveCc.canvas.height=this.height,this.style(this.waveCc.canvas,{width:a+"px"}),this.style(this.progressWave,{display:"block"}),this.progressCc&&(this.progressCc.canvas.width=this.width,this.progressCc.canvas.height=this.height,this.style(this.progressCc.canvas,{width:a+"px"})),this.clearWave()},clearWave:function(){this.waveCc.clearRect(0,0,this.width,this.height),this.progressCc&&this.progressCc.clearRect(0,0,this.width,this.height)},drawBars:function(a,b){if(a[0]instanceof Array){var c=a;if(this.params.splitChannels)return this.setHeight(c.length*this.params.height*this.params.pixelRatio),void c.forEach(this.drawBars,this);if(this.params.channel>-1){if(this.params.channel>=c.length)throw new Error("Channel doesn't exist");a=c[this.params.channel]}else a=c[0]}var d=[].some.call(a,function(a){return 0>a});d&&(a=[].filter.call(a,function(a,b){return b%2==0}));var e=.5/this.params.pixelRatio,f=this.width,g=this.params.height*this.params.pixelRatio,h=g*b||0,i=g/2,j=a.length,k=this.params.barWidth*this.params.pixelRatio,l=Math.max(this.params.pixelRatio,~~(k/2)),m=k+l,n=1;this.params.normalize&&(n=Math.max.apply(Math,a));var o=j/f;this.waveCc.fillStyle=this.params.waveColor,this.progressCc&&(this.progressCc.fillStyle=this.params.progressColor),[this.waveCc,this.progressCc].forEach(function(b){if(b)for(var c=0;f>c;c+=m){var d=Math.round(a[Math.floor(c*o)]/n*i);b.fillRect(c+e,i-d+h,k+e,2*d)}},this)},drawWave:function(a,b){if(a[0]instanceof Array){var c=a;if(this.params.splitChannels)return this.setHeight(c.length*this.params.height*this.params.pixelRatio),void c.forEach(this.drawWave,this);if(this.params.channel>-1){if(this.params.channel>=c.length)throw new Error("Channel doesn't exist");a=c[this.params.channel]}else a=c[0]}var d=[].some.call(a,function(a){return 0>a});if(!d){for(var e=[],f=0,g=a.length;g>f;f++)e[2*f]=a[f],e[2*f+1]=-a[f];a=e}var h=.5/this.params.pixelRatio,i=this.params.height*this.params.pixelRatio,j=i*b||0,k=i/2,l=~~(a.length/2),m=1;this.params.fillParent&&this.width!=l&&(m=this.width/l);var n=1;if(this.params.normalize){var o=Math.max.apply(Math,a),p=Math.min.apply(Math,a);n=-p>o?-p:o}this.waveCc.fillStyle=this.params.waveColor,this.progressCc&&(this.progressCc.fillStyle=this.params.progressColor),[this.waveCc,this.progressCc].forEach(function(b){if(b){b.beginPath(),b.moveTo(h,k+j);for(var c=0;l>c;c++){var d=Math.round(a[2*c]/n*k);b.lineTo(c*m+h,k-d+j)}for(var c=l-1;c>=0;c--){var d=Math.round(a[2*c+1]/n*k);b.lineTo(c*m+h,k-d+j)}b.closePath(),b.fill(),b.fillRect(0,k+j-h,this.width,h)}},this)},updateProgress:function(a){var b=Math.round(this.width*a)/this.params.pixelRatio;this.style(this.progressWave,{width:b+"px"})}}),a.Drawer.MultiCanvas=Object.create(a.Drawer),a.util.extend(a.Drawer.MultiCanvas,{initDrawer:function(a){if(this.maxCanvasWidth=null!=a.maxCanvasWidth?a.maxCanvasWidth:4e3,this.maxCanvasElementWidth=Math.round(this.maxCanvasWidth/this.params.pixelRatio),this.maxCanvasWidth<=1)throw"maxCanvasWidth must be greater than 1.";if(this.maxCanvasWidth%2==1)throw"maxCanvasWidth must be an even number.";this.hasProgressCanvas=this.params.waveColor!=this.params.progressColor,this.halfPixel=.5/this.params.pixelRatio,this.canvases=[]},createElements:function(){this.progressWave=this.wrapper.appendChild(this.style(document.createElement("wave"),{position:"absolute",zIndex:2,left:0,top:0,bottom:0,overflow:"hidden",width:"0",display:"none",boxSizing:"border-box",borderRightStyle:"solid",borderRightWidth:this.params.cursorWidth+"px",borderRightColor:this.params.cursorColor})),this.addCanvas()},updateSize:function(){for(var a=Math.round(this.width/this.params.pixelRatio),b=Math.ceil(a/this.maxCanvasElementWidth);this.canvases.lengthb;)this.removeCanvas();for(var c in this.canvases){var d=this.maxCanvasWidth+2*Math.ceil(this.params.pixelRatio/2);c==this.canvases.length-1&&(d=this.width-this.maxCanvasWidth*(this.canvases.length-1)),this.updateDimensions(this.canvases[c],d,this.height),this.clearWave(this.canvases[c])}},addCanvas:function(){var a={},b=this.maxCanvasElementWidth*this.canvases.length;a.wave=this.wrapper.appendChild(this.style(document.createElement("canvas"),{position:"absolute",zIndex:1,left:b+"px",top:0,bottom:0})),a.waveCtx=a.wave.getContext("2d"),this.hasProgressCanvas&&(a.progress=this.progressWave.appendChild(this.style(document.createElement("canvas"),{position:"absolute",left:b+"px",top:0,bottom:0})),a.progressCtx=a.progress.getContext("2d")),this.canvases.push(a)},removeCanvas:function(){var a=this.canvases.pop();a.wave.parentElement.removeChild(a.wave),this.hasProgressCanvas&&a.progress.parentElement.removeChild(a.progress)},updateDimensions:function(a,b,c){var d=Math.round(b/this.params.pixelRatio);a.waveCtx.canvas.width=b,a.waveCtx.canvas.height=c,this.style(a.waveCtx.canvas,{width:d+"px"}),this.style(this.progressWave,{display:"block"}),this.hasProgressCanvas&&(a.progressCtx.canvas.width=b,a.progressCtx.canvas.height=c,this.style(a.progressCtx.canvas,{width:d+"px"}))},clearWave:function(a){a.waveCtx.clearRect(0,0,a.waveCtx.canvas.width,a.waveCtx.canvas.height),this.hasProgressCanvas&&a.progressCtx.clearRect(0,0,a.progressCtx.canvas.width,a.progressCtx.canvas.height)},drawBars:function(b,c){if(b[0]instanceof Array){var d=b;if(this.params.splitChannels)return this.setHeight(d.length*this.params.height*this.params.pixelRatio),void d.forEach(this.drawBars,this);b=d[0]}var e=[].some.call(b,function(a){return 0>a});e&&(b=[].filter.call(b,function(a,b){return b%2==0}));var f=this.width,g=this.params.height*this.params.pixelRatio,h=g*c||0,i=g/2,j=b.length,k=this.params.barWidth*this.params.pixelRatio,l=Math.max(this.params.pixelRatio,~~(k/2)),m=k+l,n=1;this.params.normalize&&(n=a.util.max(b));var o=j/f;this.canvases[0].waveCtx.fillStyle=this.params.waveColor,this.canvases[0].progressCtx&&(this.canvases[0].progressCtx.fillStyle=this.params.progressColor);for(var p=0;f>p;p+=m){var q=Math.round(b[Math.floor(p*o)]/n*i);this.fillRect(p+this.halfPixel,i-q+h,k+this.halfPixel,2*q)}},drawWave:function(b,c){if(b[0]instanceof Array){var d=b;if(this.params.splitChannels)return this.setHeight(d.length*this.params.height*this.params.pixelRatio),void d.forEach(this.drawWave,this);b=d[0]}var e=[].some.call(b,function(a){return 0>a});if(!e){for(var f=[],g=0,h=b.length;h>g;g++)f[2*g]=b[g],f[2*g+1]=-b[g];b=f}var i=this.params.height*this.params.pixelRatio,j=i*c||0,k=i/2,l=~~(b.length/2),m=1;this.params.fillParent&&this.width!=l&&(m=this.width/l);var n=1;if(this.params.normalize){var o=a.util.max(b),p=a.util.min(b);n=-p>o?-p:o}this.drawLine(l,b,n,k,m,j),this.fillRect(0,k+j-this.halfPixel,this.width,this.halfPixel)},drawLine:function(a,b,c,d,e,f){for(var g in this.canvases){var h=this.canvases[g];this.setFillStyles(h),this.drawLineToContext(h.waveCtx,g,b,c,d,e,f),this.drawLineToContext(h.progressCtx,g,b,c,d,e,f)}},drawLineToContext:function(a,b,c,d,e,f,g){if(a){var h=b*this.maxCanvasWidth,i=h+a.canvas.width+1;a.beginPath(),a.moveTo(this.halfPixel,e+g);for(var j=h;i>j;j++){var k=Math.round(c[2*j]/d*e);a.lineTo((j-h)*f+this.halfPixel,e-k+g)}for(var j=i-1;j>=h;j--){var k=Math.round(c[2*j+1]/d*e);a.lineTo((j-h)*f+this.halfPixel,e-k+g)}a.closePath(),a.fill()}},fillRect:function(a,b,c,d){for(var e in this.canvases){var f=this.canvases[e],g=e*this.maxCanvasWidth,h={x1:Math.max(a,e*this.maxCanvasWidth),y1:b,x2:Math.min(a+c,e*this.maxCanvasWidth+f.waveCtx.canvas.width),y2:b+d};h.x1p;p++)o[p]=Math.max(-255,45*Math.log10(n[p]));h.push(o),l+=c-i}b(h,this)},loadFrequenciesData:function(b){var c=this,d=a.util.ajax({url:b});return d.on("success",function(a){c.drawSpectrogram(JSON.parse(a),c)}),d.on("error",function(a){c.fireEvent("error","XHR error: "+a.target.statusText)}),d},updateScroll:function(a){this.wrapper.scrollLeft=a.target.scrollLeft},resample:function(a,b){for(var b=this.width,c=[],d=1/a.length,e=1/b,f=0;b>f;f++){for(var g=new Array(a[0].length),h=0;h=j||i>=l?0:Math.min(Math.max(j,k),Math.max(l,i))-Math.max(Math.min(j,k),Math.min(l,i));if(m>0)for(var n=0;ne;e++)this.windowValues[e]=2/(a-1)*((a-1)/2-Math.abs(e-(a-1)/2));break;case"bartlettHann":for(var e=0;a>e;e++)this.windowValues[e]=.62-.48*Math.abs(e/(a-1)-.5)-.38*Math.cos(2*Math.PI*e/(a-1));break;case"blackman":d=d||.16;for(var e=0;a>e;e++)this.windowValues[e]=(1-d)/2-.5*Math.cos(2*Math.PI*e/(a-1))+d/2*Math.cos(4*Math.PI*e/(a-1));break;case"cosine":for(var e=0;a>e;e++)this.windowValues[e]=Math.cos(Math.PI*e/(a-1)-Math.PI/2);break;case"gauss":d=d||.25;for(var e=0;a>e;e++)this.windowValues[e]=Math.pow(Math.E,-.5*Math.pow((e-(a-1)/2)/(d*(a-1)/2),2));break;case"hamming":for(var e=0;a>e;e++)this.windowValues[e]=.54-.46*Math.cos(2*Math.PI*e/(a-1));break;case"hann":case void 0:for(var e=0;a>e;e++)this.windowValues[e]=.5*(1-Math.cos(2*Math.PI*e/(a-1)));break;case"lanczoz":for(var e=0;a>e;e++)this.windowValues[e]=Math.sin(Math.PI*(2*e/(a-1)-1))/(Math.PI*(2*e/(a-1)-1));break;case"rectangular":for(var e=0;a>e;e++)this.windowValues[e]=1;break;case"triangular":for(var e=0;a>e;e++)this.windowValues[e]=2/a*(a/2-Math.abs(e-(a-1)/2));break;default:throw Error("No such window function '"+c+"'")}for(var e,f=1,g=a>>1;a>f;){for(e=0;f>e;e++)this.reverseTable[e+f]=this.reverseTable[e]+g;f<<=1,g>>=1}for(e=0;a>e;e++)this.sinTable[e]=Math.sin(-Math.PI/e),this.cosTable[e]=Math.cos(-Math.PI/e);this.calculateSpectrum=function(a){var b,c,d,e=this.bufferSize,f=this.cosTable,g=this.sinTable,h=this.reverseTable,i=new Float32Array(e),j=new Float32Array(e),k=2/this.bufferSize,l=Math.sqrt,m=new Float32Array(e/2),n=Math.floor(Math.log(e)/Math.LN2);if(Math.pow(2,n)!==e)throw"Invalid buffer size, must be a power of 2.";if(e!==a.length)throw"Supplied buffer is not the same size as defined FFT. FFT Size: "+e+" Buffer Size: "+a.length;for(var o,p,q,r,s,t,u,v,w=1,x=0;e>x;x++)i[x]=a[h[x]]*this.windowValues[h[x]],j[x]=0;for(;e>w;){o=f[w],p=g[w],q=1,r=0;for(var y=0;w>y;y++){for(var x=y;e>x;)s=x+w,t=q*i[s]-r*j[s],u=q*j[s]+r*i[s],i[s]=i[x]-t,j[s]=j[x]-u,i[x]+=t,j[x]+=u,x+=w<<1;v=q,q=v*o-r*p,r=v*p+r*o}w<<=1}for(var x=0,z=e/2;z>x;x++)b=i[x],c=j[x],d=k*l(b*b+c*c),d>this.peak&&(this.peakBand=x,this.peak=d),m[x]=d;return m}},a.util.extend(a.Spectrogram,a.Observer,a.FFT)}); -------------------------------------------------------------------------------- /html/static/js/src/annotation_stages.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* 4 | * Purpose: 5 | * The view the user sees when no region has been seleted 6 | * Dependencies: 7 | * jQuey, audio-annotator.css 8 | */ 9 | function StageOneView() { 10 | this.dom = null; 11 | } 12 | 13 | StageOneView.prototype = { 14 | // Create dom 15 | create: function() { 16 | var my = this; 17 | var container = $('
'); 18 | 19 | // This btn is for the region online creation mode, not currently appended to the stage one view 20 | var button = $('