Python pygame(GUI编程)模块最完整教程(8)

news2024/7/4 4:34:26

上一篇文章:

Python pygame(GUI编程)模块最完整教程(7)_Python-ZZY的博客-CSDN博客

总目录:

README.md · Python-ZZY/Python-Pygame最完整教程 - Gitee.com

23 进阶声音操作

参考资料:

https://pyga.me/docs/ref/sndarray.html

https://pyga.me/docs/ref/midi.html

MIDI格式 - 简书

23.1 通过MIDI输出声音

pygame.midi模块操作MIDI(乐器数字接口)。各种电子乐器与计算机通过MIDI进行交互。管理MIDI输入,可以从一些MIDI输入设备获取信息;将MIDI输出,则可以模拟某种乐器播放音符。

和pg.camera一样,midi不会自动导入到pygame中,所以需要额外的导入和初始化。

import pygame as pg
from pygame import midi

pg.init()
midi.init()

下面的程序演示了如何通过midi播放从低到高的音阶(相邻音符之间相差一个半音)。

import pygame as pg
from pygame import midi

pg.init()
midi.init()

port = midi.get_default_output_id() # 获取默认的MIDI输出
midi_out = midi.Output(port)

# 速度范围0 - 127,速度127时音符持续时间最长
velocity = 100

# 声调最高音符名为127
max_note = 127

try:
    for note in range(0, max_note + 1):
    
        print(note)
        midi_out.note_on(note, velocity) # 按下音符

        # 音符播放是非阻塞的,不会等一个音符播完再执行下面的代码
    
        pg.time.wait(800) # 等待一段时间后再执行代码
        midi_out.note_off(note) # 释放音符

finally: # 退出midi
    del midi_out
    midi.quit()

上面的代码首先通过get_default_output_id方法获取默认的MIDI设备,然后创建了一个Output对象,用于管理MIDI的输出。然后通过Output.note_on按下音符,等待800ms后释放音符。 

最后通过finally代码块,无论是否出现异常都要退出midi。不显式退出虽然不太可能出现问题,但是官方建议最好还是加上finally来确保midi退出。

note_on方法可接受3个参数。第一个是音符编码,范围是0-127,相邻音符之间相差一个半音,数字越大音调越高,可参考MIDI音符代码表。第二个参数表示音符的响度(不知道为什么官方用速度来表示),范围同样是0-127,数字越大声音响度越大。第三个参数channel可选,表示播放的声道。与note_on相对,还有note_off方法用于释放音符,参数与之相同。

23.2 模拟乐器音色

pg.midi.Output对象还有一个方法set_instrument,可以将音符音色设置为不同乐器的音色。默认的音色是钢琴。

设置音色需要指定音色编码,所有编码可参考MIDI 128种音色码表。音色编码的范围仍为0-127。

pg.midi.Output.set_instrument(instrument_id, channel=0) -> None

下面的示例将所有音色的声音都播放了一遍。

import pygame as pg
from pygame import midi

pg.init()
midi.init()

port = midi.get_default_output_id() # 获取默认的MIDI输出
midi_out = midi.Output(port)

velocity = 100

max_instrument = 72

try:
    for instrument in range(70, max_instrument + 1):
    
        print(instrument)
        midi_out.set_instrument(instrument) # 设置音色
        midi_out.note_on(80, velocity) # 按下音符
    
        pg.time.wait(800)
        midi_out.note_off(80) # 释放音符

finally:
    del midi_out
    midi.quit()

23.3 写入原始MIDI信息数据

midi.Output.write用于写入较多的MIDI数据,来控制音符的播放。

Output.write(data) -> None

data必须是一个列表,其中包含多个小列表,每个列表都代表一个MIDI事件(为便于理解以下称作“操作”)。操作列表由信息列表、时间戳组成。信息列表一般是3个值或1个值,第一个值表示状态位,后面的值表示数据位(可选,默认为0)。例如下面这个data列表:

port = midi.get_default_output_id()
midi_out = midi.Output(port, latency=1) # 设置延迟为1

program_change = 192
note_on = 144
note_off = 128

data = [
    [[program_change, 40, 0], 0],
    [[note_on, 80, 127], 0],
    [[note_off, 80, 127], 1000],
    ]

midi_out.write(data)

这个data列表包含3个MIDI操作,改变程序(也就是乐器音色),按下音符,松开音符。时间戳表示触发这个操作的时间。比如这个data就表示:在时间为0ms的时候,改变音色,按下音调为80,强度为127的音符;在时间为1000ms时(注意:不是距离上次操作经过了1000ms),松开音调为80,强度为127的音符。

