24
24
* For further information contact me at johnvarouhakis@gmail.com *
25
25
******************************************************************************/
28
#include <recordmydesktop.h>
31
int JackCapture(jack_nframes_t nframes,void *jdata_t){
30
#include "rmd_types.h"
40
* Callback for capture through jack
42
* \param nframes Number of frames captured
44
* \param jdata_t Pointer to JackData struct containing port
45
* and client information
47
* \returns Zero always
49
static int JackCapture(jack_nframes_t nframes,void *jdata_t) {
33
51
JackData *jdata=(JackData *)jdata_t;
35
if((!*Running)||(Paused) || (!jdata->capture_started))
53
if (!jdata->pdata->running || jdata->pdata->paused || !jdata->capture_started) {
37
57
for(i= 0;i<jdata->nports;i++)
38
jdata->portbuf[i]=jack_port_get_buffer_p(jdata->ports[i],nframes);
58
jdata->portbuf[i]=jack_port_get_buffer(jdata->ports[i],nframes);
39
59
//vorbis analysis buffer wants uninterleaved data
40
60
//so we are simply placing the buffers for every channel
41
61
//sequentially on the ringbuffer
42
62
for(i=0;i<jdata->nports;i++)
43
(*jack_ringbuffer_write_p)(jdata->sound_buffer,
63
(*jack_ringbuffer_write)(jdata->sound_buffer,
44
64
(void *)(jdata->portbuf[i]),
46
66
sizeof(jack_default_audio_sample_t));
82
110
fprintf(stderr,"Cannot register input port \"%s\"!\n",name);
85
if(jack_connect_p(jdata->client,
113
if(jack_connect(jdata->client,
86
114
jdata->port_names[i],
87
jack_port_name_p(jdata->ports[i]))){
115
jack_port_name(jdata->ports[i]))){
88
116
fprintf(stderr,"Cannot connect input port %s to %s\n",
89
jack_port_name_p(jdata->ports[i]),
117
jack_port_name(jdata->ports[i]),
90
118
jdata->port_names[i]);
97
int LoadJackLib(void *jack_lib_handle){
99
jack_lib_handle=dlopen("libjack.so",RTLD_LAZY);
100
if(!jack_lib_handle){
101
fprintf(stderr,"%s\n",dlerror());
104
if((error=dlerror())!=NULL){
105
fprintf(stderr,"%s\n",dlerror());
107
//this macro will call return with status 1 on failure
108
DLSYM_AND_CHECK(jack_lib_handle,jack_client_new,error)
109
DLSYM_AND_CHECK(jack_lib_handle,jack_get_sample_rate,error)
110
DLSYM_AND_CHECK(jack_lib_handle,jack_set_buffer_size,error)
111
DLSYM_AND_CHECK(jack_lib_handle,jack_get_buffer_size,error)
112
DLSYM_AND_CHECK(jack_lib_handle,jack_set_process_callback,error)
113
DLSYM_AND_CHECK(jack_lib_handle,jack_on_shutdown,error)
114
DLSYM_AND_CHECK(jack_lib_handle,jack_activate,error)
115
DLSYM_AND_CHECK(jack_lib_handle,jack_client_close,error)
116
DLSYM_AND_CHECK(jack_lib_handle,jack_port_get_buffer,error)
117
DLSYM_AND_CHECK(jack_lib_handle,jack_port_register,error)
118
DLSYM_AND_CHECK(jack_lib_handle,jack_connect,error)
119
DLSYM_AND_CHECK(jack_lib_handle,jack_port_name,error)
120
DLSYM_AND_CHECK(jack_lib_handle,jack_port_name_size,error)
121
DLSYM_AND_CHECK(jack_lib_handle,jack_ringbuffer_create,error)
122
DLSYM_AND_CHECK(jack_lib_handle,jack_ringbuffer_free,error)
123
DLSYM_AND_CHECK(jack_lib_handle,jack_ringbuffer_read,error)
124
DLSYM_AND_CHECK(jack_lib_handle,jack_ringbuffer_read_space,error)
125
DLSYM_AND_CHECK(jack_lib_handle,jack_ringbuffer_write,error)
129
125
//in case the jack server shuts down
130
126
//the program should stop recording,
131
127
//encode the result(if not on the fly)
132
128
//an exit cleanly.
133
void JackShutdown(void *jdata_t){
129
static void JackShutdown(void *jdata_t) {
130
JackData *jdata = (JackData *)jdata_t;
132
jdata->pdata->running = FALSE;
134
134
fprintf (stderr, "JACK shutdown\n");
138
137
int StartJackClient(JackData *jdata){
148
147
//to connetc to a Jack Server
149
148
strcpy(rmd_client_name,"recordMyDesktop-");
150
snprintf( pidbuf, 8, "%d", pid );
152
151
strcat(rmd_client_name,pidbuf);
154
if(LoadJackLib(jdata->jack_lib_handle)){
155
fprintf (stderr,"Couldn't load the Jack library (libjack.so)!\n");
158
if ((jdata->client=(*jack_client_new_p)(rmd_client_name))==0){
153
if ((jdata->client=(*jack_client_new)(rmd_client_name))==0){
159
154
fprintf(stderr,"Could not create new client!\n"
160
155
"Make sure that Jack server is running!\n");
173
168
//(it might be in some cases, but it will certainly be the cause
174
169
//of unpredicted problems). A clean exit is preferable
175
170
//and any recording up to that point will be encoded and saved.
176
jdata->frequency=jack_get_sample_rate_p(jdata->client);
177
jdata->buffersize=jack_get_buffer_size_p(jdata->client);
171
jdata->frequency=jack_get_sample_rate(jdata->client);
172
jdata->buffersize=jack_get_buffer_size(jdata->client);
178
173
ring_buffer_size=(jdata->ringbuffer_secs*
179
174
jdata->frequency*
180
175
sizeof(jack_default_audio_sample_t)*
182
177
jdata->sound_buffer=
183
(*jack_ringbuffer_create_p)((int)(ring_buffer_size+0.5));//round up
184
jack_set_process_callback_p(jdata->client,JackCapture,jdata);
185
jack_on_shutdown_p(jdata->client,JackShutdown,jdata);
178
(*jack_ringbuffer_create)((int)(ring_buffer_size+0.5));//round up
179
jack_set_process_callback(jdata->client,JackCapture,jdata);
180
jack_on_shutdown(jdata->client,JackShutdown,jdata);
187
if (jack_activate_p(jdata->client)) {
182
if (jack_activate(jdata->client)) {
188
183
fprintf(stderr,"cannot activate client!\n");
191
186
if(SetupPorts(jdata)){
192
jack_client_close_p(jdata->client);
187
jack_client_close(jdata->client);