gpt4 book ai didi

ios - 核心音频 : How to play MIDI MusicSequence by MusicPlayer while AUGraph is deprecated?

转载 作者:行者123 更新时间:2023-12-04 13:34:29 26 4
gpt4 key购买 nike

我有一个 MIDI 合成器

 AudioComponentDescription midiSynthDesc;
midiSynthDesc.componentType = kAudioUnitType_MusicDevice;
midiSynthDesc.componentSubType = kAudioUnitSubType_MIDISynth;
midiSynthDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
midiSynthDesc.componentFlags = 0;
midiSynthDesc.componentFlagsMask = 0;
它曾经在 AUGraph 中。但是由于 AUGraph 已被弃用,我使用 AudioComponentInstanceNew 来创建它而不使用 AUNode 和 AUGraph
AudioComponent foundMIDISynthReference = AudioComponentFindNext ( NULL, &midiSynthDesc);
AudioComponentInstanceNew(foundMIDISynthReference, &midiSynthUnit);
我通过将 Sequence 附加到 AUGraph 来使用它来播放 Sequence
NSString *presetURLPath = [[NSBundle mainBundle] pathForResource:@"GortsMiniPianoJ1" ofType:@"SF2"];
NSURL * presetURL = [NSURL fileURLWithPath:presetURLPath];
[self loadFromDLSOrSoundFont: (NSURL *)presetURL withPatch: (int)3];

NSString *midiFilePath = [[NSBundle mainBundle] pathForResource:name ofType:@"mid"];
NSURL * midiFileURL = [NSURL fileURLWithPath:midiFilePath];

NewMusicPlayer(&musicPlayer);
MusicPlayerSetSequence(musicPlayer, musicSequence);
MusicSequenceSetAUGraph(musicSequence, _processingGraph);
MusicPlayerPreroll(musicPlayer);
MusicPlayerStart(musicPlayer);
但是现在 AUGraph 已弃用,仅使用 AudioUnit,如何在 Core Audio 中使用 Play MIDI Files?

最佳答案

MusicSequence 接受对 MIDIEndPointRef 的引用而不是 AUGraph。一种可能的解决方法是创建一个内部虚拟端口来接收 MusicPlayer 发送的事件并将它们重新分配到您的音频单元。这是一个简化的示例:
创建一个 MIDI 客户端:

MIDIClientRef clientRef;
id myManager;
MIDIClientCreate(CFSTR("MyMidiClient"), NULL, (__bridge void *)myManager, &clientRef);
创建一个虚拟输入端口:
MIDIEndpointRef endPointRef;
MIDIDestinationCreate(clientRef, CFSTR("MyVirtualInPort"), (MIDIReadProc)MidiInputCallback, (__bridge void *)myManager, &endPointRef);
MusicPlayer 发送的 MIDI 事件通过创建端口时引用的回调接收:
void MidiInputCallback(const MIDIPacketList *pktlist, void *refCon, void *connRefCon)
{
id myManager = (__bridge id)refCon;
MIDIPacket *packet = (MIDIPacket *)pktlist->packet;
UInt8 status, byte1, byte2;
for (unsigned int ipack = 0; ipack < pktlist->numPackets; ++ipack)
{
status = packet->data[0];
byte1 = packet->data[1];
byte2 = packet->data[2];

// Do something with the MIDI events
printf("Received Event %d %d %d\n", status, byte1, byte2);

if (packet) packet = MIDIPacketNext(packet);
}
}
创建一个非常简单的 MusicPlayer 包含一个音符:
MusicSequence musicSequence;
MusicPlayer player;
MusicTrack track;
NewMusicSequence(&musicSequence);
NewMusicPlayer(&player);
MusicPlayerSetSequence(player, musicSequence);
MusicSequenceNewTrack(musicSequence, &track);

MIDIChannelMessage msg = {
.status = 0 | 9 << 4, // channel 1, type note on
.data1 = 60, // pitch
.data2 = 80 // velocity
};
MusicTrackNewMIDIChannelEvent(track, 0.0, &msg);
msg.data2 = 0; // pseudo note off
MusicTrackNewMIDIChannelEvent(track, 4.0, &msg);
引用 EndPoint 并开始播放:播放的音符由回调接收,可以将其重定向到音乐设备类型的音频单元。
MusicSequenceSetMIDIEndpoint(musicSequence, endPointRef); //the port created above

MusicPlayerStart(player);

关于ios - 核心音频 : How to play MIDI MusicSequence by MusicPlayer while AUGraph is deprecated?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62999685/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com