需要注意的是:使用write的时候一般要把Output类的latency参数设为一个大于0的值。latency表示延迟,即写入数据之前会有一段延迟的时间,单位是ms。如果不设置延迟,那么时间戳是无效的,所有操作都会同时进行(个人觉得这个设置不太好)。因为我不需要太多延迟,所以将它设为1即可。如果延迟设为2000,则在write中的操作处理之前会延迟2000ms。延迟时间不会算进时间戳。

正如上面所说,每个操作包含操作信息,时间戳组成,那么前面的操作信息又代表什么呢?参见这篇文章:常见MIDI信息的状态位和数据位含义表。状态位的代码决定了后面数据位的含义。比如状态位144,就表示在频道1上按下音符;后面的数据位分别表示音符代码、响度代码。状态位128,则表示在频道1上释放音符;后面的数据位分别表示音符代码、响度代码。状态位192,则表示在频道1上改变音色;后面的数据位只有一个,表示乐器音色代码,由于只需要一个数据位,所以最后的数据位留空为0即可。

此外,还需要注意data列表是有顺序的,操作必须按照时间戳从小到大排列,不然有些操作无法正确执行。例如:

data = [
    [[program_change, 70, 0], 0],
    
    [[note_on, 80, 127], 0],
    [[note_on, 100, 127], 1000],
    
    [[note_off, 80, 127], 2000],
    [[note_off, 100, 127], 2000],
    ] 
'上面是正确的排列 (0 <= 1000 <= 2000 <= 2000)'

data = [
    [[program_change, 70, 0], 0],
    
    [[note_on, 80, 127], 0],
    [[note_off, 80, 127], 2000],
    
    [[note_on, 100, 127], 1000],
    [[note_off, 100, 127], 2000],
    ] 
'上面是错误的排列,时间戳没有从小到大排列'
'(0 <= 2000 !< 1000 <= 2000)'
'如果使用这种方法排列将执行不到[[note_on, 100, 127], 1000]这一段'

按照上面正确的代码播放,将达到这样的效果:首先改变音色,播放80音符;过1秒后播放100音符;再过1秒后同时结束两个音符的播放。 

23.4 midi模块索引 - 乐器数字接口

事件:midi在输入和输出时会分别产生MIDIIN和MIDIOUT两个事件。

init() -> None, quit() -> None

初始化/退出midi。

Input(device_id) -> None

Input(device_id, buffer_size) -> None

创建一个midi输入对象,device_id是输入设备的标识符,buffer_id是可缓冲的输入事件数量。

Input.close() -> None

尝试关闭midi输入(在Windows系统上可能出现问题)。

Input.poll() -> bool

判断是否有midi的输入数据

Input.read(num_events) -> midi_event_list

读取并返回未被处理的midi输入事件,num_events代表事件的数量。

Output(device_id) -> None

Output(device_id, latency=0) -> None

Output(device_id, buffer_size=256) -> None

Output(device_id, latency, buffer_size) -> None

创建midi输出对象。buffer_size是输出事件的缓冲数量,latency是输出的延迟时间。

Output.abort() -> None

中止midi传输(可能导致数据还没发完时就终止了)

Output.close() -> None

关闭midi输出对象(Windows上可能有问题)

Output.note_off(note, velocity=None, channel=0) -> None

松开音符,note是音符编码,velocity是速度,channel是频道。

Output.note_on(note, velocity, channel=0) -> None

按下音符,note是音符编码,velocity是速度,channel是频道。

Output.set_instrument(instrument_id, channel=0) -> None

设置乐器音色

Output.pitch_bend(value=0, channel=0) -> None

微调midi输出时的音高。value为正数表示升高,负数表示降低,范围是-8192到+8191,每4096代表一个半音。例如:-8192表示降低两个半音(即一个全音),4096表示升高一个半音。

Output.write(data) -> None

写入多个MIDI操作

Output.write_short(status) -> None

Output.write_short(status, data1=0, data2=0) -> None

写入单个的MIDI操作,status是状态位,data1, data2分别是两个数据位。不考虑时间戳。

Output.write_sys_ex(when, msg) -> None

写入全是系统信息的MIDI操作。

midi_output.write_sys_ex(0, '\xF0\x7D\x10\x11\x12\x13\xF7')

# 相当于:

