git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4372 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.9.8
| @@ -0,0 +1,80 @@ | |||
| /* | |||
| Copyright (C) 2004-2008 Grame | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU Lesser General Public License as published by | |||
| the Free Software Foundation; either version 2.1 of the License, or | |||
| (at your option) any later version. | |||
| This program is distributed in the hope that it will be useful, | |||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| GNU Lesser General Public License for more details. | |||
| You should have received a copy of the GNU Lesser General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| #include "JackMMCSS.h" | |||
| #include "JackError.h" | |||
| #include <assert.h> | |||
| #include <stdio.h> | |||
| namespace Jack | |||
| { | |||
| avSetMmThreadCharacteristics JackMMCSS::ffMMCSSFun1 = NULL; | |||
| avSetMmThreadPriority JackMMCSS::ffMMCSSFun2 = NULL; | |||
| avRevertMmThreadCharacteristics JackMMCSS::ffMMCSSFun3 = NULL; | |||
| JACK_HANDLE JackMMCSS::fAvrtDll; | |||
| std::map<jack_native_thread_t, HANDLE> JackMMCSS::fHandleTable; | |||
| JackMMCSS::JackMMCSS() | |||
| { | |||
| fAvrtDll = LoadJackModule("avrt.dll"); | |||
| if (fAvrtDll != NULL) { | |||
| ffMMCSSFun1 = (avSetMmThreadCharacteristics)GetJackProc(fAvrtDll, "AvSetMmThreadCharacteristicsA"); | |||
| ffMMCSSFun2 = (avSetMmThreadPriority)GetJackProc(fAvrtDll, "AvSetMmThreadPriority"); | |||
| ffMMCSSFun3 = (avRevertMmThreadCharacteristics)GetJackProc(fAvrtDll, "AvRevertMmThreadCharacteristics"); | |||
| } | |||
| } | |||
| JackMMCSS::~JackMMCSS() | |||
| {} | |||
| int JackMMCSS::MMCSSAcquireRealTime(jack_native_thread_t thread) | |||
| { | |||
| if (fHandleTable.find(thread) != fHandleTable.end()) { | |||
| return 0; | |||
| } | |||
| if (ffMMCSSFun1) { | |||
| DWORD dummy = 0; | |||
| HANDLE task = ffMMCSSFun1("Pro Audio", &dummy); | |||
| if (task == NULL) { | |||
| jack_error("Cannot use MMCSS %d", GetLastError()); | |||
| } else if (ffMMCSSFun2(task, AVRT_PRIORITY_CRITICAL)) { | |||
| fHandleTable[thread] = task; | |||
| return 0; | |||
| } | |||
| } | |||
| return -1; | |||
| } | |||
| int JackMMCSS::MMCSSDropRealTime(jack_native_thread_t thread) | |||
| { | |||
| if (fHandleTable.find(thread) != fHandleTable.end()) { | |||
| HANDLE task = fHandleTable[thread]; | |||
| ffMMCSSFun3(task); | |||
| return 0; | |||
| } else { | |||
| return -1; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,72 @@ | |||
| /* | |||
| Copyright (C) 2004-2008 Grame | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU Lesser General Public License as published by | |||
| the Free Software Foundation; either version 2.1 of the License, or | |||
| (at your option) any later version. | |||
| This program is distributed in the hope that it will be useful, | |||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| GNU Lesser General Public License for more details. | |||
| You should have received a copy of the GNU Lesser General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| #ifndef __JackMMCSS__ | |||
| #define __JackMMCSS__ | |||
| #include "JackSystemDeps.h" | |||
| #include "JackCompilerDeps.h" | |||
| #include <windows.h> | |||
| #include <map> | |||
| namespace Jack | |||
| { | |||
| typedef enum _AVRT_PRIORITY { | |||
| AVRT_PRIORITY_LOW = -1, | |||
| AVRT_PRIORITY_NORMAL, /* 0 */ | |||
| AVRT_PRIORITY_HIGH, /* 1 */ | |||
| AVRT_PRIORITY_CRITICAL /* 2 */ | |||
| } AVRT_PRIORITY, *PAVRT_PRIORITY; | |||
| typedef HANDLE (WINAPI *avSetMmThreadCharacteristics)(LPCTSTR, LPDWORD); | |||
| typedef BOOL (WINAPI *avRevertMmThreadCharacteristics)(HANDLE); | |||
| typedef BOOL (WINAPI *avSetMmThreadPriority)(HANDLE, AVRT_PRIORITY); | |||
| /*! | |||
| \brief MMCSS services. | |||
| */ | |||
| class SERVER_EXPORT JackMMCSS | |||
| { | |||
| private: | |||
| static JACK_HANDLE fAvrtDll; | |||
| static avSetMmThreadCharacteristics ffMMCSSFun1; | |||
| static avSetMmThreadPriority ffMMCSSFun2; | |||
| static avRevertMmThreadCharacteristics ffMMCSSFun3; | |||
| static std::map<jack_native_thread_t, HANDLE> fHandleTable; | |||
| public: | |||
| JackMMCSS(); | |||
| ~JackMMCSS(); | |||
| static int MMCSSAcquireRealTime(jack_native_thread_t thread); | |||
| static int MMCSSDropRealTime(jack_native_thread_t thread); | |||
| }; | |||
| } // end of namespace | |||
| #endif | |||
| @@ -17,11 +17,12 @@ | |||
| */ | |||
| #include "JackWinThread.h" | |||
| #include "JackError.h" | |||
| #include "JackTime.h" | |||
| #include <avrt.h> | |||
| #include <assert.h> | |||
| #include <stdio.h> | |||
| namespace Jack | |||
| { | |||
| @@ -55,7 +56,7 @@ DWORD WINAPI JackWinThread::ThreadHandler(void* arg) | |||
| } | |||
| JackWinThread::JackWinThread(JackRunnableInterface* runnable) | |||
| : JackThreadInterface(runnable, 0, false, 0) | |||
| : JackMMCSS(), JackThreadInterface(runnable, 0, false, 0) | |||
| { | |||
| fEvent = CreateEvent(NULL, FALSE, FALSE, NULL); | |||
| fThread = (HANDLE)NULL; | |||
| @@ -202,11 +203,17 @@ int JackWinThread::AcquireRealTimeImp(jack_native_thread_t thread, int priority) | |||
| { | |||
| jack_log("JackWinThread::AcquireRealTimeImp priority = %d", THREAD_PRIORITY_TIME_CRITICAL); | |||
| if (SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL)) { | |||
| if (priority >= 90 && MMCSSAcquireRealTime(thread) == 0) { | |||
| jack_info("MMCSS API used to acquire RT for thread: %x", thread); | |||
| return 0; | |||
| } else { | |||
| jack_error("Cannot set thread priority = %d", GetLastError()); | |||
| return -1; | |||
| jack_info("MMCSS API not used..."); | |||
| if (SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL)) { | |||
| return 0; | |||
| } else { | |||
| jack_error("Cannot set thread priority = %d", GetLastError()); | |||
| return -1; | |||
| } | |||
| } | |||
| } | |||
| @@ -222,7 +229,10 @@ int JackWinThread::DropSelfRealTime() | |||
| int JackWinThread::DropRealTimeImp(jack_native_thread_t thread) | |||
| { | |||
| if (SetThreadPriority(thread, THREAD_PRIORITY_NORMAL)) { | |||
| if (MMCSSDropRealTime(thread) == 0 ) { | |||
| jack_info("MMCSS API used to drop RT for thread: %x", thread); | |||
| return 0; | |||
| } else if (SetThreadPriority(thread, THREAD_PRIORITY_NORMAL)) { | |||
| return 0; | |||
| } else { | |||
| jack_error("Cannot set thread priority = %d", GetLastError()); | |||
| @@ -17,15 +17,15 @@ | |||
| */ | |||
| #ifndef __JackWinThread__ | |||
| #define __JackWinThread__ | |||
| #include "JackThread.h" | |||
| #include "JackMMCSS.h" | |||
| #include "JackCompilerDeps.h" | |||
| #include "JackSystemDeps.h" | |||
| #include <windows.h> | |||
| #include <map> | |||
| namespace Jack | |||
| { | |||
| @@ -36,7 +36,7 @@ typedef DWORD (WINAPI *ThreadCallback)(void *arg); | |||
| \brief Windows threads. | |||
| */ | |||
| class SERVER_EXPORT JackWinThread : public detail::JackThreadInterface | |||
| class SERVER_EXPORT JackWinThread : public JackMMCSS, public detail::JackThreadInterface | |||
| { | |||
| private: | |||
| @@ -1,7 +1,7 @@ | |||
| <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> | |||
| <CodeBlocks_workspace_file> | |||
| <Workspace title="jack"> | |||
| <Project filename="libjackserver.cbp" /> | |||
| <Project filename="libjackserver.cbp" active="1" /> | |||
| <Project filename="jack_portaudio.cbp" /> | |||
| <Project filename="jack_netdriver.cbp" /> | |||
| <Project filename="jack_netonedriver.cbp" /> | |||
| @@ -18,7 +18,7 @@ | |||
| <Project filename="jack_disconnect.cbp" /> | |||
| <Project filename="jack_test.cbp" /> | |||
| <Project filename="multiple_metro.cbp" /> | |||
| <Project filename="jack_winmme.cbp" active="1" /> | |||
| <Project filename="jack_winmme.cbp" /> | |||
| <Project filename="jack_loopback.cbp" /> | |||
| <Project filename="jackd.cbp" /> | |||
| <Project filename="jack_midi_latency_test.cbp" /> | |||
| @@ -133,7 +133,7 @@ | |||
| <Add library="odbccp32" /> | |||
| </Linker> | |||
| </Target> | |||
| <Target title="Win32 Release 32bits"> | |||
| <Target title="Win32 Release 32bits"> | |||
| <Option output="Release\bin\libjack" prefix_auto="1" extension_auto="1" /> | |||
| <Option object_output="Release" /> | |||
| <Option type="3" /> | |||
| @@ -143,7 +143,7 @@ | |||
| <Compiler> | |||
| <Add option="-O2" /> | |||
| <Add option="-Wall" /> | |||
| <Add option="-m32" /> | |||
| <Add option="-m32" /> | |||
| <Add option="-DWIN32" /> | |||
| <Add option="-DNDEBUG" /> | |||
| <Add option="-D_WINDOWS" /> | |||
| @@ -162,7 +162,7 @@ | |||
| <Add directory="tre-0.8.0\lib" /> | |||
| </Compiler> | |||
| <Linker> | |||
| <Add option="-m32" /> | |||
| <Add option="-m32" /> | |||
| <Add library="kernel32" /> | |||
| <Add library="user32" /> | |||
| <Add library="gdi32" /> | |||
| @@ -176,7 +176,7 @@ | |||
| <Add library="odbc32" /> | |||
| <Add library="odbccp32" /> | |||
| </Linker> | |||
| <ExtraCommands> | |||
| <ExtraCommands> | |||
| <Add before="windres -F pe-i386 -O coff -o Release/libjack.res libjack.rc" /> | |||
| </ExtraCommands> | |||
| </Target> | |||
| @@ -190,7 +190,7 @@ | |||
| <Compiler> | |||
| <Add option="-Wall" /> | |||
| <Add option="-g" /> | |||
| <Add option="-m32" /> | |||
| <Add option="-m32" /> | |||
| <Add option="-DWIN32" /> | |||
| <Add option="-D_DEBUG" /> | |||
| <Add option="-D_WINDOWS" /> | |||
| @@ -209,7 +209,7 @@ | |||
| <Add directory="tre-0.8.0\lib" /> | |||
| </Compiler> | |||
| <Linker> | |||
| <Add option="-m32" /> | |||
| <Add option="-m32" /> | |||
| <Add library="kernel32" /> | |||
| <Add library="user32" /> | |||
| <Add library="gdi32" /> | |||
| @@ -223,7 +223,7 @@ | |||
| <Add library="odbc32" /> | |||
| <Add library="odbccp32" /> | |||
| </Linker> | |||
| <ExtraCommands> | |||
| <ExtraCommands> | |||
| <Add before="windres -F pe-i386 -O coff -o Debug/libjack.res libjack.rc" /> | |||
| </ExtraCommands> | |||
| </Target> | |||
| @@ -237,7 +237,7 @@ | |||
| <Compiler> | |||
| <Add option="-O2" /> | |||
| <Add option="-Wall" /> | |||
| <Add option="-m32" /> | |||
| <Add option="-m32" /> | |||
| <Add option="-DWIN32" /> | |||
| <Add option="-DNDEBUG" /> | |||
| <Add option="-D_WINDOWS" /> | |||
| @@ -257,7 +257,7 @@ | |||
| <Add directory="tre-0.8.0\lib" /> | |||
| </Compiler> | |||
| <Linker> | |||
| <Add option="-m32" /> | |||
| <Add option="-m32" /> | |||
| <Add library="kernel32" /> | |||
| <Add library="user32" /> | |||
| <Add library="gdi32" /> | |||
| @@ -271,7 +271,7 @@ | |||
| <Add library="odbc32" /> | |||
| <Add library="odbccp32" /> | |||
| </Linker> | |||
| <ExtraCommands> | |||
| <ExtraCommands> | |||
| <Add before="windres -F pe-i386 -O coff -o Release/libjack.res libjack.rc" /> | |||
| </ExtraCommands> | |||
| </Target> | |||
| @@ -322,6 +322,7 @@ | |||
| <Unit filename="..\common\shm.c"> | |||
| <Option compilerVar="CC" /> | |||
| </Unit> | |||
| <Unit filename="JackMMCSS.cpp" /> | |||
| <Unit filename="JackWinNamedPipe.cpp" /> | |||
| <Unit filename="JackWinNamedPipeClientChannel.cpp" /> | |||
| <Unit filename="JackWinProcessSync.cpp" /> | |||
| @@ -32,8 +32,8 @@ | |||
| <Add directory="..\common" /> | |||
| </Compiler> | |||
| <Linker> | |||
| <Add directory="Release64\bin" /> | |||
| <Add library="libsamplerate_x86_64" /> | |||
| <Add directory="Release64\bin" /> | |||
| </Linker> | |||
| </Target> | |||
| <Target title="Win32 Debug 64bits"> | |||
| @@ -62,8 +62,8 @@ | |||
| <Add directory="..\common" /> | |||
| </Compiler> | |||
| <Linker> | |||
| <Add directory="Debug64\bin" /> | |||
| <Add library="libsamplerate_x86_64" /> | |||
| <Add directory="Debug64\bin" /> | |||
| </Linker> | |||
| </Target> | |||
| <Target title="Win32 Profiling 64bits"> | |||
| @@ -93,8 +93,8 @@ | |||
| <Add directory="..\common" /> | |||
| </Compiler> | |||
| <Linker> | |||
| <Add directory="Release64\bin" /> | |||
| <Add library="libsamplerate_x86_64" /> | |||
| <Add directory="Release64\bin" /> | |||
| </Linker> | |||
| </Target> | |||
| <Target title="Win32 Release 32bits"> | |||
| @@ -125,8 +125,8 @@ | |||
| </Compiler> | |||
| <Linker> | |||
| <Add option="-m32" /> | |||
| <Add directory="Release\bin" /> | |||
| <Add library="libsamplerate_x86" /> | |||
| <Add directory="Release\bin" /> | |||
| </Linker> | |||
| <ExtraCommands> | |||
| <Add before="windres -F pe-i386 -O coff -o Release/libjacknet.res libjacknet.rc" /> | |||
| @@ -160,8 +160,8 @@ | |||
| </Compiler> | |||
| <Linker> | |||
| <Add option="-m32" /> | |||
| <Add directory="Debug\bin" /> | |||
| <Add library="libsamplerate_x86" /> | |||
| <Add directory="Debug\bin" /> | |||
| </Linker> | |||
| <ExtraCommands> | |||
| <Add before="windres -F pe-i386 -O coff -o Debug/libjacknet.res libjacknet.rc" /> | |||
| @@ -196,8 +196,8 @@ | |||
| </Compiler> | |||
| <Linker> | |||
| <Add option="-m32" /> | |||
| <Add directory="Release\bin" /> | |||
| <Add library="libsamplerate_x86" /> | |||
| <Add directory="Release\bin" /> | |||
| </Linker> | |||
| <ExtraCommands> | |||
| <Add before="windres -F pe-i386 -O coff -o Release/libjacknet.res libjacknet.rc" /> | |||
| @@ -235,6 +235,7 @@ | |||
| <Unit filename="..\common\ringbuffer.c"> | |||
| <Option compilerVar="CC" /> | |||
| </Unit> | |||
| <Unit filename="JackMMCSS.cpp" /> | |||
| <Unit filename="JackNetWinSocket.cpp" /> | |||
| <Unit filename="JackWinThread.cpp" /> | |||
| <Unit filename="JackWinTime.c"> | |||
| @@ -289,6 +289,7 @@ | |||
| <Unit filename="..\common\shm.c"> | |||
| <Option compilerVar="CC" /> | |||
| </Unit> | |||
| <Unit filename="JackMMCSS.cpp" /> | |||
| <Unit filename="JackNetWinSocket.cpp" /> | |||
| <Unit filename="JackWinNamedPipe.cpp" /> | |||
| <Unit filename="JackWinNamedPipeClientChannel.cpp" /> | |||
| @@ -41,6 +41,8 @@ namespace Jack | |||
| driver->fInputBuffer = (jack_default_audio_sample_t**)inputBuffer; | |||
| driver->fOutputBuffer = (jack_default_audio_sample_t**)outputBuffer; | |||
| MMCSSAcquireRealTime(GetCurrentThread()); | |||
| if (statusFlags) { | |||
| if (statusFlags & paOutputUnderflow) | |||
| jack_error("JackPortAudioDriver::Render paOutputUnderflow"); | |||
| @@ -22,6 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| #include "JackAudioDriver.h" | |||
| #include "JackPortAudioDevices.h" | |||
| #include "JackMMCSS.h" | |||
| namespace Jack | |||
| { | |||
| @@ -30,7 +31,7 @@ namespace Jack | |||
| \brief The PortAudio driver. | |||
| */ | |||
| class JackPortAudioDriver : public JackAudioDriver | |||
| class JackPortAudioDriver : public JackMMCSS, public JackAudioDriver | |||
| { | |||
| private: | |||
| @@ -54,7 +55,7 @@ class JackPortAudioDriver : public JackAudioDriver | |||
| public: | |||
| JackPortAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, PortAudioDevices* pa_devices) | |||
| : JackAudioDriver(name, alias, engine, table), fStream(NULL), fInputBuffer(NULL), fOutputBuffer(NULL), | |||
| : JackMMCSS(), JackAudioDriver(name, alias, engine, table), fStream(NULL), fInputBuffer(NULL), fOutputBuffer(NULL), | |||
| fInputDevice(paNoDevice), fOutputDevice(paNoDevice) | |||
| { | |||
| fPaDevices = pa_devices; | |||
| @@ -60,7 +60,8 @@ JackWinMMEDriver::Attach() | |||
| // Inputs | |||
| for (int i = 0; i < fCaptureChannels; i++) { | |||
| JackWinMMEInputPort *input_port = input_ports[i]; | |||
| name = input_port->GetName(); | |||
| name = input_port->GetName(); | |||
| printf("register port %d",buffer_size); | |||
| if (fEngine->PortRegister(fClientControl.fRefNum, name, | |||
| JACK_DEFAULT_MIDI_TYPE, | |||
| CaptureDriverFlags, buffer_size, &index) < 0) { | |||
| @@ -22,7 +22,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| #include "JackMidiUtil.h" | |||
| #include "JackTime.h" | |||
| #include "JackWinMMEOutputPort.h" | |||
| #include "JackWinMMEOutputPort.h" | |||
| #include "JackGlobals.h" | |||
| #include "JackEngineControl.h" | |||
| using Jack::JackWinMMEOutputPort; | |||
| @@ -44,7 +46,8 @@ JackWinMMEOutputPort::HandleMessageEvent(HMIDIOUT handle, UINT message, | |||
| JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, | |||
| const char *client_name, | |||
| const char *driver_name, UINT index, | |||
| const char *driver_name, | |||
| UINT index, | |||
| size_t max_bytes, | |||
| size_t max_messages) | |||
| { | |||
| @@ -86,7 +89,7 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, | |||
| snprintf(name, sizeof(name) - 1, "%s:playback_%d", client_name, index + 1); | |||
| read_queue_ptr.release(); | |||
| thread_queue_ptr.release(); | |||
| thread_ptr.release(); | |||
| thread_ptr.release(); | |||
| return; | |||
| destroy_thread_queue_semaphore: | |||
| @@ -132,7 +135,7 @@ JackWinMMEOutputPort::Execute() | |||
| for (;;) { | |||
| if (! Wait(thread_queue_semaphore)) { | |||
| jack_log("JackWinMMEOutputPort::Execute BREAK"); | |||
| break; | |||
| } | |||
| jack_midi_event_t *event = thread_queue->DequeueEvent(); | |||
| @@ -274,7 +277,7 @@ JackWinMMEOutputPort::Init() | |||
| set_threaded_log_function(); | |||
| // XX: Can more be done? Ideally, this thread should have the JACK server | |||
| // thread priority + 1. | |||
| if (thread->AcquireSelfRealTime()) { | |||
| if (thread->AcquireSelfRealTime(GetEngineControl()->fServerPriority)) { | |||
| jack_error("JackWinMMEOutputPort::Init - could not acquire realtime " | |||
| "scheduling. Continuing anyway."); | |||
| } | |||