| @@ -293,21 +293,28 @@ OSStatus JackCoreAudioAdapter::Render(void *inRefCon, | |||
| UInt32 inNumberFrames, | |||
| AudioBufferList *ioData) | |||
| { | |||
| JackCoreAudioAdapter* adapter = static_cast<JackCoreAudioAdapter*>(inRefCon); | |||
| OSStatus err = AudioUnitRender(adapter->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, adapter->fInputData); | |||
| return static_cast<JackCoreAudioAdapter*>(inRefCon)->Render(ioActionFlags, inTimeStamp, inNumberFrames, ioData); | |||
| } | |||
| OSStatus JackCoreAudioAdapter::Render(AudioUnitRenderActionFlags *ioActionFlags, | |||
| const AudioTimeStamp *inTimeStamp, | |||
| UInt32 inNumberFrames, | |||
| AudioBufferList *ioData) | |||
| { | |||
| OSStatus err = AudioUnitRender(fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, fInputData); | |||
| if (err == noErr) { | |||
| jack_default_audio_sample_t* inputBuffer[adapter->fCaptureChannels]; | |||
| jack_default_audio_sample_t* outputBuffer[adapter->fPlaybackChannels]; | |||
| jack_default_audio_sample_t* inputBuffer[fCaptureChannels]; | |||
| jack_default_audio_sample_t* outputBuffer[fPlaybackChannels]; | |||
| for (int i = 0; i < adapter->fCaptureChannels; i++) { | |||
| inputBuffer[i] = (jack_default_audio_sample_t*)adapter->fInputData->mBuffers[i].mData; | |||
| for (int i = 0; i < fCaptureChannels; i++) { | |||
| inputBuffer[i] = (jack_default_audio_sample_t*)fInputData->mBuffers[i].mData; | |||
| } | |||
| for (int i = 0; i < adapter->fPlaybackChannels; i++) { | |||
| for (int i = 0; i < fPlaybackChannels; i++) { | |||
| outputBuffer[i] = (jack_default_audio_sample_t*)ioData->mBuffers[i].mData; | |||
| } | |||
| adapter->PushAndPull((jack_default_audio_sample_t**)inputBuffer, (jack_default_audio_sample_t**)outputBuffer, inNumberFrames); | |||
| PushAndPull((jack_default_audio_sample_t**)inputBuffer, (jack_default_audio_sample_t**)outputBuffer, inNumberFrames); | |||
| return noErr; | |||
| } else { | |||
| return err; | |||
| @@ -142,6 +142,11 @@ class JackCoreAudioAdapter : public JackAudioAdapterInterface | |||
| int GetLatency(int port_index, bool input); | |||
| OSStatus GetStreamLatencies(AudioDeviceID device, bool isInput, vector<int>& latencies); | |||
| OSStatus Render(AudioUnitRenderActionFlags *ioActionFlags, | |||
| const AudioTimeStamp *inTimeStamp, | |||
| UInt32 inNumberFrames, | |||
| AudioBufferList *ioData); | |||
| public: | |||
| @@ -283,32 +283,36 @@ OSStatus JackCoreAudioDriver::Render(void* inRefCon, | |||
| UInt32 inNumberFrames, | |||
| AudioBufferList* ioData) | |||
| { | |||
| JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inRefCon; | |||
| driver->fActionFags = ioActionFlags; | |||
| driver->fCurrentTime = inTimeStamp; | |||
| driver->fDriverOutputData = ioData; | |||
| return static_cast<JackCoreAudioDriver*>(inRefCon)->Render(ioActionFlags, inTimeStamp, ioData); | |||
| } | |||
| OSStatus JackCoreAudioDriver::Render(AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp, AudioBufferList* ioData) | |||
| { | |||
| fActionFags = ioActionFlags; | |||
| fCurrentTime = inTimeStamp; | |||
| fDriverOutputData = ioData; | |||
| // Setup threaded based log function et get RT thread parameters once... | |||
| if (set_threaded_log_function()) { | |||
| jack_log("JackCoreAudioDriver::Render : set_threaded_log_function"); | |||
| JackMachThread::GetParams(pthread_self(), &driver->fEngineControl->fPeriod, &driver->fEngineControl->fComputation, &driver->fEngineControl->fConstraint); | |||
| JackMachThread::GetParams(pthread_self(), &fEngineControl->fPeriod, &fEngineControl->fComputation, &fEngineControl->fConstraint); | |||
| if (driver->fComputationGrain > 0) { | |||
| jack_log("JackCoreAudioDriver::Render : RT thread computation setup to %d percent of period", int(driver->fComputationGrain * 100)); | |||
| driver->fEngineControl->fComputation = driver->fEngineControl->fPeriod * driver->fComputationGrain; | |||
| if (fComputationGrain > 0) { | |||
| jack_log("JackCoreAudioDriver::Render : RT thread computation setup to %d percent of period", int(fComputationGrain * 100)); | |||
| fEngineControl->fComputation = fEngineControl->fPeriod * fComputationGrain; | |||
| } | |||
| } | |||
| // Signal waiting start function... | |||
| driver->fState = true; | |||
| fState = true; | |||
| driver->CycleTakeBeginTime(); | |||
| CycleTakeBeginTime(); | |||
| if (driver->Process() < 0) { | |||
| if (Process() < 0) { | |||
| jack_error("Process error, stopping driver"); | |||
| driver->NotifyFailure(JackBackendError, "Process error, stopping driver"); // Message length limited to JACK_MESSAGE_SIZE | |||
| driver->Stop(); | |||
| NotifyFailure(JackBackendError, "Process error, stopping driver"); // Message length limited to JACK_MESSAGE_SIZE | |||
| Stop(); | |||
| kill(JackTools::GetPID(), SIGINT); | |||
| return kAudioHardwareUnsupportedOperationError; | |||
| } else { | |||
| @@ -165,6 +165,7 @@ class JackCoreAudioDriver : public JackAudioDriver | |||
| void UpdateLatencies(); | |||
| bool IsDigitalDevice(AudioDeviceID device); | |||
| OSStatus Render(AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp, AudioBufferList* ioData); | |||
| public: | |||
| @@ -30,8 +30,7 @@ namespace Jack | |||
| PaStreamCallbackFlags statusFlags, | |||
| void* userData) | |||
| { | |||
| JackPortAudioAdapter* adapter = static_cast<JackPortAudioAdapter*>(userData); | |||
| adapter->PushAndPull((jack_default_audio_sample_t**)inputBuffer, (jack_default_audio_sample_t**)outputBuffer, framesPerBuffer); | |||
| static_cast<JackPortAudioAdapter*>(userData)->PushAndPull((jack_default_audio_sample_t**)inputBuffer, (jack_default_audio_sample_t**)outputBuffer, framesPerBuffer); | |||
| return paContinue; | |||
| } | |||
| @@ -40,11 +40,13 @@ int JackPortAudioDriver::Render(const void* inputBuffer, void* outputBuffer, | |||
| PaStreamCallbackFlags statusFlags, | |||
| void* userData) | |||
| { | |||
| JackPortAudioDriver* driver = (JackPortAudioDriver*)userData; | |||
| driver->fInputBuffer = (jack_default_audio_sample_t**)inputBuffer; | |||
| driver->fOutputBuffer = (jack_default_audio_sample_t**)outputBuffer; | |||
| return static_cast<JackPortAudioDriver*>(userData)->Render(inputBuffer, outputBuffer, statusFlags); | |||
| } | |||
| //MMCSSAcquireRealTime(GetCurrentThread()); | |||
| int JackPortAudioDriver::Render(const void* inputBuffer, void* outputBuffer, PaStreamCallbackFlags statusFlags) | |||
| { | |||
| fInputBuffer = (jack_default_audio_sample_t**)inputBuffer; | |||
| fOutputBuffer = (jack_default_audio_sample_t**)outputBuffer; | |||
| if (statusFlags) { | |||
| if (statusFlags & paOutputUnderflow) | |||
| @@ -60,14 +62,14 @@ int JackPortAudioDriver::Render(const void* inputBuffer, void* outputBuffer, | |||
| if (statusFlags != paPrimingOutput) { | |||
| jack_time_t cur_time = GetMicroSeconds(); | |||
| driver->NotifyXRun(cur_time, float(cur_time - driver->fBeginDateUst)); // Better this value than nothing... | |||
| NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... | |||
| } | |||
| } | |||
| // Setup threadded based log function | |||
| // Setup threaded based log function | |||
| set_threaded_log_function(); | |||
| driver->CycleTakeBeginTime(); | |||
| return (driver->Process() == 0) ? paContinue : paAbort; | |||
| CycleTakeBeginTime(); | |||
| return (Process() == 0) ? paContinue : paAbort; | |||
| } | |||
| int JackPortAudioDriver::Read() | |||
| @@ -51,6 +51,7 @@ class JackPortAudioDriver : public JackMMCSS, public JackAudioDriver | |||
| PaError OpenStream(jack_nframes_t buffer_size); | |||
| void UpdateLatencies(); | |||
| int Render(const void* inputBuffer, void* outputBuffer, PaStreamCallbackFlags statusFlags); | |||
| public: | |||