~ubuntu-branches/ubuntu/trusty/jack-audio-connection-kit/trusty

« back to all changes in this revision

Viewing changes to drivers/portaudio/portaudio_driver.c

  • Committer: Bazaar Package Importer
  • Author(s): Luca Falavigna
  • Date: 2008-12-06 11:05:15 UTC
  • mfrom: (4.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20081206110515-xa9v9pajr9jqvfvg
Tags: 0.115.6-1ubuntu1
* Merge from Debian unstable, remaining Ubuntu changes:
  - Redirect stderr in bash completion (Debian #504488).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: c; c-file-style: "bsd"; -*- */
 
2
/*
 
3
    Copyright � Grame 2003
 
4
 
 
5
    This program is free software; you can redistribute it and/or modify
 
6
    it under the terms of the GNU General Public License as published by
 
7
    the Free Software Foundation; either version 2 of the License, or
 
8
    (at your option) any later version.
 
9
 
 
10
    This program is distributed in the hope that it will be useful,
 
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
    GNU General Public License for more details.
 
14
 
 
15
    You should have received a copy of the GNU General Public License
 
16
    along with this program; if not, write to the Free Software
 
17
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
18
 
 
19
    Grame Research Laboratory, 9, rue du Garet 69001 Lyon - France
 
20
    grame@rd.grame.fr
 
21
    
 
22
    02-09-03 : Modify jack port naming : add the name of the used driver
 
23
               Add the -n option to load a specific driver using it's name
 
24
    04-09-03 : Correct bug in -n option management : input and ouput have to be treated separately
 
25
    08-09-03 : More robust driver loading code : new portaudio_load_default and portaudio_load_driver functions.
 
26
    24-09-03 : Does not tries to load default device if the required one is not found, returns and error.
 
27
    14-10-03 : After jack port name size extension, does not use fixed length for CoreAudio driver name anymore
 
28
        09-01-04 : Handle different value for channel in and channel out (using -i and -o)
 
29
        12-01-04 : Connect port names (inverse "in" and "out")          
 
30
        13-01-04 : Correct the length of jack port : use JACK_PORT_NAME_SIZE
 
31
        22-03-04 : Remove jack_init_time, rename input and ouput ports using "capture" and "playback" 
 
32
    10-11-04 : S. Letz: Add management of -I option for use with JackPilot.
 
33
        17-11-04 : S. Letz: Better debug code.
 
34
        03-02-05 : S. Letz: fix several driver detection bugs on OSX.
 
35
        06-08-05 : S.Letz: Remove the "-I" parameter, change the semantic of "-n" parameter on OSX : -n (driver name) now correctly uses the PropertyDeviceUID
 
36
                          (persistent accross reboot...) as the identifier for the used coreaudio driver.
 
37
 
 
38
*/
 
39
 
 
40
#include <stdio.h>
 
41
#include <errno.h>
 
42
#include <string.h>
 
43
#include <stdarg.h>
 
44
 
 
45
#include <jack/engine.h>
 
46
#include "portaudio_driver.h"
 
47
 
 
48
#ifdef JACK_USE_MACH_THREADS
 
49
 
 
50
#include <CoreAudio/CoreAudio.h>
 
51
#include <CoreFoundation/CFString.h>
 
52
 
 
53
static OSStatus get_device_name_from_id(AudioDeviceID id, char name[60])
 
54
{
 
55
    UInt32 size = sizeof(char) * 60;
 
56
        OSStatus stat = AudioDeviceGetProperty(id, 0, false,
 
57
                                           kAudioDevicePropertyDeviceName,
 
58
                                           &size,
 
59
                                           &name[0]);
 
60
    return stat;
 
61
}
 
62
 
 
63
static OSStatus get_device_id_from_num(int i, AudioDeviceID * id)
 
64
{
 
65
    OSStatus theStatus;
 
66
    UInt32 theSize;
 
67
    int nDevices;
 
68
    AudioDeviceID *theDeviceList;
 
69
 
 
70
    theStatus =
 
71
        AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices,
 
72
                                     &theSize, NULL);
 
73
    nDevices = theSize / sizeof(AudioDeviceID);
 
74
    theDeviceList =
 
75
        (AudioDeviceID *) malloc(nDevices * sizeof(AudioDeviceID));
 
76
    theStatus =
 
77
        AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &theSize,
 
78
                                 theDeviceList);
 
79
 
 
80
    *id = theDeviceList[i];
 
81
    return theStatus;
 
82
}
 
83
 
 
84
static OSStatus get_device_id_from_uid(char* UID, AudioDeviceID* id)
 
85
{
 
86
        UInt32 size = sizeof(AudioValueTranslation);
 
87
        CFStringRef inIUD = CFStringCreateWithCString(NULL, UID, CFStringGetSystemEncoding());
 
88
        AudioValueTranslation value = { &inIUD, sizeof(CFStringRef), id, sizeof(AudioDeviceID) };
 
89
        if (inIUD == NULL) {
 
90
                return kAudioHardwareUnspecifiedError;
 
91
        } else {
 
92
                OSStatus res = AudioHardwareGetProperty(kAudioHardwarePropertyDeviceForUID, &size, &value);
 
93
                CFRelease(inIUD);
 
94
                return res;
 
95
        }
 
96
}
 
