博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ukulele弹奏模拟器v1.0(待完善)
阅读量:6223 次
发布时间:2019-06-21

本文共 6840 字,大约阅读时间需要 22 分钟。

写在前面

最近听beyond乐队的《灰色轨迹》听上瘾了,300多遍,震惊!!尤其喜欢最后一分半钟的吉他solo,真可谓吉他没有酒,依然让我醉如老狗。。

翻了翻网上的视频,瞬间觉得单身20年的手速都望尘莫及~~

默默拿起尤克里里弹着儿歌《小星星》不禁老泪纵横。。我撅腚要学会首像样的曲子!

学什么好呢?琢磨半天灵光一闪,《士兵突击》中不是有段吉他弹奏的曲子,名字叫《前向きな乙女心》吗?

当初说了“如果学吉他也会是因为这首曲子吧”,想不到一语成谶,那就从它开始吧!!

上网搜关于这首曲的尤克里里四线谱,找不到,淘宝问客服客服说老师还没有录制关于这首的教学视频。。

我就听,这首时长1分42秒,觉得并不是很难,一边听一遍试,发现还是很简单的~~

3 3 4 5 2 1 5 1 3 3 2 1 2 5 3

3 3 4 5 2 1 5 1 3 5 4 3 2 1 1

到30秒后发现自己图样图森破,手速太慢试不出来了。。

怎么办呢?

第一个想到的是搜计算器,会发声的计算器,微博看到有人用5个相同的计算器弹《名侦探柯南》主题曲~太机智了~但是搜了一圈,已经快十点了,好多店铺客服都打卡下班了~

于是想网上有没有模拟音阶的软件呢?有,但是好多都是钢琴的,下载了一个貌似还带病毒,买了佛冷。并且钢琴和尤克里里音色还不大一样,就想能不能通过程序搞一些愉快的事情?

有人写了关于钢琴的程序,果然是一帮有理想的骚年,钢琴88键都能做出来,我这1234567i岂不是小儿科啊,说干就干!

步骤分解

1.一边弹一边用手机录音1234567i

没错,用手机。。音质差了点,不过听了一遍还在能忍受的范围。

2.音频截取

1234567i,8段短音频,每段大概2秒钟的样子,个别音长达4秒,不禁感叹这把琴的延音是真滴好,钱花哪哪值啊(¥2480 经费在燃烧.......)。

3.界面设计

界面两个框,上面一个框实时显示按键按下后的按键数值,下面框保留自己满意的音阶,clear按钮用于快速清除框内值

框下面1234567i按键阵列,先这样吧,丑是丑了点能用先。。

4.撸代码

采用HTML5,根据按键值,读取对应的音频文件

5.哦了

(这里有个问题, 播放按键由于js无法控制匀速, 播放暂时留了个bug,  js如何实现sleep呢?欢迎留言)

 

置灰部分先忽略吧,搬完家抽时间再搞~

6.发布微信小程序

下一步准备将程序迁移至微信小游戏,之前是默认的“打飞机”,并未发布。这下把这个程序发布一下,手机上操作不是更方便吗?

微信小程序是js写,似乎更简单了~

按键图片

按键对应音频

编程,测试

发布小程序

 

关键代码 

目录结构

 

index.html

            
ukulele

ukulele弹奏模拟器v1.0

Key(1=do 2=re 3=mi 4=fa 5=so 6=la 7=xi 0=i)

ukulele.js

