объяснить какой-нибудь простой C-битный код? - PullRequest
1 голос
/ 02 февраля 2012

Мне нужна помощь в понимании простого сдвига C на исходном коде Apple / iOS LoadPresetDemo.Это очень просто, но для обеспечения контекста потребуется много места, поэтому спасибо за терпение.

Я пытаюсь понять, почему программист использует эту строку:

UInt32 noteCommand =  kMIDIMessage_NoteOn << 4 | 0;

Программист определил константы в другом месте кода (ниже).Когда я достаю свой калькулятор и ввожу 0x9 и сдвигаю его влево на 4 позиции, я получаю 0x90.Я вставил это число в код вместо строки над кодом, работает нормально, поэтому я в замешательстве.Мои два вопроса:

  1. Почему программист просто не определил константу как 0x90 ?

  2. Какова цель оператора ИЛИ в приведенном выше коде?

Я знаю, что это маленький,глупая деталь, но я хотел бы знать, есть ли за этим веская причина, и немного лучше понять битшифтинг (не каламбур ...).Полный метод и детали ниже.- Спасибо !

// some MIDI constants:
enum {
   kMIDIMessage_NoteOn    = 0x9,
   kMIDIMessage_NoteOff   = 0x8,
};



// Play the mid note
- (IBAction) startPlayMidNote:(id)sender {

    UInt32 noteNum = kMidNote;
    UInt32 onVelocity = 127;
    UInt32 noteCommand =  kMIDIMessage_NoteOn << 4 | 0;

      OSStatus result = noErr;
    require_noerr (result = MusicDeviceMIDIEvent(self.samplerUnit, noteCommand, noteNum, onVelocity, 0), logTheError);

logTheError:
   if (result != noErr) NSLog (@"Unable to start playing the mid note. Error code: %d '%.4s'\n", (int) result, (const char *)&result);
}


// Stop the mid note
  - (IBAction) stopPlayMidNote:(id)sender {

    UInt32 noteNum = kMidNote;
    UInt32 noteCommand =    kMIDIMessage_NoteOff << 4 | 0;

    OSStatus result = noErr;
    require_noerr (result = MusicDeviceMIDIEvent(self.samplerUnit, noteCommand, noteNum, 0, 0), logTheError);

 logTheError:
    if (result != noErr) NSLog (@"Unable to stop playing the mid note. Error code: %d '%.4s'\n", (int) result, (const char *)&result);
}


/*!
@function   MusicDeviceMIDIEvent
@abstract   Used to sent MIDI channel messages to an audio unit

@discussion This is the API used to send MIDI channel messages to an audio unit. The status and data parameters 
            are used exactly as described by the MIDI specification, including the combination of channel and 
            command in the status byte.

@param          inUnit
            The audio unit
@param          inStatus
            The MIDI status byte
@param          inData1
            The first MIDI data byte (value is in the range 0 < 128)
@param          inData2
            The second MIDI data byte (value is in the range 0 < 128). If the MIDI status byte only has one 
                data byte, this should be set to zero.
@param          inOffsetSampleFrame
            If you are scheduling the MIDI Event from the audio unit's render thread, then you can supply a 
                sample offset that the audio unit may apply when applying that event in its next audio unit render. 
                This allows you to schedule to the sample, the time when a MIDI command is applied and is particularly 
                important when starting new notes. If you are not scheduling in the audio unit's render thread, 
                then you should set this value to 0

@result         noErr, or an audio unit error code
*/
extern OSStatus
MusicDeviceMIDIEvent(   MusicDeviceComponent    inUnit,
                    UInt32                    inStatus,
                    UInt32                  inData1,
                    UInt32                  inData2,
                    UInt32                  inOffsetSampleFrame)                __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_5_0);

Ответы [ 5 ]

7 голосов
/ 02 февраля 2012

Причина, по которой автор написал код таким способом, скорее всего облегчит его понимание.Коды событий MIDI разделены на 2 части, где верхние 4 бита - это событие, а нижние 4 бита - номер канала.Показав вам константу, сдвинутую влево на 4 бита и присвоившую значение «0», он показал, что событие MIDI использовало эту константу в качестве кода события на канале 0.

1 голос
/ 10 марта 2012

Добавление деталей для полноты.

Цель сдвига битов состоит в том, чтобы иметь возможность указать канал

UInt32 noteCommand = kMIDIMessage_NoteOn << 4 | 0;

выход: 144

UInt32 noteCommand = kMIDIMessage_NoteOn << 4 | 1;

выход: 145

и т. Д.

1 голос
/ 02 февраля 2012

Я не уверен, что битовое ИЛИ с нулем будет выполнять что-либо, кроме неявного преобразования в int.Я подозреваю, что именно поэтому есть ИЛИ, IIRC, смещение битов на значение enum в любом случае приведет к int ...

Причиной определения констант как 0x9 и сдвигаэти четыре бита вместо использования 0x90, вероятно, имеют отношение к константам, полученным из спецификации API, документа протокола по проводному соединению или чего-то подобного.Сдвиг битов также ограничивает размер эффективного размера константы.В этом случае он будет сокращен до 28 бит, я считаю.

0 голосов
/ 02 февраля 2012
Сдвиг

- это быстрый способ умножения (сдвиг влево) или деления (сдвиг вправо) на 2 (в вашем случае четыре раза).

битовые операции могут быть полезны, когда вы хотите хранить биты состояния (флаги) в небольшом пространстве. в этом случае, возможно, перечисления являются константами из библиотеки, которые он не может изменить.

ИЛИ с 0 не имеет смысла для меня, если только он не хотел очистить бит переполнения, если таковой имеется?

0 голосов
/ 02 февраля 2012

Я не знаком с Objective-C, но я предполагаю, что ИЛИ с 0 столь же бесполезен в Objective-C, как и в обычном C.1003 * совпадает с kMIDIMessage_NoteOff << 4 - оригинальный программист, вероятно, просто забыл удалить его, по любой причине.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...