JACK example clients
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.

169 lines
3.8KB

  1. /*
  2. * To change this license header, choose License Headers in Project Properties.
  3. * To change this template file, choose Tools | Templates
  4. * and open the template in the editor.
  5. */
  6. /*
  7. * File: main.cpp
  8. * Author: thorsten
  9. *
  10. * Created on 12. August 2018, 00:23
  11. */
  12. #include <cstdlib>
  13. #include <ctime>
  14. #include <cmath>
  15. #include <iostream>
  16. extern "C" {
  17. #include <jack/jack.h>
  18. #include <unistd.h>
  19. }
  20. using namespace std;
  21. float accel = 8.0;
  22. struct Instrument {
  23. float freqA;
  24. float freqB;
  25. float shiftA;
  26. float shiftB;
  27. float power;
  28. bool signum;
  29. jack_default_audio_sample_t buffer[44100];
  30. float compute(float x) {
  31. float y = sin(x * freqA + shiftA);
  32. if (signum) y = -signbit(y) * 2.0 + 1.0;
  33. y *= (cos(x * freqB + shiftB) + 1.0) / 2.0;
  34. y /= 1 + pow(x, power);
  35. return y;
  36. }
  37. void randomize() {
  38. freqA = (float) rand() / RAND_MAX * 0.19 + 0.01;
  39. freqB = (float) rand() / RAND_MAX * 0.01 + 0.005;
  40. shiftA = (float) rand() / RAND_MAX * 0.2;
  41. shiftB = (float) rand() / RAND_MAX * 0.2;
  42. power = (float) rand() / RAND_MAX * 0.2 + 0.2;
  43. signum = rand() & 1;
  44. for (int i = 0; i < sizeof (buffer) / sizeof (buffer[0]); ++i) buffer[i] = 0;
  45. for (int i = 0; i < (float) sizeof (buffer) / (float) sizeof (buffer[0]) / accel; ++i) {
  46. buffer[i] = compute((float) i / accel);
  47. }
  48. float sum = 0;
  49. for (int i = 0; i < sizeof (buffer) / sizeof (buffer[0]); ++i) sum += buffer[i];
  50. for (int i = 0; i < sizeof (buffer) / sizeof (buffer[0]); ++i) buffer[i] /= sum;
  51. for (int i = 0; i < sizeof (buffer) / sizeof (buffer[0]); ++i) buffer[i] *= 200;
  52. }
  53. };
  54. struct Pattern {
  55. Instrument aud;
  56. bool pat[16];
  57. int bounds(int i) {
  58. while (i < 0) i += 16;
  59. while (i >= 16) i -= 16;
  60. return i;
  61. }
  62. void randomize() {
  63. for (int i = 0; i < 16; ++i) pat[i] = false;
  64. for (int i = 0; i < 4; ++i) {
  65. if (rand() & 1) {
  66. pat[4 * i] = true;
  67. if (rand() & 1) {
  68. pat[bounds(4 * i + 2)] = true;
  69. }
  70. if (rand() & 1) {
  71. pat[bounds(4 * i - 1)] = true;
  72. }
  73. }
  74. }
  75. }
  76. };
  77. int index = 0;
  78. int counter = 0;
  79. int x;
  80. jack_client_t *jc;
  81. jack_port_t *jp;
  82. Pattern patterns[10];
  83. void randomize() {
  84. for (int i = 0; i < sizeof (patterns) / sizeof (patterns[0]); ++i) {
  85. patterns[i].aud.randomize();
  86. patterns[i].randomize();
  87. }
  88. }
  89. int myCallback(jack_nframes_t nframes, void *arg) {
  90. if (jack_port_connected(jp)) {
  91. jack_default_audio_sample_t *b = (jack_default_audio_sample_t *) jack_port_get_buffer(jp, nframes);
  92. for (int j = 0; j < nframes; ++j) {
  93. b[j] = 0;
  94. for (int i = 0; i < sizeof (patterns) / sizeof (patterns[0]); ++i) {
  95. if (patterns[i].pat[index]) {
  96. b[j] += patterns[i].aud.buffer[x + j];
  97. }
  98. }
  99. }
  100. x += nframes;
  101. if (x > (44100 / accel)) {
  102. x = 0;
  103. index += 1;
  104. if (index >= 16) {
  105. index = 0;
  106. counter += 1;
  107. if (counter >= 4) {
  108. counter = 0;
  109. randomize();
  110. }
  111. }
  112. }
  113. }
  114. return 0;
  115. }
  116. /*
  117. *
  118. */
  119. int main(int argc, char** argv) {
  120. time_t t;
  121. time(&t);
  122. srand(t);
  123. randomize();
  124. jack_status_t stat;
  125. jc = jack_client_open("TokisBeat", JackNullOption, &stat);
  126. jack_set_process_callback(jc, myCallback, 0);
  127. cout << stat << endl;
  128. jp = jack_port_register(jc, "Mono Port", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
  129. jack_activate(jc);
  130. while (true) {
  131. usleep(1000);
  132. }
  133. return 0;
  134. }