jackaudio.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /*
  2. This file is part of QTau
  3. Copyright (C) 2013-2018 Tobias "Tomoko" Platen <tplaten@posteo.de>
  4. Copyright (C) 2013 digited <https://github.com/digited>
  5. Copyright (C) 2010-2013 HAL@ShurabaP <https://github.com/haruneko>
  6. QTau is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. SPDX-License-Identifier: GPL-3.0+
  17. */
  18. #define __devloglevel__ 4
  19. #include "jackaudio.h"
  20. #include <assert.h>
  21. #include <stdio.h>
  22. #include <QDebug>
  23. #include <QIcon>
  24. #include <QMessageBox>
  25. #include <stdint.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <sys/eventfd.h>
  29. #include <unistd.h>
  30. #include <jack/midiport.h>
  31. #include <iostream>
  32. int JackAudio::createEFD() {
  33. _eventfd = eventfd(0, 0);
  34. return _eventfd;
  35. }
  36. int JackAudio::readMidiData(char *buffer, int maxlength) {
  37. int count = jack_ringbuffer_read_space(this->_midi_rb);
  38. if (count > 0) {
  39. if (count > maxlength) count = maxlength;
  40. jack_ringbuffer_read(this->_midi_rb, buffer, count);
  41. }
  42. return count;
  43. }
  44. int JackAudio::process(jack_nframes_t nframes, void *arg) {
  45. JackAudio *conn = (JackAudio *)arg;
  46. // midi input handing
  47. void *port_buf = jack_port_get_buffer(conn->_midi_port, nframes);
  48. jack_nframes_t event_count = jack_midi_get_event_count(port_buf);
  49. if (event_count > 0) {
  50. for (jack_nframes_t i = 0; i < event_count; i++) {
  51. jack_midi_event_t in_event;
  52. // jack_position_t position;
  53. jack_midi_event_get(&in_event, port_buf, i);
  54. // FIXME: sysex support
  55. jack_ringbuffer_write(conn->_midi_rb, (char *)in_event.buffer,
  56. in_event.size);
  57. }
  58. }
  59. // audio output
  60. sample_t *write_samp =
  61. (sample_t *)jack_port_get_buffer(conn->_write_port, nframes);
  62. if (jack_ringbuffer_read_space(conn->_write_rb) >=
  63. sizeof(sample_t) * nframes) {
  64. jack_ringbuffer_read(conn->_write_rb, (char *)write_samp,
  65. sizeof(sample_t) * nframes);
  66. } else {
  67. for (unsigned int i = 0; i < nframes; i++)
  68. write_samp[i] = 0.0; // buffer underrun
  69. DEVLOG_DEBUG("xrun in JackAudio::process");
  70. }
  71. // transport control
  72. if (conn->_use_transport) {
  73. conn->_transport_state = jack_transport_query(conn->_client, NULL);
  74. if (conn->_transport_state == JackTransportStopped &&
  75. conn->_previous_transport_state == JackTransportRolling) {
  76. conn->_state_changed = true;
  77. }
  78. if (conn->_transport_state == JackTransportStarting &&
  79. conn->_previous_transport_state != JackTransportStarting) {
  80. conn->_state_changed = true;
  81. }
  82. if (conn->_transport_state == JackTransportRolling &&
  83. conn->_previous_transport_state != JackTransportRolling) {
  84. conn->_state_changed = true;
  85. }
  86. conn->_previous_transport_state = conn->_transport_state;
  87. }
  88. if (conn->_transport_command == TRANSPORT_START)
  89. jack_transport_start(conn->_client);
  90. if (conn->_transport_command == TRANSPORT_STOP)
  91. jack_transport_stop(conn->_client);
  92. if (conn->_transport_command == TRANSPORT_ZERO) {
  93. jack_position_t pos;
  94. pos.valid = (jack_position_bits_t)0;
  95. pos.frame = 0;
  96. jack_transport_stop(conn->_client);
  97. jack_transport_reposition(conn->_client, &pos);
  98. }
  99. if (conn->_transport_command == TRANSPORT_STARTPOS) {
  100. jack_position_t pos;
  101. pos.valid = (jack_position_bits_t)0;
  102. pos.frame = conn->_startpos * conn->sampleRate();
  103. jack_transport_stop(conn->_client);
  104. jack_transport_reposition(conn->_client, &pos);
  105. jack_transport_start(conn->_client);
  106. }
  107. conn->_transport_command = 0;
  108. // notify
  109. uint64_t u = 1;
  110. if (write(conn->_eventfd, &u, sizeof(uint64_t)) != 8) return 1;
  111. // no error
  112. return 0;
  113. }
  114. int JackAudio::sync(jack_transport_state_t state, jack_position_t *pos,
  115. void *arg) {
  116. (void)state;
  117. // start tranport
  118. JackAudio *conn = (JackAudio *)arg;
  119. if (conn->_use_transport) {
  120. conn->_position = pos->frame;
  121. return 1;
  122. } else
  123. return 1;
  124. }
  125. JackAudio::JackAudio(bool autoconnect) {
  126. _client = jack_client_open("QTau", JackNoStartServer, NULL);
  127. if (_client == NULL) {
  128. QMessageBox msgbox;
  129. msgbox.setText("jack is not running");
  130. msgbox.exec();
  131. exit(1);
  132. }
  133. _buffer_size = jack_get_buffer_size(_client);
  134. // TODO configurable port names ???
  135. _write_port = jack_port_register(_client, "out", JACK_DEFAULT_AUDIO_TYPE,
  136. JackPortIsOutput, _buffer_size);
  137. _write_rb = jack_ringbuffer_create(sizeof(sample_t) * 4096);
  138. _midi_rb = jack_ringbuffer_create(4096);
  139. _midi_port = jack_port_register(_client, "midi_in", JACK_DEFAULT_MIDI_TYPE,
  140. JackPortIsInput, 0);
  141. jack_set_process_callback(_client, process, this);
  142. jack_set_sync_callback(_client, sync, this);
  143. jack_activate(_client);
  144. if (autoconnect) {
  145. jack_connect(_client, "QTau:out", "system:playback_2"); // FOR testing
  146. jack_connect(_client, "QTau:out", "system:playback_1"); // FOR testing
  147. }
  148. _transport_command = TRANSPORT_ZERO;
  149. _use_transport = true;
  150. _playback = false;
  151. }
  152. int JackAudio::sampleRate() { return jack_get_sample_rate(_client); }
  153. int JackAudio::writeData(void *framebuf, int bytes_per_frame) {
  154. if (jack_ringbuffer_write_space(_write_rb) >= (unsigned int)bytes_per_frame) {
  155. return jack_ringbuffer_write(_write_rb, (char *)framebuf, bytes_per_frame);
  156. }
  157. DEVLOG_DEBUG("xrun in JackAudio::writeData"); // FIXME do not log while
  158. // program startup
  159. return 0; // not data was written
  160. }
  161. float *JackAudio::allocateBuffer() {
  162. if (_buffer_size == 0) return NULL;
  163. return new float[_buffer_size];
  164. }
  165. void JackAudio::shutdown() {
  166. jack_deactivate(_client);
  167. jack_client_close(_client);
  168. }