确定 MIDI 文件的时间划分

2024-03-04

我正在用Python编写一个脚本来解析MIDI文件(是的,我知道Python存在MIDI解析库,但对于我的用例来说,如果我从头开始制作它是最简单的)。

我遇到的问题之一是时间划分。标头的最后两个字节指定时间划分,但我无法确定文件的时间划分是否以每节拍的滴答数或每秒的帧数表示。经过一番阅读后,似乎顶部字节的顶部位指示了时间划分中的哪一个。我感到困惑的是,一个字节的顶部位是字节的第一位还是最后一位一个字节的位,以及如何完整读取 MIDI 时分。

编辑:例如,我的 MIDI 文件的标头如下:

4d54 6864 0000 0006 0000 0001 0078

0078 are the two bytes that denote the time sig, but I am confused as how to interpret it.

Edit 2:

def openmidi(file):
    tmbr = []
    f = open(file, "rb")#opening the midi in binary mode
    loopfile = True
    while loopfile == True:
        cb = f.read(1)
        if cb != b'':#checking if there are still bytes left to read
            tmbr.append(cb)
        else:
            loopfile = False
    return tmbr

def byteread(num):#will read and return the specified number of bytes
    global bytecounter
    bytehold = b''
    for i in range(0, num):#reads specified number of bytes
        bytehold+=midibytearray[i+bytecounter]#number of increment plus the read position
    bytecounter+=num#after reading is done read position is incremented by the number of bytes read.
    return bytehold#after looping is done the specified bytes are returned.

def timetype(deltatimebytes):#used to determine if the time division is in ticks per beat or frames per second.
    if str(deltatimebytes).replace("b'","").replace("'","")[0:2] == "00":
        return True#if true the time division is in ticks per beat.
    else:
        return False#the time division is in frames per second.


global bytecounter
bytecounter = 0 #keeps track of what position in the file is being read.

midibytearray = openmidi("C:\\Users\\gabep\\Desktop\\Electrorchestrion\\Midis\\BONEY M.Rasputin K.mid") #array that the bytes will be stored in.



header = byteread(4)
chunklength = byteread(4)
formattype = byteread(2)
numofmtrkchunks = byteread(2)
deltatime = byteread(2)#if no tempo is assigned, 120bpm is assumed.
print(deltatime)

print("Header: "+str(header.decode("utf-8")))
print("MThd chunk length: "+str(int(chunklength.hex(), 16)))
print("Midi Format Type: "+str(int(formattype.hex(), 16)))
print("Number of MTrk chunks (number of tracks): "+str(int(numofmtrkchunks.hex(), 16)))



print("Delta time: "+str(int(deltatime.hex(), 16)))
if timetype(deltatime.hex()) == True:
    print("Time signature is in ticks per beat")
else:
    print("Time signature is in frames per second")

也许你不知道官方的 MIDI 规范是可用的,你可以下载文档 https://www.midi.org/specifications/item/the-midi-1-0-specification免费。 (您需要先注册为网站用户)。它包括详细的SMF 格式。

这是标题块的描述。


文件开头的标头块指定了有关文件中数据的一些基本信息。这是完整块的语法:

<Header Chunk> = <chunk type> <length> <format> <ntrks> <division>

如上所述,<chunk type>是四个 ASCII 字符“MThd”;<length>是数字 6 的 32 位表示(高字节在前)。 数据部分包含三个 16 位字,首先存储最高有效字节。 第一个词,<format>,指定文件的整体组织。只有三个值<format>指定:

0=文件包含单个多通道轨道

1=该文件包含一个或多个同步轨道(或 MIDI 输出) 顺序

2=该文件包含一个或多个顺序独立的单轨模式 下面提供了有关这些格式的更多信息。

下一句话,<ntrks>,是文件中轨道块的数量。对于格式 0 文件,它始终为 1。

第三个字, <division>,指定增量时间的含义。它有两种格式,一种用于公制时间,另一种用于基于时间码的时间:

  |bits                                        |
  |15|14        ...         8|7     ...      0 |
  |--|-----------------------|-----------------|
  | 0|         ticks per quarter-note          |
  | 1| negative SMPTE format | ticks per frame |