97
 
 
98
#else
 
99
typedef unsigned int AudioDeviceID;
 
100
#endif
 
101
 
 
102
#define PRINTDEBUG 1
 
103
 
 
104
void PALog(char *fmt, ...)
 
105
{
 
106
#ifdef PRINTDEBUG
 
107
    va_list ap;
 
108
    va_start(ap, fmt);
 
109
    fprintf(stderr, "JCA: ");
 
110
    vfprintf(stderr, fmt, ap);
 
111
    va_end(ap);
 
112
#endif
 
113
}
 
114
 
 
115
static int
 
116
paCallback(void *inputBuffer, void *outputBuffer,
 
117
                             unsigned long framesPerBuffer,
 
118
                             PaTimestamp outTime, void *userData)
 
119
{
 
120
        portaudio_driver_t * driver = (portaudio_driver_t*)userData;
 
121
 
 
122
        driver->inPortAudio = (float*)inputBuffer;
 
123
        driver->outPortAudio = (float*)outputBuffer;
 
124
        driver->last_wait_ust = jack_get_microseconds();
 
125
        return driver->engine->run_cycle(driver->engine, framesPerBuffer, 0);
 
126
}
 
127
 
 
128
static int
 
129
portaudio_driver_attach (portaudio_driver_t *driver, jack_engine_t *engine)
 
130
{
 
131
        jack_port_t *port;
 
132
        int port_flags;
 
133
        channel_t chn;
 
134
        char buf[JACK_PORT_NAME_SIZE];
 
135
                
 
136
        driver->engine = engine;
 
137
        
 
138
        driver->engine->set_buffer_size (engine, driver->frames_per_cycle);
 
139
        driver->engine->set_sample_rate (engine, driver->frame_rate);
 
140
        
 
141
        port_flags = JackPortIsOutput|JackPortIsPhysical|JackPortIsTerminal;
 
142
 
 
143
        /*
 
144
        if (driver->has_hw_monitoring) {
 
145
                        port_flags |= JackPortCanMonitor;
 
146
        }
 
147
        */
 
148
 
 
149
        for (chn = 0; chn < driver->capture_nchannels; chn++) {
 
150
                        //snprintf (buf, sizeof(buf) - 1, "%s:capture%lu", driver->driver_name, chn+1);
 
151
                        snprintf (buf, sizeof(buf) - 1, "%s:out%lu", driver->driver_name, chn+1);
 
152
 
 
153
                        if ((port = jack_port_register (driver->client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0)) == NULL) {
 
154
                                        jack_error ("portaudio: cannot register port for %s", buf);
 
155
                                        break;
 
156
                        }
 
157
 
 
158
                        /* XXX fix this so that it can handle: systemic (external) latency
 
159
                        */
 
160
 
 
161
                        jack_port_set_latency (port, driver->frames_per_cycle);
 
162
                        driver->capture_ports = jack_slist_append (driver->capture_ports, port);
 
163
        }
 
164
        
 
165
        port_flags = JackPortIsInput|JackPortIsPhysical|JackPortIsTerminal;
 
166
 
 
167
        for (chn = 0; chn < driver->playback_nchannels; chn++) {
 
168
                        //snprintf (buf, sizeof(buf) - 1, "%s:playback%lu", driver->driver_name, chn+1);
 
169
                        snprintf (buf, sizeof(buf) - 1, "%s:in%lu", driver->driver_name, chn+1);
 
170
 
 
171
                        if ((port = jack_port_register (driver->client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0)) == NULL) {
 
172
                                        jack_error ("portaudio: cannot register port for %s", buf);
 
173
                                        break;
 
174
                        }
 
175
                        
 
176
                        /* XXX fix this so that it can handle: systemic (external) latency
 
177
                        */
 
178
        
 
179
                        jack_port_set_latency (port, driver->frames_per_cycle);
 
180
                        driver->playback_ports = jack_slist_append (driver->playback_ports, port);
 
181
        }
 
182
 
 
183
        jack_activate (driver->client);
 
184
        return 0; 
 
185
}
 
186
 
 
187
static int
 
188
portaudio_driver_detach (portaudio_driver_t *driver, jack_engine_t *engine)
 
189
{
 
190
        JSList *node;
 
191
 
 
192
        if (driver->engine == 0) {
 
193
                        return -1;
 
194
        }
 
195
 
 
196
        for (node = driver->capture_ports; node; node = jack_slist_next (node)) {
 
197
                        jack_port_unregister (driver->client, ((jack_port_t *) node->data));
 
198
        }
 
199
 
 
200
        jack_slist_free (driver->capture_ports);
 
201
        driver->capture_ports = 0;
 
202
                        
 
203
        for (node = driver->playback_ports; node; node = jack_slist_next (node)) {
 
204
                        jack_port_unregister (driver->client, ((jack_port_t *) node->data));
 
205
        }
 
206
 
 
207
        jack_slist_free (driver->playback_ports);
 
208
        driver->playback_ports = 0;
 
209
        
 
210
        driver->engine = 0;
 
211
        return 0; 
 
212
}
 