function press(){    var currentId = parseInt(event.currentTarget.id);    ring(currentId);    var yinjie = toYinjie(currentId);    append(yinjie);}window.onkeydown = function(event){    var keyCode = event.keyCode;    ring(keyCode);    var arr = [97,98,99,100,101,102,103,96,49,50,51,52,53,54,55,48];    var boo = isInArray(arr, keyCode);    if(boo){        var yinjie = toYinjie(keyCode);        append(yinjie);    }}function ring(value){    var targetId = toTargetId(value);    var element = document.getElementById(targetId);    keyDown(element);}function keyDown(element){    if(element!=null){        element.currentTime = 0;        if(element.paused){            element.play();        }    }}function resetTemp(){    document.getElementById("temp").value = "";}function resetPlay(){    document.getElementById("replay").value = "";}function append(value){    document.getElementById("temp").value += value;    document.getElementById("replay").value += value;}function replay(){    var vals = document.getElementById("replay").value;    // 自动演奏 间隔1s    for(var i = 0; i < vals.length; i++){        var v = vals.charAt(i);        var keycode = toKeycode(v);        async function test(){          var temple=await sleep(1000);          ring(parseInt(keycode));          return temple;        }//                ring(parseInt(keycode));    }}function sleep (time) {    return new Promise((resolve) => setTimeout(resolve, time));}function isInArray(arr, value){    for(var i = 0; i < arr.length; i++){        if(value === arr[i]){            return true;        }    }    return false;}function toKeycode(value){    var keycode = null;    switch(value){        case "1":            keycode = "97";            break;        case "2":            keycode = "98";            break;        case "3":            keycode = "99";            break;        case "4":            keycode = "100";            break;        case "5":            keycode = "101";            break;        case "6":            keycode = "102";            break;        case "7":            keycode = "103";            break;        case "i":            keycode = "96";            break;    }    return keycode;}function toYinjie(value){    var yinjie = null;    switch(value){        case 49:        case 97:            yinjie = "1";            break;        case 50:        case 98:            yinjie = "2";            break;        case 51:        case 99:            yinjie = "3";            break;        case 52:        case 100:            yinjie = "4";            break;        case 53:        case 101:            yinjie = "5";            break;        case 54:        case 102:            yinjie = "6";            break;        case 55:        case 103:            yinjie = "7";            break;        case 48:        case 96:            yinjie = "i";            break;    }    return yinjie;}function toTargetId(value){    var targetId = null;    switch(value){        case 49:        case 97:            targetId = "do";            break;        case 50:        case 98:            targetId = "re";            break;        case 51:        case 99:            targetId = "mi";            break;        case 52:        case 100:            targetId = "fa";            break;        case 53:        case 101:            targetId = "so";            break;        case 54:        case 102:            targetId = "la";            break;        case 55:        case 103:            targetId = "xi";            break;        case 48:        case 96:            targetId = "ido";            break;    }    return targetId;}// 圣诞歌function christmas(){    }// 小星星function star(){    }// 小蜜蜂function bee(){    }

ukulele.css

h1{
color: blueviolet;}.textarea {
width: 650px; height: 250px; background: rgba(255, 255, 255, 0); font-family: "arial, helvetica, sans-serif"; font-size: 48px; color: purple; border-color: pink;}.key{
width:100px; height:100px; background-size: 100% 100%; border-radius: 50px; background-color: pink; outline: none;}.cls , .play{
width: 86px; height: 86px; border-radius: 5px; background-color: deepskyblue; outline: none;}.cls{
background-image: url(../img/del.png);}.play{
background-image: url(../img/play.png);}.demo{
width: 130px; height: 100px; border-radius: 20px; background-color: pink; outline: none;}body {
background-image: url(../img/bg.png); background-repeat: no-repeat; background-attachment: fixed; background-size: cover;}

 

 

代码已分别上传至github,喜欢的园友可以戳戳

简单感受一下~

以下是微信小程序识别码,欢迎试玩鸭~

 

感谢

转载于:https://www.cnblogs.com/yadongliang/p/10777256.html

你可能感兴趣的文章
Android屏幕尺寸适配注意事项
查看>>
JAVA代码中加了Try...Catch的执行顺序
查看>>
三个c#入门小程序
查看>>
docker中使用systemd
查看>>
[模拟电路] 1、模拟调制、解调电路原理
查看>>
Android Nine Patch图片及按钮背景
查看>>
在.NET中调用Oracle9i存储过程经验总结
查看>>
Eclipse崩溃后无法启动的问题解决
查看>>
Android Studio git ignore
查看>>
springmvc
查看>>
22.2. 用户认证
查看>>
1.7. User interfaces
查看>>
阿里Druid数据连接池在SSM框架中的配置使用
查看>>
基于Metronic的Bootstrap开发框架经验总结(17)-- 使用 summernote插件实现HTML文档的编辑和图片插入操作...
查看>>
Linux虚拟主机通过程序实现二级域名绑定到子目录
查看>>
7.12. cvs diff
查看>>
Android酷炫实用的开源框架(UI框架)
查看>>
Winform开发框架之对话框样式同化
查看>>
一脸懵逼学习Linux的Shell编程
查看>>
Jmeter调试工具---Debug Sampler
查看>>