文章编写背景

玩了N久的Freepiano,碍于本人没有天赋,左右手一直没法协调。
于是,突然奇想,也是代码设计的思路:

用多线程的方式,开两个线程,然后通过按键模拟的方式,分别模拟左右手去演奏。觉得可行,于是开干

依赖

import time
import pyautogui
import keyboard
from threading import Thread

大致分析

按键模拟

首先要研究按键模拟,就是获取所有键盘的Mapping值。然后发现很多坑:
1、部分依赖不支持小键盘(键盘最右边)
2、部分按键不能模拟(menu,right crtl等)
3、键盘上的按键是不一样的,但是他们的mapping值是一样的(home page up 等)

这时候需要分两步走,获取所有按键对应的mapping值,然后配置一个Mapping 常量,我们可以借助下面的片段:

import keyboard
# keyboard.press_and_release('num lock')  # 小键盘锁键
def on_key_press(event):print("按键:", event.name)keyboard.on_press(on_key_press)
keyboard.wait()

运行后,任意按键会打印对应的Mapping值,这里注意的是小键盘的锁切换后会不一样
然后得到一个mapping常量(按自身实际配置):

left_hand_mapping = {'1': 'q','111': '8','2': 'w',"222": "9",'3': 'e','33': '3','4': 'r','44': '4','5': 't','55': '5','6': 'y','66': '6','7': 'u','77': '7','P': ' '
}right_hand_mapping = {'1': 'end','2': 'down','3': 'pagedown','333': 'alt','4': 'left','5': 'clear','555': "f2",'6': 'right','666': 'f1','666#': 'backspace','7': 'home','P': ' '
}

综合上面的坑,要对freepiano进行键位修改,这里的思路是放弃小键盘的锁键,还有HOME等功能键,见下图:

PS:这里要注意新按键的通道,因为左右手的力度是不一样的。

线程模拟

开始编码模拟左右手,因为左右手的演奏速度是不一样的,所以这里要做区分。
左手按键与松开:

def play_left_hand(melody):for note in melody:if note == "-":time.sleep(stop_note)press_key(note, 'left')time.sleep(note_duration_left)release_key_left(note)def release_key_left(note):if note in left_hand_mapping:keyboard.release(left_hand_mapping[note])

右手按键与松开:

def play_right_hand(melody):for note in melody:if note == "-":time.sleep(stop_note)press_key(note, 'right')time.sleep(note_duration_right)release_key_right(note)
def release_key_right(note):if note in right_hand_mapping:keyboard.release(right_hand_mapping[note])

按键方法:

def press_key(note, hand):if hand == 'left' and note in left_hand_mapping:left_hand_key = left_hand_mapping[note]keyboard.press(left_hand_key)if hand == 'right' and note in right_hand_mapping:right_hand_key = right_hand_mapping[note]keyboard.press(right_hand_key)

乐谱设计

这里是最重要的,这里我们用两个列表分别存左右手的音符。具体字符需要根据实际mapping值来设计

 left_hand_melody = ['33', '66', '77', '111', '-', '44', '66', '77', '111', '-', '55', '66', '222', '111', '77']right_hand_melody = ["666", "666", "666", "-", "666", "666#", "666#", "666#", "555", "555", "555", "-", "555","333", "333", "333", "333"]

这是一段某游戏登录前奏。乐谱地址:简谱

具体效果

效果不理想,休止音符和节奏没设计好,下版本更新。。。。
具体效果:

python演奏Freepiano(双手合奏)DEMO1

。TBD

完整代码

key_mapping.py:

left_hand_mapping = {'1': 'q','111': '8','2': 'w',"222": "9",'3': 'e','33': '3','4': 'r','44': '4','5': 't','55': '5','6': 'y','66': '6','7': 'u','77': '7','P': ' '
}right_hand_mapping = {'1': 'end','2': 'down','3': 'pagedown','333': 'alt','4': 'left','5': 'clear','555': "f2",'6': 'right','666': 'f1','666#': 'backspace','7': 'home','P': ' '
}

piano.py

import time
import pyautogui
import keyboard
from threading import Thread
from key_mapping import *def play_left_hand(melody):for note in melody:if note == "-":time.sleep(stop_note)press_key(note, 'left')time.sleep(note_duration_left)release_key_left(note)def play_right_hand(melody):for note in melody:if note == "-":time.sleep(stop_note)press_key(note, 'right')time.sleep(note_duration_right)release_key_right(note)def press_key(note, hand):if hand == 'left' and note in left_hand_mapping:left_hand_key = left_hand_mapping[note]keyboard.press(left_hand_key)if hand == 'right' and note in right_hand_mapping:right_hand_key = right_hand_mapping[note]keyboard.press(right_hand_key)def release_key_left(note):if note in left_hand_mapping:keyboard.release(left_hand_mapping[note])def release_key_right(note):if note in right_hand_mapping:keyboard.release(right_hand_mapping[note])if __name__ == '__main__':repeat = Trueright_first = Trueleft_hand_melody = ['33', '66', '77', '111', '-', '44', '66', '77', '111', '-', '55', '66', '222', '111', '77']right_hand_melody = ["666", "666", "666", "-", "666", "666#", "666#", "666#", "555", "555", "555", "-", "555","333", "333", "333", "333"]note_duration_left = 0.4  # 每个音符的持续时间(秒) 左手note_duration_right = 0.3  # 每个音符的持续时间(秒) 左手stop_note = 0.1  # 休止音符# 切换到FreePiano界面time.sleep(2)freepiano_window = pyautogui.getWindowsWithTitle("FreePiano")[0]freepiano_window.activate()# 简谱是否重复if repeat:left_hand_melody.append("-")left_hand_melody += left_hand_melodyright_hand_melody.append("-")right_hand_melody += right_hand_melody# 启动左手伴奏和右手主旋律线程left_hand_thread = Thread(target=play_left_hand, args=(left_hand_melody,))right_hand_thread = Thread(target=play_right_hand, args=(right_hand_melody,))left_hand_thread.start()right_hand_thread.start()left_hand_thread.join()right_hand_thread.join()

