首先,我不是一个专业的程序员,我只是一个学生谁有一个优秀的图书馆,米迪-多特网有一个小问题。
我使用Midi库用C#语言用Visual编写了一个简单的应用程序。但我遇到了一个非常令人困惑的问题。
我在Form1.cs中放置了一些代码
public void NoteOn(NoteOnMessage msg) {
if (InvokeRequired) {
BeginInvoke(noteOnHandler, msg);
return;
}
inputStatusLabel.Text = String.Format("{0}", msg.Pitch);
String nutka = inputStatusLabel.Text;
if (nutka == "A0") {
clock.Schedule(new NoteOnMessage(outputDevice, Channel.Channel1, Pitch.A0, 80, 2));
}
}所以,我放置了新的字符串,并将其命名为坚果,坚果卡将收到我的USB键盘上按下的音符的名称。然后,我放置IF状态,并将nutka与"A0“(键盘上的第一个音符)进行比较。
如果是"A0“,我按下了outputDevice播放的特定音符。它会播放两次,一次是我在键盘上按下键(带有A0键),第二次是当我释放那个键时。
我在public void NoteOn(NoteOnMessage msg)上做了一个断点,注意到一个应用程序在这里返回了两次,并且播放了两次这个注释,但仍然不知道为什么。
还有一件事,有一个方法public void NoteOff(NoteOffMessage message),但它似乎不起作用。
我真的搞不懂,我在找人帮忙。
更新 ..。更新.更新
另一个问题出现了(第一部分由于CL和Chris 的建议和逐步的解释而得到了解决)。
谢谢贾斯汀:)我认为没有任何问题的生活是不可能的
有了clock.Schedule,我只能弹MIDI的声音,但我想弹钢琴音符(wav文件格式),在4-5周后,我的大学将帮助我录制我自己的钢琴声音为每一个音符。我也想同时播放他们。
我以为一切都会好起来现在..。同时播放有问题。我试着检查三种可能性:
1)我试着从我拥有的基本音符库中弹奏钢琴声音,并使用SoundPlayer:
SoundPlayer noteA0 = new SoundPlayer(Properties.Resources.A0);
noteA0.Play();我使用它的每一个不同的SoundPlayer名称的笔记语句(取决于音符名称),我注意到-我不能同时播放音符。
2)所以我使用了下一个WMP库和WindowsMediaPlayer:
例如:
var noteA0 = new WMPLib.WindowsMediaPlayer();
noteA0.URL = @"c:\sounds\piano\A0.wav";好的..。它同时播放,但看起来我弹的音符越多,或者我只弹一首歌,我就有更大的延迟,最后我的节目继续播放任何东西.
我试着用Microsoft.DirectX.AudioVideoPlayback:
Audio noteA1 = new Audio(@"C:\sounds\piano\A1.wav");
noteA1.Play();我开始我的程序,按了一个键,砰!崩溃时带有错误消息:
An unhandled exception of type 'System.BadImageFormatException' occurred in Midi.dll
Additional information: Could not load file or assembly 'Microsoft.DirectX.AudioVideoPlayback.dll' or one of its dependencies.
It is not a valid Win32 application. (Exception from HRESULT: 0x800700C1)当然,我没有忘记使用:
using System.Media;
using Microsoft.DirectX.AudioVideoPlayback;
using Microsoft.DirectX;现在我不知道我还能做些什么--我需要一个有经验的人的帮助:)
发布于 2015-06-19 22:55:17
在CL.'s answer上展开,下面是可能发生的一系列事件:
Note On message, with a Pitch of A0, and a velocity (准确的速度可能每次都不同)。if语句匹配,因此发送一个Note On message, with a pitch of A0, and a velocity of 80。这里是棘手的地方。当您释放密钥时,一些MIDI设备以相同的音调发送相应的Note Off消息。其他设备将以相同的音高发送第二条Note On消息,但速度为0。这两种类型的消息在功能上是(或者应该是)等价的,每个设备都可以停止音符播放(甚至两者兼而有之)。所以,
Note On message, with a Pitch of A0, and a Velocity of 0。if语句匹配,所以会发送一个Note On message, with a pich of A0, and a velocity of 80。由于速度为0的Note On也是Note,所以您的代码正在将键盘的"Note“重新打开为Note,从而播放了两次声音。
作为Chris Dunaway suggested,您需要通过测试速度为0来确定Note是否实际上是"Note“。
if (nutka == "A0" && msg.Velocity != 0) {
clock.Schedule(new NoteOnMessage(outputDevice, Channel.Channel1, Pitch.A0, 80, 2));
}发布于 2015-06-19 08:37:40
MIDI 1.0的详细规范说:
MIDI提供了两种大致相同的关闭音符(声音)的方法。可以通过为相同的音符号码和信道发送便笺关闭消息,或者通过为该音符和速度值为零的信道发送便笺消息而关闭便笺。使用“零速度笔记”的优点是,当使用运行状态时,可以避免发送额外的状态字节。 由于这种效率,发送速度值为零的便笺信息是最常用的方法。然而,一些键盘仪器实现释放速度,其中使用一个注释关闭代码(8nH)伴随一个“速度关闭”字节。接收者必须能够识别关闭音符的任何一种方法,并应以相同的方式对待它们。
https://stackoverflow.com/questions/30933030
复制相似问题