Синтез MIDI в iOS неверный ход WRT изгиб тона: LSB игнорируется

Либо есть серьезная ошибка в коде синтеза MIDI от Apple, либо я делаю что-то неправильно. Вот мое понимание этого. Когда вы отправляете MIDI-команду изгиба высоты тона, диапазон изгиба составляет от -8192 до 8191, переносится до 0. (Так что фактический диапазон от 0 до 16383.) Это число разделено на два 7-битных поля, так что действительно это означает, что у вас есть 128 значений грубого контроля и 128 значений тонкого контроля.

Вот пример наклона высоты тона, который я написал, аналогично командам в LoadPresetDemo от Apple.

// '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); 

Когда bendMSB (грубое управление) изменяется, высота тона отличная. Но когда изменяется bendLSB (тонкий контроль), ничего не происходит. Другими словами, похоже, что MIDI-синтезатор Apple игнорирует 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 полутонов, разница в каждом втором грубом изменении. В 2 полутонах (по умолчанию) для внесения изменений требуется 4 или более грубых изменения.

Другими словами, не только LSB, очевидно, игнорируется, но также кажется, что минимальное количество центов для изменения высоты тона. Может ли быть зафиксировано одно из этих ограничений? И если нет, есть ли какие-либо программные синтезаторные рамки для iOS с более высоким разрешением сгиба?

Хм … возможно, применение kAudioUnitSubType_Varispeed или kAudioUnitSubType_NewTimePitch даст лучшие результаты …

Неправильное сообщение об изгибе тона. Вместо этого:

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

сделай это:

 UInt32 bendCommand = kMIDIMessage_PitchBend << 4 | 0; OSStatus result = MusicDeviceMIDIEvent(self.samplerUnit, bendCommand, bendLSB, bendMSB, 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, bendCommand, bendLSB, bendMSB, 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, 0x64, 0, 0); MusicDeviceMIDIEvent(self.samplerUnit, 0xB0, 0x65, 0, 0); MusicDeviceMIDIEvent(self.samplerUnit, 0xB0, 0x06, semitones, 0); MusicDeviceMIDIEvent(self.samplerUnit, 0xB0, 0x26, cents, 0); //The following two lines are not really necessary. They only matter if additional controller 0x06 or 0x26 messages are sent //MusicDeviceMIDIEvent(self.samplerUnit, 0xB0, 0x64, 0x7F, 0); //MusicDeviceMIDIEvent(self.samplerUnit, 0xB0, 0x65, 0x7F, 0); } 

Я создал три кнопки и назначил их bendDown: bendCenter: и bendUp:

Запустите программу и нажмите кнопку bendCenter . Затем, при выбранном звуке тромбона, нажмите и удерживайте кнопку «Mid Note». Удерживая эту кнопку, нажмите кнопки bendUp или bendDown . Я слышу изменения тона, когда LSB изменяется, и MSB остается неизменным.

  • Получить обратный вызов MusicSequence из воспроизведения MIDI
  • экспорт midi со звуковыми шрифтами на iOS
  • Получать уведомления, когда изменен MIDI-источник или источник
  • Проблемы с задержкой с MIDI Over Bluetooth
  • iOS записывает файл midi
  • Parse Midi Packet в iOS
  • Изменить подпись времени в MusicSequence
  • ios - смешивание файлов midi, каждый со своим звуковым шрифтом
  • Как увеличить громкость / усиление MIDI-синтезатора без искажений в iOS?
  • Как конвертировать Midi Time Code в фактическое время с помощью CoreMidi
  • Чтение файлов Midi на IOS
  • Давайте будем гением компьютера.