midi_output.write_sys_ex(pg.midi.time(), # midi计时器的时间
                         [0xF0, 0x7D, 0x10, 0x11, 0x12, 0x13, 0xF7])

get_default_input_id() -> default_id

获取默认的MIDI输入设备

get_default_output_id() -> default_id

获取默认的MIDI输出设备

get_device_info(an_id) -> (interf, name, input, output, opened)

get_device_info(an_id) -> None

获取给定设备ID的信息。返回值一般是元组,ID超出范围会返回None。元组中各个值的含义:interf表示描述设备接口的字符串(例如"ALSA"),name表示设备名称(例如"Midi Through Port-0"),input表示该设备是否为输入设备(1或0),output表示该设备是否为输出设备(1或0),opened表示该设备是否为开启状态。

midis2events(midi_events, device_id) -> [Event, ...]

将MIDI事件转换为pygame事件。midi_events也就是传递给Output.write的data参数中的每个操作列表。

time() -> time

返回midi计时器得到的时间(从midi.init开始算)

frequency_to_midi(midi_note) -> midi_note

将频率转换为MIDI音符代码(会圆整到最接近的那个音符)

midi_to_ansi_note(midi_note) -> ansi_note

将MIDI音符代码转换为ansi音符格式的字符串

MidiException(errno) -> None

MIDI异常。当MIDI设备找不到,或者其他原因时可能报错。

23.5 sndarray模块索引 - Sound与numpy数组

pg.sndarray用于pg.mixer.Sound和numpy数组之间的转换,和pg.surfarray一样依赖于numpy库。

声音数据是由每秒数千个样本组成的,每个样本都是在特定时刻的波的振幅。例如,在22khz格式中,阵列的单元号5是5/22000秒后的波的振幅。

array(Sound) -> array

将声音对象复制并转换为numpy数组,更改数组不会改变声音对象本身。

samples(Sound) -> array

将声音对象之间转换为numpy数组,更改数组将改变声音对象本身。

make_sound(array) -> Sound

将声音样本数组转换为Sound对象。

24 pygame探索

参考资料:pygame — pygame-ce v2.4.0 documentation

24.1 pygame主模块索引

pygame主模块里面并没有什么特别重要的内容,因为学习pygame的时候,读者已经了解了主模块中常用的函数,接下来将整理一些函数的用法。

以下是pygame主模块中唯一可能用到的4个东西(剩下的都没什么用)。

init() -> (numpass, numfail)

初始化pygame所有子模块,并返回初始化成功的数量和失败的数量。

其实在pygame的每个子模块中都有init和quit方法,用于初始化和退出单个的子模块。pygame功能很多,有时候并不用于单纯的编写游戏,有时候也会用于播放音乐等等。如果只需要使用pygame.mixer模块,就无需初始化整个的pygame,只需要调用pygame.mixer.init()而非pygame.init()。

quit() -> None

退出pygame,与init方法相反。这个方法会关闭pygame窗口。调用pg.quit方法并不会退出整个python程序,只会退出pygame。有时候有必要在退出时顺便调用sys.exit来确保python程序完全退出。

register_quit(callable) -> None

注册一个函数。当调用pygame.quit时,会调用它。

error

pygame.error继承于Exception,表示一些pygame相关的异常。可用于异常捕获。

24.2 环境变量

部分pygame的行为可以通过环境变量来控制,即操作os.environ。例如:

import os
os.environ["环境变量名"] = "环境变量值"

下面是一些可能用到的pygame相关环境变量及用法。

PM_RECOMMENDED_INPUT_DEVICE

设置默认的MIDI输入设备

PM_RECOMMENDED_OUTPUT_DEVICE

设置默认的MIDI输出设备

PYGAME_DISPLAY

pygame的显示索引(即pg.display.set_mode的display参数),默认为"0"

PYGAME_FORCE_SCALE

强制set_mode使用缩放显示模式,是"default"或"photo"。如果设置了“photo”,则缩放使用最慢但质量最高的各向异性缩放算法(如果可用)。必须在调用pygame.display.set_mode()之前设置

PYGAME_BLEND_ALPHA_SDL2

这使得pygame对所有alpha混合使用SDL2 blitter。SDL2绘制器有时比默认的要快,但使用不同的公式,因此最终颜色可能不同。必须在调用pygame.init()初始化所有导入的pygame模块之前设置。

PYGAME_HIDE_SUPPORT_PROMPT

是否隐藏pygame启动时打印的那一段提示,设置为"1"表示隐藏。

PYGAME_CAMERA

