这是一个发送MIDI数据的极其简单的CoreMIDI OS X应用程序.问题是它不起作用.编译好,并运行.它报告没有错误,并且不会崩溃.创建的源在MIDI监视器中可见.但是,没有MIDI数据出来.
有人能告诉我这里我做错了什么吗?
#include <CoreMIDI/CoreMIDI.h>
int main(int argc, char *args[])
{
MIDIClientRef theMidiClient;
MIDIEndpointRef midiOut;
MIDIPortRef outPort;
char pktBuffer[1024];
MIDIPacketList* pktList = (MIDIPacketList*) pktBuffer;
MIDIPacket *pkt;
Byte midiDataToSend[] = {0x91, 0x3c, 0x40};
int i;
MIDIClientCreate(CFSTR("Magical MIDI"), NULL, NULL,
&theMidiClient);
MIDISourceCreate(theMidiClient, CFSTR("Magical MIDI Source"),
&midiOut);
MIDIOutputPortCreate(theMidiClient, CFSTR("Magical MIDI Out Port"),
&outPort);
pkt = MIDIPacketListInit(pktList);
pkt = MIDIPacketListAdd(pktList, 1024, pkt, 0, 3, midiDataToSend);
for (i = 0; i < 100; i++) {
if (pkt == NULL || MIDISend(outPort, midiOut, …Run Code Online (Sandbox Code Playgroud) 可能目前这实际上是不可能的,这是不幸的.我正在尝试调用CoreMIDI API来设置MIDI输入.这就是我在Swift中要做的事情:
var midiClient = MIDIClientRef()
var inputPort = MIDIEndpointRef()
var status: OSStatus
func readProc(packetList: UnsafePointer<MIDIPacketList>, readProcRefCon: UnsafeMutablePointer<Void>, srcConnRefCon: UnsafeMutablePointer<Void>) -> Void {
}
status = MIDIClientCreate("MIDI client", nil, nil, &midiClient);
status = MIDIDestinationCreate(midiClient, "MIDI input", readProc, nil, &inputPort);
Run Code Online (Sandbox Code Playgroud)
但我得到这个错误:'(UnsafePointer,UnsafeMutablePointer,UnsafeMutablePointer) - > Void'不能转换为'MIDIReadProc'
MIDIReadProc的typedef如下:
typealias MIDIReadProc = CFunctionPointer<((UnsafePointer<MIDIPacketList>, UnsafeMutablePointer<Void>, UnsafeMutablePointer<Void>) -> Void)>
Run Code Online (Sandbox Code Playgroud)
有没有办法让我的readProc方法的函数指针传递给MIDIDestinationCreate API?
在Xcode 11 beta 6的iOS 13模拟器中,启用MIDI Network Session时崩溃。
通过didFinishLaunching:WithOptions:在一个新项目中向AppDelegate添加以下行,我能够进行复制:
MIDINetworkSession.default().isEnabled = true
MIDINetworkSession.default().connectionPolicy = .anyone
Run Code Online (Sandbox Code Playgroud)
在iOS 13模拟器中运行时,该应用将在以下第一行崩溃,并在控制台上显示“找不到MIDI网络驱动程序”。iOS 12和更早版本的模拟器不受影响。
奇怪的是,似乎并不是我的所有iOS 13模拟器都受到影响。看来我在Xcode 11 beta 4和更早版本中使用的所有iOS 13模拟器都能正常工作。唯一受影响的模拟器可能是我在Xcode 11 beta 5及以后版本中首次使用的模拟器。
我假设这是一个Beta软件错误,并且已经向Apple提交了该错误。但是我觉得在这里进行记录很聪明,以防其他人遇到它。
更新时间:2019-09-11
对于Xcode 11.0 GM种子(包括新的iPhone 11型号)中的模拟器,这仍然是我的问题。
更新时间:2019-09-30
Xcode 11.1 GM种子中仍然存在问题。我按照Evan的回答中的步骤进行操作,似乎可以解决该问题。
我无法在CoreMIDI for iOS上找到太多信息.甚至可以通过向设备本身发送消息来播放MIDI声音.iPhone或iPad是否安装了MIDI设备,或者您是否必须将设备连接到接口?
面对两个错误.
此代码适用于iOS 4和5,但在更新到6后,它无法正常工作(
我找到了以下内容,但不知道如何在代码中修复它.
从iOS 6开始,应用程序需要在其UIBackgroundModes中包含音频密钥才能使用CoreMIDI的MIDISourceCreate和MIDIDestinationCreate函数.如果没有密钥集,这些函数将返回kMIDINotPermitted(-10844).
2012-09-23 03:40:04.773 MidiStudio [1017:907]错误(创建MIDI虚拟源): - 10844:错误域= NSMachErrorDomain代码= -10844"操作无法完成.(马赫错误-10844. )"
2012-09-23 03:40:04.777 MidiStudio [1017:907]错误(创建MIDI虚拟目标): - 10844:错误域= NSMachErrorDomain代码= -10844"操作无法完成.(马赫错误-10844. )"
这是'source'的代码:
-(void)setVirtualSourceEnabled:(BOOL)virtualSourceEnabled {
if ( virtualSourceEnabled == self.virtualSourceEnabled ) return;
if ( virtualSourceEnabled ) {
NSString *name = virtualEndpointName ? virtualEndpointName : [[[NSBundle mainBundle] infoDictionary] valueForKey:(NSString*)kCFBundleNameKey];
OSStatus s = MIDISourceCreate(client, (CFStringRef)name, &virtualSourceEndpoint);
NSLogError(s, @"Create MIDI virtual source");
if ( s != noErr ) return;
virtualSourceDestination = [[PGMidiVirtualSourceDestination alloc] initWithMidi:self endpoint:virtualSourceEndpoint];
[delegate midi:self destinationAdded:virtualSourceDestination];
[[NSNotificationCenter defaultCenter] postNotificationName:PGMidiDestinationAddedNotification …Run Code Online (Sandbox Code Playgroud) MusicPlayer的API依赖于可变长度数组作为结构的最后一个成员来处理未知大小的数据传递.查看生成的接口MusicPlayer,此方法中使用的结构将其最后一个元素呈现在单个值元组中.
例:
struct MusicEventUserData {
var length: UInt32
var data: (UInt8)
}
Run Code Online (Sandbox Code Playgroud)
我怀疑这一点是否已被正式曝光,但有没有人想出这种语法是红鲱鱼还是真的很重要?我不认为有办法通过swift处理任意大小的东西,但这在从C调用时有帮助吗?
我刚刚发现CABTMIDILocalPeripheralViewControlleriOS用于处理启用蓝牙MIDI可发现性的用户设置.这很好,但是为了将蓝牙集成到我的应用程序的网络MIDI连接的其余部分,能够直接从我的应用程序的代码处理启用而不是依赖这个不透明的VC是很好的.有谁知道这是否可能?
我正在努力实现一些看起来应该很简单的东西:在Mac应用程序中侦听MIDI消息,并使用它们来播放现有AVAudioUnit乐器的音符.
假设:我需要在与我的CoreMIDI客户端关联的MIDIReadBlock(通过MIDIInputPortCreateWithBlockMIDIClientRef)和我可以从我的AVAudioUnit的AUAudioUnit(via scheduleMIDIEventBlock)获得的AUScheduleMIDIEventBlock 之间建立一个桥梁.这似乎比它应该更复杂,因为我将使用原始MIDI数据 - 我觉得音频单元必须支持一些易于与CoreMIDI一起使用的MIDI抽象,但我找不到任何相关的例子这个的.也许有一种方法可以使用MIDIOutputPortCreateAV/AUAudioUnit?
我正在寻找的是一个将MIDI输入直接输入音频单元(理想情况下使用Swift 3)的工作示例,但如果您知道任何相对较新的相关资源,请分享这些链接.这些API的文档稀疏性非常令人沮丧.谢谢!
我在一个类上使用AudioKit的AKMIDIListener协议来监听MIDI消息.这适用于标准消息,例如Note On,但SysEx消息不会通过.
func receivedMIDINoteOn(noteNumber: MIDINoteNumber, velocity: MIDIVelocity, channel: MIDIChannel) {
NSLog("Note On \(noteNumber), \(velocity), \(channel)") // works perfectly
}
func receivedMIDISystemCommand(_ data: [MIDIByte]) {
NSLog("SysEx \(data)") // never triggers
// More code to handle the messages...
}
Run Code Online (Sandbox Code Playgroud)
SysEx消息从外部硬件或测试软件发送.我已经使用MIDI监控应用程序来确保正确发送消息,但在我的应用程序中它们没有触发receivedMIDISystemCommand.
接收我缺少的SysEx消息是否还需要其他步骤?
提前感谢任何线索.
要让MIDI通过蓝牙工作,我需要使用CoreAudioKit框架.这很好用,但我无法在模拟器上编译.
ld: framework not found CoreAudioKit我认为它应该根据文档工作
我在代码中有这个,这就是我可以删除框架而没有问题的原因.
#if !TARGET_IPHONE_SIMULATOR
#import <CoreAudioKit/CoreAudioKit.h>
#endif
Run Code Online (Sandbox Code Playgroud)