AudioTimeStamp format + 'MusicDeviceMIDIEvent' - PullRequest
6 голосов
/ 04 марта 2012

Могу ли я получить небольшую помощь с этим?

В тестовом проекте у меня есть AUSampler -> MixerUnit -> ioUnit и настроен обратный вызов рендеринга. Все работает Я использую метод MusicDeviceMIDIEvent, как определено в MusicDevice.h, для воспроизведения midi noteOn & noteOff. Таким образом, в коде хакерского теста ниже, noteOn происходит в течение .5 сек. каждые 2 секунды.

MusicDeviceMIDIEvent (ниже) принимает параметр: inOffsetSampleFrame, чтобы запланировать событие на будущее. То, что я хотел бы сделать, это сыграть noteOn и запланировать noteOff одновременно (без проверки времени взлома, которую я делаю ниже). Я просто не понимаю, каким должно быть значение inOffsetSampleFrame (например, чтобы воспроизвести ноту в 0,5 секунды или 0,2 секунды. (Другими словами, я не понимаю основы звуковой синхронизации ...).

Так что, если бы кто-то мог провести меня через арифметику, чтобы получить правильные значения из входящего AudioTimeStamp, это было бы здорово! Также, возможно, поправьте меня / уточните любой из этих:

  1. AudioTimeStamp->mSampleTime - sampleTime - время текущий образец "ломтик"? Это в миллисекундах?

  2. AudioTimeStamp->mHostTime -? host - компьютер, на котором запущено приложение, и это время (в миллисекундах?) с момента запуска компьютера? Это ОГРОМНОЕ число. Разве это не переворачивается, а затем вызывает проблемы?

  3. inNumberFrames - похоже, это 512 на iOS5 (устанавливается через kAudioUnitProperty_MaximumFramesPerSlice). Итак, образец сделан до 512 кадров?

  4. Я видел много предупреждений, чтобы не перегружать рендеринг. функция - в частности, чтобы избежать вызовов Objective C - я понимаю причина, но как тогда сообщать пользовательский интерфейс или делать другие обработка

Полагаю, все. Спасибо за терпение со мной!

inOffsetSampleFrame Если вы планируете MIDI-событие из потока рендеринга аудиоустройства, вы можете указать Смещение сэмпла, которое аудиоустройство может применить, применяя то событие в его следующем рендере аудиоустройства. Это позволяет вам планировать к образцу время, когда применяется команда MIDI, и особенно важно при запуске новых заметок. Если вы не планируете в потоке рендеринга аудиоустройства, тогда вы должны установить это значение на 0

// Функция MusicDeviceMIDIEvent def:

extern OSStatus
MusicDeviceMIDIEvent(   MusicDeviceComponent    inUnit,
                    UInt32                  inStatus,
                    UInt32                  inData1,
                    UInt32                  inData2,
                    UInt32                  inOffsetSampleFrame)

// мой обратный вызов

OSStatus  MyCallback(   void *                          inRefCon,
                 AudioUnitRenderActionFlags *   ioActionFlags,
                 const AudioTimeStamp *         inTimeStamp,
                 UInt32                         inBusNumber,
                 UInt32                         inNumberFrames,
                 AudioBufferList *              ioData)
{

Float64 sampleTime = inTimeStamp->mSampleTime;
UInt64 hostTime = inTimeStamp->mHostTime;

[(__bridge Audio*)inRefCon audioEvent:sampleTime andHostTime:hostTime];

return 1;
}  

// Метод OBJ-C

- (void)audioEvent:(Float64) sampleTime andHostTime:(UInt64)hostTime
{
OSStatus result = noErr;

Float64 nowTime = (sampleTime/self.graphSampleRate); // sample rate: 44100.0
if (nowTime - lastTime > 2) {

    UInt32 noteCommand =    kMIDIMessage_NoteOn << 4 | 0;
    result = MusicDeviceMIDIEvent (mySynthUnit, noteCommand, 60, 120, 0); 
    lastTime = sampleTime/self.graphSampleRate;
}

if (nowTime - lastTime > .5) {
    UInt32   noteCommand =  kMIDIMessage_NoteOff << 4 | 0;
    result = MusicDeviceMIDIEvent (mySynthUnit, noteCommand, 60, 0, 0);
}
}

1 Ответ

3 голосов
/ 16 апреля 2012

Ответ здесь заключается в том, что я неправильно понял цель inOffsetSampleFrame, несмотря на то, что она была названа удачно.Я подумал, что смогу использовать его для планирования события noteOff на какое-то произвольное время в будущем, поэтому мне не нужно было управлять noteOffs, но область его действия просто находится в текущем примере кадра.Ну хорошо.

...