jack1 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

635 lines
18KB

  1. /*
  2. Copyright © Grame, 2003.
  3. Copyright © Johnny Petrantoni, 2003.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. Grame Research Laboratory, 9, rue du Garet 69001 Lyon - France
  16. grame@rd.grame.fr
  17. Johnny Petrantoni, johnny@lato-b.com - Italy, Rome.
  18. Jan 30, 2004: Johnny Petrantoni: first code of the coreaudio driver, based on portaudio driver by Stephane Letz.
  19. Feb 02, 2004: Johnny Petrantoni: fixed null cycle, removed double copy of buffers in AudioRender, the driver works fine (tested with Built-in Audio and Hammerfall RME), but no cpu load is displayed.
  20. Feb 03, 2004: Johnny Petrantoni: some little fix.
  21. Feb 03, 2004: Stephane Letz: some fix in AudioRender.cpp code.
  22. Feb 03, 2004: Johnny Petrantoni: removed the default device stuff (useless, in jackosx, because JackPilot manages this behavior), the device must be specified. and all parameter must be correct.
  23. Feb 04, 2004: Johnny Petrantoni: now the driver supports interfaces with multiple interleaved streams (such as the MOTU 828).
  24. Nov 05, 2004: S.Letz: correct management of -I option for use with JackPilot.
  25. Nov 15, 2004: S.Letz: Set a default value for deviceID.
  26. Nov 30, 2004: S.Letz: In coreaudio_driver_write : clear to avoid playing dirty buffers when the client does not produce output anymore.
  27. TODO:
  28. - fix cpu load behavior.
  29. - multiple-device processing.
  30. */
  31. #include <stdio.h>
  32. #include <string.h>
  33. #include <jack/engine.h>
  34. #include <CoreAudio/CoreAudio.h>
  35. #include "coreaudio_driver.h"
  36. #include "AudioRenderBridge.h"
  37. const int CAVersion = 2;
  38. void JCALog(char *fmt, ...);
  39. static OSStatus GetDeviceNameFromID(AudioDeviceID id, char name[60])
  40. {
  41. UInt32 size = sizeof(char) * 60;
  42. OSStatus stat = AudioDeviceGetProperty(id, 0, false,
  43. kAudioDevicePropertyDeviceName,
  44. &size,
  45. &name[0]);
  46. return stat;
  47. }
  48. static OSStatus get_device_id_from_num(int i, AudioDeviceID * id)
  49. {
  50. OSStatus theStatus;
  51. UInt32 theSize;
  52. int nDevices;
  53. AudioDeviceID *theDeviceList;
  54. theStatus = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices,
  55. &theSize, NULL);
  56. nDevices = theSize / sizeof(AudioDeviceID);
  57. theDeviceList =
  58. (AudioDeviceID *) malloc(nDevices * sizeof(AudioDeviceID));
  59. theStatus = AudioHardwareGetProperty(kAudioHardwarePropertyDevices,
  60. &theSize, theDeviceList);
  61. *id = theDeviceList[i];
  62. return theStatus;
  63. }
  64. int coreaudio_runCycle(void *driver, long bufferSize)
  65. {
  66. coreaudio_driver_t *ca_driver = (coreaudio_driver_t *) driver;
  67. ca_driver->last_wait_ust = jack_get_microseconds();
  68. return ca_driver->engine->run_cycle(ca_driver->engine, bufferSize, 0);
  69. }
  70. static int
  71. coreaudio_driver_attach(coreaudio_driver_t * driver,
  72. jack_engine_t * engine)
  73. {
  74. jack_port_t *port;
  75. int port_flags;
  76. channel_t chn;
  77. char buf[JACK_PORT_NAME_SIZE];
  78. driver->engine = engine;
  79. driver->engine->set_buffer_size(engine, driver->frames_per_cycle);
  80. driver->engine->set_sample_rate(engine, driver->frame_rate);
  81. port_flags =
  82. JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
  83. /*
  84. if (driver->has_hw_monitoring) {
  85. port_flags |= JackPortCanMonitor;
  86. }
  87. */
  88. for (chn = 0; chn < driver->capture_nchannels; chn++) {
  89. //snprintf (buf, sizeof(buf) - 1, "capture_%lu", chn+1);
  90. snprintf(buf, sizeof(buf) - 1, "%s:out%lu", driver->driver_name,
  91. chn + 1);
  92. if ((port = jack_port_register(driver->client, buf,
  93. JACK_DEFAULT_AUDIO_TYPE, port_flags,
  94. 0)) == NULL) {
  95. jack_error("coreaudio: cannot register port for %s", buf);
  96. break;
  97. }
  98. /* XXX fix this so that it can handle: systemic (external) latency
  99. */
  100. jack_port_set_latency(port, driver->frames_per_cycle);
  101. driver->capture_ports =
  102. jack_slist_append(driver->capture_ports, port);
  103. }
  104. port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
  105. for (chn = 0; chn < driver->playback_nchannels; chn++) {
  106. //snprintf (buf, sizeof(buf) - 1, "playback_%lu", chn+1);
  107. snprintf(buf, sizeof(buf) - 1, "%s:in%lu", driver->driver_name,
  108. chn + 1);
  109. if ((port = jack_port_register(driver->client, buf,
  110. JACK_DEFAULT_AUDIO_TYPE, port_flags,
  111. 0)) == NULL) {
  112. jack_error("coreaudio: cannot register port for %s", buf);
  113. break;
  114. }
  115. /* XXX fix this so that it can handle: systemic (external) latency
  116. */
  117. jack_port_set_latency(port, driver->frames_per_cycle);
  118. driver->playback_ports =
  119. jack_slist_append(driver->playback_ports, port);
  120. }
  121. jack_activate(driver->client);
  122. return 0;
  123. }
  124. static int
  125. coreaudio_driver_detach(coreaudio_driver_t * driver,
  126. jack_engine_t * engine)
  127. {
  128. JSList *node;
  129. if (driver->engine == 0) {
  130. return -1;
  131. }
  132. for (node = driver->capture_ports; node; node = jack_slist_next(node)) {
  133. jack_port_unregister(driver->client, ((jack_port_t *) node->data));
  134. }
  135. jack_slist_free(driver->capture_ports);
  136. driver->capture_ports = 0;
  137. for (node = driver->playback_ports; node; node = jack_slist_next(node)) {
  138. jack_port_unregister(driver->client, ((jack_port_t *) node->data));
  139. }
  140. jack_slist_free(driver->playback_ports);
  141. driver->playback_ports = 0;
  142. driver->engine = 0;
  143. return 0;
  144. }
  145. static int
  146. coreaudio_driver_null_cycle(coreaudio_driver_t * driver,
  147. jack_nframes_t nframes)
  148. {
  149. int i;
  150. if (!driver->isInterleaved) {
  151. for (i = 0; i < driver->playback_nchannels; i++) {
  152. memset(driver->outcoreaudio[i], 0x0, nframes * sizeof(float));
  153. }
  154. } else {
  155. memset(driver->outcoreaudio[0], 0x0,
  156. nframes * sizeof(float) * driver->playback_nchannels);
  157. }
  158. return 0;
  159. }
  160. static int
  161. coreaudio_driver_read(coreaudio_driver_t * driver, jack_nframes_t nframes)
  162. {
  163. jack_default_audio_sample_t *buf;
  164. channel_t chn;
  165. jack_port_t *port;
  166. JSList *node;
  167. int i;
  168. int b = 0;
  169. for (chn = 0, node = driver->capture_ports; node;
  170. node = jack_slist_next(node), chn++) {
  171. port = (jack_port_t *) node->data;
  172. if (!driver->isInterleaved) {
  173. if (jack_port_connected(port)
  174. && (driver->incoreaudio[chn] != NULL)) {
  175. float *in = driver->incoreaudio[chn];
  176. buf = jack_port_get_buffer(port, nframes);
  177. memcpy(buf, in, sizeof(float) * nframes);
  178. }
  179. } else {
  180. if (jack_port_connected(port)
  181. && (driver->incoreaudio[b] != NULL)) {
  182. int channels = driver->channelsPerInputStream[b];
  183. if (channels <= chn) {
  184. b++;
  185. if (driver->numberOfInputStreams > 1
  186. && b < driver->numberOfInputStreams) {
  187. channels = driver->channelsPerInputStream[b];
  188. chn = 0;
  189. } else
  190. return 0;
  191. }
  192. if (channels > 0) {
  193. float *in = driver->incoreaudio[b];
  194. buf = jack_port_get_buffer(port, nframes);
  195. for (i = 0; i < nframes; i++)
  196. buf[i] = in[channels * i + chn];
  197. }
  198. }
  199. }
  200. }
  201. driver->engine->transport_cycle_start(driver->engine,
  202. jack_get_microseconds());
  203. return 0;
  204. }
  205. static int
  206. coreaudio_driver_write(coreaudio_driver_t * driver, jack_nframes_t nframes)
  207. {
  208. jack_default_audio_sample_t *buf;
  209. channel_t chn;
  210. jack_port_t *port;
  211. JSList *node;
  212. int i,bytes = nframes*sizeof(float);
  213. int b = 0;
  214. for (chn = 0, node = driver->playback_ports; node;
  215. node = jack_slist_next(node), chn++) {
  216. port = (jack_port_t *) node->data;
  217. if (!driver->isInterleaved) {
  218. if (jack_port_connected(port)
  219. && (driver->outcoreaudio[chn] != NULL)) {
  220. float *out = driver->outcoreaudio[chn];
  221. buf = jack_port_get_buffer(port, nframes);
  222. memcpy(out, buf, sizeof(float) * nframes);
  223. /* clear to avoid playing dirty buffers when the client does not produce output anymore */
  224. memset(buf, 0, bytes);
  225. }
  226. } else {
  227. if (jack_port_connected(port)
  228. && (driver->outcoreaudio[b] != NULL)) {
  229. int channels = driver->channelsPerOuputStream[b];
  230. if (channels <= chn) {
  231. b++;
  232. if (driver->numberOfOuputStreams > 1
  233. && b < driver->numberOfOuputStreams) {
  234. channels = driver->channelsPerOuputStream[b];
  235. chn = 0;
  236. } else
  237. return 0;
  238. }
  239. if (channels > 0) {
  240. float *out = driver->outcoreaudio[b];
  241. buf = jack_port_get_buffer(port, nframes);
  242. for (i = 0; i < nframes; i++)
  243. out[channels * i + chn] = buf[i];
  244. /* clear to avoid playing dirty buffers when the client does not produce output anymore */
  245. memset(buf, 0, bytes);
  246. }
  247. }
  248. }
  249. }
  250. return 0;
  251. }
  252. static int coreaudio_driver_audio_start(coreaudio_driver_t * driver)
  253. {
  254. return (!startPandaAudioProcess(driver->stream)) ? -1 : 0;
  255. }
  256. static int coreaudio_driver_audio_stop(coreaudio_driver_t * driver)
  257. {
  258. return (!stopPandaAudioProcess(driver->stream)) ? -1 : 0;
  259. }
  260. #if 0
  261. static int
  262. coreaudio_driver_bufsize(coreaudio_driver_t * driver,
  263. jack_nframes_t nframes)
  264. {
  265. /* This gets called from the engine server thread, so it must
  266. * be serialized with the driver thread. Stopping the audio
  267. * also stops that thread. */
  268. closePandaAudioInstance(driver->stream);
  269. driver->stream =
  270. openPandaAudioInstance((float) driver->frame_rate,
  271. driver->frames_per_cycle, driver->capturing,
  272. driver->playing, &driver->driver_name[0]);
  273. if (!driver->stream)
  274. return FALSE;
  275. setHostData(driver->stream, driver);
  276. setCycleFun(driver->stream, coreaudio_runCycle);
  277. setParameter(driver->stream, 'inte', &driver->isInterleaved);
  278. driver->incoreaudio = getPandaAudioInputs(driver->stream);
  279. driver->outcoreaudio = getPandaAudioOutputs(driver->stream);
  280. return startPandaAudioProcess(driver->stream);
  281. }
  282. #endif
  283. /** create a new driver instance
  284. */
  285. static jack_driver_t *coreaudio_driver_new(char *name,
  286. jack_client_t * client,
  287. jack_nframes_t frames_per_cycle,
  288. jack_nframes_t rate,
  289. int capturing,
  290. int playing,
  291. int chan_in,
  292. int chan_out,
  293. char *driver_name,
  294. AudioDeviceID deviceID)
  295. {
  296. coreaudio_driver_t *driver;
  297. JCALog("coreaudio beta %d driver\n", CAVersion);
  298. driver = (coreaudio_driver_t *) calloc(1, sizeof(coreaudio_driver_t));
  299. jack_driver_init((jack_driver_t *) driver);
  300. if (!jack_power_of_two(frames_per_cycle)) {
  301. fprintf(stderr, "CA: -p must be a power of two.\n");
  302. goto error;
  303. }
  304. driver->frames_per_cycle = frames_per_cycle;
  305. driver->frame_rate = rate;
  306. driver->capturing = capturing;
  307. driver->playing = playing;
  308. driver->attach = (JackDriverAttachFunction) coreaudio_driver_attach;
  309. driver->detach = (JackDriverDetachFunction) coreaudio_driver_detach;
  310. driver->read = (JackDriverReadFunction) coreaudio_driver_read;
  311. driver->write = (JackDriverReadFunction) coreaudio_driver_write;
  312. driver->null_cycle =
  313. (JackDriverNullCycleFunction) coreaudio_driver_null_cycle;
  314. //driver->bufsize = (JackDriverBufSizeFunction) coreaudio_driver_bufsize;
  315. driver->start = (JackDriverStartFunction) coreaudio_driver_audio_start;
  316. driver->stop = (JackDriverStopFunction) coreaudio_driver_audio_stop;
  317. driver->stream = NULL;
  318. char deviceName[60];
  319. bzero(&deviceName[0], sizeof(char) * 60);
  320. get_device_id_from_num(0,&deviceID);
  321. if (!driver_name) {
  322. if (GetDeviceNameFromID(deviceID, deviceName) != noErr)
  323. goto error;
  324. } else {
  325. strcpy(&deviceName[0], driver_name);
  326. }
  327. driver->stream =
  328. openPandaAudioInstance((float) rate, frames_per_cycle, chan_in,
  329. chan_out, &deviceName[0]);
  330. if (!driver->stream)
  331. goto error;
  332. driver->client = client;
  333. driver->period_usecs =
  334. (((float) driver->frames_per_cycle) / driver->frame_rate) *
  335. 1000000.0f;
  336. setHostData(driver->stream, driver);
  337. setCycleFun(driver->stream, coreaudio_runCycle);
  338. setParameter(driver->stream, 'inte', &driver->isInterleaved);
  339. setParameter(driver->stream, 'nstr', &driver->numberOfInputStreams);
  340. setParameter(driver->stream, 'nstO', &driver->numberOfOuputStreams);
  341. JCALog("There are %d input streams.\n", driver->numberOfInputStreams);
  342. JCALog("There are %d output streams.\n", driver->numberOfOuputStreams);
  343. driver->channelsPerInputStream =
  344. (int *) malloc(sizeof(int) * driver->numberOfInputStreams);
  345. driver->channelsPerOuputStream =
  346. (int *) malloc(sizeof(int) * driver->numberOfOuputStreams);
  347. setParameter(driver->stream, 'cstr', driver->channelsPerInputStream);
  348. setParameter(driver->stream, 'cstO', driver->channelsPerOuputStream);
  349. driver->incoreaudio = getPandaAudioInputs(driver->stream);
  350. driver->outcoreaudio = getPandaAudioOutputs(driver->stream);
  351. driver->playback_nchannels = chan_out;
  352. driver->capture_nchannels = chan_in;
  353. strcpy(&driver->driver_name[0], &deviceName[0]);
  354. // steph
  355. //jack_init_time();
  356. return ((jack_driver_t *) driver);
  357. error:
  358. JCALog("Cannot open the coreaudio stream\n");
  359. free(driver);
  360. return NULL;
  361. }
  362. /** free all memory allocated by a driver instance
  363. */
  364. static void coreaudio_driver_delete(coreaudio_driver_t * driver)
  365. {
  366. /* Close coreaudio stream and terminate */
  367. closePandaAudioInstance(driver->stream);
  368. free(driver->channelsPerInputStream);
  369. free(driver->channelsPerOuputStream);
  370. free(driver);
  371. }
  372. //== driver "plugin" interface =================================================
  373. /* DRIVER "PLUGIN" INTERFACE */
  374. const char driver_client_name[] = "coreaudio";
  375. jack_driver_desc_t *driver_get_descriptor()
  376. {
  377. jack_driver_desc_t *desc;
  378. unsigned int i;
  379. desc = calloc(1, sizeof(jack_driver_desc_t));
  380. strcpy(desc->name, "coreaudio");
  381. desc->nparams = 10;
  382. desc->params = calloc(desc->nparams, sizeof(jack_driver_param_desc_t));
  383. i = 0;
  384. strcpy(desc->params[i].name, "channel");
  385. desc->params[i].character = 'c';
  386. desc->params[i].type = JackDriverParamInt;
  387. desc->params[i].value.ui = 2;
  388. strcpy(desc->params[i].short_desc, "Maximum number of channels");
  389. strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
  390. i++;
  391. strcpy(desc->params[i].name, "channelin");
  392. desc->params[i].character = 'i';
  393. desc->params[i].type = JackDriverParamInt;
  394. desc->params[i].value.ui = 2;
  395. strcpy(desc->params[i].short_desc, "Maximum number of input channels");
  396. strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
  397. i++;
  398. strcpy(desc->params[i].name, "channelout");
  399. desc->params[i].character = 'o';
  400. desc->params[i].type = JackDriverParamInt;
  401. desc->params[i].value.ui = 2;
  402. strcpy(desc->params[i].short_desc, "Maximum number of ouput channels");
  403. strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
  404. i++;
  405. strcpy(desc->params[i].name, "capture");
  406. desc->params[i].character = 'C';
  407. desc->params[i].type = JackDriverParamBool;
  408. desc->params[i].value.i = TRUE;
  409. strcpy(desc->params[i].short_desc, "Whether or not to capture");
  410. strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
  411. i++;
  412. strcpy(desc->params[i].name, "playback");
  413. desc->params[i].character = 'P';
  414. desc->params[i].type = JackDriverParamBool;
  415. desc->params[i].value.i = TRUE;
  416. strcpy(desc->params[i].short_desc, "Whether or not to playback");
  417. strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
  418. i++;
  419. strcpy(desc->params[i].name, "duplex");
  420. desc->params[i].character = 'D';
  421. desc->params[i].type = JackDriverParamBool;
  422. desc->params[i].value.i = TRUE;
  423. strcpy(desc->params[i].short_desc, "Capture and playback");
  424. strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
  425. i++;
  426. strcpy(desc->params[i].name, "rate");
  427. desc->params[i].character = 'r';
  428. desc->params[i].type = JackDriverParamUInt;
  429. desc->params[i].value.ui = 44100U;
  430. strcpy(desc->params[i].short_desc, "Sample rate");
  431. strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
  432. i++;
  433. strcpy(desc->params[i].name, "period");
  434. desc->params[i].character = 'p';
  435. desc->params[i].type = JackDriverParamUInt;
  436. desc->params[i].value.ui = 128U;
  437. strcpy(desc->params[i].short_desc, "Frames per period");
  438. strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
  439. i++;
  440. strcpy(desc->params[i].name, "name");
  441. desc->params[i].character = 'n';
  442. desc->params[i].type = JackDriverParamString;
  443. desc->params[i].value.ui = 128U;
  444. strcpy(desc->params[i].short_desc, "Driver name");
  445. strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
  446. i++;
  447. strcpy(desc->params[i].name, "id");
  448. desc->params[i].character = 'I';
  449. desc->params[i].type = JackDriverParamInt;
  450. desc->params[i].value.i = 0;
  451. strcpy(desc->params[i].short_desc, "Audio Device ID");
  452. strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
  453. return desc;
  454. }
  455. jack_driver_t *driver_initialize(jack_client_t * client,
  456. const JSList * params)
  457. {
  458. jack_nframes_t srate = 44100;
  459. jack_nframes_t frames_per_interrupt = 128;
  460. int capture = FALSE;
  461. int playback = FALSE;
  462. int chan_in = 2;
  463. int chan_out = 2;
  464. char *name = NULL;
  465. AudioDeviceID deviceID = 0;
  466. const JSList *node;
  467. const jack_driver_param_t *param;
  468. for (node = params; node; node = jack_slist_next(node)) {
  469. param = (const jack_driver_param_t *) node->data;
  470. switch (param->character) {
  471. case 'n':
  472. name = (char *) param->value.str;
  473. break;
  474. case 'D':
  475. capture = TRUE;
  476. playback = TRUE;
  477. break;
  478. case 'c':
  479. chan_in = chan_out = (int) param->value.ui;
  480. break;
  481. case 'i':
  482. chan_in = (int) param->value.ui;
  483. break;
  484. case 'o':
  485. chan_out = (int) param->value.ui;
  486. break;
  487. case 'C':
  488. capture = param->value.i;
  489. break;
  490. case 'P':
  491. playback = param->value.i;
  492. break;
  493. case 'r':
  494. srate = param->value.ui;
  495. break;
  496. case 'p':
  497. frames_per_interrupt = (unsigned int) param->value.ui;
  498. break;
  499. case 'I':
  500. deviceID = (AudioDeviceID) param->value.ui;
  501. break;
  502. }
  503. }
  504. /* duplex is the default */
  505. if (!capture && !playback) {
  506. capture = TRUE;
  507. playback = TRUE;
  508. }
  509. return coreaudio_driver_new("coreaudio", client, frames_per_interrupt,
  510. srate, capture, playback, chan_in,
  511. chan_out, name, deviceID);
  512. }
  513. void driver_finish(jack_driver_t * driver)
  514. {
  515. coreaudio_driver_delete((coreaudio_driver_t *) driver);
  516. }