Правильное использование MIDIPacketListAdd (CoreMIDI)

Я пытаюсь использовать MIDIPacketListAdd CoreAudio, делая это (на Mac):

MIDIPacketListAdd(packetList, PACKETLIST_SIZE, currentPacket, mach_absolute_time, len, data);

Я думал о вызове метода несколько раз перед его отправкой, чтобы в моем списке пакетов был> 1 пакет. Однако, когда я это делаю, количество пакетов никогда не увеличивается, и я получаю пакетList->packet[0] с постоянно увеличивающимся пакетом[0].data.

1) Как правильно использовать этот метод? Я просмотрел несколько примеров, в том числе пример из «Learning Core Audio» — похоже, все они отправляют только один пакет.

2) Есть ли улучшение производительности, если я упакую несколько пакетов в 1 список пакетов по сравнению с отправкой 1 списка пакетов с 1 пакетом несколько раз?

Спасибо, ценю любую помощь по этому поводу.

Изменить для продолжения: вот как я запускаю список пакетов

#define PACKETLIST_SIZE 512

- (void) initPacketList {

    if (packetList) {
        free(packetList);
        packetList = NULL;
    }

    packetList = (MIDIPacketList *)malloc(PACKETLIST_SIZE * sizeof(char));
    currentPacket = MIDIPacketListInit(packetList);
}

- (void) clearPacketList {

    packetList->numPackets = 0;
        currentPacket = MIDIPacketListInit(packetList);
}

- (void) addPacketToPacketList:(Byte*) data ofLength:(int) len {

    NSLog(@"length %d", len); 
    //NSLog(@"%lld", mach_absolute_time());
    currentPacket = MIDIPacketListAdd(packetList, PACKETLIST_SIZE, currentPacket, mach_absolute_time, len, data);

    //if (!currentPacket) exit(1);

}

person lppier    schedule 10.04.2013    source источник


Ответы (1)


Ответ находится в документации для MIDIPacketListAdd.

Возвращаемое значение

Возвращает null, если в пакете не было места для события; в противном случае возвращает указатель пакета, который следует передать как curPacket при последующем вызове этой функции.

Итак, вы, вероятно, хотите что-то вроде:

currentPacket = MIDIPacketListAdd(packetList, PACKETLIST_SIZE, currentPacket, mach_absolute_time, len, data);

Обязательно проверяйте, является ли currentPacket NULL после каждого раза.

Производительность должна быть выше, если вы поместите несколько пакетов в один список пакетов, так как вы делаете меньше межпроцессных запросов к MIDI-серверу, но, честно говоря, это вряд ли будет заметно на современном Mac.

Изменить: вот что вы делаете неправильно.

packetList = (MIDIPacketList *)malloc(PACKETLIST_SIZE * sizeof(char));

sizeof(char) всегда равно 1 в языке C по определению. malloc(PACKETLIST_SIZE) это все, что вам нужно.

currentPacket = MIDIPacketListAdd(packetList, PACKETLIST_SIZE, currentPacket, mach_absolute_time, len, data);

Это дало мне предупреждение компилятора, потому что вы передаете адрес функции mach_absolute_time, а не вызываете функцию. Вы имели в виду:

currentPacket = MIDIPacketListAdd(packetList, PACKETLIST_SIZE, currentPacket, mach_absolute_time(), len, data);

Как только я это сделал, я увидел увеличение на packetList->numPackets, как и ожидалось.

Однако обратите внимание на две вещи:

  • Если вы хотите отправить MIDI-данные немедленно, просто укажите временную метку 0.

  • Если вы вызываете MIDIPacketListAdd с той же отметкой времени, что и предыдущий вызов, то он просто объединяет ваши данные с предыдущим пакетом. Вы увидите, что packetList->numPackets и currentPacket останутся прежними, но currentPacket->length увеличится.

Вот почему вы не видели увеличения packetList->numPackets: адрес mach_absolute_time является константой, поэтому ваша временная метка каждый раз была одинаковой.

person Kurt Revis    schedule 10.04.2013
comment
привет Курт, я делаю именно так, как описано выше, но мои данные все еще запихиваются в один пакет, когда я проверяю его с помощью отладчика. packageList-›packet[0]-›data становится длиннее, когда следующий фрагмент данных должен быть в следующем пакете package[1]. - person lppier; 11.04.2013
comment
Другой вопрос: если размер моего packageList->packet[0]->data составляет, скажем, 9 байт, будут ли последние 6 байт игнорироваться синтезатором/виртуальным инструментом, на который я их отправляю? - person lppier; 11.04.2013
comment
Отладчик вводит вас в заблуждение. MIDIPacket — это структура переменной длины — она имеет 6 байтов заголовка (4 байта timeStamp, 2 байта length), а затем от 1 до 65535 байтов данных. MIDIPacketList — это всего лишь один или несколько MIDIPackets, хранящихся в памяти последовательно. Проблема в том, что вы не можете реально представить структуры переменной длины в C. Таким образом, вы не можете сказать packet[1], чтобы перейти ко второму пакету — ни компилятор, ни отладчик не сделают правильную вещь. Используйте MIDIPacketListNext или посмотрите непосредственно на необработанную память. - person Kurt Revis; 11.04.2013
comment
Кроме того, length вашего пакета должен точно соответствовать длине данных, которые вы хотите отправить. Если вы хотите, чтобы он отправил 3 байта, длина должна быть 3. Я понятия не имею, почему вы установили его на 9, а затем добавили 6 дополнительных байтов мусора. CoreMIDI (вероятно) отправит его как есть, но если это недопустимый MIDI, приемник может сделать что угодно. - person Kurt Revis; 11.04.2013
comment
Ах, я с.. еще одна вещь, которую я нахожу странной. Несмотря на то, что я вызываю currentPacket = MIDIPacketListAdd(packetList, PACKETLIST_SIZE, currentPacket, mach_absolute_time, len, data) 3 раза перед отправкой списка пакетов, список пакетов-›numPackets по-прежнему равен 1 каждый раз, когда я его печатаю. Это что-то, что я обновляю сам? - person lppier; 11.04.2013
comment
Я не устанавливаю длину пакета на › 3.len в MIDIPacketListAdd всегда равно 3. Извините, что ввел вас в заблуждение, когда я сказал 9, я имел в виду значение, которое я видел в отладчике. - person lppier; 11.04.2013
comment
packetList->numPackets должно увеличиваться на 1 после каждого вызова MIDIPacketListAdd. Вы уверены, что PACKETLIST_SIZE достаточно велико? Если он слишком мал, то один из вызовов MIDIPacketListAdd потерпит неудачу, оставит список пакетов без изменений и вернет NULL. - person Kurt Revis; 11.04.2013
comment
Привет, Курт, я обновил свой вопрос, добавив больше кода. PACKETLIST_SIZE равен 512. Я делаю что-то не так в своем коде? - person lppier; 11.04.2013
comment
Попробовал ваш код и отредактировал. Я забыл, что произошло, когда вы указали ту же метку времени для последующих вызовов MIDIPacketListAdd. - person Kurt Revis; 11.04.2013
comment
Действительно работает - большое спасибо за помощь! Ты бог миди! XD Простите меня за ошибки новичка... - person lppier; 11.04.2013