213
 
 
214
static int
 
215
portaudio_driver_null_cycle (portaudio_driver_t* driver, jack_nframes_t nframes)
 
216
{
 
217
        memset(driver->outPortAudio, 0, (driver->playback_nchannels * nframes * sizeof(float)));
 
218
        return 0;
 
219
}
 
220
 
 
221
static int
 
222
portaudio_driver_read (portaudio_driver_t *driver, jack_nframes_t nframes)
 
223
{
 
224
        jack_default_audio_sample_t *buf;
 
225
        channel_t chn;
 
226
        jack_port_t *port;
 
227
        JSList *node;
 
228
        int i;
 
229
 
 
230
        for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) {
 
231
                        
 
232
                        port = (jack_port_t *)node->data;
 
233
                        
 
234
                        if (jack_port_connected (port) && (driver->inPortAudio != NULL)) {
 
235
                                int channels = driver->capture_nchannels;
 
236
                                float* in = driver->inPortAudio;
 
237
                                buf = jack_port_get_buffer (port, nframes); 
 
238
                                for (i = 0; i< nframes; i++) buf[i] = in[channels*i+chn];
 
239
                        }
 
240
 
 
241
        }
 
242
   
 
243
        driver->engine->transport_cycle_start (driver->engine,
 
244
                                           jack_get_microseconds ());
 
245
        return 0;
 
246
}          
 
247
 
 
248
 
 
249
static int
 
250
portaudio_driver_write (portaudio_driver_t *driver, jack_nframes_t nframes)
 
251
{
 
252
        jack_default_audio_sample_t *buf;
 
253
        channel_t chn;
 
254
        jack_port_t *port;
 
255
        JSList *node;
 
256
        int i,bytes = nframes*sizeof(float);
 
257
        
 
258
        /* Clear in case of nothing is connected */
 
259
        memset(driver->outPortAudio, 0, driver->playback_nchannels*bytes);
 
260
                        
 
261
        for (chn = 0, node = driver->playback_ports; node; node = jack_slist_next (node), chn++) {
 
262
                        
 
263
                        port = (jack_port_t *)node->data;
 
264
                        
 
265
                        if (jack_port_connected (port) && (driver->outPortAudio != NULL)) {
 
266
                                        int channels = driver->playback_nchannels;
 
267
                                        float* out = driver->outPortAudio;
 
268
                                        buf = jack_port_get_buffer (port, nframes);
 
269
                                        for (i = 0; i< nframes; i++) out[channels*i+chn] = buf[i];
 
270
                        }
 
271
        }
 
272
        
 
273
        return 0;
 
274
}
 
275
 
 
276
static int
 
277
portaudio_driver_audio_start (portaudio_driver_t *driver)
 
278
{
 
279
        PaError err = Pa_StartStream(driver->stream);
 
280
        return (err != paNoError) ? -1 : 0;
 
281
}
 
282
 
 
283
static int
 
284
portaudio_driver_audio_stop (portaudio_driver_t *driver)
 
285
{
 
286
        PaError err = Pa_StopStream(driver->stream);
 
287
        return (err != paNoError) ? -1 : 0;
 
288
}
 
289
 
 
290
static int
 
291
portaudio_driver_set_parameters (portaudio_driver_t* driver,
 
292
                                   jack_nframes_t nframes,
 
293
                                   jack_nframes_t rate)
 
294
{
 
295
        int capturing = driver->capturing;
 
296
        int playing = driver->playing;
 
297
 
 
298
        int err = Pa_OpenStream(
 
299
                &driver->stream,
 
300
                ((capturing) ? Pa_GetDefaultInputDeviceID() : paNoDevice),      
 
301
                ((capturing) ? driver->capture_nchannels : 0),             
 
302
                paFloat32,              /* 32-bit float input */
 
303
                NULL,
 
304
                ((playing) ? Pa_GetDefaultOutputDeviceID() : paNoDevice),
 
305
                ((playing) ?  driver->playback_nchannels : 0),        
 
306
                paFloat32,              /* 32-bit float output */
 
307
                NULL,
 
308
                rate,                   /* sample rate */
 
309
                nframes,                /* frames per buffer */
 
310
                0,                              /* number of buffers = default min */
 
311
                paClipOff,              /* we won't output out of
 
312
                                                * range samples so don't
 
313
                                                * bother clipping them */
 
314
                paCallback,
 
315
                driver);
 
316
    
 
317
        if (err == paNoError) {
 
318
        
 
319
                driver->period_usecs = (((float) driver->frames_per_cycle)
 
320
                                        / driver->frame_rate) * 1000000.0f;
 
321
                driver->frame_rate = rate;
 
322
                driver->frames_per_cycle = nframes;
 
323
 
 
324
                /* tell engine about buffer size */
 
325
                if (driver->engine) {
 
326
                        driver->engine->set_buffer_size (
 
327
                                driver->engine, driver->frames_per_cycle);
 
328
                }
 
329
                return 0;
 
330
 
 
331
        } else { 
 
332
 
 
333
                // JOQ: this driver is dead.  How do we terminate it?
 
334
                Pa_Terminate();
 
335
                jack_error("Unable to set portaudio parameters");
 
336
                jack_error("Error number: %d", err);
 
337
                jack_error("Error message: %s", Pa_GetErrorText(err));
 
338
                return EIO;
 
339
        }
 
340
}
 
