jack.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. Author: Harry van Haaren
  3. E-mail: harryhaaren@gmail.com
  4. Copyright (C) 2010 Harry van Haaren
  5. Copyright (C) 2015 Tobias Platen
  6. PrintSynth 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. PrintJackMidi 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 PrintJackMidi. If not, see <http://www.gnu.org/licenses/>. */
  16. #include "jack.hpp"
  17. #include "midi.h"
  18. #include <unistd.h>
  19. using namespace std;
  20. Jack::Jack()
  21. {
  22. std::cout << "Jack()" << std::flush;
  23. if ((client = jack_client_open("SampleMidiSynth", JackNullOption, NULL)) == 0)
  24. {
  25. std::cout << "jack server not running?" << std::endl;
  26. }
  27. synth.init(jack_get_sample_rate(client),jack_get_buffer_size(client));
  28. bufferSize = jack_get_buffer_size(client);
  29. inputPort = jack_port_register (client, "midi_in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
  30. outputPort = jack_port_register (client, "audio_out", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
  31. inputBuffer = jack_ringbuffer_create(4096);
  32. outputBuffer = jack_ringbuffer_create(4096*sizeof(float));
  33. jack_set_process_callback (client, staticProcess, static_cast<void*>(this));
  34. std::cout << "\t\t\tDone!" << std::endl;
  35. }
  36. Jack::~Jack()
  37. {
  38. std::cout << "~Jack()" << std::endl;
  39. }
  40. void Jack::activate()
  41. {
  42. std::cout << "activate()" << std::flush;
  43. if (jack_activate(client) != 0)
  44. {
  45. std::cout<< "cannot activate client" << std::endl;
  46. return;
  47. }
  48. std::cout << "\t\tDone!" << std::endl;
  49. jack_connect(client,"a2j:LPK25 [20] (capture): LPK25 MIDI 1","SampleMidiSynth:midi_in");
  50. jack_connect(client,"SampleMidiSynth:audio_out","system:playback_1");
  51. jack_connect(client,"SampleMidiSynth:audio_out","system:playback_2");
  52. std::thread* thr = new std::thread(Jack::staticWorkerThread,this);
  53. }
  54. int Jack::staticProcess(jack_nframes_t nframes, void *arg)
  55. {
  56. return static_cast<Jack*>(arg)->process(nframes);
  57. }
  58. int Jack::process(jack_nframes_t nframes)
  59. {
  60. jack_midi_event_t in_event;
  61. jack_nframes_t event_index = 0;
  62. jack_position_t position;
  63. jack_transport_state_t transport;
  64. // get the port data
  65. void* inputPortBuf = jack_port_get_buffer( inputPort, nframes );
  66. void* outputPortBuf = jack_port_get_buffer( outputPort, nframes );
  67. jack_nframes_t event_count = jack_midi_get_event_count(inputPortBuf);
  68. if(event_count > 0)
  69. {
  70. for(int i=0; i<event_count; i++)
  71. {
  72. jack_midi_event_get(&in_event, inputPortBuf, i);
  73. unsigned char event[4];
  74. event[0]=0;
  75. event[1]=in_event.buffer[0];
  76. event[2]=in_event.buffer[1];
  77. event[3]=in_event.buffer[2];
  78. if(jack_ringbuffer_write_space(inputBuffer)>4)
  79. {
  80. jack_ringbuffer_write(inputBuffer,(char*)event,4);
  81. }
  82. }
  83. }
  84. jack_default_audio_sample_t *out = (jack_default_audio_sample_t *) jack_port_get_buffer (outputPort, nframes);
  85. if(jack_ringbuffer_read_space(outputBuffer)>nframes*sizeof(float)*2)
  86. {
  87. jack_ringbuffer_read(outputBuffer,(char*)out,nframes*sizeof(float));
  88. }
  89. return 0;
  90. }
  91. void Jack::staticWorkerThread(Jack* self)
  92. {
  93. fprintf(stderr,"worker thread - non realtime\n");
  94. while(1)
  95. {
  96. if(jack_ringbuffer_read_space(self->inputBuffer)>=4) {
  97. unsigned char event[4];
  98. jack_ringbuffer_read(self->inputBuffer,(char*)event,4);
  99. int sb=event[1];
  100. int notenum = event[2];
  101. int velocity = event[3];
  102. if(MIDI_STATUS(sb)==MIDI_NOTEOFF || (MIDI_STATUS(sb)==MIDI_NOTEON && velocity==0)) self->synth.noteOff(notenum);
  103. else if(MIDI_STATUS(sb)==MIDI_NOTEON) self->synth.noteOn(notenum,velocity);
  104. }
  105. if(jack_ringbuffer_write_space(self->outputBuffer)>=self->bufferSize*sizeof(float))
  106. {
  107. float buffer[self->bufferSize];
  108. self->synth.fill(buffer,self->bufferSize);
  109. jack_ringbuffer_write(self->outputBuffer,(char*)buffer,self->bufferSize*sizeof(float));
  110. }
  111. usleep(1000);
  112. }
  113. }