Audio plugin host https://kx.studio/carla
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.

669 lines
18KB

  1. /*
  2. * Carla Native Plugins
  3. * Copyright (C) 2013 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or 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. * For a full copy of the GNU General Public License see the GPL.txt file
  16. */
  17. #include "CarlaNative.h"
  18. #include "audio_decoder/ad.h"
  19. #include <pthread.h>
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <unistd.h>
  24. #define PROGRAM_COUNT 16
  25. #ifdef _WIN32
  26. # define OS_SEP '\\'
  27. #else
  28. # define OS_SEP '/'
  29. #endif
  30. typedef struct adinfo ADInfo;
  31. typedef pthread_mutex_t Mutex;
  32. typedef pthread_t Thread;
  33. typedef struct _AudioFilePool {
  34. float* buffer[2];
  35. uint32_t startFrame;
  36. uint32_t size;
  37. } AudioFilePool;
  38. typedef struct _AudioFilePrograms {
  39. uint32_t current;
  40. const char* fullNames[PROGRAM_COUNT];
  41. const char* shortNames[PROGRAM_COUNT];
  42. } AudioFilePrograms;
  43. typedef struct _AudioFileInstance {
  44. HostDescriptor* host;
  45. void* filePtr;
  46. ADInfo fileNfo;
  47. uint32_t lastFrame;
  48. uint32_t maxFrame;
  49. AudioFilePool pool;
  50. AudioFilePrograms programs;
  51. bool loopMode;
  52. bool needsRead;
  53. bool doProcess;
  54. bool doQuit;
  55. Mutex mutex;
  56. Thread thread;
  57. } AudioFileInstance;
  58. // ------------------------------------------------------------------------------------------
  59. void zeroFloat(float* data, unsigned size)
  60. {
  61. for (unsigned i=0; i < size; ++i)
  62. *data++ = 0.0f;
  63. }
  64. void audiofile_read_poll(AudioFileInstance* const handlePtr)
  65. {
  66. if (handlePtr == NULL)
  67. {
  68. fprintf(stderr, "R: invalid instance\n");
  69. return;
  70. }
  71. if (handlePtr->fileNfo.frames == 0)
  72. {
  73. //fprintf(stderr, "R: no song loaded\n");
  74. handlePtr->needsRead = false;
  75. return;
  76. }
  77. int64_t lastFrame = handlePtr->lastFrame;
  78. int64_t readFrame = lastFrame;
  79. if (lastFrame >= handlePtr->maxFrame)
  80. {
  81. if (handlePtr->loopMode)
  82. {
  83. //fprintf(stderr, "R: DEBUG read loop, lastFrame:%i, maxFrame:%i\n", handlePtr->lastFrame, handlePtr->maxFrame);
  84. if (handlePtr->maxFrame >= handlePtr->pool.size)
  85. {
  86. readFrame %= handlePtr->maxFrame;
  87. }
  88. else
  89. {
  90. readFrame = 0;
  91. lastFrame -= lastFrame % handlePtr->maxFrame;
  92. }
  93. }
  94. else
  95. {
  96. //fprintf(stderr, "R: transport out of bounds\n");
  97. handlePtr->needsRead = false;
  98. return;
  99. }
  100. }
  101. // temp data buffer
  102. const uint32_t tmpSize = handlePtr->pool.size * handlePtr->fileNfo.channels;
  103. float tmpData[tmpSize];
  104. zeroFloat(tmpData, tmpSize);
  105. {
  106. fprintf(stderr, "R: poll data - reading at %li:%02li\n", readFrame/44100/60, (readFrame/44100) % 60);
  107. ad_seek(handlePtr->filePtr, readFrame);
  108. ssize_t i, j, rv = ad_read(handlePtr->filePtr, tmpData, tmpSize);
  109. i = j = 0;
  110. // lock, and put data asap
  111. pthread_mutex_lock(&handlePtr->mutex);
  112. for (; i < handlePtr->pool.size && j < rv; j++)
  113. {
  114. if (handlePtr->fileNfo.channels == 1)
  115. {
  116. handlePtr->pool.buffer[0][i] = tmpData[j];
  117. handlePtr->pool.buffer[1][i] = tmpData[j];
  118. i++;
  119. }
  120. else
  121. {
  122. if (j % 2 == 0)
  123. {
  124. handlePtr->pool.buffer[0][i] = tmpData[j];
  125. }
  126. else
  127. {
  128. handlePtr->pool.buffer[1][i] = tmpData[j];
  129. i++;
  130. }
  131. }
  132. }
  133. if (handlePtr->loopMode && readFrame+j == handlePtr->maxFrame)
  134. {
  135. while (i < handlePtr->pool.size)
  136. {
  137. for (j=0; i < handlePtr->pool.size && j < rv; j++)
  138. {
  139. if (handlePtr->fileNfo.channels == 1)
  140. {
  141. handlePtr->pool.buffer[0][i] = tmpData[j];
  142. handlePtr->pool.buffer[1][i] = tmpData[j];
  143. i++;
  144. }
  145. else
  146. {
  147. if (j % 2 == 0)
  148. {
  149. handlePtr->pool.buffer[0][i] = tmpData[j];
  150. }
  151. else
  152. {
  153. handlePtr->pool.buffer[1][i] = tmpData[j];
  154. i++;
  155. }
  156. }
  157. }
  158. }
  159. }
  160. else
  161. {
  162. for (; i < handlePtr->pool.size; i++)
  163. {
  164. handlePtr->pool.buffer[0][i] = 0.0f;
  165. handlePtr->pool.buffer[1][i] = 0.0f;
  166. }
  167. }
  168. handlePtr->pool.startFrame = lastFrame;
  169. // done
  170. pthread_mutex_unlock(&handlePtr->mutex);
  171. }
  172. handlePtr->needsRead = false;
  173. }
  174. void audiofile_load_filename(AudioFileInstance* const handlePtr, const char* const filename)
  175. {
  176. // wait for jack processing to end
  177. handlePtr->doProcess = false;
  178. pthread_mutex_lock(&handlePtr->mutex);
  179. pthread_mutex_unlock(&handlePtr->mutex);
  180. // clear old data
  181. if (handlePtr->filePtr != NULL)
  182. {
  183. ad_close(handlePtr->filePtr);
  184. handlePtr->filePtr = NULL;
  185. }
  186. ad_clear_nfo(&handlePtr->fileNfo);
  187. if (filename == NULL)
  188. return;
  189. // open new
  190. handlePtr->filePtr = ad_open(filename, &handlePtr->fileNfo);
  191. if (handlePtr->filePtr != NULL)
  192. {
  193. ad_dump_nfo(99, &handlePtr->fileNfo);
  194. if (handlePtr->fileNfo.frames == 0)
  195. fprintf(stderr, "L: filename \"%s\" has 0 frames\n", filename);
  196. if ((handlePtr->fileNfo.channels == 1 || handlePtr->fileNfo.channels == 2) && handlePtr->fileNfo.frames > 0)
  197. {
  198. handlePtr->maxFrame = handlePtr->fileNfo.frames;
  199. audiofile_read_poll(handlePtr);
  200. handlePtr->doProcess = true;
  201. }
  202. else
  203. {
  204. ad_close(handlePtr->filePtr);
  205. handlePtr->filePtr = NULL;
  206. ad_clear_nfo(&handlePtr->fileNfo);
  207. }
  208. }
  209. }
  210. static void audiofile_thread_idle(void* ptr)
  211. {
  212. AudioFileInstance* const handlePtr = (AudioFileInstance*)ptr;
  213. while (! handlePtr->doQuit)
  214. {
  215. if (handlePtr->needsRead || handlePtr->lastFrame - handlePtr->pool.startFrame >= handlePtr->pool.size*3/4)
  216. audiofile_read_poll(handlePtr);
  217. else
  218. usleep(50*1000);
  219. }
  220. pthread_exit(NULL);
  221. }
  222. // ------------------------------------------------------------------------------------------
  223. static bool gADInitiated = false;
  224. // ------------------------------------------------------------------------------------------
  225. static PluginHandle audiofile_instantiate(const PluginDescriptor* _this_, HostDescriptor* host)
  226. {
  227. AudioFileInstance* const handlePtr = (AudioFileInstance*)malloc(sizeof(AudioFileInstance));
  228. if (handlePtr == NULL)
  229. return NULL;
  230. if (! gADInitiated)
  231. {
  232. ad_init();
  233. gADInitiated = true;
  234. }
  235. // init
  236. handlePtr->host = host;
  237. handlePtr->filePtr = NULL;
  238. handlePtr->lastFrame = 0;
  239. handlePtr->maxFrame = 0;
  240. handlePtr->pool.buffer[0] = NULL;
  241. handlePtr->pool.buffer[1] = NULL;
  242. handlePtr->pool.startFrame = 0;
  243. handlePtr->pool.size = 0;
  244. handlePtr->programs.current = 0;
  245. handlePtr->loopMode = true;
  246. handlePtr->needsRead = false;
  247. handlePtr->doProcess = false;
  248. handlePtr->doQuit = false;
  249. ad_clear_nfo(&handlePtr->fileNfo);
  250. pthread_mutex_init(&handlePtr->mutex, NULL);
  251. for (uint32_t i=0; i < PROGRAM_COUNT; i++)
  252. {
  253. handlePtr->programs.fullNames[i] = NULL;
  254. handlePtr->programs.shortNames[i] = NULL;
  255. }
  256. // create audio pool
  257. handlePtr->pool.size = host->get_sample_rate(host->handle) * 6; // 6 secs
  258. handlePtr->pool.buffer[0] = (float*)malloc(sizeof(float) * handlePtr->pool.size);
  259. if (handlePtr->pool.buffer[0] == NULL)
  260. {
  261. free(handlePtr);
  262. return NULL;
  263. }
  264. handlePtr->pool.buffer[1] = (float*)malloc(sizeof(float) * handlePtr->pool.size);
  265. if (handlePtr->pool.buffer[1] == NULL)
  266. {
  267. free(handlePtr->pool.buffer[0]);
  268. free(handlePtr);
  269. return NULL;
  270. }
  271. zeroFloat(handlePtr->pool.buffer[0], handlePtr->pool.size);
  272. zeroFloat(handlePtr->pool.buffer[1], handlePtr->pool.size);
  273. pthread_create(&handlePtr->thread, NULL, (void*)&audiofile_thread_idle, handlePtr);
  274. return handlePtr;
  275. // unused
  276. (void)_this_;
  277. }
  278. static void audiofile_cleanup(PluginHandle handle)
  279. {
  280. AudioFileInstance* const handlePtr = (AudioFileInstance*)handle;
  281. // wait for processing to end
  282. handlePtr->doProcess = false;
  283. handlePtr->doQuit = true;
  284. pthread_mutex_lock(&handlePtr->mutex);
  285. pthread_join(handlePtr->thread, NULL);
  286. pthread_mutex_unlock(&handlePtr->mutex);
  287. pthread_mutex_destroy(&handlePtr->mutex);
  288. if (handlePtr->filePtr != NULL)
  289. ad_close(handlePtr->filePtr);
  290. if (handlePtr->pool.buffer[0] != NULL)
  291. free(handlePtr->pool.buffer[0]);
  292. if (handlePtr->pool.buffer[1] != NULL)
  293. free(handlePtr->pool.buffer[1]);
  294. for (uint32_t i=0; i < PROGRAM_COUNT; i++)
  295. {
  296. if (handlePtr->programs.fullNames[i] != NULL)
  297. free((void*)handlePtr->programs.fullNames[i]);
  298. if (handlePtr->programs.shortNames[i] != NULL)
  299. free((void*)handlePtr->programs.shortNames[i]);
  300. }
  301. free(handlePtr);
  302. }
  303. static uint32_t audiofile_get_parameter_count(PluginHandle handle)
  304. {
  305. return 1;
  306. // unused
  307. (void)handle;
  308. }
  309. static const Parameter* audiofile_get_parameter_info(PluginHandle handle, uint32_t index)
  310. {
  311. if (index != 0)
  312. return NULL;
  313. static Parameter param;
  314. param.name = "Loop Mode";
  315. param.unit = NULL;
  316. param.hints = PARAMETER_IS_ENABLED|PARAMETER_IS_BOOLEAN;
  317. param.ranges.def = 1.0f;
  318. param.ranges.min = 0.0f;
  319. param.ranges.max = 1.0f;
  320. param.ranges.step = 1.0f;
  321. param.ranges.stepSmall = 1.0f;
  322. param.ranges.stepLarge = 1.0f;
  323. param.scalePointCount = 0;
  324. param.scalePoints = NULL;
  325. return &param;
  326. // unused
  327. (void)handle;
  328. }
  329. static float audiofile_get_parameter_value(PluginHandle handle, uint32_t index)
  330. {
  331. AudioFileInstance* const handlePtr = (AudioFileInstance*)handle;
  332. if (index != 0)
  333. return 0.0f;
  334. return handlePtr->loopMode ? 1.0f : 0.0f;
  335. // unused
  336. (void)handle;
  337. }
  338. static uint32_t audiofile_get_program_count(PluginHandle handle)
  339. {
  340. return PROGRAM_COUNT;
  341. // unused
  342. (void)handle;
  343. }
  344. const MidiProgram* audiofile_get_program_info(PluginHandle handle, uint32_t index)
  345. {
  346. AudioFileInstance* const handlePtr = (AudioFileInstance*)handle;
  347. if (index >= PROGRAM_COUNT)
  348. return NULL;
  349. static MidiProgram midiProgram;
  350. midiProgram.bank = 0;
  351. midiProgram.program = index;
  352. midiProgram.name = handlePtr->programs.shortNames[index];
  353. if (midiProgram.name == NULL)
  354. midiProgram.name = "";
  355. return &midiProgram;
  356. }
  357. static void audiofile_set_parameter_value(PluginHandle handle, uint32_t index, float value)
  358. {
  359. AudioFileInstance* const handlePtr = (AudioFileInstance*)handle;
  360. if (index != 0)
  361. return;
  362. handlePtr->loopMode = (value > 0.5f);
  363. handlePtr->needsRead = true;
  364. }
  365. static void audiofile_set_program(PluginHandle handle, uint32_t bank, uint32_t program)
  366. {
  367. AudioFileInstance* const handlePtr = (AudioFileInstance*)handle;
  368. if (bank != 0 || program >= PROGRAM_COUNT)
  369. return;
  370. if (handlePtr->programs.current != program)
  371. {
  372. audiofile_load_filename(handlePtr, handlePtr->programs.fullNames[program]);
  373. handlePtr->programs.current = program;
  374. }
  375. }
  376. static void audiofile_set_custom_data(PluginHandle handle, const char* key, const char* value)
  377. {
  378. AudioFileInstance* const handlePtr = (AudioFileInstance*)handle;
  379. if (strncmp(key, "file", 4) != 0)
  380. return;
  381. if (key[4] < '0' || key[4] > '9')
  382. return;
  383. if (key[5] < '0' || key[5] > '9')
  384. return;
  385. uint8_t tens = key[4]-'0';
  386. uint8_t nums = key[5]-'0';
  387. uint32_t program = tens*10 + nums;
  388. if (program >= PROGRAM_COUNT)
  389. return;
  390. if (handlePtr->programs.fullNames[program] != NULL)
  391. free((void*)handlePtr->programs.fullNames[program]);
  392. if (handlePtr->programs.shortNames[program] != NULL)
  393. free((void*)handlePtr->programs.shortNames[program]);
  394. handlePtr->programs.fullNames[program] = strdup(value);
  395. {
  396. const char* shortName1 = strrchr(value, OS_SEP)+1;
  397. //const char* shortName2 = strchr(shortName1, '.');
  398. handlePtr->programs.shortNames[program] = strdup(shortName1);
  399. }
  400. if (handlePtr->programs.current == program)
  401. audiofile_load_filename(handlePtr, value);
  402. }
  403. static void audiofile_ui_show(PluginHandle handle, bool show)
  404. {
  405. AudioFileInstance* const handlePtr = (AudioFileInstance*)handle;
  406. if (! show)
  407. return;
  408. const char* const filename = handlePtr->host->ui_open_file(handlePtr->host->handle, false, "Open Audio File", "");
  409. if (filename != NULL)
  410. {
  411. char fileStr[4+2+1] = { 'f', 'i', 'l', 'e', 0, 0, 0 };
  412. fileStr[4] = '0' + (handlePtr->programs.current / 10);
  413. fileStr[5] = '0' + (handlePtr->programs.current % 10);
  414. handlePtr->host->ui_custom_data_changed(handlePtr->host->handle, fileStr, filename);
  415. }
  416. handlePtr->host->ui_closed(handlePtr->host->handle);
  417. }
  418. static void audiofile_process(PluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, uint32_t midiEventCount, const MidiEvent* midiEvents)
  419. {
  420. AudioFileInstance* const handlePtr = (AudioFileInstance*)handle;
  421. const TimeInfo* const timePos = handlePtr->host->get_time_info(handlePtr->host->handle);
  422. float* out1 = outBuffer[0];
  423. float* out2 = outBuffer[1];
  424. if (! handlePtr->doProcess)
  425. {
  426. //fprintf(stderr, "P: no process\n");
  427. handlePtr->lastFrame = timePos->frame;
  428. zeroFloat(out1, frames);
  429. zeroFloat(out2, frames);
  430. return;
  431. }
  432. // not playing
  433. if (! timePos->playing)
  434. {
  435. //fprintf(stderr, "P: not rolling\n");
  436. if (timePos->frame == 0 && handlePtr->lastFrame > 0)
  437. handlePtr->needsRead = true;
  438. handlePtr->lastFrame = timePos->frame;
  439. zeroFloat(out1, frames);
  440. zeroFloat(out2, frames);
  441. return;
  442. }
  443. pthread_mutex_lock(&handlePtr->mutex);
  444. // out of reach
  445. if (timePos->frame + frames < handlePtr->pool.startFrame || (timePos->frame >= handlePtr->maxFrame && ! handlePtr->loopMode))
  446. {
  447. //fprintf(stderr, "P: non-continuous playback, out of reach %u vs %u\n", timePos->frame + frames, handlePtr->maxFrame);
  448. handlePtr->lastFrame = timePos->frame;
  449. handlePtr->needsRead = true;
  450. pthread_mutex_unlock(&handlePtr->mutex);
  451. zeroFloat(out1, frames);
  452. zeroFloat(out2, frames);
  453. return;
  454. }
  455. int64_t poolFrame = (int64_t)timePos->frame - handlePtr->pool.startFrame;
  456. int64_t poolSize = handlePtr->pool.size;
  457. for (uint32_t i=0; i < frames; i++, poolFrame++)
  458. {
  459. if (poolFrame >= 0 && poolFrame < poolSize)
  460. {
  461. out1[i] = handlePtr->pool.buffer[0][poolFrame];
  462. out2[i] = handlePtr->pool.buffer[1][poolFrame];
  463. // reset
  464. handlePtr->pool.buffer[0][poolFrame] = 0.0f;
  465. handlePtr->pool.buffer[1][poolFrame] = 0.0f;
  466. }
  467. else
  468. {
  469. out1[i] = 0.0f;
  470. out2[i] = 0.0f;
  471. }
  472. }
  473. handlePtr->lastFrame = timePos->frame;
  474. pthread_mutex_unlock(&handlePtr->mutex);
  475. return;
  476. // unused
  477. (void)inBuffer;
  478. (void)midiEventCount;
  479. (void)midiEvents;
  480. }
  481. // -----------------------------------------------------------------------
  482. static const PluginDescriptor audiofileDesc = {
  483. .category = PLUGIN_CATEGORY_UTILITY,
  484. .hints = PLUGIN_IS_RTSAFE|PLUGIN_HAS_GUI,
  485. .audioIns = 0,
  486. .audioOuts = 2,
  487. .midiIns = 0,
  488. .midiOuts = 0,
  489. .parameterIns = 1,
  490. .parameterOuts = 0,
  491. .name = "Audio File",
  492. .label = "audiofile",
  493. .maker = "falkTX",
  494. .copyright = "GNU GPL v2+",
  495. .instantiate = audiofile_instantiate,
  496. .cleanup = audiofile_cleanup,
  497. .get_parameter_count = audiofile_get_parameter_count,
  498. .get_parameter_info = audiofile_get_parameter_info,
  499. .get_parameter_value = audiofile_get_parameter_value,
  500. .get_parameter_text = NULL,
  501. .get_midi_program_count = audiofile_get_program_count,
  502. .get_midi_program_info = audiofile_get_program_info,
  503. .set_parameter_value = audiofile_set_parameter_value,
  504. .set_midi_program = audiofile_set_program,
  505. .set_custom_data = audiofile_set_custom_data,
  506. .ui_show = audiofile_ui_show,
  507. .ui_idle = NULL,
  508. .ui_set_parameter_value = NULL,
  509. .ui_set_midi_program = NULL,
  510. .ui_set_custom_data = NULL,
  511. .activate = NULL,
  512. .deactivate = NULL,
  513. .process = audiofile_process,
  514. .get_chunk = NULL,
  515. .set_chunk = NULL
  516. };
  517. // -----------------------------------------------------------------------
  518. void carla_register_native_plugin_audiofile()
  519. {
  520. carla_register_native_plugin(&audiofileDesc);
  521. }
  522. // -----------------------------------------------------------------------
  523. // amalgamated build
  524. #include "audio_decoder/ad_ffmpeg.c"
  525. #include "audio_decoder/ad_plugin.c"
  526. #include "audio_decoder/ad_soundfile.c"
  527. // -----------------------------------------------------------------------