23 #include "JackNetInterface.h"
24 #include "JackAudioAdapterInterface.h"
33 #define MASTER_NAME_SIZE 256
63 jack_nframes_t buffer_size;
64 jack_nframes_t sample_rate;
65 char master_name[MASTER_NAME_SIZE];
71 typedef struct _jack_net_slave jack_net_slave_t;
73 typedef int (* JackNetSlaveProcessCallback) (jack_nframes_t buffer_size,
75 float** audio_input_buffer,
77 void** midi_input_buffer,
79 float** audio_output_buffer,
81 void** midi_output_buffer,
84 typedef int (*JackNetSlaveBufferSizeCallback) (jack_nframes_t nframes,
void *arg);
85 typedef int (*JackNetSlaveSampleRateCallback) (jack_nframes_t nframes,
void *arg);
86 typedef void (*JackNetSlaveShutdownCallback) (
void* data);
88 LIB_EXPORT jack_net_slave_t* jack_net_slave_open(
const char* ip,
int port,
const char* name,
jack_slave_t* request,
jack_master_t* result);
89 LIB_EXPORT
int jack_net_slave_close(jack_net_slave_t* net);
91 LIB_EXPORT
int jack_net_slave_activate(jack_net_slave_t* net);
92 LIB_EXPORT
int jack_net_slave_deactivate(jack_net_slave_t* net);
94 LIB_EXPORT
int jack_set_net_slave_process_callback(jack_net_slave_t* net, JackNetSlaveProcessCallback net_callback,
void *arg);
95 LIB_EXPORT
int jack_set_net_slave_buffer_size_callback(jack_net_slave_t* net, JackNetSlaveBufferSizeCallback bufsize_callback,
void *arg);
96 LIB_EXPORT
int jack_set_net_slave_sample_rate_callback(jack_net_slave_t* net, JackNetSlaveSampleRateCallback samplerate_callback,
void *arg);
97 LIB_EXPORT
int jack_set_net_slave_shutdown_callback(jack_net_slave_t* net, JackNetSlaveShutdownCallback shutdown_callback,
void *arg);
101 typedef struct _jack_net_master jack_net_master_t;
103 LIB_EXPORT jack_net_master_t* jack_net_master_open(
const char* ip,
int port,
const char* name,
jack_master_t* request,
jack_slave_t* result);
104 LIB_EXPORT
int jack_net_master_close(jack_net_master_t* net);
106 LIB_EXPORT
int jack_net_master_recv(jack_net_master_t* net,
int audio_input,
float** audio_input_buffer,
int midi_input,
void** midi_input_buffer);
107 LIB_EXPORT
int jack_net_master_send(jack_net_master_t* net,
int audio_output,
float** audio_output_buffer,
int midi_output,
void** midi_output_buffer);
111 typedef struct _jack_adapter jack_adapter_t;
113 LIB_EXPORT jack_adapter_t* jack_create_adapter(
int input,
int output,
114 jack_nframes_t host_buffer_size,
115 jack_nframes_t host_sample_rate,
116 jack_nframes_t adapted_buffer_size,
117 jack_nframes_t adapted_sample_rate);
118 LIB_EXPORT
int jack_destroy_adapter(jack_adapter_t* adapter);
119 LIB_EXPORT
void jack_flush_adapter(jack_adapter_t* adapter);
121 LIB_EXPORT
int jack_adapter_push_and_pull(jack_adapter_t* adapter,
float** input,
float** output,
unsigned int frames);
122 LIB_EXPORT
int jack_adapter_pull_and_push(jack_adapter_t* adapter,
float** input,
float** output,
unsigned int frames);
124 #define LOG_LEVEL_INFO 1
125 #define LOG_LEVEL_ERROR 2
127 LIB_EXPORT
void jack_error(
const char *fmt, ...);
128 LIB_EXPORT
void jack_info(
const char *fmt, ...);
129 LIB_EXPORT
void jack_log(
const char *fmt, ...);
141 float** fAudioCaptureBuffer;
142 float** fAudioPlaybackBuffer;
155 assert(strlen(ip) < 32);
156 strcpy(fMulticastIP, ip);
157 fSocket.SetPort(port);
158 fRequest.buffer_size = request->buffer_size;
159 fRequest.sample_rate = request->sample_rate;
160 fRequest.audio_input = request->audio_input;
161 fRequest.audio_output = request->audio_output;
162 fAudioCaptureBuffer = NULL;
163 fAudioPlaybackBuffer = NULL;
164 fMidiCaptureBuffer = NULL;
165 fMidiPlaybackBuffer = NULL;
174 if (SocketAPIInit() < 0) {
175 jack_error(
"Can't init Socket API, exiting...");
180 if (fSocket.NewSocket() == SOCKET_ERROR) {
181 jack_error(
"Can't create the network management input socket : %s", StrError(NET_ERROR_CODE));
186 if (fSocket.Bind() == SOCKET_ERROR) {
187 jack_error(
"Can't bind the network manager socket : %s", StrError(NET_ERROR_CODE));
193 if (fSocket.JoinMCastGroup(fMulticastIP) == SOCKET_ERROR) {
194 jack_error(
"Can't join multicast group : %s", StrError(NET_ERROR_CODE));
198 if (fSocket.SetLocalLoop() == SOCKET_ERROR) {
199 jack_error(
"Can't set local loop : %s", StrError(NET_ERROR_CODE));
203 if (fSocket.SetTimeOut(MANAGER_INIT_TIMEOUT) == SOCKET_ERROR) {
204 jack_error(
"Can't set timeout : %s", StrError(NET_ERROR_CODE));
215 SessionParamsNToH(&net_params, &fParams);
217 if ((rx_bytes == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) {
218 jack_error(
"Error in receive : %s", StrError(NET_ERROR_CODE));
219 if (++attempt == 10) {
220 jack_error(
"Can't receive on the socket, exiting net manager" );
226 switch (GetPacketType(&fParams)) {
228 case SLAVE_AVAILABLE:
230 SessionParamsDisplay(&fParams);
250 result->audio_input = fParams.fSendAudioChannels;
251 result->audio_output = fParams.fReturnAudioChannels;
252 result->midi_input = fParams.fSendMidiChannels;
253 result->midi_output = fParams.fReturnMidiChannels;
254 result->mtu = fParams.fMtu;
255 result->latency = fParams.fNetworkLatency;
266 if (fParams.fProtocolVersion != MASTER_PROTOCOL) {
267 jack_error(
"Error : slave is running with a different protocol %s", fParams.fName);
272 fSocket.GetName(fParams.fMasterNetName);
274 fParams.fPeriodSize = fRequest.buffer_size;
275 fParams.fSampleRate = fRequest.sample_rate;
277 if (fRequest.audio_input == -1) {
278 if (fParams.fSendAudioChannels == -1) {
279 jack_error(
"Error : master and slave use -1 for wanted inputs...");
282 result->audio_input = fParams.fSendAudioChannels;
283 jack_info(
"Takes slave %d inputs", fParams.fSendAudioChannels);
285 }
else if (fParams.fSendAudioChannels == -1) {
286 fParams.fSendAudioChannels = fRequest.audio_input;
287 jack_info(
"Takes master %d inputs", fRequest.audio_input);
288 }
else if (fParams.fSendAudioChannels != fRequest.audio_input) {
289 jack_error(
"Error : master wants %d inputs and slave wants %d inputs...", fRequest.audio_input, fParams.fSendAudioChannels);
293 if (fRequest.audio_output == -1) {
294 if (fParams.fReturnAudioChannels == -1) {
295 jack_error(
"Error : master and slave use -1 for wanted outputs...");
298 result->audio_output = fParams.fReturnAudioChannels;
299 jack_info(
"Takes slave %d outputs", fParams.fReturnAudioChannels);
301 }
else if (fParams.fReturnAudioChannels == -1) {
302 fParams.fReturnAudioChannels = fRequest.audio_output;
303 jack_info(
"Takes master %d outputs", fRequest.audio_output);
304 }
else if (fParams.fReturnAudioChannels != fRequest.audio_output) {
305 jack_error(
"Error : master wants %d outputs and slave wants %d outputs...", fRequest.audio_output, fParams.fReturnAudioChannels);
313 if (!JackNetMasterInterface::Init()) {
336 if (fParams.fSendAudioChannels > 0) {
337 fAudioCaptureBuffer =
new float*[fParams.fSendAudioChannels];
338 for (
int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) {
339 fAudioCaptureBuffer[audio_port_index] =
new float[fParams.fPeriodSize];
340 fNetAudioCaptureBuffer->SetBuffer(audio_port_index, fAudioCaptureBuffer[audio_port_index]);
344 if (fParams.fSendMidiChannels > 0) {
345 fMidiCaptureBuffer =
new JackMidiBuffer*[fParams.fSendMidiChannels];
346 for (
int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
347 fMidiCaptureBuffer[midi_port_index] = (
JackMidiBuffer*)
new float[fParams.fPeriodSize];
348 fNetMidiCaptureBuffer->SetBuffer(midi_port_index, fMidiCaptureBuffer[midi_port_index]);
352 if (fParams.fReturnAudioChannels > 0) {
353 fAudioPlaybackBuffer =
new float*[fParams.fReturnAudioChannels];
354 for (
int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) {
355 fAudioPlaybackBuffer[audio_port_index] =
new float[fParams.fPeriodSize];
356 fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, fAudioPlaybackBuffer[audio_port_index]);
360 if (fParams.fReturnMidiChannels > 0) {
361 fMidiPlaybackBuffer =
new JackMidiBuffer*[fParams.fReturnMidiChannels];
362 for (
int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
363 fMidiPlaybackBuffer[midi_port_index] = (
JackMidiBuffer*)
new float[fParams.fPeriodSize];
364 fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, fMidiPlaybackBuffer[midi_port_index]);
371 if (fAudioPlaybackBuffer) {
372 for (
int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++)
373 delete[] fAudioPlaybackBuffer[audio_port_index];
374 delete[] fAudioPlaybackBuffer;
375 fAudioPlaybackBuffer = NULL;
378 if (fMidiPlaybackBuffer) {
379 for (
int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++)
380 delete[] (fMidiPlaybackBuffer[midi_port_index]);
381 delete[] fMidiPlaybackBuffer;
382 fMidiPlaybackBuffer = NULL;
385 if (fAudioCaptureBuffer) {
386 for (
int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++)
387 delete[] fAudioCaptureBuffer[audio_port_index];
388 delete[] fAudioCaptureBuffer;
389 fAudioCaptureBuffer = NULL;
392 if (fMidiCaptureBuffer) {
393 for (
int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++)
394 delete[] fMidiCaptureBuffer[midi_port_index];
395 delete[] fMidiCaptureBuffer;
396 fMidiCaptureBuffer = NULL;
400 int Read(
int audio_input,
float** audio_input_buffer,
int midi_input,
void** midi_input_buffer)
405 assert(audio_input == fParams.fReturnAudioChannels);
407 for (
int audio_port_index = 0; audio_port_index < audio_input; audio_port_index++) {
408 fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, audio_input_buffer[audio_port_index]);
411 for (
int midi_port_index = 0; midi_port_index < midi_input; midi_port_index++) {
412 fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, ((
JackMidiBuffer**)midi_input_buffer)[midi_port_index]);
416 int res = SyncRecv();
417 if ((res == 0) || (res == SOCKET_ERROR)) {
430 int Write(
int audio_output,
float** audio_output_buffer,
int midi_output,
void** midi_output_buffer)
434 assert(audio_output == fParams.fSendAudioChannels);
436 for (
int audio_port_index = 0; audio_port_index < audio_output; audio_port_index++) {
437 fNetAudioCaptureBuffer->SetBuffer(audio_port_index, audio_output_buffer[audio_port_index]);
440 for (
int midi_port_index = 0; midi_port_index < midi_output; midi_port_index++) {
441 fNetMidiCaptureBuffer->SetBuffer(midi_port_index, ((
JackMidiBuffer**)midi_output_buffer)[midi_port_index]);
449 if (SyncSend() == SOCKET_ERROR) {
454 if (DataSend() == SOCKET_ERROR) {
459 jack_info(
"Connection is not synched, skip cycle...");
471 void EncodeTransportData()
474 void DecodeTransportData()
483 JackNetSlaveProcessCallback fProcessCallback;
486 JackNetSlaveShutdownCallback fShutdownCallback;
489 JackNetSlaveBufferSizeCallback fBufferSizeCallback;
490 void* fBufferSizeArg;
492 JackNetSlaveSampleRateCallback fSampleRateCallback;
493 void* fSampleRateArg;
496 float** fAudioCaptureBuffer;
497 float** fAudioPlaybackBuffer;
509 fProcessCallback(NULL),fProcessArg(NULL),
510 fShutdownCallback(NULL), fShutdownArg(NULL),
511 fBufferSizeCallback(NULL), fBufferSizeArg(NULL),
512 fSampleRateCallback(NULL), fSampleRateArg(NULL),
513 fAudioCaptureBuffer(NULL), fAudioPlaybackBuffer(NULL),
514 fMidiCaptureBuffer(NULL), fMidiPlaybackBuffer(NULL)
516 char host_name[JACK_CLIENT_NAME_SIZE];
519 assert(strlen(ip) < 32);
520 strcpy(fMulticastIP, ip);
521 fParams.fMtu = request->mtu;
522 fParams.fTransportSync = 0;
523 fParams.fSendAudioChannels = request->audio_input;
524 fParams.fReturnAudioChannels = request->audio_output;
525 fParams.fSendMidiChannels = request->midi_input;
526 fParams.fReturnMidiChannels = request->midi_output;
527 fParams.fNetworkLatency = request->latency;
528 fParams.fSampleEncoder = request->encoder;
529 fParams.fKBps = request->kbps;
530 fParams.fSlaveSyncMode = 1;
531 fConnectTimeOut = request->time_out;
534 GetHostName(host_name, JACK_CLIENT_NAME_SIZE);
535 snprintf(fParams.fName, JACK_CLIENT_NAME_SIZE,
"%s_%s", host_name, name);
536 fSocket.GetName(fParams.fSlaveNetName);
539 fSocket.SetPort(port);
540 fSocket.SetAddress(fMulticastIP, port);
549 if ((fParams.fSampleEncoder == JackCeltEncoder) && (fParams.fKBps == 0)) {
554 if ((fParams.fSampleEncoder == JackOpusEncoder) && (fParams.fKBps == 0)) {
560 if (fParams.fNetworkLatency > NETWORK_MAX_LATENCY) {
561 jack_error(
"Error : network latency is limited to %d", NETWORK_MAX_LATENCY);
566 if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) {
572 if (!JackNetSlaveInterface::InitRendering()) {
584 if (result != NULL) {
585 result->buffer_size = fParams.fPeriodSize;
586 result->sample_rate = fParams.fSampleRate;
587 result->audio_input = fParams.fSendAudioChannels;
588 result->audio_output = fParams.fReturnAudioChannels;
589 result->midi_input = fParams.fSendMidiChannels;
590 result->midi_output = fParams.fReturnMidiChannels;
591 strcpy(result->master_name, fParams.fMasterNetName);
601 if (fShutdownCallback) {
602 fShutdownCallback(fShutdownArg);
606 if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) {
612 if (!JackNetSlaveInterface::InitRendering()) {
624 if (fBufferSizeCallback) {
625 fBufferSizeCallback(fParams.fPeriodSize, fBufferSizeArg);
628 if (fSampleRateCallback) {
629 fSampleRateCallback(fParams.fSampleRate, fSampleRateArg);
646 fAudioCaptureBuffer =
new float*[fParams.fSendAudioChannels];
647 for (
int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) {
648 fAudioCaptureBuffer[audio_port_index] =
new float[fParams.fPeriodSize];
649 fNetAudioCaptureBuffer->SetBuffer(audio_port_index, fAudioCaptureBuffer[audio_port_index]);
652 fMidiCaptureBuffer =
new JackMidiBuffer*[fParams.fSendMidiChannels];
653 for (
int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
654 fMidiCaptureBuffer[midi_port_index] = (
JackMidiBuffer*)
new float[fParams.fPeriodSize];
655 fNetMidiCaptureBuffer->SetBuffer(midi_port_index, fMidiCaptureBuffer[midi_port_index]);
658 fAudioPlaybackBuffer =
new float*[fParams.fReturnAudioChannels];
659 for (
int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) {
660 fAudioPlaybackBuffer[audio_port_index] =
new float[fParams.fPeriodSize];
661 fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, fAudioPlaybackBuffer[audio_port_index]);
664 fMidiPlaybackBuffer =
new JackMidiBuffer*[fParams.fReturnMidiChannels];
665 for (
int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
666 fMidiPlaybackBuffer[midi_port_index] = (
JackMidiBuffer*)
new float[fParams.fPeriodSize];
667 fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, fMidiPlaybackBuffer[midi_port_index]);
673 if (fAudioCaptureBuffer) {
674 for (
int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) {
675 delete[] fAudioCaptureBuffer[audio_port_index];
677 delete[] fAudioCaptureBuffer;
678 fAudioCaptureBuffer = NULL;
681 if (fMidiCaptureBuffer) {
682 for (
int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
683 delete[] (fMidiCaptureBuffer[midi_port_index]);
685 delete[] fMidiCaptureBuffer;
686 fMidiCaptureBuffer = NULL;
689 if (fAudioPlaybackBuffer) {
690 for (
int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) {
691 delete[] fAudioPlaybackBuffer[audio_port_index];
693 delete[] fAudioPlaybackBuffer;
694 fAudioPlaybackBuffer = NULL;
697 if (fMidiPlaybackBuffer) {
698 for (
int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
699 delete[] fMidiPlaybackBuffer[midi_port_index];
701 delete[] fMidiPlaybackBuffer;
702 fMidiPlaybackBuffer = NULL;
707 void EncodeTransportData()
710 void DecodeTransportData()
716 UInt64 period, constraint;
717 period = constraint = UInt64(1000000000.f * (
float(fParams.fPeriodSize) /
float(fParams.fSampleRate)));
718 UInt64 computation = JackTools::ComputationMicroSec(fParams.fPeriodSize) * 1000;
719 fThread.SetParams(period, computation, constraint);
721 return (fThread.AcquireSelfRealTime(80) == 0);
728 while (fThread.GetStatus() == JackThread::kRunning) {
729 if (Process() == SOCKET_ERROR) {
738 fThread.DropRealTime();
739 fThread.SetStatus(JackThread::kIniting);
741 if (Restart() == 0 &&
Init()) {
742 fThread.SetStatus(JackThread::kRunning);
753 if (SyncRecv() == SOCKET_ERROR) {
765 if (SyncSend() == SOCKET_ERROR) {
775 if (Read() == SOCKET_ERROR) {
779 fProcessCallback(fParams.fPeriodSize,
780 fParams.fSendAudioChannels,
782 fParams.fSendMidiChannels,
783 (
void**)fMidiCaptureBuffer,
784 fParams.fReturnAudioChannels,
785 fAudioPlaybackBuffer,
786 fParams.fReturnMidiChannels,
787 (
void**)fMidiPlaybackBuffer,
791 if (Write() == SOCKET_ERROR) {
800 return (fProcessCallback == 0) ? -1 : fThread.StartSync();
805 return (fProcessCallback == 0) ? -1 : fThread.Kill();
809 int SetProcessCallback(JackNetSlaveProcessCallback net_callback,
void *arg)
811 if (fThread.GetStatus() == JackThread::kRunning) {
814 fProcessCallback = net_callback;
820 int SetShutdownCallback(JackNetSlaveShutdownCallback shutdown_callback,
void *arg)
822 if (fThread.GetStatus() == JackThread::kRunning) {
825 fShutdownCallback = shutdown_callback;
831 int SetBufferSizeCallback(JackNetSlaveBufferSizeCallback bufsize_callback,
void *arg)
833 if (fThread.GetStatus() == JackThread::kRunning) {
836 fBufferSizeCallback = bufsize_callback;
837 fBufferSizeArg = arg;
842 int SetSampleRateCallback(JackNetSlaveSampleRateCallback samplerate_callback,
void *arg)
844 if (fThread.GetStatus() == JackThread::kRunning) {
847 fSampleRateCallback = samplerate_callback;
848 fSampleRateArg = arg;
858 jack_nframes_t host_buffer_size,
859 jack_nframes_t host_sample_rate,
860 jack_nframes_t adapted_buffer_size,
861 jack_nframes_t adapted_sample_rate)
864 fCaptureChannels = input;
865 fPlaybackChannels = output;
873 if (fCaptureChannels > 0) {
876 if (fPlaybackChannels > 0) {
881 AdaptRingBufferSize();
882 jack_info(
"Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize);
884 if (fRingbufferCurSize > DEFAULT_RB_SIZE) {
885 fRingbufferCurSize = DEFAULT_RB_SIZE;
887 jack_info(
"Fixed ringbuffer size = %d frames", fRingbufferCurSize);
890 for (
int i = 0; i < fCaptureChannels; i++ ) {
892 fCaptureRingBuffer[i]->Reset(fRingbufferCurSize);
894 for (
int i = 0; i < fPlaybackChannels; i++ ) {
896 fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize);
899 if (fCaptureChannels > 0) {
900 jack_log(
"ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace());
902 if (fPlaybackChannels > 0) {
903 jack_log(
"WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace());
914 for (
int i = 0; i < fCaptureChannels; i++ ) {
915 fCaptureRingBuffer[i]->Reset(fRingbufferCurSize);
917 for (
int i = 0; i < fPlaybackChannels; i++ ) {
918 fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize);
927 using namespace Jack;
929 LIB_EXPORT jack_net_slave_t* jack_net_slave_open(
const char* ip,
int port,
const char* name,
jack_slave_t* request,
jack_master_t* result)
932 if (slave->Open(result) == 0) {
933 return (jack_net_slave_t*)slave;
940 LIB_EXPORT
int jack_net_slave_close(jack_net_slave_t* net)
948 LIB_EXPORT
int jack_set_net_slave_process_callback(jack_net_slave_t* net, JackNetSlaveProcessCallback net_callback,
void *arg)
951 return slave->SetProcessCallback(net_callback, arg);
954 LIB_EXPORT
int jack_net_slave_activate(jack_net_slave_t* net)
957 return slave->Start();
960 LIB_EXPORT
int jack_net_slave_deactivate(jack_net_slave_t* net)
963 return slave->Stop();
966 LIB_EXPORT
int jack_set_net_slave_buffer_size_callback(jack_net_slave_t *net, JackNetSlaveBufferSizeCallback bufsize_callback,
void *arg)
969 return slave->SetBufferSizeCallback(bufsize_callback, arg);
972 LIB_EXPORT
int jack_set_net_slave_sample_rate_callback(jack_net_slave_t *net, JackNetSlaveSampleRateCallback samplerate_callback,
void *arg)
975 return slave->SetSampleRateCallback(samplerate_callback, arg);
978 LIB_EXPORT
int jack_set_net_slave_shutdown_callback(jack_net_slave_t *net, JackNetSlaveShutdownCallback shutdown_callback,
void *arg)
981 return slave->SetShutdownCallback(shutdown_callback, arg);
986 LIB_EXPORT jack_net_master_t* jack_net_master_open(
const char* ip,
int port,
const char* name,
jack_master_t* request,
jack_slave_t* result)
989 if (master->Open(result) == 0) {
990 return (jack_net_master_t*)master;
997 LIB_EXPORT
int jack_net_master_close(jack_net_master_t* net)
1005 LIB_EXPORT
int jack_net_master_recv(jack_net_master_t* net,
int audio_input,
float** audio_input_buffer,
int midi_input,
void** midi_input_buffer)
1008 return master->Read(audio_input, audio_input_buffer, midi_input, midi_input_buffer);
1011 LIB_EXPORT
int jack_net_master_send(jack_net_master_t* net,
int audio_output,
float** audio_output_buffer,
int midi_output,
void** midi_output_buffer)
1014 return master->Write(audio_output, audio_output_buffer, midi_output, midi_output_buffer);
1019 LIB_EXPORT jack_adapter_t* jack_create_adapter(
int input,
int output,
1020 jack_nframes_t host_buffer_size,
1021 jack_nframes_t host_sample_rate,
1022 jack_nframes_t adapted_buffer_size,
1023 jack_nframes_t adapted_sample_rate)
1026 return (jack_adapter_t*)
new JackNetAdapter(input, output, host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate);
1032 LIB_EXPORT
int jack_destroy_adapter(jack_adapter_t* adapter)
1038 LIB_EXPORT
void jack_flush_adapter(jack_adapter_t* adapter)
1044 LIB_EXPORT
int jack_adapter_push_and_pull(jack_adapter_t* adapter,
float** input,
float** output,
unsigned int frames)
1047 return slave->PushAndPull(input, output, frames);
1050 LIB_EXPORT
int jack_adapter_pull_and_push(jack_adapter_t* adapter,
float** input,
float** output,
unsigned int frames)
1053 return slave->PullAndPush(input, output, frames);
1056 static void jack_format_and_log(
int level,
const char *prefix,
const char *fmt, va_list ap)
1058 static const char* netjack_log = getenv(
"JACK_NETJACK_LOG");
1059 static bool is_netjack_log = (netjack_log) ? atoi(netjack_log) : 0;
1061 if (is_netjack_log) {
1065 if (prefix != NULL) {
1066 len = strlen(prefix);
1067 memcpy(buffer, prefix, len);
1072 vsnprintf(buffer + len,
sizeof(buffer) - len, fmt, ap);
1073 printf(
"%s", buffer);
1078 LIB_EXPORT
void jack_error(
const char *fmt, ...)
1082 jack_format_and_log(LOG_LEVEL_INFO,
"Jack: ", fmt, ap);
1086 LIB_EXPORT
void jack_info(
const char *fmt, ...)
1090 jack_format_and_log(LOG_LEVEL_INFO,
"Jack: ", fmt, ap);
1094 LIB_EXPORT
void jack_log(
const char *fmt, ...)
1098 jack_format_and_log(LOG_LEVEL_INFO,
"Jack: ", fmt, ap);
int InitMaster(jack_slave_t *result)
The base class for runnable objects, that have an Init and Execute method to be called in a threa...
SERVER_EXPORT void jack_error(const char *fmt,...)
Base class for Resampler.
SERVER_EXPORT void jack_info(const char *fmt,...)
Base class for audio adapters.
Exception possibly thrown by Net slaves.
This structure containes master/slave connection parameters, it's used to setup the whole system...
SERVER_EXPORT void jack_log(const char *fmt,...)
Darwin threads. Real-time threads are actually "time constraint" threads.