src/JackCommand.h
branchv_0
changeset 2 e5f0d3f92eb4
parent 1 001b956610ca
child 3 0222c20f590f
equal deleted inserted replaced
1:001b956610ca 2:e5f0d3f92eb4
    21 #include <memory>
    21 #include <memory>
    22 #include <unistd.h>
    22 #include <unistd.h>
    23 #include <pthread.h>
    23 #include <pthread.h>
    24 #include <sys/mman.h>
    24 #include <sys/mman.h>
    25 #include <atomic>
    25 #include <atomic>
       
    26 #include <functional>
    26 
    27 
    27 #include <jack/jack.h>
    28 #include <jack/jack.h>
    28 #include <jack/midiport.h>
    29 #include <jack/midiport.h>
    29 #include <jack/ringbuffer.h>
    30 #include <jack/ringbuffer.h>
    30 
    31 
    59 	struct MidiMessage {
    60 	struct MidiMessage {
    60 		uint8_t buffer[4096];
    61 		uint8_t buffer[4096];
    61 		uint32_t size;
    62 		uint32_t size;
    62 		uint32_t time;
    63 		uint32_t time;
    63 	};
    64 	};
    64 
    65 	
    65 public:
    66 public:
    66 
    67 
    67 	int enqueueMessage(jack_nframes_t frames) {
    68 	int enqueueMessage(jack_nframes_t frames) {
    68 		void* buffer = jack_port_get_buffer(jackPort, frames);
    69 		void* buffer = jack_port_get_buffer(jackPort, frames);
    69 		if (buffer == nullptr) throw JackException(L"Unable to get port buffer."); // TODO: exception in RT callback?
    70 		if (buffer == nullptr) throw JackException(L"Unable to get port buffer."); // TODO: exception in RT callback?
   135 
   136 
   136 	void finish(int sig) {
   137 	void finish(int sig) {
   137 		continueProcessing = false;
   138 		continueProcessing = false;
   138 	}
   139 	}
   139 
   140 
   140 	void processJackStream(ostream &output) {
   141 	void processJackStream(std::shared_ptr<writer::RelationalWriter> writer, std::function<void() > relationalWriterFlush) {
   141 		// Relation headers:
   142 		// Relation headers:
   142 		std::shared_ptr<RelationalWriter> writer(Factory::create(output));
       
   143 		vector<AttributeMetadata> metadata;
   143 		vector<AttributeMetadata> metadata;
   144 		metadata.push_back({L"event", TypeId::STRING});
   144 		metadata.push_back({L"event", TypeId::STRING});
   145 		metadata.push_back({L"channel", TypeId::INTEGER});
   145 		metadata.push_back({L"channel", TypeId::INTEGER});
   146 		metadata.push_back({L"note_on", TypeId::BOOLEAN});
   146 		metadata.push_back({L"note_on", TypeId::BOOLEAN});
   147 		metadata.push_back({L"note_pitch", TypeId::INTEGER});
   147 		metadata.push_back({L"note_pitch", TypeId::INTEGER});
   148 		metadata.push_back({L"note_velocity", TypeId::INTEGER});
   148 		metadata.push_back({L"note_velocity", TypeId::INTEGER});
   149 		metadata.push_back({L"controller_id", TypeId::INTEGER});
   149 		metadata.push_back({L"controller_id", TypeId::INTEGER});
   150 		metadata.push_back({L"controller_value", TypeId::INTEGER});
   150 		metadata.push_back({L"controller_value", TypeId::INTEGER});
   151 		writer->startRelation(L"midi", metadata, true);
   151 		writer->startRelation(L"midi", metadata, true);
   152 		output.flush();
   152 		relationalWriterFlush();
   153 
   153 
   154 		// Initialize JACK connection:
   154 		// Initialize JACK connection:
   155 		std::string clientName = "relpipe-in-jack";
   155 		std::string clientName = "relpipe-in-jack";
   156 		jack_client_t* client = jack_client_open(clientName.c_str(), JackNullOption, nullptr);
   156 		jack_client_t* client = jack_client_open(clientName.c_str(), JackNullOption, nullptr);
   157 		if (client == nullptr) throw JackException(L"Could not create JACK client.");
   157 		if (client == nullptr) throw JackException(L"Could not create JACK client.");
   175 			const size_t queuedMessages = jack_ringbuffer_read_space(ringBuffer) / sizeof (MidiMessage);
   175 			const size_t queuedMessages = jack_ringbuffer_read_space(ringBuffer) / sizeof (MidiMessage);
   176 			for (size_t i = 0; i < queuedMessages; ++i) {
   176 			for (size_t i = 0; i < queuedMessages; ++i) {
   177 				MidiMessage m;
   177 				MidiMessage m;
   178 				jack_ringbuffer_read(ringBuffer, (char*) &m, sizeof (MidiMessage));
   178 				jack_ringbuffer_read(ringBuffer, (char*) &m, sizeof (MidiMessage));
   179 				processMessage(writer, &m);
   179 				processMessage(writer, &m);
   180 				output.flush();
   180 				relationalWriterFlush();
   181 			}
   181 			}
   182 			pthread_cond_wait(&dataReady, &messageThreadLock);
   182 			pthread_cond_wait(&dataReady, &messageThreadLock);
   183 		}
   183 		}
   184 		pthread_mutex_unlock(&messageThreadLock);
   184 		pthread_mutex_unlock(&messageThreadLock);
   185 
   185