jack2 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.

519 lines
15KB

  1. /* link with */
  2. #include <math.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <limits.h>
  7. #include <math.h>
  8. #include <errno.h>
  9. #include <time.h>
  10. #include <vector>
  11. #include <stack>
  12. #include <string>
  13. #include <map>
  14. #include <iostream>
  15. #include <libgen.h>
  16. #include <jack/jack.h>
  17. // g++ -O3 -lm -lsndfile myfx.cpp
  18. using namespace std;
  19. #define max(x,y) (((x)>(y)) ? (x) : (y))
  20. #define min(x,y) (((x)<(y)) ? (x) : (y))
  21. // abs is now predefined
  22. //template<typename T> T abs (T a) { return (a<T(0)) ? -a : a; }
  23. inline int lsr (int x, int n)
  24. {
  25. return int(((unsigned int)x) >> n);
  26. }
  27. /******************************************************************************
  28. *******************************************************************************
  29. VECTOR INTRINSICS
  30. *******************************************************************************
  31. *******************************************************************************/
  32. inline void *aligned_calloc(size_t nmemb, size_t size)
  33. {
  34. return (void*)((unsigned)(calloc((nmemb*size) + 15, sizeof(char))) + 15 & 0xfffffff0);
  35. }
  36. /******************************************************************************
  37. *******************************************************************************
  38. USER INTERFACE
  39. *******************************************************************************
  40. *******************************************************************************/
  41. class UI
  42. {
  43. bool fStopped;
  44. public:
  45. UI() : fStopped(false)
  46. {}
  47. virtual ~UI()
  48. {}
  49. // -- active widgets
  50. virtual void addButton(char* label, float* zone) = 0;
  51. virtual void addToggleButton(char* label, float* zone) = 0;
  52. virtual void addCheckButton(char* label, float* zone) = 0;
  53. virtual void addVerticalSlider(char* label, float* zone, float init, float min, float max, float step) = 0;
  54. virtual void addHorizontalSlider(char* label, float* zone, float init, float min, float max, float step) = 0;
  55. virtual void addNumEntry(char* label, float* zone, float init, float min, float max, float step) = 0;
  56. // -- passive widgets
  57. virtual void addNumDisplay(char* label, float* zone, int precision) = 0;
  58. virtual void addTextDisplay(char* label, float* zone, char* names[], float min, float max) = 0;
  59. virtual void addHorizontalBargraph(char* label, float* zone, float min, float max) = 0;
  60. virtual void addVerticalBargraph(char* label, float* zone, float min, float max) = 0;
  61. // -- frames and labels
  62. virtual void openFrameBox(char* label) = 0;
  63. virtual void openTabBox(char* label) = 0;
  64. virtual void openHorizontalBox(char* label) = 0;
  65. virtual void openVerticalBox(char* label) = 0;
  66. virtual void closeBox() = 0;
  67. virtual void show() = 0;
  68. virtual void run() = 0;
  69. void stop()
  70. {
  71. fStopped = true;
  72. }
  73. bool stopped()
  74. {
  75. return fStopped;
  76. }
  77. };
  78. struct param
  79. {
  80. float* fZone;
  81. float fMin;
  82. float fMax;
  83. param(float* z, float a, float b) : fZone(z), fMin(a), fMax(b)
  84. {}
  85. };
  86. class CMDUI : public UI
  87. {
  88. int fArgc;
  89. char** fArgv;
  90. stack<string> fPrefix;
  91. map<string, param> fKeyParam;
  92. void addOption(char* label, float* zone, float min, float max)
  93. {
  94. string fullname = fPrefix.top() + label;
  95. fKeyParam.insert(make_pair(fullname, param(zone, min, max)));
  96. }
  97. void openAnyBox(char* label)
  98. {
  99. string prefix;
  100. if (label && label[0]) {
  101. prefix = fPrefix.top() + "-" + label;
  102. } else {
  103. prefix = fPrefix.top();
  104. }
  105. fPrefix.push(prefix);
  106. }
  107. public:
  108. CMDUI(int argc, char *argv[]) : UI(), fArgc(argc), fArgv(argv)
  109. {
  110. fPrefix.push("--");
  111. }
  112. virtual ~CMDUI()
  113. {}
  114. virtual void addButton(char* label, float* zone)
  115. {}
  116. ;
  117. virtual void addToggleButton(char* label, float* zone)
  118. {}
  119. ;
  120. virtual void addCheckButton(char* label, float* zone)
  121. {}
  122. ;
  123. virtual void addVerticalSlider(char* label, float* zone, float init, float min, float max, float step)
  124. {
  125. addOption(label, zone, min, max);
  126. }
  127. virtual void addHorizontalSlider(char* label, float* zone, float init, float min, float max, float step)
  128. {
  129. addOption(label, zone, min, max);
  130. }
  131. virtual void addNumEntry(char* label, float* zone, float init, float min, float max, float step)
  132. {
  133. addOption(label, zone, min, max);
  134. }
  135. // -- passive widgets
  136. virtual void addNumDisplay(char* label, float* zone, int precision)
  137. {}
  138. virtual void addTextDisplay(char* label, float* zone, char* names[], float min, float max)
  139. {}
  140. virtual void addHorizontalBargraph(char* label, float* zone, float min, float max)
  141. {}
  142. virtual void addVerticalBargraph(char* label, float* zone, float min, float max)
  143. {}
  144. virtual void openFrameBox(char* label)
  145. {
  146. openAnyBox(label);
  147. }
  148. virtual void openTabBox(char* label)
  149. {
  150. openAnyBox(label);
  151. }
  152. virtual void openHorizontalBox(char* label)
  153. {
  154. openAnyBox(label);
  155. }
  156. virtual void openVerticalBox(char* label)
  157. {
  158. openAnyBox(label);
  159. }
  160. virtual void closeBox()
  161. {
  162. fPrefix.pop();
  163. }
  164. virtual void show()
  165. {}
  166. virtual void run()
  167. {
  168. char c;
  169. printf("Type 'q' to quit\n");
  170. while ((c = getchar()) != 'q') {
  171. sleep(1);
  172. }
  173. }
  174. void print()
  175. {
  176. map<string, param>::iterator i;
  177. cout << fArgc << "\n";
  178. cout << fArgv[0] << " option list : ";
  179. for (i = fKeyParam.begin(); i != fKeyParam.end(); i++) {
  180. cout << "[ " << i->first << " " << i->second.fMin << ".." << i->second.fMax << " ] ";
  181. }
  182. //cout << " infile outfile\n";
  183. }
  184. void process_command()
  185. {
  186. map<string, param>::iterator p;
  187. for (int i = 1; i < fArgc; i++) {
  188. if (fArgv[i][0] == '-') {
  189. p = fKeyParam.find(fArgv[i]);
  190. if (p == fKeyParam.end()) {
  191. cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n";
  192. print();
  193. exit(1);
  194. }
  195. char* end;
  196. *(p->second.fZone) = float(strtod(fArgv[i + 1], &end));
  197. i++;
  198. }
  199. }
  200. }
  201. void process_init()
  202. {
  203. map<string, param>::iterator p;
  204. for (int i = 1; i < fArgc; i++) {
  205. if (fArgv[i][0] == '-') {
  206. p = fKeyParam.find(fArgv[i]);
  207. if (p == fKeyParam.end()) {
  208. cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n";
  209. exit(1);
  210. }
  211. char* end;
  212. *(p->second.fZone) = float(strtod(fArgv[i + 1], &end));
  213. i++;
  214. }
  215. }
  216. }
  217. };
  218. //----------------------------------------------------------------
  219. // d�inition du processeur de signal
  220. //----------------------------------------------------------------
  221. class dsp
  222. {
  223. protected:
  224. int fSamplingFreq;
  225. public:
  226. dsp()
  227. {}
  228. virtual ~dsp()
  229. {}
  230. virtual int getNumInputs() = 0;
  231. virtual int getNumOutputs() = 0;
  232. virtual void buildUserInterface(UI* interface) = 0;
  233. virtual void init(int samplingRate) = 0;
  234. virtual void compute(int len, float** inputs, float** outputs) = 0;
  235. virtual void conclude()
  236. {}
  237. };
  238. //----------------------------------------------------------------------------
  239. // FAUST generated code
  240. //----------------------------------------------------------------------------
  241. class mydsp : public dsp
  242. {
  243. private:
  244. class SIG0
  245. {
  246. private:
  247. int fSamplingFreq;
  248. public:
  249. int getNumInputs()
  250. {
  251. return 0;
  252. }
  253. int getNumOutputs()
  254. {
  255. return 1;
  256. }
  257. void init(int samplingFreq)
  258. {
  259. fSamplingFreq = samplingFreq;
  260. }
  261. void fill (int count, float output[])
  262. {
  263. for (int i = 0; i < count; i++) {
  264. output[i] = 0.000000f;
  265. }
  266. }
  267. };
  268. float R0_0;
  269. float fslider0;
  270. float ftbl0[65536];
  271. int R1_0;
  272. float fdata0;
  273. float fslider1;
  274. public:
  275. virtual int getNumInputs()
  276. {
  277. return 1;
  278. }
  279. virtual int getNumOutputs()
  280. {
  281. return 1;
  282. }
  283. virtual void init(int samplingFreq)
  284. {
  285. fSamplingFreq = samplingFreq;
  286. R0_0 = 0.0;
  287. fslider0 = 0.000000f;
  288. SIG0 sig0;
  289. sig0.init(samplingFreq);
  290. sig0.fill(65536, ftbl0);
  291. R1_0 = 0;
  292. fdata0 = (1.000000e-03f * fSamplingFreq);
  293. fslider1 = 0.000000f;
  294. }
  295. virtual void buildUserInterface(UI* interface)
  296. {
  297. interface->openVerticalBox("echo-simple");
  298. interface->openVerticalBox("echo 1000");
  299. interface->addHorizontalSlider("feedback", &fslider0, 0.000000f, 0.000000f, 100.000000f, 0.100000f);
  300. interface->addHorizontalSlider("millisecond", &fslider1, 0.000000f, 0.000000f, 1000.000000f, 0.100000f);
  301. interface->closeBox();
  302. interface->closeBox();
  303. }
  304. virtual void compute (int count, float** input, float** output)
  305. {
  306. float* input0 __attribute__ ((aligned(16)));
  307. input0 = input[0];
  308. float* output0 __attribute__ ((aligned(16)));
  309. output0 = output[0];
  310. float ftemp0 = (1.000000e-02f * fslider0);
  311. int itemp0 = int((int((fdata0 * fslider1)) - 1));
  312. for (int i = 0; i < count; i++) {
  313. R1_0 = ((1 + R1_0) & 65535);
  314. ftbl0[R1_0] = R0_0;
  315. R0_0 = (input0[i] + (ftemp0 * ftbl0[((R1_0 - itemp0) & 65535)]));
  316. output0[i] = R0_0;
  317. }
  318. }
  319. };
  320. mydsp DSP;
  321. /******************************************************************************
  322. *******************************************************************************
  323. JACK AUDIO INTERFACE
  324. *******************************************************************************
  325. *******************************************************************************/
  326. //----------------------------------------------------------------------------
  327. // number of input and output channels
  328. //----------------------------------------------------------------------------
  329. int gNumInChans;
  330. int gNumOutChans;
  331. //----------------------------------------------------------------------------
  332. // Jack ports
  333. //----------------------------------------------------------------------------
  334. jack_port_t *input_ports[256];
  335. jack_port_t *output_ports[256];
  336. //----------------------------------------------------------------------------
  337. // tables of noninterleaved input and output channels for FAUST
  338. //----------------------------------------------------------------------------
  339. float* gInChannel[256];
  340. float* gOutChannel[256];
  341. //----------------------------------------------------------------------------
  342. // Jack Callbacks
  343. //----------------------------------------------------------------------------
  344. int srate(jack_nframes_t nframes, void *arg)
  345. {
  346. printf("the sample rate is now %u/sec\n", nframes);
  347. return 0;
  348. }
  349. void jack_shutdown(void *arg)
  350. {
  351. exit(1);
  352. }
  353. int process (jack_nframes_t nframes, void *arg)
  354. {
  355. for (int i = 0; i < gNumInChans; i++) {
  356. gInChannel[i] = (float *)jack_port_get_buffer(input_ports[i], nframes);
  357. }
  358. for (int i = 0; i < gNumOutChans; i++) {
  359. gOutChannel[i] = (float *)jack_port_get_buffer(output_ports[i], nframes);
  360. }
  361. DSP.compute(nframes, gInChannel, gOutChannel);
  362. return 0;
  363. }
  364. //-------------------------------------------------------------------------
  365. // MAIN
  366. //-------------------------------------------------------------------------
  367. int main(int argc, char *argv[] )
  368. {
  369. char jackname[256];
  370. char** physicalInPorts;
  371. char** physicalOutPorts;
  372. jack_client_t* client;
  373. CMDUI* interface = new CMDUI(argc, argv);
  374. DSP.buildUserInterface(interface);
  375. snprintf(jackname, 255, "%s", basename(argv[0]));
  376. if ((client = jack_client_new(jackname)) == 0) {
  377. fprintf(stderr, "jack server not running?\n");
  378. return 1;
  379. }
  380. jack_set_process_callback(client, process, 0);
  381. jack_set_sample_rate_callback(client, srate, 0);
  382. jack_on_shutdown(client, jack_shutdown, 0);
  383. gNumInChans = DSP.getNumInputs();
  384. gNumOutChans = DSP.getNumOutputs();
  385. for (int i = 0; i < gNumInChans; i++) {
  386. char buf[256];
  387. snprintf(buf, 256, "in_%d", i);
  388. input_ports[i] = jack_port_register(client, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
  389. }
  390. for (int i = 0; i < gNumOutChans; i++) {
  391. char buf[256];
  392. snprintf(buf, 256, "out_%d", i);
  393. output_ports[i] = jack_port_register(client, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
  394. }
  395. DSP.init(jack_get_sample_rate(client));
  396. DSP.buildUserInterface(interface);
  397. interface->process_command();
  398. physicalInPorts = (char **)jack_get_ports(client, NULL, NULL, JackPortIsPhysical | JackPortIsInput);
  399. physicalOutPorts = (char **)jack_get_ports(client, NULL, NULL, JackPortIsPhysical | JackPortIsOutput);
  400. if (jack_activate(client)) {
  401. fprintf(stderr, "cannot activate client");
  402. return 1;
  403. }
  404. if (physicalOutPorts != NULL) {
  405. for (int i = 0; i < gNumInChans && physicalOutPorts[i]; i++) {
  406. jack_connect(client, physicalOutPorts[i], jack_port_name(input_ports[i]));
  407. }
  408. }
  409. if (physicalInPorts != NULL) {
  410. for (int i = 0; i < gNumOutChans && physicalInPorts[i]; i++) {
  411. jack_connect(client, jack_port_name(output_ports[i]), physicalInPorts[i]);
  412. }
  413. }
  414. interface->run();
  415. jack_deactivate(client);
  416. for (int i = 0; i < gNumInChans; i++) {
  417. jack_port_unregister(client, input_ports[i]);
  418. }
  419. for (int i = 0; i < gNumOutChans; i++) {
  420. jack_port_unregister(client, output_ports[i]);
  421. }
  422. jack_client_close(client);
  423. return 0;
  424. }