iOS中的MIDI合成行为不正确WRT俯仰弯曲:LSB被忽略

iOS中的MIDI合成行为不正确WRT俯仰弯曲:LSB被忽略,第1张

概述Apple的MIDI合成代码中有一个严重的错误,或者我做错了什么.这是我对它的理解.当您发送弯音MIDI命令时,弯曲的范围是-8192到8191,转换为0.(所以实际范围是0到16383.)这个数字被分成两个7位字段,所以真的这意味着你有128个粗控制值和128个精细控制值. 这是我写的弯音样本,类似于Apple LoadPresetDemo中的命令. // 'ratio' is the % am Apple的MIDI合成代码中有一个严重的错误,或者我做错了什么.这是我对它的理解.当您发送弯音MIDI命令时,弯曲的范围是-8192到8191,转换为0.(所以实际范围是0到16383.)这个数字被分成两个7位字段,所以真的这意味着你有128个粗控制值和128个精细控制值.

这是我写的弯音样本,类似于Apple LoadPresetDemo中的命令.

// 'ratio' is the % amount to bend in current pitch range,from -1.0 to 1.0// 'note' is the MIDI note to bendNSUInteger bendValue = 8191 + 1 + (8191 * ratio);NSUInteger bendMSB = (bendValue >> 7) & 0x7F;NSUInteger bendLSB = bendValue & 0x7F;UInt32 noteNum = note;UInt32 noteCommand = kMIDIMessage_PitchBend << 4 | 0;Osstatus result = MusicDeviceMIDIEvent(self.samplerUnit,noteCommand,noteNum,bendMSB,bendLSB);

当弯曲MSB(粗调)改变时,音高弯曲得很好.但是当bendLSB(精细控制)改变时,没有任何反应.换句话说,似乎Apple的MIDI合成器忽略了LSB,这意味着音符仅在丑陋的离散块中弯曲.

这是另一种做同样事情的方式:

// 'ratio' is the % amount to bend in current pitch range,from -1.0 to 1.0AudioUnitParameterValue bendValue = 63 + 1 + (63 * ratio); // this is a CGfloat under the hoodAudioUnitSetParameter(self.samplerUnit,kAUGroupParameterID_PitchBend,kAudioUnitScope_Group,bendValue,0);

这表现出与前一个例子相同的行为.关于这种做法的另外有趣的是,kAUGroupParameterID_PitchBend的文档指定值范围应为-8192到8191,这完全不起作用.实际范围显示为0到127,浮点(精细控制)被忽略.

最后,如果您进行以下调用以调整弯音范围:

// 'semitones' is the number of semitones (100 cents) to set the pitch bend range to// 'cents' is the additional number of cents to set the pitch bend range toUInt32 status = 0xB0 | 0;MusicDeviceMIDIEvent(self.samplerUnit,status,0x64,0x00,0);        // rpn pitch bend range.MusicDeviceMIDIEvent(self.samplerUnit,0x65,0);MusicDeviceMIDIEvent(self.samplerUnit,0x06,semitones,0);   // Data entry MSBMusicDeviceMIDIEvent(self.samplerUnit,0x26,cents,0);       // Data entry LSB (optional)MusicDeviceMIDIEvent(self.samplerUnit,0x7F,0);        // rpn resetMusicDeviceMIDIEvent(self.samplerUnit,0);

你能猜出会发生什么吗?这是正确的,LSB消息被忽略,并且音高轮范围仅改变所提供的半音的数量.

这里发生了什么?这是Apple的错误还是我错过了什么? (可能是一个设置参数?)或者它可能根本不是一个错误?也许Apple的合成器在设计上没有那么高的细节水平? MIDI标准是否合法?!救命!

编辑:

当弯音范围设定为40个半音时,每个粗略的变化都会产生可听见的差异.当弯音范围设置为10个半音时,只有每一秒的粗略变化都会产生差异.在2个半音(默认值)下,需要4个或更多粗略变化才能产生差异.

换句话说,LSB不仅显然被忽略了,而且似乎还有一个最小的分数可以改变.可以修复这些限制吗?如果没有,是否有适用于iOS的软件合成框架具有更高的弯曲分辨率?

嗯…也许应用kAudioUnitSubType_Varispeed或kAudioUnitSubType_NewTimePitch会产生更好的结果……

解决方法 您的弯音信息不正确.而不是这个:

UInt32 noteCommand = kMIDIMessage_PitchBend << 4 | 0;Osstatus result = MusicDeviceMIDIEvent(self.samplerUnit,bendLSB);

做这个:

UInt32 bendCommand = kMIDIMessage_PitchBend << 4 | 0;Osstatus result = MusicDeviceMIDIEvent(self.samplerUnit,bendCommand,bendLSB,0);

音符值不是弯音命令的一部分. (另外,我将变量noteCommand的名称更改为bendCommand以更准确地反映其用途.)

在LoadPresetDemo中,我向MainVIEwController.m添加了一个属性:

@property (reaDWrite) NSInteger bendValue;

而这段代码:

- (voID)sendBendValue:(NSInteger)bendValue {    //bendValue in the range [-8192,8191]    const UInt32 bendCommand = kMIDIMessage_PitchBend << 4 | 0;    bendValue += 8192;    UInt32 bendMSB = (bendValue >> 7) & 0x7F;    UInt32 bendLSB = bendValue & 0x7F;    NSLog(@"MSB=%d,LSB=%d",(unsigned int)bendMSB,(unsigned int)bendLSB);    Osstatus result = MusicDeviceMIDIEvent(self.samplerUnit,0);    NSAssert (result == noErr,@"Unable to send pitch bend message. Error code: %d '%.4s'",(int) result,(const char *)&result);}- (IBAction)bendDown:(ID)sender {    self.bendValue = MAX(-8192,self.bendValue - 0x20);    [self sendBendValue:self.bendValue];}- (IBAction)bendCenter:(ID)sender {    self.bendValue = 0;    [self setBendRange:50 cents:0];    [self sendBendValue:self.bendValue];}- (IBAction)bendUp:(ID)sender {    self.bendValue = MIN(8191,self.bendValue + 0x20);    [self sendBendValue:self.bendValue];}-(voID)setBendRange:(UInt32)semitones cents:(UInt32)cents {    MusicDeviceMIDIEvent(self.samplerUnit,0xB0,0);    MusicDeviceMIDIEvent(self.samplerUnit,0);    //The following two lines are not really necessary. They only matter if additional controller 0x06 or 0x26 messages are sent    //MusicDeviceMIDIEvent(self.samplerUnit,0);    //MusicDeviceMIDIEvent(self.samplerUnit,0);  }

我创建了三个按钮并将它们分配给bendDown:,bendCenter:和bendUp:.

运行程序并按下bendCenter按钮.然后,选择长号音,按住“MID Note”按钮.按住该按钮的同时,按下bendUp或bendDown按钮.当LSB改变且MSB保持不变时,我可以听到音调的变化.

总结

以上是内存溢出为你收集整理的iOS中的MIDI合成行为不正确WRT俯仰弯曲:LSB被忽略全部内容,希望文章能够帮你解决iOS中的MIDI合成行为不正确WRT俯仰弯曲:LSB被忽略所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1065044.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存