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.

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