jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

240 lines
8.3KB

  1. /*
  2. Copyright (C) 2001 Paul Davis
  3. Copyright (C) 2004-2006 Grame
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. #ifdef WIN32
  17. #pragma warning (disable : 4786)
  18. #endif
  19. #include "JackAudioDriver.h"
  20. #include "JackTime.h"
  21. #include "JackError.h"
  22. #include "JackEngineControl.h"
  23. #include "JackClientControl.h"
  24. #include "JackPort.h"
  25. #include "JackGraphManager.h"
  26. #include "JackEngine.h"
  27. #include <assert.h>
  28. namespace Jack
  29. {
  30. JackAudioDriver::JackAudioDriver(const char* name, JackEngine* engine, JackSynchro** table)
  31. : JackDriver(name, engine, table),
  32. fCaptureChannels(0),
  33. fPlaybackChannels(0),
  34. fWithMonitorPorts(false)
  35. {}
  36. JackAudioDriver::~JackAudioDriver()
  37. {}
  38. int JackAudioDriver::Open(jack_nframes_t nframes,
  39. jack_nframes_t samplerate,
  40. int capturing,
  41. int playing,
  42. int inchannels,
  43. int outchannels,
  44. bool monitor,
  45. const char* capture_driver_name,
  46. const char* playback_driver_name,
  47. jack_nframes_t capture_latency,
  48. jack_nframes_t playback_latency)
  49. {
  50. fCaptureChannels = inchannels;
  51. fPlaybackChannels = outchannels;
  52. fWithMonitorPorts = monitor;
  53. return JackDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency);
  54. }
  55. int JackAudioDriver::Attach()
  56. {
  57. JackPort* port;
  58. jack_port_id_t port_index;
  59. char buf[JACK_PORT_NAME_SIZE];
  60. unsigned long port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
  61. int i;
  62. JackLog("JackAudioDriver::Attach fBufferSize = %ld fSampleRate = %ld\n", fEngineControl->fBufferSize, fEngineControl->fSampleRate);
  63. for (i = 0; i < fCaptureChannels; i++) {
  64. snprintf(buf, sizeof(buf) - 1, "%s:%s:out%d", fClientControl->fName, fCaptureDriverName, i + 1);
  65. if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, (JackPortFlags)port_flags)) == NO_PORT) {
  66. jack_error("driver: cannot register port for %s", buf);
  67. return -1;
  68. }
  69. port = fGraphManager->GetPort(port_index);
  70. port->SetLatency(fEngineControl->fBufferSize + fCaptureLatency);
  71. fCapturePortList[i] = port_index;
  72. JackLog("JackAudioDriver::Attach fCapturePortList[i] %ld = \n", port_index);
  73. }
  74. port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
  75. for (i = 0; i < fPlaybackChannels; i++) {
  76. snprintf(buf, sizeof(buf) - 1, "%s:%s:in%d", fClientControl->fName, fPlaybackDriverName, i + 1);
  77. if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, (JackPortFlags)port_flags)) == NO_PORT) {
  78. jack_error("driver: cannot register port for %s", buf);
  79. return -1;
  80. }
  81. port = fGraphManager->GetPort(port_index);
  82. port->SetLatency(fEngineControl->fBufferSize + fPlaybackLatency);
  83. fPlaybackPortList[i] = port_index;
  84. JackLog("JackAudioDriver::Attach fPlaybackPortList[i] %ld = \n", port_index);
  85. // Monitor ports
  86. if (fWithMonitorPorts) {
  87. JackLog("Create monitor port \n");
  88. snprintf(buf, sizeof(buf) - 1, "%s:%s:monitor_%u", fClientControl->fName, fPlaybackDriverName, i + 1);
  89. if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, JackPortIsOutput)) == NO_PORT) {
  90. jack_error("Cannot register monitor port for %s", buf);
  91. return -1;
  92. } else {
  93. port = fGraphManager->GetPort(port_index);
  94. port->SetLatency(fEngineControl->fBufferSize);
  95. fMonitorPortList[i] = port_index;
  96. }
  97. }
  98. }
  99. return 0;
  100. }
  101. int JackAudioDriver::Detach()
  102. {
  103. int i;
  104. JackLog("JackAudioDriver::Detach\n");
  105. for (i = 0; i < fCaptureChannels; i++) {
  106. fGraphManager->ReleasePort(fClientControl->fRefNum, fCapturePortList[i]);
  107. }
  108. for (i = 0; i < fPlaybackChannels; i++) {
  109. fGraphManager->ReleasePort(fClientControl->fRefNum, fPlaybackPortList[i]);
  110. if (fWithMonitorPorts)
  111. fGraphManager->ReleasePort(fClientControl->fRefNum, fMonitorPortList[i]);
  112. }
  113. return 0;
  114. }
  115. int JackAudioDriver::Write()
  116. {
  117. for (int i = 0; i < fPlaybackChannels; i++) {
  118. if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) > 0) {
  119. float* buffer = GetOutputBuffer(i);
  120. int size = sizeof(float) * fEngineControl->fBufferSize;
  121. // Monitor ports
  122. if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[i]) > 0)
  123. memcpy(GetMonitorBuffer(i), buffer, size);
  124. }
  125. }
  126. return 0;
  127. }
  128. int JackAudioDriver::Process()
  129. {
  130. return (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync();
  131. }
  132. /*
  133. The driver ASYNC mode: output buffers computed at the *previous cycle* are used, the server does not
  134. synchronize to the end of client graph execution.
  135. */
  136. int JackAudioDriver::ProcessAsync()
  137. {
  138. if (Read() < 0) { // Read input buffers for the current cycle
  139. jack_error("ProcessAsync: read error");
  140. return 0;
  141. }
  142. if (Write() < 0) { // Write output buffers from the previous cycle
  143. jack_error("ProcessAsync: write error");
  144. return 0;
  145. }
  146. if (fIsMaster) {
  147. fEngine->Process(fLastWaitUst); // fLastWaitUst is set in the "low level" layer
  148. fGraphManager->ResumeRefNum(fClientControl, fSynchroTable);
  149. ProcessSlaves();
  150. } else {
  151. fGraphManager->ResumeRefNum(fClientControl, fSynchroTable);
  152. }
  153. return 0;
  154. }
  155. /*
  156. The driver SYNC mode: the server does synchronize to the end of client graph execution,
  157. output buffers computed at the *current cycle* are used.
  158. */
  159. int JackAudioDriver::ProcessSync()
  160. {
  161. if (Read() < 0) { // Read input buffers for the current cycle
  162. jack_error("ProcessSync: read error");
  163. return 0;
  164. }
  165. if (fIsMaster) {
  166. if (fEngine->Process(fLastWaitUst)) { // fLastWaitUst is set in the "low level" layer
  167. fGraphManager->ResumeRefNum(fClientControl, fSynchroTable);
  168. if (ProcessSlaves() < 0)
  169. jack_error("JackAudioDriver::ProcessSync ProcessSlaves error, engine may now behave abnormally!!");
  170. if (fGraphManager->SuspendRefNum(fClientControl, fSynchroTable, fEngineControl->fTimeOutUsecs) < 0)
  171. jack_error("JackAudioDriver::ProcessSync SuspendRefNum error, engine may now behave abnormally!!");
  172. } else { // Graph not finished: do not activate it
  173. jack_error("JackAudioDriver::ProcessSync: error");
  174. }
  175. if (Write() < 0) // Write output buffers for the current cycle
  176. jack_error("Process: write error");
  177. } else {
  178. fGraphManager->ResumeRefNum(fClientControl, fSynchroTable);
  179. }
  180. return 0;
  181. }
  182. void JackAudioDriver::NotifyXRun(jack_time_t callback_usecs)
  183. {
  184. fEngine->NotifyXRun(callback_usecs);
  185. }
  186. jack_default_audio_sample_t* JackAudioDriver::GetInputBuffer(int port_index)
  187. {
  188. assert(fCapturePortList[port_index]);
  189. return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[port_index], fEngineControl->fBufferSize);
  190. }
  191. jack_default_audio_sample_t* JackAudioDriver::GetOutputBuffer(int port_index)
  192. {
  193. assert(fPlaybackPortList[port_index]);
  194. return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[port_index], fEngineControl->fBufferSize);
  195. }
  196. jack_default_audio_sample_t* JackAudioDriver::GetMonitorBuffer(int port_index)
  197. {
  198. assert(fPlaybackPortList[port_index]);
  199. return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[port_index], fEngineControl->fBufferSize);
  200. }
  201. } // end of namespace