一个类似节奏大师游戏的音乐节奏编辑工具



  • 本工具主要为自己开发音乐游戏所用的编辑软件,功能主要编辑音乐节奏,然后保存节奏数据为json格式,然后在节奏游戏中导入这些节奏数据,可以达到节奏大师的效果。暂时没有添加长安节奏类功能。感觉节奏类游戏千变万化,这个工具以后会进行细节的改进,现在眼下先干着IT文化节的作品展示做了小功能了呜呜。

    工具缺点:
    不能加载中文路径(由于用了libzplay做频谱)

    软件功能:
    1,支持加载大部分格式音乐文件
    2,编辑游戏节奏的时候支持回播编辑
    3,支持细微调节节奏点的位置
    4,双击节奏点可以删除该节奏点
    5,一键清除所有节奏点

    操作方式:
    1,打开音乐文件(不能出现中文路径)
    0_1461117374585_upload-50dd6d9f-c416-49f3-9bfd-4e9a665337b8
    2,点击播放按钮播放,或者按space建播放/暂停
    0_1461117446113_upload-d5e56080-0ff4-480a-bf4e-eaaac886691f
    3,在播放的过程中可以按着音乐节奏编辑节奏点,编辑按键为F,G,H,J
    0_1461117636910_upload-a0498546-399f-4d62-9432-4228b4b6715d
    4,微调节奏
    0_1461117787005_upload-127b9ce9-11a9-4445-8a33-26afae8f76e0
    5,保存的时候会在当前音乐文件目录中的Data目录生成对应音乐文件名的json数据
    0_1461117894514_upload-1359f79b-1a0f-486c-8883-69464d5ebb3e
    0_1461117930580_upload-17a3db81-379b-4eba-afcb-5d682082e3cf
    源码分享
    tommego



  • 厉害,没想到这么快就把节奏编辑的软件制作好了。试问中间的梯形Rectangle是如何实现的呢?



  • 其实早两个星期就写好了,我都给我师弟帮我录节奏了, 后来他们说录取完了不好调整,所以我今天下午又改成了qq音速的节奏编辑模式



  • 中间梯形的很简单,就直接把它x轴转60度左右
    代码实现部分以下:

                Rectangle{
                    width: root.width
                    height:root.height/2
                    color:"#99a066"
    
                    Item{
                        width: 1200
                        height: music_duration*1000+500
                        clip:true
                        id:padroot
                        transform: Rotation {
                            origin.x: padroot.width/2;
                            origin.y: padroot.height;
                            axis { x: 1; y: 0; z: 0 }
                            angle: 50 }
                        anchors.horizontalCenter: parent.horizontalCenter
                        anchors.bottom: parent.bottom
                        Rectangle{
                            anchors.bottom: parent.bottom
                            anchors.bottomMargin: 500+2
                            width: parent.width
                            height:4
                            color:"#12aaff"
                        }
    
                        Rectangle{
                            y:current_position*20
                            width:parent.width
                            height:music_duration*1000
                            id:musicPad
                            color:"#44000000"
                            Behavior on y{
                                PropertyAnimation{
                                    properties: "y"
                                    duration: 50
                                }
                            }
    
                            Column{
                                spacing: 1000-3
                                height:parent.height
                                anchors.centerIn: parent
                                Repeater{
                                    model: music_duration
                                    delegate: Rectangle{
                                        width: musicPad.width
                                        height: 3
                                        color:"#aa000000"
                                        Text{
                                            anchors.centerIn: parent
                                            text:""+(music_duration-index)+"s"
                                            font.pointSize: 120
                                            color:"#33eeff12"
                                        }
                                    }
                                }
                            }
    
                            Repeater{
                                model: datasModel
                                delegate: Rectangle{
                                    width: 150
                                    height: 60
                                    id:spot
                                    radius: height/2
                                    color:selected?"#12eeaa":"#99000000"
                                    x:pindex*300+75
                                    y:(music_duration-(pos*20)/1000)*musicPad.height/music_duration-30
                                    z:selected?2:1
    
                                    Rectangle{
                                        anchors.top: parent.bottom
                                        anchors.topMargin: 20
                                        width: 80
                                        height:60
                                        radius: height/2
                                        visible: selected
                                        color:"#ee6612"
                                        anchors.horizontalCenter: parent.horizontalCenter
                                        Rectangle{
                                            width: 3
                                            height: 20
                                            color:parent.color
                                            anchors.horizontalCenter: parent.horizontalCenter
                                            anchors.bottom: parent.top
                                        }
    
                                        Text{
                                            anchors.centerIn: parent
                                            color:"#ffffff"
                                            text:"delete"
                                            font.pointSize: 15
                                        }
    
                                        MouseArea{
                                            anchors.fill: parent
                                            onClicked: datasModel.remove(index);
                                        }
                                    }
    
                                    MouseArea{
                                        anchors.fill: parent
                                        drag.target: spot
                                        drag.minimumY: 0
                                        drag.maximumY: music_duration*1000
                                        drag.axis: Drag.YAxis
                                        onClicked: {
                                            for(var a=0;a<datasModel.count;a++){
                                                datasModel.setProperty(a,"selected",false);
                                            }
                                            datasModel.setProperty(index,"selected",true);
                                        }
                                        onPressed: {
                                            for(var a=0;a<datasModel.count;a++){
                                                datasModel.setProperty(a,"selected",false);
                                            }
                                            datasModel.setProperty(index,"selected",true);
                                        }
    
                                        onReleased: {
                                            datasModel.setProperty(index,"pos",50*(music_duration-(spot.y+30)*music_duration/musicPad.height));
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
    


  • @tommego 嗯,好创意。这也是能够创造出三维感的好办法!

    应该是沿着X轴旋转60度角。



  • @jiangcaiyang 对的,这样既能达到三维效果,又减少开销



  • shurufahuaile,ni hao lihai



  • 感谢分享,望早日可以完成。



  • 谢谢楼主,居然一下子提供了这么多开源软件,其中有几个还很不错~



  • awesome!


Log in to reply
 

最近的回复

  • 在USD安装好之后,我们就要研究如何编写USDView的插件了,因为我们的二次开发功能都是在USD上做的,所以我们要理解USDView的各种机制才能够达到我们研发的目标。这里介绍一下如何编写USDView的插件。

    USDView是USD项目中比较重量级的应用了,基于Qt(PySide,PySide2)和PyOpenGL的应用。底层渲染依然是Hydra。这是一款渲染影视的渲染框架。后端可以接入OpenGL以及英特尔提出的Embree。它在设计的时候也预留了插件的功能。它在官网有详细的教程解释。

    插件本身

    这里我在Linux下演示如何载入USDView的插件。我写好了一个USDView的插件,名叫TutorialPlugin。它由三个插件组成的:

    tutorialPlugin ├── __init__.py ├── plugInfo.json └── printer.py

    写法和官网的一致。这里我贴出来吧。
    init.py

    from pxr import Tf from pxr.Usdviewq.plugin import PluginContainer import printer class TutorialPluginContainer(PluginContainer): def registerPlugins(self, plugRegistry, usdviewApi): self._printMessage = plugRegistry.registerCommandPlugin( "TutorialPluginContainer.printMessage", "Print Message", printer.printMessage ) def configureView(self, plugRegistry, plugUIBuilder): tutMenu = plugUIBuilder.findOrCreateMenu("Tutorial") tutMenu.addItem(self._printMessage) Tf.Type.Define(TutorialPluginContainer)

    painter.py

    print("Imported printer!") def printMessage(usdviewApi): print("Hello, World!")

    plugInfo.py文件在Windows测试中,使用pluginfo.py也能被认识。果然Linux是大小写敏感的,Windows并不敏感。

    { "Plugins": [ { "Type": "python", "Name": "tutorialPlugin", "Info": { "Types": { "tutorialPlugin.TutorialPluginContainer": { "bases": ["pxr.Usdviewq.plugin.PluginContainer"], "displayName": "Usdview Tutorial Plugin" } } } } ] }

    最后就是自己编写USDView调用的脚本了。因为是Linux,所以脚本是Shell脚本。内容大概是这样的:

    #!/bin/sh export LD_LIBRARY_PATH=/usr/local/USD/lib64:$LD_LIBRARY_PATH export PYTHONPATH=$PYTHONPATH:/usr/local/USD/lib/python # 这里非常重要,目的是设置usdView的环境变量,让usdView能够顺利地载入插件 currentDir=$(cd `dirname $0`; pwd) export PXR_PLUGINPATH_NAME=$currentDir/tutorialPlugin /usr/local/USD/bin/usdview $currentDir/model/7_29_1.usda

    比较重要的是设置PXR_PLUGINPATH_NAME变量。为的是让USDView顺利地找到插件位置。大家也可以设置TF_DEBUG为PLUG_SEARCH_INFO来检查当PXR_PLUGINPATH_NAME变量设置了以后,究竟有哪些插件得到了载入。
    给一个效果图:
    21d97c31-58ef-41ed-92c3-c27aff391dcc-image.png ![0_1573535993045_在Linux运行带有插件的USDView.gif](正在上传 93%)

    注意其中Tutorial菜单,这就是我们载入的插件。
    如果你对我分享的资产、插件或者是脚本感兴趣,可以加入我创建的小组,在文件分享里找到它。
    上海USD研究小组

    read more
  • 就在不久前我分享了USD在Windows上的构建方法,其实我也一直没有放弃在开发领域最擅长的Linux中构建USD。不过,在Linux中要成功地构建USD,比Windows的要难不少。尤其是各种麻烦的依赖库,仍然要解决才行。之前一直在CentOS 7构建,没有成功,而且CentOS构建的话,相关的资料更少,坑更多,而Deepin是国产的Linux桌面系统,友好一些,这样可以少一些困难。目前成功地在Deepin Linux上顺利地编译成功了。

    那么,咱们开始在Linux构建USD吧。

    测试并且安装Python

    有些Linux发行版,默认安装了Python,有的则没。如果你安装了Python,可以测试一下,命令是:

    python --version

    如果报错,那么使用apt安装吧。

    sudo apt install python

    为了安装PyOpenGL等库,还是推荐安装pip。有关安装pip的资料还是挺多的,pip类似npm,是一个包管理器,非常方便,推荐安装。这里有一个获取pip的脚本。我发出来。获取pip的命令是:

    python -m get-pip.py

    拿到USD的代码

    毕竟是在github中获取的USD代码,那么最好安装git,并且设置github的账户以及公钥。然后熟练利用git命令进行如下的操作:

    git clone https://github.com/PixarAnimationStudios/USD

    获取USD依赖的库

    由于依然在github上获取相关的库,获取库的速度大家都知道比较慢,于是我将库上传到我创建的USD小组里了,大家感兴趣的话,可以加入这个QQ群(小组),获取相关的库,然后解压之。
    上海USD小组

    获取USD其它的依赖(包括cmake)

    由于Linux开源的特性,很多底层的库都要到包管理器中寻找,如果编译出错了。记得勤用apt来搜索相关的库。命令是:

    apt search cmake
    pip install pyside2

    值得注意的是,USD在19.11的时候,明确说不支持cmake2了,看来大家要在apt中安装cmake3了。

    编译

    USD在Linux的编译和Windows的差不多,差别在于一个是用Shell脚本,另外一个是用bat脚本。这里我将Shell脚本贴出来给大家参考:

    #!/bin/sh # 最后构建USD项目 baseDir=${baseDir:=$(cd `dirname $0`; pwd)} echo $baseDir pushd $baseDir sudo python $baseDir/USD/build_scripts/build_usd.py -j 4 -v --python --build-args=USD,"-DPYSIDE_USE_PYSIDE2=TRUE -DPYSIDE_BIN_DIR=/usr/local/lib/python2.7/dist-packages/PySide2 -DBOOST_LIBRARYDIR=" /usr/local/USD popd 编译可能遇到的问题 权限问题。这个是最常见的了。Windows的权限问题没有那么严重,而Linux是权限everywhere。于是安装USD的时候,它推荐的位置是/usr/local/USD,这个地方是要权限的。所以记得用sudo,没有设置密码的赶紧用passwd root设置密码了。 遇到找不到编译器的问题。很简单,没有安装编译器呗。Linux默认编译器是g++,所以一定要执行

    sudo apt install g++

    这样才能够解决找不到编译器的问题。同样的,如果想要以后对USD进行调试,那么gdb也是必不可少的,推荐一同安装。

    编译完成

    如果你到了这一步,那么非常恭喜,你已经克服了超多的难关,到达了胜利的彼岸。但是不是要测试一下是否成功地运行了USD呢?我们还是要运行一下USDView来测试一下的嘛。于是我们还是要写一段shell脚本来测试USDView的运行情况:

    #!/bin/sh export LD_LIBRARY_PATH=/usr/local/USD/lib64:$LD_LIBRARY_PATH export PYTHONPATH=$PYTHONPATH:/usr/local/USD/lib/python /usr/local/USD/bin/usdview /media/jiangyimin/Data/models/UsdSkelExamples/HumanFemale/HumanFemale.walk.usd

    由于要寻找库的路径,因此记得及时设置LD_LIBRARY_PATH环境变量。如果一切顺利的话,那么会出现这样的效果:Linux运行USDView

    read more
  • 记住了哦,USD不是咱们所说的美元哦,是迪士尼皮克斯工作室推出的一款动画全流程的工具,简单地说,是用来串流程的,USD的使用借鉴了脚本编程的一些思想,让动画的资产变得可配置,也变得可维护。让同时其提出的几个工具,使得它变成一个较为完整的工具链。
    USD的官方网站(开源)在这里。

    https://openusd.org

    接下来我将告诉大家如何在Windows下构建USD。

    安装Python

    首先呢,是安装USD的依赖项。USD的依赖项挺多,最重要的是Python,因为USD的构建脚本就是用Python写的。所以去Python官网下载Python吧,目前测试成功的是Python2.7。当然你也可以安装Python 3.5,只是我没有测试过,不清楚是否可用。Python的下载地址是:

    https://www.python.org/downloads

    一般来说,安装好了Python,它会给你设置环境变量,或者有一些教程让你们设定环境变量,不过呢,这里我不建议设定环境变量,这样让我们的所有软件运行环境都污染了(可能没有什么事),之后我会写一个脚本来教大家如何书写批处理来让简化操作,真正做到“即用即走”。

    下载Visual Studio 2017

    这不用强调了吧。目前VS2017是必备的软件了,而且有免费社区版,再也不用破解了,赶紧下载一个。安装在合适的位置就好了。

    安装Maya 2018

    一般来说,Maya每年都有发布一个版本,但是2018的格外稳定,推荐安装。为什么要安装Maya呢?因为Maya是一款几乎全能的DCC,可以导出很多模型到USD中,所以USD顺便构建了Maya的插件(这个插件名字叫usdMaya,不过核心代码转到了Autodesk里了,详见https://github.com/Autodesk/maya-usd,此插件除了PXR的USD,还有AL的USD),我也将Maya 2018放在了我们讨论小组群中,大家可以下载。
    USD研究小组.jpg
    我将Maya 2018安装到D:\Develop\Autodesk\Maya2018中。

    安装USD的其余依赖项

    由于USD的python脚本会使用curl或者是powershell的下载功能进行下载,但是由于很多依赖项是从github下载的,下载速度实在是太慢了,所以我将其余的依赖项打包好了,放在USD_dependencies文件夹中,供需要的朋友下载。USD的依赖项已经上传到我们讨论小组群群里了,大家可以下载。
    USD研究小组.jpg

    编写构建USD的脚本

    我的USD安装的位置是D:\Develop\USD,打算安装的位置是D:\Develop\USD_build_19_11,根据这两个路径开始编写构建USD的脚本:

    :: 构建USD的脚本 :: 设置编译器的很多环境变量 set Path=D:\Develop\Python27;^ D:\Develop\Python27\Scripts;^ D:\Develop\NASM;^ D:\Develop\Autodesk\Maya2018\bin;^ D:\Develop\cmake\bin;^ %Path% set PYTHONPATH=%PYTHONPATH%;D:\Develop\Autodesk\Maya2018\Python\Lib\site-packages;D:\Develop\Autodesk\Maya2018\Python\Lib\site-packages :: 复制pyside2-uic到pyside-uic.exe 中,使其造成能够找到pyside2-uic.exe的假象 copy D:\Develop\Autodesk\Maya2018\bin\pyside2-uic D:\Develop\Autodesk\Maya2018\bin\pyside2-uic.exe :: 使用pip安装PyOpenGL pip install PyOpenGL :: 复制本地build_usd_local.bat 到 目标的路径上 copy /Y %cd%\build_usd_local.py D:\Develop\USD\build_scripts call D:\Develop\VS2017\VC\Auxiliary\Build\vcvars64.bat :: 最后构建USD项目 python D:\Develop\USD\build_scripts\build_usd_local.py ^ -j4 ^ --build-args "USD,-DPYSIDE_USE_PYSIDE2=TRUE -DPYSIDE_BIN_DIR=D:\Develop\Autodesk\Maya2018\bin" ^ --maya --maya-location "D:\Develop\Autodesk\Maya2018\bin" ^ --materialx ^ D:\Develop\USD_build_19_11 :: 最后删除build_usd_local文件 del D:\Develop\USD\build_scripts\build_usd_local.py pause

    大家成功了吗?肯定有遇到很多问题,包括我遇到的一直卡住的Boost编译问题。大家遇到什么编译问题,可以在此留言,我会尽可能回答大家问题。

    成功编译USD后,可以编写插件来试试USDView,大家可以试试看吧,不过仍然要设置环境变量。USDView运行的脚本如下:

    set Path=^ D:\Develop\Python27;^ D:\Develop\USD_Build\lib;^ D:\Develop\USD_Build\bin;^ D:\Develop\USD_Build\third_party\maya\lib;^ D:\Develop\Autodesk\Maya2018\bin;^ %Path% set MAYA_PLUG_IN_PATH=%MAYA_PLUG_IN_PATH%;^ D:\Develop\USD_Build\third_party\maya\plugin set PYTHONPATH=%PYTHONPATH%;^ D:\Develop\USD_Build\lib\python;^ D:\Develop\Autodesk\Maya2018\Python\Lib\site-packages set MAYA_SCRIPT_PATH=%MAYA_SCRIPT_PATH%;^ D:\Develop\USD_Build\third_party\maya\lib\usd\usdMaya\resources;^ D:\Develop\USD_Build\third_party\maya\plugin\pxrUsdPreviewSurface\resources set XBMLANGPATH=%XBMLANGPATH%;^ D:\Develop\USD_Build\third_party\maya\lib\usd\usdMaya\resources @python "D:\Develop\USD_Build\bin\usdview" %cd%\7_29_1.usda

    USDView运行的截图是这样的:
    USDView运行效果

    看到最终结果,还是很有成就感的。

    read more
  • @天幸健 要么程序一启动就camera.start(),然后再camera.stop(),接着需要的时候再camera.start()。

    read more

关注我们

微博
QQ群