Формат AudioTimeStamp + 'MusicDeviceMIDIEvent'

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

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

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

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

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

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

  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);
}
}
6
задан No Grabbing 7 March 2012 в 06:53
поделиться