设置摄像机的后端,如"opencv"。必须在pg.camera初始化之前调用。

SDL_IME_SHOW_UI

是否显示输入候选框。必须在pg.display.set_mode前面调用

SDL_VIDEO_CENTERED

是否将窗口设在屏幕中央。必须在pg.display.set_mode前面调用

SDL_VIDEO_WINDOW_POS

设置pygame窗口的位置(左上角),格式为"x, y"。必须在pg.display.set_mode前面调用

SDL_VIDEO_ALLOW_SCREENSAVER

默认情况下,pygame运行时会禁用屏保,如果设为"1"则表示允许显示屏幕保护系统。

SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS

默认情况下,当窗口不在焦点中时,游戏手柄这样的设备不会更新。然而,使用这个环境变量,即使窗口在后台,也有可能获得操纵杆更新。必须在调用pygame.init()之前设置。

24.3 _sdl2

pygame._sdl2模块中包含了一些实验性的SDL2功能,可能在未来有更改。_sdl2中还包含一些子模块。_sdl2不会被自动导入到pygame里面。

_sdl2包含以下几个模块:

模块名描述
controller操作控制器(如游戏手柄)
touch触屏输入
windowpygame多窗口创建
video包括图像、纹理等

下一篇文章

制作中(可能要等很久)……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/860387.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在编程下仰望

编程的尽头是数学 数学的尽头是物理 物理的尽头是哲学 哲学的尽头是耶稣 路漫漫其修远兮&#xff0c; 各位码农同仁 好自珍重

Kafka第一课概述与安装

生产经验 面试重点 Broker面试重点 代码,开发重点 67 章了解 如何记录行为数据 1. Kafka概述 1.产生原因 前端 传到日志 日志传到Flume 传到HADOOP 但是如果数据特比大&#xff0c;HADOOP就承受不住了 2.Kafka解决问题 控流消峰 Flume传给Kafka 存到Kafka Hadoop 从Kafka…

geoserver编辑样式 【开发工具QGis的初次使用】

geoserver编辑样式 开发工具配置中文语言 geoserver样式的更改 开发工具 链接: geoserver样式style的更改 链接: QGis开发工具的安装及使用 配置中文语言 setting > options > general > 中文 geoserver样式的更改 链接: geoserver样式style的更改 利用QGIs Q…

3DMAX动力学布料模拟插件DynamoCloth使用方法

3DMAX动力学布料模拟DynamoCloth是一个&#xff08;实时&#xff09;GPU加速的3ds Max Cloth动力学插件&#xff0c;与原生Cloth修改器相比&#xff0c;性能提高了10-100倍。 3DMAX动力学布料模拟是实时的&#xff0c;能够实现实时的自然互动&#xff0c;并将创作过程从试错转…

代码随想录算法训练营第十五天| 层序遍历(即广度优先搜索), 226.翻转二叉树,101. 对称二叉树

层序遍历(即广度优先搜索) 需要借用一个队列来实现&#xff0c;队列先进先出&#xff0c;符合一层一层遍历的逻辑&#xff0c;而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。 思路是先把根节点加入队列&#xff0c;然后在遍历下一层前&#xff0c;先将队列拥有的当前层…

LeetCode150道面试经典题--找出字符串中第一个匹配项的下标(简单)

1.题目 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不是 haystack 的一部分&#xff0c;则返回 -1 。 2.示例 3.思路 回溯算法&#xff1a;首先将…

【CSS3】CSS3 动画 ⑥ ( 动画属性示例 | 精灵图帧动画效果实现 )

文章目录 一、需求说明二、代码分析1、动画属性2、布局分析3、动画实现 三、完整代码示例 一、需求说明 给定一张精灵图 , 其中有多个 动画帧 对应的图片 , 下图的大小是 1600 x 100 像素 , 截图展示如下 : 实际图片 : 二、代码分析 1、动画属性 使用上图实现 逐帧动画 效果 …

智慧工地云平台源码

智慧工地可以实现对人员管理、施工进度、安全管理、材料管理、设备管理、环境监测等方面的实时监控和管理&#xff0c;提高施工效率和质量&#xff0c;降低安全风险和环境污染。在道路施工中&#xff0c;智慧工地可以实现对道路状况、交通流量、施工进度等方面的实时监控和管理…

Wlan——802.11协议物理层关键技术(OFDM、MIMO、BSS)和CSMA/CD机制的介绍