341
 
 
342
static int
 
343
portaudio_driver_reset_parameters (portaudio_driver_t* driver,
 
344
                                   jack_nframes_t nframes,
 
345
                                   jack_nframes_t rate)
 
346
{
 
347
        if (!jack_power_of_two(nframes)) {
 
348
                jack_error("PA: frames must be a power of two "
 
349
                         "(64, 512, 1024, ...)");
 
350
                return EINVAL;
 
351
        }
 
352
 
 
353
        Pa_CloseStream(driver->stream);
 
354
        return portaudio_driver_set_parameters (driver, nframes, rate);
 
355
}
 
356
 
 
357
static int
 
358
portaudio_driver_bufsize (portaudio_driver_t* driver, jack_nframes_t nframes)
 
359
{
 
360
        int rc;
 
361
 
 
362
        /* This gets called from the engine server thread, so it must
 
363
         * be serialized with the driver thread.  Stopping the audio
 
364
         * also stops that thread. */
 
365
 
 
366
        if (portaudio_driver_audio_stop (driver)) {
 
367
                jack_error ("PA: cannot stop to set buffer size");
 
368
                return EIO;
 
369
        }
 
370
 
 
371
        rc = portaudio_driver_reset_parameters (driver, nframes,
 
372
                                                driver->frame_rate);
 
373
 
 
374
        if (portaudio_driver_audio_start (driver)) {
 
375
                jack_error ("PA: cannot restart after setting buffer size");
 
376
                rc = EIO;
 
377
        }
 
378
 
 
379
        return rc;
 
380
}
 
381
 
 
382
//== instance creation/destruction =============================================
 
383
 
 
384
static int portaudio_load_default (portaudio_driver_t *driver, 
 
385
                                    int numDevices, 
 
386
                                    int capturing, 
 
387
                                    int playing, 
 
388
                                    int* inputDeviceID,
 
389
                                    int* outputDeviceID)
 
390
{
 
391
    const PaDeviceInfo *pdi;
 
392
    int i,j;
 
393
    int found = 0;
 
394
    
 
395
    PALog("Look for default driver\n");
 
396
    
 
397
    *inputDeviceID = Pa_GetDefaultInputDeviceID();
 
398
    *outputDeviceID = Pa_GetDefaultOutputDeviceID();
 
399
 
 
400
    for(i=0; i<numDevices; i++)
 
401
    {
 
402
        pdi = Pa_GetDeviceInfo(i);
 
403
        PALog("---------------------------------------------- #%d\n", i);
 
404
        
 
405
        if (i == Pa_GetDefaultInputDeviceID()) {
 
406
            driver->capture_nchannels = (capturing) ? pdi->maxInputChannels : 0;
 
407
            strcpy (driver->driver_name,pdi->name);
 
408
            found = 1;
 
409
        }
 
410
        
 
411
        if (i == Pa_GetDefaultOutputDeviceID()){
 
412
            driver->playback_nchannels = (playing) ? pdi->maxOutputChannels : 0;
 
413
            strcpy (driver->driver_name,pdi->name);
 
414
            found = 1;
 
415
        }
 
416
        
 
417
        PALog("\nName         = %s\n", pdi->name);
 
418
        PALog("Max Inputs = %d ", pdi->maxInputChannels);
 
419
        PALog("Max Outputs = %d\n", pdi->maxOutputChannels);
 
420
        if( pdi->numSampleRates == -1 ){
 
421
            PALog("Sample Rate Range = %f to %f\n", pdi->sampleRates[0], pdi->sampleRates[1]);
 
422
        }else{
 
423
            PALog("Sample Rates =");
 
424
            for(j=0; j<pdi->numSampleRates; j++){
 
425
                PALog(" %8.2f,", pdi->sampleRates[j]);
 
426
            }
 
427
            PALog("\n");
 
428
        }
 
429
        
 
430
        PALog("Native Sample Formats = ");
 
431
        if (pdi->nativeSampleFormats & paInt8)        PALog("paInt8, ");
 
432
        if (pdi->nativeSampleFormats & paUInt8)       PALog("paUInt8, ");
 
433
        if (pdi->nativeSampleFormats & paInt16)       PALog("paInt16, ");
 
434
        if (pdi->nativeSampleFormats & paInt32)       PALog("paInt32, ");
 
435
        if (pdi->nativeSampleFormats & paFloat32)     PALog("paFloat32, ");
 
436
        if (pdi->nativeSampleFormats & paInt24)       PALog("paInt24, ");
 
437
        if (pdi->nativeSampleFormats & paPackedInt24) PALog("paPackedInt24, ");
 
438
        PALog("\n");
 
439
    }
 
440
    
 
441
    return found;
 
442
}
 
