在 Mathematica 和 MIDI 踏板事件中叠加音乐曲目
Posted
技术标签:
【中文标题】在 Mathematica 和 MIDI 踏板事件中叠加音乐曲目【英文标题】:Superposing music tracks in Mathematica & MIDI pedal events 【发布时间】:2011-11-06 21:21:01 【问题描述】:以下所有内容均指音乐/MIDI(SoundNote
对象),而不是采样声音。
不幸的是,Mathematica 似乎无法导入 MIDI。我正在尝试基于MIDI <-> CSV 为单乐器文件(专注于钢琴)制作一个简单的 MIDI 导入器。
在 Mathematica 中叠加两个 Sound
对象的最简单方法是什么?
Show
将它们连接起来,它不会叠加。
一个不太简单的方法是将Sound
拆解成SoundNote
s,将每个SoundNote
s时间规范转换成Tstart, Tend
格式,再将它们组合成一个新的声音。有没有简单的方法?
第二个问题:
是否有一种简单的方法来处理 Mathematica 中的踏板事件,同时仍然使用内部声音表示和 MIDI 播放器,而不是通过其他方式播放 MIDI?
【问题讨论】:
【参考方案1】:1。叠加
为了能够叠加两个Sound
对象,应该有一个共同的时间原点。一个简单的SoundNote
对象有自己的时间来源,因此在这些列表上使用Sound
只会将它们连接起来并连续播放它们。您必须为每个使用绝对时间才能叠加它们。这样,您可以在同时演奏多种乐器的情况下创作 MIDI 音乐。
这是一个叠加的简短示例(未经过修饰)。低音由钢琴演奏,高音由单簧管演奏。
tempo = 110;
eighthNoteDuration = 60/tempo/2;
trebleNotes = "E5", "D#5", "E5", "D#5", "E5", "B", "D5", "C5", "A",
None, "C", "E", "A", "B", None, "E", "G#", "B", "C5", None, "E",
"E5", "D#5", "E5", "D#5", "E5", "B", "D5", "C5", "A", None, "C",
"E", "A", "B", None, "E", "C5", "B", "A";
trebleNoteDurations = 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1,
1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1,
1, 4 eighthNoteDuration;
trebleTimings =
Partition[
Accumulate@Flatten@Transpose@ConstantArray[0, Length@#], # &@
trebleNoteDurations, 2];
bassNotes = None, None, "A2", "E3", "A3", None, None, "E3", "G#3",
"B3", None, None, "A2", "E3", "A3", None, None, None, "A2", "E3",
"A3", None, None, "E3", "G#3", "B3", None, None, "A2", "E3", "A3",
None;
bassNoteDurations = 2, 6, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1,
2, 6, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1 eighthNoteDuration;
bassTimings =
Partition[
Accumulate@Flatten@Transpose@ConstantArray[0, Length@#], # &@
bassNoteDurations, 2];
Sound[Join[
SoundNote[#1, #2,
"Piano"] & @@@ (bassNotes, bassTimings\[Transpose]),
SoundNote[#1, #2,
"Clarinet"] & @@@ (trebleNotes, trebleTimings\[Transpose])]]
2。踏板效果
至于你的第二个问题,我认为你不能使用 MIDI 再现踏板效果。 MIDI 格式非常简单,实际上并不传输任何声音。它携带的所有信息都是
-
正在播放的音符(音高)
音符的持续时间(速度)
触发事件以开始和停止笔记
您选择再现声音的乐器完全取决于您的系统,并且在不同系统上再现声音的方式可能不同。现在,如果您想重现踏板效果,您将必须编写一个函数将其分解为与踏板实际效果非常相似的单个 MIDI 事件。
例如,您可以修改SoundNote
或创建一个新函数,当传递选项Sustain -> t
时,将注释延长t
秒。您可以使这更加现实,并将t
秒分成更小的段,SoundVolume -> v
作为附加选项,v
随每个段线性/对数递减。
【讨论】:
谢谢!我正在考虑类似的事情,似乎没有更简单的方法。关于踏板,它实际上是 MIDI 的一部分。在 CSV 表示中,踩下或松开踏板显示为Control_c, 0, 64, 127
,表示将控制器 64 的值设置为 127(踩下踏板)或 0(松开踏板)。当然,这取决于使用的 MIDI 乐器是否会对这个事件做些什么,但通常任何钢琴风格的乐器都应该响应它。
我想我将在 Mathematica 中使用我自己的 MIDI 表示,并为 Sound
对象和 MIDI 文件编写一个转换器。使用Sound
对象,您可以通过扩展每个音符直到踏板被释放来模拟延音踏板。
我很确定 MIDI 可以传输踏板信息。它通过 CC #64 传输,我只是不知道您将如何在 Mathematica 上实现它。 Source,另外,yoda 对 MIDI 的评论非常不完整 - yoda,您是指 MIDI 协议本身还是 Mathematica 上的 MIDI?【参考方案2】:
关于你的第二个问题:
之前我 reported 谈到 Mathematica 连接到 Nintendo Wiimote 和 Balanceboard 的能力,使用程序 GlovePie 和 PPJoy,这是一个虚拟操纵杆驱动程序,它可以让 Mathematica 通过模拟操纵杆与您的设备交互(MMA 可以使用ControllerState
或 ControllerInformation
)。据我所知,GlovePie 也支持 MIDI。你可以试试看。
【讨论】:
Mac 版 Mathematica 通过 ControllerState[] 函数原生支持 MIDI 设备。无需任何虚拟操纵杆驱动程序。 @ragfield 我猜 Windows 没有,对吧?当我将钢琴连接到计算机时,我从ControllerInformation[]
收到“未检测到控制器设备”。
其实我一直在寻找一种输出声音的方法,同时也考虑到延音踏板的效果(我现在只对钢琴风格的乐器感兴趣),但这似乎并不在 Mathematica 中是可能的。 GlovePie 让我做的是使用外部 MIDI 键盘(可能也使用踏板)控制 Mathematica。
@szabolcs 正确,ControllerState 中的内置 MIDI 支持仅限 Mac。
@szabolcs 我认为这里的时间可能是个问题。耳朵对声音产生的延迟非常敏感。这就是音乐家总是使用 ASIO 驱动程序的原因。在将 MIDI 数据提供给 Mathematica(也不能保证实时处理)之前通过两个程序路由 MIDI 数据在这个意义上可能远非最佳。【参考方案3】:
您可以使用卷积组合或叠加声波,如本页上的 Mathematica 代码所示:
http://www.copperthoughts.com/projects/convolution/
【讨论】:
OP 已经明确表示他在谈论 MIDI 对象而不是采样声音。您不能将 MIDI 对象与任何东西进行卷积... @yoda,但 MIDI 对象在某种意义上是声音的表示。因此,除了转换为声音,卷积可能是有效的。这只会使他的解决方案不完整。 @rcollyer MIDI 对象是一组指令。如何渲染输出取决于系统。从理论上讲,您可以将其转换为采样声音,进行卷积,然后返回一组 MIDI 指令(如果结果甚至可以由 MIDI 表示)。但是 MIDI 文件并不那么容易操作、采样和导出,正如我在尝试为this question 提出解决方案时发现的那样。以上是关于在 Mathematica 和 MIDI 踏板事件中叠加音乐曲目的主要内容,如果未能解决你的问题,请参考以下文章
c_cpp 发送midi程序更改并根据按下的脚踏板控制更改消息