zoukankan      html  css  js  c++  java
  • ukulele弹奏模拟器v1.0(待完善)

    写在前面

    最近听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

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <title>ukulele</title>
            <link rel="stylesheet" href="css/ukulele.css" />
            <script type="text/javascript" src="js/ukulele.js" ></script>
        </head>
        <body>
            <div align="center">
                <h1>ukulele弹奏模拟器v1.0</h1>
                <table>
                    <tr>
                        <td align="right">
                            <textarea id="temp" class="textarea"></textarea>
                        </td>
                        <td align="left">
                            <input type="button" class="cls" onclick="resetTemp()" />
                        </td>
                    </tr>
                    <tr>
                        <td align="right">
                            <textarea id="replay" class="textarea"></textarea>
                        </td>
                        <td align="left">
                            <input type="button" class="cls" onclick="resetPlay()">
                            <input type="button" class="play" onclick="replay()" />
                        </td>
                    </tr>
                </table>
            </div>
            <div align="center">
                <h1>Key(1=do 2=re 3=mi 4=fa 5=so 6=la 7=xi 0=i)</h1>
                <audio src="mp3/1do.mp3" id="do" controls="controls" hidden="hidden"></audio>
                <audio src="mp3/2re.mp3" id="re" controls="controls" hidden="hidden"></audio>
                <audio src="mp3/3mi.mp3" id="mi" controls="controls" hidden="hidden"></audio>
                <audio src="mp3/4fa.mp3" id="fa" controls="controls" hidden="hidden"></audio>
                <audio src="mp3/5so.mp3" id="so" controls="controls" hidden="hidden"></audio>
                <audio src="mp3/6la.mp3" id="la" controls="controls" hidden="hidden"></audio>
                <audio src="mp3/7xi.mp3" id="xi" controls="controls" hidden="hidden"></audio>
                <audio src="mp3/ido.mp3" id="ido" controls="controls" hidden="hidden"></audio>
                <input type="button" class="key" id="97" onclick="press()" style="background-image: url(img/1.png);" />
                <input type="button" class="key" id="98" onclick="press()" style="background-image: url(img/2.png);" />
                <input type="button" class="key" id="99" onclick="press()" style="background-image: url(img/3.png);" />
                <input type="button" class="key" id="100" onclick="press()" style="background-image: url(img/4.png);" />
                <input type="button" class="key" id="101" onclick="press()" style="background-image: url(img/5.png);" />
                <input type="button" class="key" id="102" onclick="press()" style="background-image: url(img/6.png);" />
                <input type="button" class="key" id="103" onclick="press()" style="background-image: url(img/7.png);" />
                <input type="button" class="key" id="96" onclick="press()" style="background-image: url(img/0.png);" />
            </div>
            <div align="center">
                <input type="button" class="demo" id="christmas" onclick="christmas()" style="background-image: url(img/christmas.png);" alt="圣诞歌"/>
                <input type="button" class="demo" id="star" onclick="star()" style="background-image: url(img/star.png);" alt="小星星"/>
                <input type="button" class="demo" id="bee" onclick="bee()" style="background-image: url(img/bee.png);" alt="小蜜蜂"/>
            </div>
        </body>
    </html>

    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://xiguanchendian.github.io/ukulele/

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

    感谢

  • 相关阅读:
    《区块链-解密构建基于信用的下一代互联网》_黄步添下载
    《SpringBoot+Vue全栈开发实战》_王松
    《SpringCloud微服务架构进阶》_朱荣鑫资料分享
    算法开发书籍推荐
    《深入理解SpringCloud与微服务构建》 《微服务架构基础(SpringBoot+SpringCloud+Docker)》 《重新定义SpringCloud实战》 《疯狂SpringCloud微服务架构实战》 《微服务架构实战基于SpringBootSpringCloudDocker》 《云原生Java:SpringBoot、SpringCloud与CloudFoundry弹性系统设计》
    运维书籍推荐
    elementUI表格内容的行列合并
    ios:项目报错Undefined symbols for architecture x86_64:
    LINUX :2020年kail linux扫描抓包破解wifi密码流程
    pr加字幕
  • 原文地址:https://www.cnblogs.com/yadongliang/p/10777256.html
Copyright © 2011-2022 走看看