443
 
 
444
static int portaudio_load_driver (portaudio_driver_t *driver, 
 
445
                                    int numDevices, 
 
446
                                    int capturing, 
 
447
                                    int playing, 
 
448
                                    int* inputDeviceID,
 
449
                                    int* outputDeviceID,
 
450
                                    char* driver_name)
 
451
{
 
452
    const PaDeviceInfo *pdi;
 
453
    int found = 0;
 
454
    int i,j;
 
455
    
 
456
    PALog("Look for %s driver\n",driver_name);
 
457
      
 
458
    for(i=0; i<numDevices; i++)
 
459
    {
 
460
        pdi = Pa_GetDeviceInfo(i);
 
461
        PALog("---------------------------------------------- #%d\n", i);
 
462
        
 
463
                // compare the first character
 
464
                if (strncmp (driver_name, pdi->name,
 
465
                     JACK_DRIVER_PARAM_STRING_MAX) == 0) {
 
466
                if (pdi->maxInputChannels > 0) {
 
467
                        *inputDeviceID = i;
 
468
                        driver->capture_nchannels =
 
469
                        (capturing) ? pdi->maxInputChannels : 0;
 
470
                        strcpy(driver->driver_name,pdi->name);
 
471
                        PALog("Found input driver = %s\n", driver_name);
 
472
                        found = 1;
 
473
                }
 
474
            if (pdi->maxOutputChannels > 0) {
 
475
                        *outputDeviceID = i;
 
476
                        driver->playback_nchannels =
 
477
                        (playing) ? pdi->maxOutputChannels : 0;
 
478
                        strcpy (driver->driver_name,pdi->name);
 
479
                        PALog("Found output driver = %s\n", driver_name);
 
480
                        found = 1;
 
481
                } else {
 
482
                        PALog("Found driver without input or ouput = %s\n",
 
483
                       driver_name);
 
484
            }
 
485
        }
 
486
                        
 
487
        PALog("\nName         = %s\n", pdi->name);
 
488
        PALog("Max Inputs = %d ", pdi->maxInputChannels);
 
489
        PALog("Max Outputs = %d\n", pdi->maxOutputChannels);
 
490
        if( pdi->numSampleRates == -1 ){
 
491
            PALog("Sample Rate Range = %f to %f\n", pdi->sampleRates[0],
 
492
                        pdi->sampleRates[1]);
 
493
        }else{
 
494
            PALog("Sample Rates =");
 
495
            for(j=0; j<pdi->numSampleRates; j++){
 
496
                PALog(" %8.2f,", pdi->sampleRates[j]);
 
497
            }
 
498
            PALog("\n");
 
499
        }
 
500
        
 
501
        PALog("Native Sample Formats = ");
 
502
        if (pdi->nativeSampleFormats & paInt8)        PALog("paInt8, ");
 
503
        if (pdi->nativeSampleFormats & paUInt8)       PALog("paUInt8, ");
 
504
        if (pdi->nativeSampleFormats & paInt16)       PALog("paInt16, ");
 
505
        if (pdi->nativeSampleFormats & paInt32)       PALog("paInt32, ");
 
506
        if (pdi->nativeSampleFormats & paFloat32)     PALog("paFloat32, ");
 
507
        if (pdi->nativeSampleFormats & paInt24)       PALog("paInt24, ");
 
508
        if (pdi->nativeSampleFormats & paPackedInt24) PALog("paPackedInt24, ");
 
509
        PALog("\n");
 
510
    }
 
511
    
 
512
    return found;
 
513
}
 
514
 
 
515
/** create a new driver instance
 
516
 */
 
517
static jack_driver_t *
 
518
portaudio_driver_new (char *name, 
 
519
                                jack_client_t* client,
 
520
                                jack_nframes_t frames_per_cycle,
 
521
                                jack_nframes_t rate,
 
522
                                int capturing,
 
523
                                int playing,
 
524
                                int chan_in, 
 
525
                                int chan_out,
 
526
                                DitherAlgorithm dither,
 
527
                                char* driver_name)
 
