Apple の MIDI シンセシス コードに重大なバグがあるか、何か間違ったことをしている可能性があります。これが私の理解です。ピッチ ベンド MIDI コマンドを送信すると、ベンドの範囲は -8192 ~ 8191 で、0 までトランスポーズされます (したがって、実際の範囲は 0 ~ 16383 です)。この数値は 2 つの 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 bend
NSUInteger 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.0
AudioUnitParameterValue bendValue = 63 + 1 + (63 * ratio); // this is a CGFloat under the hood
AudioUnitSetParameter(self.samplerUnit,
kAUGroupParameterID_PitchBend,
kAudioUnitScope_Group,
0,
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 to
UInt32 status = 0xB0 | 0;
MusicDeviceMIDIEvent(self.samplerUnit, status, 0x64, 0x00, 0); // RPN pitch bend range.
MusicDeviceMIDIEvent(self.samplerUnit, status, 0x65, 0x00, 0);
MusicDeviceMIDIEvent(self.samplerUnit, status, 0x06, semitones, 0); // Data entry MSB
MusicDeviceMIDIEvent(self.samplerUnit, status, 0x26, cents, 0); // Data entry LSB (optional)
MusicDeviceMIDIEvent(self.samplerUnit, status, 0x64, 0x7F, 0); // RPN reset
MusicDeviceMIDIEvent(self.samplerUnit, status, 0x65, 0x7F, 0);
何が起こるか推測できますか?そうです、LSB メッセージは無視され、ピッチ ホイールの範囲は指定された半音数だけ変化します。
何が起きてる?これは Apple のバグですか、それとも何か不足していますか? (おそらく設定パラメータ?) それともバグではないのでしょうか? もしかしたら、Apple のシンセは設計上、そのレベルの詳細を持っていないのでしょうか? そういうのってMIDI規格で合法なの!? ヘルプ!
編集:
ピッチ ベンド レンジが 40 半音に設定されている場合、粗い変化ごとに聞き取れる違いが生じます。ピッチベンド範囲が 10 半音に設定されている場合、1 秒ごとの粗い変化だけが違いを生みます。2 半音 (デフォルト) では、違いを生むには 4 回以上の粗い変更が必要です。
言い換えれば、LSB が無視されているように見えるだけでなく、ピッチが変化する最小セント数があるように見えます。これらの制限のいずれかを修正できますか? そうでない場合、曲げの解像度が高い iOS 用のソフトウェア シンセ フレームワークはありますか?
うーん... kAudioUnitSubType_Varispeed または kAudioUnitSubType_NewTimePitch を適用すると、より良い結果が得られるかもしれません...