| @@ -293,21 +293,28 @@ OSStatus JackCoreAudioAdapter::Render(void *inRefCon, | |||||
| UInt32 inNumberFrames, | UInt32 inNumberFrames, | ||||
| AudioBufferList *ioData) | 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) { | 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; | 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; | return noErr; | ||||
| } else { | } else { | ||||
| return err; | return err; | ||||
| @@ -142,6 +142,11 @@ class JackCoreAudioAdapter : public JackAudioAdapterInterface | |||||
| int GetLatency(int port_index, bool input); | int GetLatency(int port_index, bool input); | ||||
| OSStatus GetStreamLatencies(AudioDeviceID device, bool isInput, vector<int>& latencies); | OSStatus GetStreamLatencies(AudioDeviceID device, bool isInput, vector<int>& latencies); | ||||
| OSStatus Render(AudioUnitRenderActionFlags *ioActionFlags, | |||||
| const AudioTimeStamp *inTimeStamp, | |||||
| UInt32 inNumberFrames, | |||||
| AudioBufferList *ioData); | |||||
| public: | public: | ||||
| @@ -283,32 +283,36 @@ OSStatus JackCoreAudioDriver::Render(void* inRefCon, | |||||
| UInt32 inNumberFrames, | UInt32 inNumberFrames, | ||||
| AudioBufferList* ioData) | 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... | // Setup threaded based log function et get RT thread parameters once... | ||||
| if (set_threaded_log_function()) { | if (set_threaded_log_function()) { | ||||
| jack_log("JackCoreAudioDriver::Render : 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... | // 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"); | 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); | kill(JackTools::GetPID(), SIGINT); | ||||
| return kAudioHardwareUnsupportedOperationError; | return kAudioHardwareUnsupportedOperationError; | ||||
| } else { | } else { | ||||
| @@ -165,6 +165,7 @@ class JackCoreAudioDriver : public JackAudioDriver | |||||
| void UpdateLatencies(); | void UpdateLatencies(); | ||||
| bool IsDigitalDevice(AudioDeviceID device); | bool IsDigitalDevice(AudioDeviceID device); | ||||
| OSStatus Render(AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp, AudioBufferList* ioData); | |||||
| public: | public: | ||||
| @@ -30,8 +30,7 @@ namespace Jack | |||||
| PaStreamCallbackFlags statusFlags, | PaStreamCallbackFlags statusFlags, | ||||
| void* userData) | 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; | return paContinue; | ||||
| } | } | ||||
| @@ -40,11 +40,13 @@ int JackPortAudioDriver::Render(const void* inputBuffer, void* outputBuffer, | |||||
| PaStreamCallbackFlags statusFlags, | PaStreamCallbackFlags statusFlags, | ||||
| void* userData) | 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) { | ||||
| if (statusFlags & paOutputUnderflow) | if (statusFlags & paOutputUnderflow) | ||||
| @@ -60,14 +62,14 @@ int JackPortAudioDriver::Render(const void* inputBuffer, void* outputBuffer, | |||||
| if (statusFlags != paPrimingOutput) { | if (statusFlags != paPrimingOutput) { | ||||
| jack_time_t cur_time = GetMicroSeconds(); | 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(); | set_threaded_log_function(); | ||||
| driver->CycleTakeBeginTime(); | |||||
| return (driver->Process() == 0) ? paContinue : paAbort; | |||||
| CycleTakeBeginTime(); | |||||
| return (Process() == 0) ? paContinue : paAbort; | |||||
| } | } | ||||
| int JackPortAudioDriver::Read() | int JackPortAudioDriver::Read() | ||||
| @@ -51,6 +51,7 @@ class JackPortAudioDriver : public JackMMCSS, public JackAudioDriver | |||||
| PaError OpenStream(jack_nframes_t buffer_size); | PaError OpenStream(jack_nframes_t buffer_size); | ||||
| void UpdateLatencies(); | void UpdateLatencies(); | ||||
| int Render(const void* inputBuffer, void* outputBuffer, PaStreamCallbackFlags statusFlags); | |||||
| public: | public: | ||||