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.

173 lines
6.2KB

  1. /*
  2. Copyright (C) 2008 Grame
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. */
  15. #include "JackPortAudioIOAdapter.h"
  16. #include "portaudio.h"
  17. #include "JackError.h"
  18. namespace Jack
  19. {
  20. int JackPortAudioIOAdapter::Render(const void* inputBuffer, void* outputBuffer,
  21. unsigned long framesPerBuffer,
  22. const PaStreamCallbackTimeInfo* timeInfo,
  23. PaStreamCallbackFlags statusFlags,
  24. void* userData)
  25. {
  26. JackPortAudioIOAdapter* adapter = static_cast<JackPortAudioIOAdapter*>(userData);
  27. float** paBuffer;
  28. float* buffer;
  29. if (!adapter->fRunning) {
  30. adapter->fRunning = true;
  31. jack_time_t time = jack_get_time();
  32. adapter->fProducerDLL.Init(time);
  33. adapter->fConsumerDLL.Init(time);
  34. }
  35. // DLL
  36. jack_time_t time = jack_get_time();
  37. adapter->fProducerDLL.IncFrame(time);
  38. jack_nframes_t time1 = adapter->fConsumerDLL.Time2Frames(time);
  39. jack_nframes_t time2 = adapter->fProducerDLL.Time2Frames(time);
  40. double src_ratio_output = double(time2) / double(time1);
  41. double src_ratio_input = double(time1) / double(time2);
  42. if (src_ratio_input < 0.7f || src_ratio_input > 1.3f) {
  43. jack_error("src_ratio_input = %f", src_ratio_input);
  44. src_ratio_input = 1;
  45. time1 = 1;
  46. time2 = 1;
  47. }
  48. if (src_ratio_output < 0.7f || src_ratio_output > 1.3f) {
  49. jack_error("src_ratio_output = %f", src_ratio_output);
  50. src_ratio_output = 1;
  51. time1 = 1;
  52. time2 = 1;
  53. }
  54. src_ratio_input = Range(0.7f, 1.3f, src_ratio_input);
  55. src_ratio_output = Range(0.7f, 1.3f, src_ratio_output);
  56. jack_log("Callback resampler src_ratio_input = %f src_ratio_output = %f", src_ratio_input, src_ratio_output);
  57. paBuffer = (float**)inputBuffer;
  58. for (int i = 0; i < adapter->fCaptureChannels; i++) {
  59. buffer = (float*)paBuffer[i];
  60. adapter->fCaptureRingBuffer[i]->SetRatio(time1, time2);
  61. adapter->fCaptureRingBuffer[i]->WriteResample(buffer, framesPerBuffer);
  62. }
  63. paBuffer = (float**)outputBuffer;
  64. for (int i = 0; i < adapter->fPlaybackChannels; i++) {
  65. buffer = (float*)paBuffer[i];
  66. adapter->fPlaybackRingBuffer[i]->SetRatio(time2, time1);
  67. adapter->fPlaybackRingBuffer[i]->ReadResample(buffer, framesPerBuffer);
  68. }
  69. return paContinue;
  70. }
  71. int JackPortAudioIOAdapter::Open()
  72. {
  73. PaError err;
  74. PaStreamParameters inputParameters;
  75. PaStreamParameters outputParameters;
  76. PaDeviceIndex inputDevice;
  77. PaDeviceIndex outputDevice;
  78. if (JackIOAdapterInterface::Open() < 0)
  79. return -1;
  80. err = Pa_Initialize();
  81. if (err != paNoError) {
  82. jack_error("JackPortAudioIOAdapter::Pa_Initialize error = %s\n", Pa_GetErrorText(err));
  83. goto error;
  84. }
  85. jack_log("JackPortAudioIOAdapter::Pa_GetDefaultInputDevice %ld", Pa_GetDefaultInputDevice());
  86. jack_log("JackPortAudioIOAdapter::Pa_GetDefaultOutputDevice %ld", Pa_GetDefaultOutputDevice());
  87. jack_log("JackPortAudioIOAdapter::Open fBufferSize = %ld fSampleRate %f", fBufferSize, fSampleRate);
  88. inputDevice = Pa_GetDefaultInputDevice();
  89. outputDevice = Pa_GetDefaultOutputDevice();
  90. inputParameters.device = inputDevice;
  91. inputParameters.channelCount = fCaptureChannels;
  92. inputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output
  93. inputParameters.suggestedLatency = (inputDevice != paNoDevice) // TODO: check how to setup this on ASIO
  94. ? Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency
  95. : 0;
  96. inputParameters.hostApiSpecificStreamInfo = NULL;
  97. outputParameters.device = outputDevice;
  98. outputParameters.channelCount = fPlaybackChannels;
  99. outputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output
  100. outputParameters.suggestedLatency = (outputDevice != paNoDevice) // TODO: check how to setup this on ASIO
  101. ? Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency
  102. : 0;
  103. outputParameters.hostApiSpecificStreamInfo = NULL;
  104. err = Pa_OpenStream(&fStream,
  105. (inputDevice == paNoDevice) ? 0 : &inputParameters,
  106. (outputDevice == paNoDevice) ? 0 : &outputParameters,
  107. fSampleRate,
  108. fBufferSize,
  109. paNoFlag, // Clipping is on...
  110. Render,
  111. this);
  112. if (err != paNoError) {
  113. jack_error("Pa_OpenStream error = %s", Pa_GetErrorText(err));
  114. goto error;
  115. }
  116. err = Pa_StartStream(fStream);
  117. if (err != paNoError) {
  118. jack_error("Pa_StartStream error = %s", Pa_GetErrorText(err));
  119. goto error;
  120. }
  121. jack_log("JackPortAudioIOAdapter::Open OK");
  122. return 0;
  123. error:
  124. Pa_Terminate();
  125. return -1;
  126. }
  127. int JackPortAudioIOAdapter::Close()
  128. {
  129. jack_log("JackPortAudioIOAdapter::Close");
  130. Pa_StopStream(fStream);
  131. jack_log("JackPortAudioIOAdapter:: Pa_StopStream");
  132. Pa_CloseStream(fStream);
  133. jack_log("JackPortAudioIOAdapter:: Pa_CloseStream");
  134. Pa_Terminate();
  135. jack_log("JackPortAudioIOAdapter:: Pa_Terminate");
  136. return JackIOAdapterInterface::Close();
  137. }
  138. int JackPortAudioIOAdapter::SetBufferSize(jack_nframes_t buffer_size)
  139. {
  140. JackIOAdapterInterface::SetBufferSize(buffer_size);
  141. Close();
  142. return Open();
  143. }
  144. } // namespace