528
{
 
529
        portaudio_driver_t *driver;
 
530
        PaError err = paNoError;
 
531
        int numDevices;
 
532
        int inputDeviceID,outputDeviceID;
 
533
        int found;
 
534
        
 
535
        PALog("portaudio driver version : %d\n", kVersion);
 
536
        PALog("creating portaudio driver ... %" PRIu32 "|%" PRIu32 "\n",
 
537
                frames_per_cycle, rate);
 
538
 
 
539
        driver = (portaudio_driver_t *) calloc (1, sizeof (portaudio_driver_t));
 
540
 
 
541
        jack_driver_init ((jack_driver_t *) driver);
 
542
 
 
543
        if (!jack_power_of_two(frames_per_cycle)) {
 
544
                jack_error ("PA: -p must be a power of two.");
 
545
                goto error;
 
546
        }
 
547
 
 
548
        driver->frames_per_cycle = frames_per_cycle;
 
549
        driver->frame_rate = rate;
 
550
        driver->capturing = capturing;
 
551
        driver->playing = playing;
 
552
 
 
553
        driver->attach = (JackDriverAttachFunction) portaudio_driver_attach;
 
554
        driver->detach = (JackDriverDetachFunction) portaudio_driver_detach;
 
555
        driver->read = (JackDriverReadFunction) portaudio_driver_read;
 
556
        driver->write = (JackDriverReadFunction) portaudio_driver_write;
 
557
        driver->null_cycle = (JackDriverNullCycleFunction) portaudio_driver_null_cycle;
 
558
        driver->bufsize = (JackDriverBufSizeFunction) portaudio_driver_bufsize;
 
559
        driver->start = (JackDriverStartFunction) portaudio_driver_audio_start;
 
560
        driver->stop = (JackDriverStopFunction) portaudio_driver_audio_stop;
 
561
        driver->stream = NULL;
 
562
 
 
563
#ifdef JACK_USE_MACH_THREADS    
 
564
        AudioDeviceID device_id;
 
565
        if (driver_name) {
 
566
                if (get_device_id_from_uid(driver_name, &device_id) != noErr)
 
567
                        goto error;
 
568
                if (get_device_name_from_id(device_id, driver->driver_name) != noErr)
 
569
                        goto error;
 
570
        } else {
 
571
                if (get_device_id_from_num(0, &device_id) != noErr)
 
572
                        goto error; 
 
573
                if (get_device_name_from_id(device_id, driver->driver_name) != noErr)
 
574
                        goto error;
 
575
        }
 
576
#endif
 
577
       
 
578
        err = Pa_Initialize();
 
579
        PALog("Pa_Initialize OK \n");
 
580
        
 
581
        PALog("Driver name required %s\n",driver->driver_name);
 
582
        numDevices = Pa_CountDevices();
 
583
        
 
584
        if( numDevices < 0 ){
 
585
                PALog("ERROR: Pa_CountDevices returned 0x%x\n", numDevices);
 
586
                err = numDevices;
 
587
                goto error;
 
588
        }
 
589
        
 
590
        PALog("Number of devices = %d\n", numDevices);
 
591
 
 
592
        if (strcmp(driver->driver_name,"") == 0) {
 
593
                found = portaudio_load_default(driver,numDevices,capturing,playing,&inputDeviceID,&outputDeviceID);
 
594
                if (!found) {
 
595
                        PALog("ERROR : default driver has not been found\n");
 
596
                        err = paHostError;
 
597
                        goto error;
 
598
                }
 
599
        }else{
 
600
                found = portaudio_load_driver(driver,numDevices,capturing,playing,&inputDeviceID,&outputDeviceID,driver->driver_name);
 
601
                if (!found) {
 
602
                         PALog("ERROR : driver %s has not been found \n",driver->driver_name);
 
603
                         err = paHostError;
 
604
                         goto error;
 
605
                }
 
606
        }
 
607
 
 
608
        if (err != paNoError) goto error;
 
609
        
 
610
        PALog("Pa_GetDefaultOutputDeviceID() %ld\n", (long)Pa_GetDefaultOutputDeviceID());
 
611
        PALog("Pa_GetDefaultInputDeviceID() %ld\n",  (long)Pa_GetDefaultInputDeviceID());
 
612
        
 
613
        PALog("--------------------------------------------------\n");
 
614
        PALog("CoreAudio driver %s will be loaded\n", driver->driver_name);
 
615
        PALog("inputDeviceID %ld\n",  (long)inputDeviceID);
 
616
        PALog("outputDeviceID %ld\n",  (long)outputDeviceID);
 
617
        PALog("driver->capture_nchannels %ld\n", driver->capture_nchannels);
 
618
        PALog("driver->playback_nchannels %ld\n", driver->playback_nchannels);
 
619
        
 
620
        PALog("chan_in, chan_out %ld %ld\n",  (long)chan_in,  (long)chan_out);
 
621
        
 
622
        if (chan_in > 0) 
 
623
                driver->capture_nchannels = (driver->capture_nchannels < chan_in) ? driver->capture_nchannels : chan_in;
 
624
        
 
625
        if (chan_out > 0) 
 
626
                driver->playback_nchannels = (driver->playback_nchannels < chan_out) ? driver->playback_nchannels : chan_out;
 
627
                
 
628
        PALog("driver->capture_nchannels %ld\n", driver->capture_nchannels);
 
629
        PALog("driver->playback_nchannels %ld\n", driver->playback_nchannels);
 
630
        
 
631
        err = Pa_OpenStream(&driver->stream,
 
632
                                                ((capturing && (driver->capture_nchannels > 0)) ? inputDeviceID : paNoDevice),
 
633
                                                ((capturing) ? driver->capture_nchannels : 0),             
 
634
                                                paFloat32,      // 32 bit floating point input 
 
635
                                                NULL,
 
636
                                                ((playing && (driver->playback_nchannels > 0)) ? outputDeviceID : paNoDevice),
 
637
                                                ((playing) ? driver->playback_nchannels : 0),        
 
638
                                                paFloat32,  // 32 bit floating point output 
 
639
                                                NULL,
 
640
                                                rate,
 
641
                                                frames_per_cycle,            // frames per buffer 
 
642
                                                0,              // number of buffers, if zero then use default minimum 
 
643
                                                paClipOff,      // we won't output out of range samples so don't bother clipping them 
 
644
                                                paCallback,
 
645
                                                driver);
 
646
        
 
647
        if (err != paNoError) goto error;
 
648
        
 
649
        driver->client = client; 
 
650
        driver->period_usecs = (((float) driver->frames_per_cycle) / driver->frame_rate) * 1000000.0f;
 
651
        return((jack_driver_t *) driver);
 
652
 
 
653
error:
 
654
 
 
655
        Pa_Terminate();
 
656
        jack_error("An error occured while using the portaudio stream");
 
657
        jack_error("Error number: %d", err);
 
658
        jack_error("Error message: %s", Pa_GetErrorText(err));
 
659
        free(driver);
 
660
        return NULL;
 
661
}
 