python自动演奏Freepiano【双手合奏】相关推荐

  1. 用Python自动生成数据日报!

    今天聊聊怎么用Python自动生成数据日报! 其实我觉得蛮简单,核心就是你组装好日报的内容模板,然后将变化的量交给python去填充,需要用到的基本就是python处理excel.word和ppt等相 ...

  2. python自动更新excel_Python办公自动化(六)|自动更新表格,告别繁琐

    今天我们讲解的案例是如何使用Python自动更新Excel表格,简单来说就是每天都会对Excel中多个sheet进行更新,需要操作完后可以用程序完成第一张sheet 汇总表的更新,大概就是这样 当然实 ...

  3. Python 之vim编写python自动补全

    Pydiction :vim - python自动补全插件 插件的安装如下: 1.下载插件包 https://github.com/vim-scripts/Pydiction 可以直接下载,也可git ...

  4. python资料百度网盘-python自动保存百度盘资源到百度盘中的实例代码

    本实例的实现逻辑是,应用selenium UI自动化登录百度盘,读取存储百度分享地址和提取码的txt文档,打开百度盘分享地址,填入提取码,然后保存到指定的目录中 全部代码如下: # -*-coding ...

  5. python画轨迹曲线-python 自动轨迹绘制的实例代码

    用到的思维: 自动化思维,数据和功能分开处理,用数据驱动程序自动运行 接口化设计,数据与程序的对接方式要清晰明了 二维数据应用,应用维度组织数据,二维数据最常用 代码 # AutoTrace.py i ...

  6. python自动化办公兼职-用Python自动办公,做职场高手(完结)

    教程目录: ┣━07.S2 Word自动化处理,又快又好做文档 ┃ ┣━36 本章介绍 ┣━08.[Word]S2-1 轻松用Python快速生成Word文档 ┃ ┣━45.[真实案例]S2-1-3 ...

  7. python自动创建目录_python自动目录环境

    python自动目录环境 1.建立工程目录** mkdir /myApp cd /myApp 2.建立 Python 虚拟环境 (1)Python3.3以上的版本通过venv模块原生支持虚拟环境 在m ...

  8. python自动源码_谷歌推出Tangent开源库,在Python源代码上做自动微分

    原标题:谷歌推出Tangent开源库,在Python源代码上做自动微分 李林 编译自 Google Research Blog 谷歌今天推出了一个新的开源Python自动微分库:Tangent. 和现 ...

  9. python自动答题免费_直播答题?Python助你自动搜题之新手篇!

    承接前文关于Python自动搜题的介绍https://zhuanlan.zhihu.com/p/32828411,此篇面向新手小白进行解析,助你成功运行自动搜题的python程序. A部分是介绍思路, ...

最新文章

  1. 数据库之存储引擎,数据类型-30
  2. esp8266设置sta失败_使用NodeMCU_ESP8266驱动OLED
  3. 机房做隔断为什么要用防火玻璃?
  4. jQuery 仿淘宝 鼠标悬停显示大图效果
  5. Oracle分组取出每组的第一笔数据
  6. Go 语言标准库中 atomic.Value
  7. Windows2008的安装
  8. python xlwings api_2021-01-13python,xlwings,api运用,及一些问题
  9. JQuery实现ajax跨域
  10. 翻译:重载解决和Null
  11. 敏捷开发般若敏捷系列之五:如何推广敏捷(中)(无寿者,回报,破我执)...
  12. 【Teradata】系统吞吐量重要参数QPS(TPS)、并发数、响应时间
  13. IOS开发之把 Array 和 Dictionaries 序列化成 JSON 对象
  14. |Vijos|NOIP2015|模拟|P1975 扫雷游戏
  15. 《电磁学》学习笔记1——电场
  16. 步进电机和步进电机电机驱动器
  17. Linux入门基础学习参考资料
  18. 这16个数据可视化案例,惊艳了全球数据行业
  19. 华为 BGP路由聚合
  20. 《SRE Google运维解密》散文

热门文章

  1. 激光打印机硒鼓加分量及寿命
  2. 规范IT监理的主旋律
  3. 如何制作营养膳食计算器_如何通过构建自动膳食计划器节省时间和金钱
  4. 正交表 软件测试作业,软件测试单元3 黑盒测试
  5. springboot 订单重复提交_防止表单重复提交(springboot,redis)
  6. SQL 窗口函数:ROWS与RANGE
  7. 全景播放器,免安装支持全景视频
  8. 运行office弹出stdole32
  9. [转载]中国文明网:拒绝语言暴力不做孩子的差评师
  10. Dubbo之dubbo协议