目录 802.11协议的发展 802.11协议物理层关键技术 信道捆绑技术 OFDM/OFDMA技术 Short-Gi短保护间隔技术 MIMO/MU-MIMO技术 QAM技术 BSS Color快速识别 802.11MAC层关键技术CSMA/CD机制 为什么无线提出了CSMA/CD机制 CSMA/CD的工作机制 CSMA/CD的工作原理 CSMA/CD…

matlab进行mex时出现 error LNK2019: 无法解析的外部符号

解决方法分成三个步骤&#xff1a; 1、直接在simulink模块运行出现错误&#xff0c;找不到该s函数&#xff1b; 2、需要确认安装了编译器。mex -setup 确认安装了编译器&#xff0c;再次mex xxx.c未解决&#xff1b; 3、再次查找资料发现可能编译器不知道具体的位置&#xff0c…

Java训练六

目录 一、除数不能为0 二、校验年龄格式 三、终端循环 四、 计算最大公约数 一、除数不能为0 使用静态变量、静态方法以及throws关键字&#xff0c;实现当两个数相除且除数为0时&#xff0c;程序会捕获并处理抛出的ArithmeticException异常&#xff08;算术异常&#xff09…

电脑合上盖子无线网络不会断开

控制面板\硬件和声音\电源选项\系统设置 最终选择不会采取任何操作 选择不会采取任何操作

学习C语言第三天 :关系操作符、逻辑操作符

1.关系操作符 C语言用于比较的表达式&#xff0c;称为“关系表达式”里面使用的运算符就称(relationalexpression)&#xff0c;为“关系运算符” (relationaloperator) &#xff0c;主要有下面6个。 > 大于运算符 < 小于运算符 > 大于等于运算符 < 小于等…

分布式 - 消息队列Kafka:Kafka生产者架构和配置参数

文章目录 1. kafka 生产者发送消息整体架构2. Kafka 生产者重要参数配置01. acks02. 消息传递时间03. linger.ms04. buffer.memory05. batch.size06. max.in.flight.requests.per.connection07. compression.type08. max.request.size09. receive.buffer.bytes和 send.buffer.b…

如何使用appuploader制作apple证书​

转载&#xff1a;如何使用appuploader制作apple证书​ 如何使用appuploader制作apple证书​ 一.证书管理​ 点击首页的证书管理 二.新建证书​ 点击“添加”&#xff0c;新建一个证书文件 免费账号制作证书只有7天有效期&#xff0c;没有推送消息功能&#xff0c;推送证书…

anaconda 基本指令

1.anaconda创建环境 例如我们创建一个名称为img2word&#xff0c;python版本为3.9的环境 conda create -n img2word python3.9在这个命令中&#xff1a; create 是告诉 Conda 你要创建一个新的环境。-n img2word 是设置新环境的名称为 img2word。python3.9 是告诉 Conda 在这…

PS AI版本安装教程

好久没写博客了&#xff0c;今天更新一下子吧&#xff01; 随着chatGPT的提出&#xff0c;各种软件逐渐开始镶嵌人工智能&#xff0c;为我们的生活带来了极大的便利&#xff01;话不多说&#xff0c;开始介绍今天的主角&#xff0c;PS的AI版本。 安装教程&#xff1a; 1.安装…

Linux学习之sed删除、追加、插入、更改、读写文件、下一行、打印、退出和seq命令

cat /etc/redhat-release看到操作系统是CentOS Linux release 7.6.1810&#xff0c;uname -r看到内核版本是3.10.0-957.el7.x86_64&#xff0c;sed --version可以看到sed版本是4.2.2。 echo a : 1 : good : g >> sed_daicpnrwq.txt echo b : 2 : well : w >> sed…

LC-删除排序链表中的重复元素

LC-删除排序链表中的重复元素 链接&#xff1a;https://leetcode.cn/problems/remove-duplicates-from-sorted-list/description/ 思路&#xff1a;这题其实不难&#xff0c;链表已经排序&#xff0c;我们只要把相邻的两个节点的值进行比较&#xff0c;如果相同&#xff0c;删…

基于SpringBoot的社区团购系统设计【附开题|万字文档(LW)和搭建文档】

主要功能 前台界面&#xff1a; ①首页、商品信息推荐、社区信息、商品信息展示、查看更多等 ②商品信息、名称类型查询、添加购物车、立即购买、积分兑换、点我收藏、赞一下、踩一下、评论等 ③团购信息、社区信息、购物车等 ④个人中心、我的订单、我的地址、我的收藏等 后台…