662
 
 
663
/** free all memory allocated by a driver instance
 
664
 */
 
665
static void
 
666
portaudio_driver_delete (portaudio_driver_t *driver)
 
667
{
 
668
        /* Close PortAudio stream and terminate */
 
669
        Pa_CloseStream(driver->stream);
 
670
        Pa_Terminate();
 
671
        free(driver);
 
672
}
 
673
 
 
674
//== driver "plugin" interface =================================================
 
675
 
 
676
/* DRIVER "PLUGIN" INTERFACE */
 
677
 
 
678
jack_driver_desc_t *
 
679
driver_get_descriptor ()
 
680
{
 
681
        jack_driver_desc_t * desc;
 
682
        unsigned int i;
 
683
        desc = calloc (1, sizeof (jack_driver_desc_t));
 
684
 
 
685
        strcpy (desc->name, "portaudio");
 
686
        desc->nparams = 10;
 
687
        desc->params = calloc (desc->nparams,
 
688
                               sizeof (jack_driver_param_desc_t));
 
689
 
 
690
        i = 0;
 
691
        strcpy (desc->params[i].name, "channel");
 
692
        desc->params[i].character  = 'c';
 
693
        desc->params[i].type       = JackDriverParamInt;
 
694
        desc->params[i].value.ui   = 0;
 
695
        strcpy (desc->params[i].short_desc, "Maximum number of channels");
 
696
        strcpy (desc->params[i].long_desc, desc->params[i].short_desc);
 
697
        
 
698
        i++;
 
699
        strcpy (desc->params[i].name, "channelin");
 
700
        desc->params[i].character  = 'i';
 
701
        desc->params[i].type       = JackDriverParamInt;
 
702
        desc->params[i].value.ui   = 0;
 
703
        strcpy (desc->params[i].short_desc, "Maximum number of input channels");
 
704
        strcpy (desc->params[i].long_desc, desc->params[i].short_desc);
 
705
 
 
706
        i++;
 
707
        strcpy (desc->params[i].name, "channelout");
 
708
        desc->params[i].character  = 'o';
 
709
        desc->params[i].type       = JackDriverParamInt;
 
710
        desc->params[i].value.ui   = 0;
 
711
        strcpy (desc->params[i].short_desc, "Maximum number of ouput channels");
 
712
        strcpy (desc->params[i].long_desc, desc->params[i].short_desc);
 
713
 
 
714
        i++;
 
715
        strcpy (desc->params[i].name, "capture");
 
716
        desc->params[i].character  = 'C';
 
717
        desc->params[i].type       = JackDriverParamBool;
 
718
        desc->params[i].value.i    = TRUE;
 
719
        strcpy (desc->params[i].short_desc, "Whether or not to capture");
 
720
        strcpy (desc->params[i].long_desc, desc->params[i].short_desc);
 
721
 
 
722
        i++;
 
723
        strcpy (desc->params[i].name, "playback");
 
724
        desc->params[i].character  = 'P';
 
725
        desc->params[i].type       = JackDriverParamBool;
 
726
        desc->params[i].value.i    = TRUE;
 
727
        strcpy (desc->params[i].short_desc, "Whether or not to playback");
 
728
        strcpy (desc->params[i].long_desc, desc->params[i].short_desc);
 
729
 
 
730
        i++;
 
731
        strcpy (desc->params[i].name, "duplex");
 
732
        desc->params[i].character  = 'D';
 
733
        desc->params[i].type       = JackDriverParamBool;
 
734
        desc->params[i].value.i    = TRUE;
 
735
        strcpy (desc->params[i].short_desc, "Capture and playback");
 
736
        strcpy (desc->params[i].long_desc, desc->params[i].short_desc);
 
737
 
 
738
        i++;
 
739
        strcpy (desc->params[i].name, "rate");
 
740
        desc->params[i].character  = 'r';
 
741
        desc->params[i].type       = JackDriverParamUInt;
 
742
        desc->params[i].value.ui   = 48000U;
 
743
        strcpy (desc->params[i].short_desc, "Sample rate");
 
744
        strcpy (desc->params[i].long_desc, desc->params[i].short_desc);
 
745
 
 
746
        i++;
 
747
        strcpy (desc->params[i].name, "period");
 
748
        desc->params[i].character  = 'p';
 
749
        desc->params[i].type       = JackDriverParamUInt;
 
750
        desc->params[i].value.ui   = 1024U;
 
751
        strcpy (desc->params[i].short_desc, "Frames per period");
 
752
        strcpy (desc->params[i].long_desc, desc->params[i].short_desc);
 
753
        
 
754
        i++;
 
755
        strcpy (desc->params[i].name, "name");
 
756
        desc->params[i].character  = 'n';
 
757
        desc->params[i].type       = JackDriverParamString;
 
758
        desc->params[i].value.ui   = 128U;
 
759
        strcpy (desc->params[i].short_desc, "Driver name");
 
760
        strcpy (desc->params[i].long_desc, desc->params[i].short_desc);
 
761
 
 
762
        i++;
 
763
        strcpy (desc->params[i].name, "dither");
 
764
        desc->params[i].character  = 'z';
 
765
        desc->params[i].type       = JackDriverParamChar;
 
766
        desc->params[i].value.c    = '-';
 
767
        strcpy (desc->params[i].short_desc, "Dithering mode");
 
768
        strcpy (desc->params[i].long_desc,
 
769
                "  Dithering Mode:\n"
 
770
                "    r : rectangular\n"
 
771
                "    t : triangular\n"
 
772
                "    s : shaped\n"
 
773
                "    - : no dithering");
 
774
        
 
775
    return desc;
 
776
}
 
