123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- /*
- Author: Harry van Haaren
- E-mail: harryhaaren@gmail.com
- Copyright (C) 2010 Harry van Haaren
- Copyright (C) 2015 Tobias Platen
- PrintSynth is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- PrintJackMidi 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 General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with PrintJackMidi. If not, see <http://www.gnu.org/licenses/>. */
- #include "jack.hpp"
- #include <unistd.h>
- #include "midi.h"
- using namespace std;
- Jack::Jack() {
- std::cout << "Jack()" << std::flush;
- if ((client = jack_client_open("SampleMidiSynth", JackNullOption, NULL)) ==
- 0) {
- std::cout << "jack server not running?" << std::endl;
- }
- synth.init(jack_get_sample_rate(client), jack_get_buffer_size(client));
- bufferSize = jack_get_buffer_size(client);
- inputPort = jack_port_register(client, "midi_in", JACK_DEFAULT_MIDI_TYPE,
- JackPortIsInput, 0);
- outputPort = jack_port_register(client, "audio_out", JACK_DEFAULT_AUDIO_TYPE,
- JackPortIsOutput, 0);
- inputBuffer = jack_ringbuffer_create(4096);
- outputBuffer = jack_ringbuffer_create(4096 * sizeof(float));
- jack_set_process_callback(client, staticProcess, static_cast<void *>(this));
- std::cout << "\t\t\tDone!" << std::endl;
- }
- Jack::~Jack() { std::cout << "~Jack()" << std::endl; }
- void Jack::activate() {
- std::cout << "activate()" << std::flush;
- if (jack_activate(client) != 0) {
- std::cout << "cannot activate client" << std::endl;
- return;
- }
- std::cout << "\t\tDone!" << std::endl;
- jack_connect(client, "a2j:MIDIMATE II [20] (capture): MIDIMATE II MIDI 1",
- "SampleMidiSynth:midi_in");
- jack_connect(client, "SampleMidiSynth:audio_out", "system:playback_1");
- jack_connect(client, "SampleMidiSynth:audio_out", "system:playback_2");
- std::thread *thr = new std::thread(Jack::staticWorkerThread, this);
- (void) thr;
- }
- int Jack::staticProcess(jack_nframes_t nframes, void *arg) {
- return static_cast<Jack *>(arg)->process(nframes);
- }
- int Jack::process(jack_nframes_t nframes) {
- jack_midi_event_t in_event;
- //jack_nframes_t event_index = 0;
- //jack_position_t position;
- //jack_transport_state_t transport;
- // get the port data
- void *inputPortBuf = jack_port_get_buffer(inputPort, nframes);
- //void *outputPortBuf = jack_port_get_buffer(outputPort, nframes);
- jack_nframes_t event_count = jack_midi_get_event_count(inputPortBuf);
- if (event_count > 0) {
- for (uint i = 0; i < event_count; i++) {
- jack_midi_event_get(&in_event, inputPortBuf, i);
- unsigned char event[4];
- event[0] = 0;
- event[1] = in_event.buffer[0];
- event[2] = in_event.buffer[1];
- event[3] = in_event.buffer[2];
- if (jack_ringbuffer_write_space(inputBuffer) > 4) {
- jack_ringbuffer_write(inputBuffer, (char *)event, 4);
- }
- }
- }
- jack_default_audio_sample_t *out =
- (jack_default_audio_sample_t *)jack_port_get_buffer(outputPort, nframes);
- if (jack_ringbuffer_read_space(outputBuffer) > nframes * sizeof(float) * 2) {
- jack_ringbuffer_read(outputBuffer, (char *)out, nframes * sizeof(float));
- }
- return 0;
- }
- void Jack::staticWorkerThread(Jack *self) {
- fprintf(stderr, "worker thread - non realtime\n");
- while (1) {
- if (jack_ringbuffer_read_space(self->inputBuffer) >= 4) {
- unsigned char event[4];
- jack_ringbuffer_read(self->inputBuffer, (char *)event, 4);
- int sb = event[1];
- int arg1 = event[2];
- int arg2 = event[3];
- if (MIDI_STATUS(sb) == MIDI_NOTEOFF ||
- (MIDI_STATUS(sb) == MIDI_NOTEON && arg2 == 0))
- self->synth.noteOff(arg1);
- else if (MIDI_STATUS(sb) == MIDI_NOTEON)
- self->synth.noteOn(arg1, arg2);
- else if (MIDI_STATUS(sb) == MIDI_CONTROLLER)
- self->synth.controllerEvent(arg1, arg2);
- else if (MIDI_STATUS(sb) == MIDI_PITCHBEND)
- self->synth.pitchBend(arg1, arg2);
- }
- if (jack_ringbuffer_write_space(self->outputBuffer) >=
- self->bufferSize * sizeof(float)) {
- float buffer[self->bufferSize];
- self->synth.fill(buffer, self->bufferSize);
- jack_ringbuffer_write(self->outputBuffer, (char *)buffer,
- self->bufferSize * sizeof(float));
- }
- usleep(1000);
- }
- }
|