~ubuntu-branches/ubuntu/karmic/recordmydesktop/karmic

« back to all changes in this revision

Viewing changes to src/rmd_jack.c

  • Committer: Bazaar Package Importer
  • Author(s): Alan Pope
  • Date: 2009-04-21 10:57:22 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20090421105722-w6l4gz958gva15wn
Tags: 0.3.8.1-0ubuntu1
* New upstream release (LP: #364674)
* debian/control: Fixed libjack0.100.0-dev dependancy
* debian/control: Fixed project home page

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
*   For further information contact me at johnvarouhakis@gmail.com            *
25
25
******************************************************************************/
26
26
 
27
 
 
28
 
#include <recordmydesktop.h>
29
 
 
30
 
#ifdef HAVE_JACK_H
31
 
int JackCapture(jack_nframes_t nframes,void *jdata_t){
 
27
#include "config.h"
 
28
#include "rmd_jack.h"
 
29
 
 
30
#include "rmd_types.h"
 
31
 
 
32
#include <pthread.h>
 
33
 
 
34
#include <string.h>
 
35
 
 
36
#ifdef HAVE_LIBJACK
 
37
 
 
38
 
 
39
/**
 
40
*   Callback for capture through jack
 
41
*
 
42
*   \param  nframes Number of frames captured
 
43
*
 
44
*   \param jdata_t  Pointer to JackData struct containing port
 
45
*                   and client information
 
46
*
 
47
*   \returns Zero always
 
48
*/
 
49
static int JackCapture(jack_nframes_t nframes,void *jdata_t) {
32
50
    int i=0;
33
51
    JackData *jdata=(JackData *)jdata_t;
34
52
 
35
 
    if((!*Running)||(Paused) || (!jdata->capture_started))
 
53
    if (!jdata->pdata->running  || jdata->pdata->paused || !jdata->capture_started) {
36
54
        return 0;
 
55
    }
 
56
 
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]),
45
65
                                   nframes*
46
66
                                   sizeof(jack_default_audio_sample_t));
59
79
    return 0;
60
80
}
61
81
 
62
 
int SetupPorts(JackData *jdata){
 
82
/**
 
83
*   Register and Activate specified ports
 
84
*
 
85
*   \param jdata_t  Pointer to JackData struct containing port
 
86
*                   and client information
 
87
*
 
88
*   \returns 0 on Success, 1 on failure
 
89
*/
 
90
static int SetupPorts(JackData *jdata) {
63
91
    int i=0;
64
92
    jdata->ports=malloc(sizeof(jack_port_t *)*
65
93
                               jdata->nports);
72
100
        char name[64];//recordMyDesktop:input_n<64 is enough for full name
73
101
        char num[8];
74
102
        strcpy(name,"input_");
75
 
        I16TOA((i+1),num);
 
103
        snprintf( num, 8, "%d", i+1 );
76
104
        strcat(name,num);
77
 
        if((jdata->ports[i]=jack_port_register_p(jdata->client,
 
105
        if((jdata->ports[i]=jack_port_register(jdata->client,
78
106
                                                 name,
79
107
                                                 JACK_DEFAULT_AUDIO_TYPE,
80
108
                                                 JackPortIsInput,
82
110
            fprintf(stderr,"Cannot register input port \"%s\"!\n",name);
83
111
            return 1;
84
112
        }
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]);
91
119
            return 1;
92
120
        }
94
122
    return 0;
95
123
}
96
124
 
97
 
int LoadJackLib(void *jack_lib_handle){
98
 
    char *error;
99
 
    jack_lib_handle=dlopen("libjack.so",RTLD_LAZY);
100
 
    if(!jack_lib_handle){
101
 
        fprintf(stderr,"%s\n",dlerror());
102
 
        return 1;
103
 
    }
104
 
    if((error=dlerror())!=NULL){
105
 
        fprintf(stderr,"%s\n",dlerror());
106
 
    }
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)
126
 
 
127
 
    return 0;
128
 
}
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;
 
131
 
 
132
    jdata->pdata->running = FALSE;
 
133
 
134
134
    fprintf (stderr, "JACK shutdown\n");
135
 
    *Running=0;
136
135
}
137
136
 
138
137
int StartJackClient(JackData *jdata){
148
147
    //to connetc to a Jack Server
149
148
    strcpy(rmd_client_name,"recordMyDesktop-");
150
149
    pid=getpid();
151
 
    I16TOA(pid,pidbuf)
 
150
    snprintf( pidbuf, 8, "%d", pid );
152
151
    strcat(rmd_client_name,pidbuf);
153
152
 
154
 
    if(LoadJackLib(jdata->jack_lib_handle)){
155
 
        fprintf (stderr,"Couldn't load the Jack library (libjack.so)!\n");
156
 
        return 14;
157
 
    }
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");
161
156
        return 15;
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)*
181
176
                      jdata->nports);
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);
186
181
 
187
 
    if (jack_activate_p(jdata->client)) {
 
182
    if (jack_activate(jdata->client)) {
188
183
        fprintf(stderr,"cannot activate client!\n");
189
184
        return 16;
190
185
    }
191
186
    if(SetupPorts(jdata)){
192
 
        jack_client_close_p(jdata->client);
 
187
        jack_client_close(jdata->client);
193
188
        return 17;
194
189
    }
195
190
 
199
194
int StopJackClient(JackData *jdata){
200
195
    int ret=0;
201
196
 
202
 
    (*jack_ringbuffer_free_p)(jdata->sound_buffer);
203
 
    if(jack_client_close_p(jdata->client)){
 
197
    (*jack_ringbuffer_free)(jdata->sound_buffer);
 
198
    if(jack_client_close(jdata->client)){
204
199
        fprintf(stderr,"Cannot close Jack client!\n");
205
200
        ret=1;
206
201
    }