777
 
 
778
const char driver_client_name[] = "portaudio";
 
779
 
 
780
jack_driver_t *
 
781
driver_initialize (jack_client_t *client, const JSList * params)
 
782
{
 
783
        jack_nframes_t srate = 48000;
 
784
        jack_nframes_t frames_per_interrupt = 1024;
 
785
        AudioDeviceID deviceID = 0;
 
786
        int capture = FALSE;
 
787
        int playback = FALSE;
 
788
        int chan_in = -1;
 
789
        int chan_out = -1;
 
790
        DitherAlgorithm dither = None;
 
791
        const JSList * node;
 
792
        const jack_driver_param_t * param;
 
793
        char *name = NULL;
 
794
 
 
795
#ifdef JACK_USE_MACH_THREADS    
 
796
        get_device_id_from_num(0,&deviceID); // takes a default value (first device)
 
797
#endif
 
798
        
 
799
        for (node = params; node; node = jack_slist_next (node)) {
 
800
                param = (const jack_driver_param_t *) node->data;
 
801
 
 
802
                switch (param->character) {
 
803
                
 
804
                case 'n':
 
805
                        name = (char *) param->value.str;
 
806
                        PALog("Driver name found %s\n",name);
 
807
                        break;
 
808
                        
 
809
                case 'D':
 
810
                        capture = TRUE;
 
811
                        playback = TRUE;
 
812
                        break;
 
813
                                    
 
814
                case 'c':
 
815
                        chan_in = (int) param->value.ui;
 
816
                        chan_out = (int) param->value.ui;
 
817
                        break;
 
818
                        
 
819
                case 'i':
 
820
                        chan_in = (int) param->value.ui;
 
821
                        break;
 
822
                
 
823
                case 'o':
 
824
                        chan_out = (int) param->value.ui;
 
825
                        break;
 
826
    
 
827
                case 'C':
 
828
                        capture = param->value.i;
 
829
                        break;
 
830
    
 
831
                case 'P':
 
832
                        playback = param->value.i;
 
833
                        break;
 
834
 
 
835
                case 'r':
 
836
                        srate = param->value.ui;
 
837
                        break;
 
838
                                    
 
839
                case 'p':
 
840
                        frames_per_interrupt = (unsigned int) param->value.ui;
 
841
                        break;
 
842
                        
 
843
                case 'z':
 
844
                        switch ((int) param->value.c) {
 
845
                        case '-':
 
846
                                dither = None;
 
847
                                break;
 
848
    
 
849
                        case 'r':
 
850
                                dither = Rectangular;
 
851
                                break;
 
852
    
 
853
                        case 's':
 
854
                                dither = Shaped;
 
855
                                break;
 
856
    
 
857
                        case 't':
 
858
                        default:
 
859
                                dither = Triangular;
 
860
                                break;
 
861
                        }
 
862
                        break;
 
863
                }
 
864
        }
 
865
 
 
866
        /* duplex is the default */
 
867
        if (!capture && !playback) {
 
868
                capture = TRUE;
 
869
                playback = TRUE;
 
870
        }
 
871
 
 
872
        return portaudio_driver_new ("portaudio", client, frames_per_interrupt,
 
873
                                     srate, capture, playback, chan_in,
 
874
                                     chan_out, dither, name);
 
875
}
 
876
 
 
877
void
 
878
driver_finish (jack_driver_t *driver)
 
879
{
 
880
        portaudio_driver_delete ((portaudio_driver_t *) driver);
 
881
}
 
882