如果位 15<division>是零,位 14 到 0 代表构成四分音符的增量时间“刻度”的数量。例如,如果<division>是 96,则文件中两个事件之间的八分音符的时间间隔将为 48。如果<division>是一个,文件中的增量时间对应于秒的细分,与 SMPTE 和 MIDI 时间代码一致。位 14 到 8 包含四个值 -24、-25、-29 或 -30 之一,对应于四种标准 SMPTE 和 MIDI 时间码格式(-29 对应于 30 个丢帧),并表示帧数每秒。这些负数以二进制补码形式存储。第二个字节(存储正值)是帧内的分辨率:典型值可能是 4(MIDI 时间码分辨率), 8、10、80(位分辨率)或 100。该系统允许精确指定基于时间码的轨道,但也通过指定 25 帧/秒和每帧 40 个单位的分辨率来允许基于毫秒的轨道。如果文件中的事件以 30 帧时间码的位分辨率存储,则除法字将为 E250 十六进制。


在您的示例中,您的第三个单词(十六进制 0078)意味着<division>每个四分音符 120 个刻度。

文件中事件的增量时间以刻度为单位给出。拍号是另一件完全不同的事情。它是节奏的指示,是一种元事件类型。 (参见规范第 10 页)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

确定 MIDI 文件的时间划分 的相关文章

  • Python Pandas 滚动聚合一列列表

    我有一个简单的数据框 df 和一列列表lists 我想根据以下内容生成一个附加列lists The df好像 import pandas as pd lists 1 1 2 1 2 3 3 2 9 7 9 4 2 7 3 5 create
  • 在函数内的 for 循环上使用 tqdm 来检查进度

    我正在使用 for 循环迭代目录树内的一大组文件 这样做时 我想通过控制台中的进度条来监视进度 因此 我决定使用 tqdm 来实现此目的 目前 我的代码如下所示 for dirPath subdirList fileList in tqdm
  • 如何同时运行多个功能[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有以下代码 my func1 my func2 my func3 my func4 my func5 是否可以同时计算函数的数据 而
  • 使用 Python 和 lmfit 拟合复杂模型?

    我想适合椭偏仪 http en wikipedia org wiki Ellipsometry使用 LMFit 将数据转换为复杂模型 两个测量参数 psi and delta 是复杂函数中的变量rho 我可以尝试将问题分离为实部和虚部共享参
  • Scrapy 文件管道不下载文件

    我的任务是构建一个可以下载所有内容的网络爬虫 pdfs 在给定站点中 Spider 在本地计算机和抓取集线器上运行 由于某种原因 当我运行它时 它只下载一些但不是全部的 pdf 通过查看输出中的项目可以看出这一点JSON 我已经设定MEDI
  • Python Selenium 打印另存为 PDF 等待文件名输入

    我正在尝试通过打印对话框将网站另存为 PDF 我的代码允许我另存为pdf 但要求我输入文件名 我不知道如何将文件名传递到弹出框 附上我的代码 import time from selenium import webdriver import
  • 为什么需要设置WORKON_HOME环境变量?

    我已经有一段时间没有使用 python 虚拟环境了 但我也安装了虚拟环境包装器 我的问题是 在文档页面中它说要这样做 export WORKON HOME Envs mkdir p WORKON HOME source usr local
  • 如何知道python运行脚本的路径?

    sys arg 0 给我 python 脚本 例如 python hello py 返回 sys arg 0 的 hello py 但我需要知道 hello py 位于完整路径中的位置 我怎样才能用Python做到这一点 os path a
  • 使用会话在 Django 中将文件从一个视图传递到另一个视图

    我当前的工作项目要求我允许用户上传各种格式的文件 目前仅处理 CSV 格式 然后使用包含的数据来绘制图表Pandas http pandas pydata org 图书馆 我决定将图形渲染到模板的最简单方法是为图形创建特定视图 然后将图像从
  • Python在没有pandas的情况下解码excel表

    我正在尝试在 python 中读取 excel 文件而不使用pandas or xlrd 我一直在尝试将结果转换为bytes to utf 8没有任何成功 xls 文件中的数据 colA colB colC spc 1D0 20190705
  • Eclipse/PyDev 中未使用导入警告,尽管已使用

    我正在我的文件中导入一个绘图包 如下所示 import matplotlib pyplot as plt 稍后我会在我的代码中成功使用此导入 fig plt figure figsize 16 10 然而 Eclipse 告诉我 未使用的导
  • 如何通过selenium中弹出的身份验证?

    我正在尝试使用带有 Selenium 的 Python 脚本加载需要身份验证的网页 options webdriver ChromeOptions prefs download default directory r download de
  • 如何从邻接表高效创建稀疏邻接矩阵?

    我正在与last fm http labrosa ee columbia edu millionsong lastfm数据集来自百万歌曲数据集 http labrosa ee columbia edu millionsong 数据以一组 j
  • 从给定的项目列表创建子列表

    我首先要说的是以下问题不是为了家庭作业目的即使因为我几个月前就完成了软件工程师的工作 无论如何 今天我正在工作 一位朋友向我询问了这个奇怪的排序问题 我有一个包含 1000 行的列表 每行代表一个数字 我想创建 10 个子列表 每个子列表都
  • 如何将两列 pandas Dataframe 移动并堆叠为一列?

    我有一个下面提到的数据框 ETHNIC SEX USUBJID 0 HISPANIC OR LATINO F 16 1 HISPANIC OR LATINO M 8 2 HISPANIC OR LATINO Total 24 3 NOT H
  • tf.print() vs Python print vs tensor.eval()

    看来在Tensorflow中 至少有三种方法可以打印出张量的值 我一直在读here https www freecodecamp org news debugging tensorflow a starter e6668ce72617 an
  • 用 pandas DataFrame 替换 mysql 数据库表中的行

    Python 版本 2 7 6 熊猫版本 0 17 1 MySQLdb 版本 1 2 5 在我的数据库中 PRODUCT 我有一张桌子 XML FEED 表 XML FEED 很大 数百万条记录 我有一个 pandas DataFrame
  • PyQt5按钮lambda变量变成布尔值[重复]

    这个问题在这里已经有答案了 当我运行下面的代码时 它显示如下 为什么 x 不是 x 而是变成布尔值 这种情况仅发生在传递到用 lambda 调用的函数中的第一个参数上 错误的 y home me model some file from P
  • 如何有效地比较 pandas DataFrame 中的行?

    我有一个 pandas 数据框 其中包含雷击记录以及时间戳和全球位置 格式如下 Index Date Time Lat Lon Good fix 0 1 20160101 00 00 00 9962692 7 1961 60 7604 1
  • 使用 python 将 CSV 文件上传到 Microsoft Azure 存储帐户

    我正在尝试上传一个 csv使用 python 将文件写入 Microsoft Azure 存储帐户 我已经发现C sharp https blogs msdn microsoft com jmstall 2012 08 03 convert

随机推荐

  • 它不是将数据插入数据库

    我想将数据插入到Image Question桌子 但它不会执行插入操作Image Question Table 我收到两个错误 注意 未定义的偏移量 0 in 第 305 行 注意 未定义的偏移量 第 305 行上的 3 in 这是您可以使
  • 如何解决“无法解析某些模块 oracledb”?

    我已经设置了一个流星项目并导入了oracledb节点包 https github com oracle node oracledb 但是在通过启动项目后meteor run我收到控制台构建错误 说明Unable to resolve som
  • 将任何数据类型序列化为向量 - 使用reinterpret_cast?

    我在搜索中没有找到任何直接相关的内容 所以如果这是重复的 请原谅 我想要做的是通过网络连接序列化数据 我的方法是将我需要传输的所有内容转换为std vector lt uint8 t gt 并在接收端将数据解包到适当的变量中 我的方法如下
  • 方法可以变成静态的,但是应该吗?

    ReSharper 喜欢指出每个 ASP NET 页面的多个可以静态化的函数 如果我将它们设为静态会对我有帮助吗 我应该将它们设为静态并将它们移至实用程序类吗 在我看来 性能 命名空间污染等都是次要的 问问自己什么是合乎逻辑的 该方法在逻辑
  • xsl:如何选择节点中的前x个字符?

    我在 XML 文档中有以下节点
  • Android,我可以使用 putExtra 传递多个值吗

    我想将两个值传递给另一个活动 我可以用 putExtra 来做到这一点 还是必须以更复杂的方式来做到这一点 从我的阅读看来 例如 这样的东西可以工作吗 public final static String ID EXTRA com fnes
  • 删除 Firefox 中的默认选择框箭头

    我必须删除 Firefox 中的默认选择框箭头 我使用了下面的代码 webkit appearance none moz appearance none background rgba 0 0 0 0 它在 Chrome 中运行良好 但它在
  • 保存照片并立即使用

    我有以下用于拍照并将其保存到相机胶卷的代码 我需要能够在保存后使用它 而不必返回图库并选择它 我还没有找到任何关于如何执行此操作的示例 IBOutlet weak var imagePicked UIImageView IBAction f
  • 为 webRTC 使用特定端口

    当使用 webRTC 创建点对点音频连接时 如果用户位于路由器后面 我们使用的 STUN 服务器将返回公共 IP 现在在 ICE 对象中 我可以看到 rport 始终介于 50000 及以上 有没有办法使用特定端口 以便用户不必打开所有这些
  • Servlet 3.1 - 多部分异步处理

    我正在测试 Servlet 3 1 API 来处理多部分请求 我对同步处理某些部分 文本字段 和异步处理其他部分 文件字段 感兴趣 乍一看 它似乎在 Servlet 3 1 中不可用 要么在异步上下文中通过 request getInput
  • 使用adapter-static时如何在sveltekit上使用获取参数?

    我在构建时收到错误消息 无法访问url searchParams在启用预渲染的页面上 如何加载和使用get参数 svelte config js import adapter from sveltejs adapter static imp
  • Twitter bootstrap - 单击时聚焦于模式内的文本区域

    刚刚开始使用 bootstrap 这真是太棒了 我正在尝试解决这个问题 我在模式窗口内有一个用于反馈的文本区域 效果很好 但我希望当您单击按钮激活模式时 焦点位于文本区域上 而且我似乎无法让它发挥作用 这是一个小提琴 http jsfidd
  • 如何更改 Grafana 中的背景颜色?

    我想修改 Grafana 中的深色主题 以便它使用 000000作为背景颜色 我见过 如何更改Grafana的默认黑色 https stackoverflow com questions 41006070 how to change def
  • 使用 msbuild 从 VS 2008 升级到 2010 时未保留构建顺序和依赖项

    我正在升级 VS 2008 解决方案以在 VS 2010 上运行我成功地在 VS 2010 中构建 我现在的下一步是配置运行 TFS 2008 的构建机器每当我开始构建时 它都会按字母顺序执行我的项目 而不考虑依赖关系 我用谷歌搜索了很多
  • 用于检查文件大小是否比之前的检查有所增加的 VB 脚本

    我需要一个 VB 脚本来检查文件大小并捕获它 并在下一次检查中将其与上一次检查进行比较 如果大小增加 则应提示文件大小增加 你可以尝试一下这个vbscript Option Explicit const bytesToKb 1024 Dim
  • 如何将画布内容转换为图像?

    from Tkinter import root Tk cv Canvas root cv create rectangle 10 10 50 50 cv pack root mainloop 我想将画布内容转换为位图或其他图像 然后执行其
  • R 中生存数据的左删失

    我想对左右删失的数据进行生存分析 Kaplan Meier 和 Cox PH 建模 我正在研究特定基因 基因 0 或 1 存在与不存在时发生心律失常 AF 的时间 然而 一些受试者在招募时被发现已经存在心律失常 因此应该进行审查 我已阅读生
  • Twisted 中的多重响应

    我正在尝试开发简单的TCP 使用 Twisted 和 Pygame 进行客户端 服务器游戏 但我在向客户端发送数据时遇到困难 Twisted 不允许我连续发送多个响应 这就是我想做的 我有方法处理玩家状态更改并将其重新发送给其他客户端 de
  • ASP.NET Core 中 Mongodb 数据存储的基于简单令牌的身份验证/授权

    我需要实现非常简单的身份验证机制 基本上有两个角色 Owners and Users 我认为拥有 Enum 就足够了 应用程序本身是SPA 通过Asp net core实现webapi 我看到文章 如何使用 EF Identity 实现它
  • 确定 MIDI 文件的时间划分

    我正在用Python编写一个脚本来解析MIDI文件 是的 我知道Python存在MIDI解析库 但对于我的用例来说 如果我从头开始制作它是最简单的 我遇到的问题之一是时间划分 标头的最后两个字节指定时间划分 但我无法确定文件的时间划分是否以