我想知道一个简单的CoreAudio组件(子类型为kAudioUnitSubType_HALOutput,例如)是否可以通过MIDI键盘进行参数控制,假设MIDI音符编号被转换为插入振荡器频率?另一方面,通过GUI元素控制这样的参数就像梦一样。
我在整个网络上找不到这样一个代码的例子。 我不需要SinSynth,Sampler,MusicDevice,SoundFonts,Midi文件,GM,ADSR,插件级别的功能等。
只需要一条简单的信息或暗示如何通过midiReadProc读取的MIDI数据包中的数据传递给音频渲染回调,就像滑块的值一样。有了MIDI似乎有一个线程问题,我没有找到关于。
的文档我更喜欢在CoreAudio API中执行此操作,如果可能的话,我确定必须这样做。
另一方面,使用Apple预制的乐器设备会让我走向一个完全错误的方向。
提前致谢,
CA
答案 0 :(得分:0)
您似乎想要使用MIDI键盘控制AudioUnit的一些参数或属性。在这种情况下,您需要的只是MIDIPacket
的{{1}}字段。
你可以看到每个字节的含义here。
之后,根据所需字节的值,您需要设置属性或参数值。
答案 1 :(得分:0)
这是对我所学习并同时开展工作的问题的简约回答。这是一个使 midiReadProc 生成 audioRenderProc 可以接受的值作为参数的问题。请注意,这适用于独立应用程序。对于编写AU插件,我建议理解并使用Apple提供的 CoreAudioUtilityClasses 。 C :
中最简单的createMidi示例//these have to be declared somewhere
MIDIClientRef midiclient;
MIDIPortRef midiin;
void createMIDI (void)
{
//create MIDI input and client - - - - - - - - - - -
midiclient = 0;
CheckError(MIDIClientCreate(CFSTR("MIDI_Client"),
NULL,
/*midiClientNotifyRefCon*/NULL,
&midiclient),
"MIDI Client Create Error\n");
CheckError(MIDIInputPortCreate(midiclient,
CFSTR("MIDI_Input"),
midiReadProc,
NULL,
&midiin),
"MIDI Port Create Error\n");
//connect MIDI - - - - - - - - - - - - - - - - - - -
ItemCount mSrcs = MIDIGetNumberOfSources();
printf("MIDI Sources: %ld\n", (long)mSrcs);
ItemCount iSrc;
for (iSrc=0; iSrc<mSrcs; iSrc++) {
MIDIEndpointRef src = MIDIGetSource(iSrc);
MIDIPortConnectSource(midiin, src, NULL);
}
}
CheckError()是由C.Adamson&amp; K.Avila,ISBN 0-321-63684-8 ......
...和一个普通的C midiReadProc 模板。请注意,许多MIDI硬件制造商没有实现标准化的noteOff事件,而是由零速度noteOn组成的“黑客”版本,由于涉嫌改善MIDI延迟问题,但他们几乎没有记录它。因此,必须检查两种情况:
void midiReadProc(const MIDIPacketList *packetList,
void* readProcRefCon,
void* srcConnRefCon)
{
Byte note;
Byte velocity;
MIDIPacket *packet = (MIDIPacket*)packetList->packet;
int count = packetList->numPackets;
for (int k=0; k < count; k++) {
Byte midiStatus = packet->data[0];
Byte midiChannel = midiStatus & 0x0F;
Byte midiCommand = midiStatus >> 4;
if ((midiCommand == 0x08)||(midiCommand == 0x09)){
if(midiCommand == 0x09){
note = packet->data[1] & 0x7F;
velocity = packet->data[2] & 0x7F;
if (velocity == 0x0){ //"hacked" note-off
; //do something
}else{//note on
; //do something
}
}
if(midiCommand == 0x08){ //proper note-off
;//do something
}
}else{
;//do something else
}
packet = MIDIPacketNext(packet);
}//end for (k = 0; ...;...)
}
其他一切都是共同良好的编程实践的问题。