展开/填充 Matlab 矩阵
我对 Matlab 还很陌生,所以需要一个简单的解释。
我有一些 MIDI 数据,看起来有点像这样:
时间开/关音符
10 1 61
90 0 61
90 1 72
92 1 87
100 0 72
我想要做的是扩展或“填充”空白,以便我在每个时刻都有一行,并且我有显示哪些音符处于打开状态的列(通常有多个音符同时)。
最终目标是对给定时间的音符(和声不和谐音)之间的整体关系进行一些计算。
所以我想也许我需要为每个可能的音符(有 127 个)创建一个新列,然后每次都添加 1 或 0。或者也许我可以有一个矩阵,它只告诉我哪些音符处于打开状态(因此列数有所不同)。
我自己写了伪代码,但不知道如何实现。我怀疑有一个简单的函数可以做到这一点。这是我的伪代码:
从 0 开始,在新的“注释矩阵”中的时间 0
对于数字:0 到 n
如果该数字与时间列中的数字匹配,请转到该行的开/关列。
如果开/关列中为 1,则将注释列中的数字复制到相应行的“注释矩阵”
如果为 0,则不复制/不执行任何操作。
如果数字与时间列中的数字不匹配
复制上一行(如果没有注释,则可以为空)。
对于新“注释矩阵”中的每一行,将数字从低到高排列在不同的列中。
那么谁能告诉我该怎么办?我在这里用头撞砖墙!
I'm pretty new at Matlab so would need a baby-steps explanation.
I have some MIDI data which looks a bit like this:
time on/off note
10 1 61
90 0 61
90 1 72
92 1 87
100 0 72
What I want to do is expand or 'fill-in' the gaps so that I have a row for every single moment in time, and I have columns which show which notes are on (there is often more than one note at the same time).
the ultimate goal is to do some calculations about the overall relationship between notes on (the harmonic dissonance) at a given time.
So I was thinking that maybe I needed a new column for every single possible note (there are 127), and then a 1 or 0 for every time. Or maybe I can just have a matrix which just tells me which notes are on (so the number of columns varies).
I wrote my own pseudo-code, but have no idea how to implement it. I suspect there is a simple function that can do this. Here is my pseudo-code:
start with 0, at time 0 in a new 'notes-on matrix'
for numbers: 0 to n
if the number matches a number in the time column, go to the on/off column for that row.
if 1 in on/off column then copy number in notes column to 'notes-on matrix' for corresponding row
if 0 then don't copy/do nothing.
if number doesn't match number in time column
copy the previous row (which can be blank if there were no notes on).
for each row in the new 'notes-on matrix', arrange numbers low to high in different columns.
So can anyone tell me what to do?? I'm banging my head against a brick wall here!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
即使列表的顺序完全随机,这里的解决方案也可以工作。它基于以下思想:向量
[0 1 0 0 -1 0 0]
的累积和为[0 1 1 1 0 0 0]
。这对应于时间 2 中的“on”,以及时间 5 中的“off”。现在我们需要做的就是用1
和-1
填充一个数组,然后运行CUMSUM 将其转换为每列都有 1 的数组每当声音开启
时。我假设有 128 个音符 (0-127),并且您希望在最后有一个静音时间步长(如果所有音符最终结束)。请注意,Matlab 从 1 开始计数,因此时间 0 对应于行 #1。
为了完整性,之前的解决方案:
Here's a solution that will work even if the list is in a completely random order. It is based on the following idea: The cumulative sum of the vector
[0 1 0 0 -1 0 0]
is[0 1 1 1 0 0 0]
. This corresponds to "on" in time 2, and "off" in time 5. Now all we need to do is populate an array with1
and-1
, and run CUMSUM to transform it into an array that has, in each column, ones whenever the sound ison
.I assume that there are 128 notes (0-127), and that you want to have one time step of silence (if all notes eventually end) at the very end. Note that Matlab starts counting at 1, so time 0 corresponds to row #1.
The previous solution, for completeness: