-
Notifications
You must be signed in to change notification settings - Fork 24
/
jack.c
156 lines (129 loc) · 3.92 KB
/
jack.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <jack/jack.h>
#include "jack.h"
#include "config.h"
jack_client_t *client;
jack_port_t **output_ports;
#ifdef INPUT
jack_port_t *input_port;
#endif
int process(jack_nframes_t nframes, void *arg) {
jack_default_audio_sample_t *out[g_num_channels+1];
#ifdef INPUT
jack_default_audio_sample_t *in;
#endif
t_callback callback = (t_callback) arg;
int i;
for (i = 0; i < g_num_channels; ++i) {
out[i] = jack_port_get_buffer(output_ports[i], nframes);
}
#ifdef INPUT
in = jack_port_get_buffer(input_port, nframes);
callback(nframes, in, out);
#else
callback(nframes, NULL, out);
#endif
return 0;
}
void jack_shutdown(void *arg) {
if (output_ports) free(output_ports);
exit(1);
}
extern jack_client_t *jack_start(t_callback callback, bool autoconnect) {
const char *client_name = "dirt";
const char *server_name = NULL;
jack_options_t options = JackNullOption;
jack_status_t status;
int i;
char portname[16];
/* open a client connection to the JACK server */
client = jack_client_open(client_name, options, &status, server_name);
if (client == NULL) {
fprintf(stderr, "jack_client_open() failed, "
"status = 0x%2.0x\n", status);
if (status & JackServerFailed) {
fprintf(stderr, "Unable to connect to JACK server\n");
}
exit(1);
}
if (status & JackServerStarted) {
fprintf(stderr, "JACK server started\n");
}
if (status & JackNameNotUnique) {
client_name = jack_get_client_name(client);
fprintf(stderr, "unique name `%s' assigned\n", client_name);
}
jack_set_process_callback(client, process, (void *) callback);
jack_on_shutdown(client, jack_shutdown, 0);
printf("engine sample rate: %" PRIu32 "\n",
jack_get_sample_rate(client));
#ifdef INPUT
strcpy(portname, "input");
input_port = jack_port_register(client, portname,
JACK_DEFAULT_AUDIO_TYPE,
JackPortIsInput, 0);
if (input_port == NULL) {
fprintf(stderr, "no JACK input ports available\n");
exit(1);
}
#endif
output_ports = malloc((g_num_channels + 1) * sizeof(jack_port_t*));
if (!output_ports) {
fprintf(stderr, "no memory to allocate `output_ports'\n");
exit(1);
}
for (i = 0; i < g_num_channels; ++i) {
sprintf(portname, "output_%d", i);
output_ports[i] = jack_port_register(client, portname,
JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, 0);
if (output_ports[i] == NULL) {
fprintf(stderr, "no more JACK ports available\n");
if (output_ports) free(output_ports);
exit(1);
}
}
output_ports[g_num_channels] = NULL;
if (jack_activate(client)) {
fprintf(stderr, "cannot activate client");
if (output_ports) free(output_ports);
exit(1);
}
if (autoconnect) {
const char **ports;
ports = jack_get_ports(client, NULL, NULL,
JackPortIsPhysical|JackPortIsInput);
if (!ports) {
fprintf(stderr, "cannot find any physical capture ports\n");
} else {
for (i = 0; i < g_num_channels; ++i) {
if (ports[i] == NULL) {
break;
}
//sprintf(portname, "output_%d", i);
if (jack_connect(client, jack_port_name(output_ports[i]), ports[i])) {
fprintf(stderr, "cannot connect output ports\n");
}
}
free(ports);
}
#ifdef INPUT
ports = jack_get_ports(client, NULL, NULL,
JackPortIsPhysical|JackPortIsOutput);
//strcpy(portname, "input");
if (!ports) {
fprintf(stderr, "cannot find any physical capture ports\n");
} else {
if (jack_connect(client, ports[0], jack_port_name(input_port))) {
fprintf(stderr, "cannot connect input port\n");
}
free(ports);
}
#endif
}
return(client);
}