Sampler in ChucK
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.

155 lines
4.7KB

  1. //TODO: turn off adcThru when recording, and turn it back on afterwards
  2. //TODO: Effects break panning for some unknown reason
  3. //TODO varying number of bars
  4. NRev reverb => LPF lpf => HPF hpf => Dyno outputLimiter => dac;
  5. outputLimiter.limit();
  6. reverb @=> UGen @ outputWet; // Reference to wet output
  7. outputLimiter @=> UGen @ outputDry; // Reference to dry output
  8. outputLimiter @=> UGen @ mainOutput; // Reference to main output
  9. // Capture mic/line in and monitor through DAC. Limit
  10. adc => Dyno inputLimiter => Gain adcThru => mainOutput; // Monitor input
  11. inputLimiter.limit();
  12. inputLimiter @=> UGen @ mainInput;
  13. // Default parameters
  14. 1 => float adcThruLevel;
  15. 1 => int adcThruMute;
  16. adcThruLevel * adcThruMute => adcThru.gain;
  17. 10000 => lpf.freq;
  18. 10 => hpf.freq;
  19. // Plug in the pedals
  20. LoopPedal pedals[4];
  21. for( 0 => int i; i < pedals.cap(); i++ ) {
  22. pedals[i].recordFrom(mainInput);
  23. pedals[i].outputTo(outputWet, outputDry);
  24. }
  25. // Create the metronome
  26. Metronome metronome;
  27. spork ~metronome.run();
  28. // Start listening to OSC messages
  29. OscIn oin; 9000 => oin.port;
  30. oin.listenAll();
  31. OscMsg msg;
  32. // Event loop
  33. while (true) {
  34. oin => now;
  35. while (oin.recv(msg)) {
  36. if (msg.address=="/input") {
  37. msg.getFloat(0) => adc.gain;
  38. msg.getFloat(1) => adcThruLevel;
  39. adcThruLevel * adcThruMute => adcThru.gain;
  40. }
  41. else if(msg.address=="/delay") {
  42. msg.getFloat(0)::second => dur loopTime;
  43. msg.getFloat(1) => float feedback;
  44. for( 0 => int i; i < pedals.cap(); i++ ) {
  45. pedals[i].setLoopPoint(loopTime);
  46. pedals[i].setFeedback(feedback);
  47. }
  48. }
  49. else if(msg.address=="/channel") {
  50. msg.getInt(0) => int i;
  51. pedals[i].setGain(msg.getFloat(1));
  52. pedals[i].setPan(msg.getFloat(2));
  53. pedals[i].setWet(msg.getFloat(3));
  54. }
  55. else if(msg.address=="/arm") {
  56. msg.getInt(0) => int channel;
  57. (channel<0) => adcThruMute;
  58. adcThruLevel * adcThruMute => adcThru.gain;
  59. for( 0 => int i; i < pedals.cap(); i++ ) { pedals[i].arm(i==channel); }
  60. }
  61. else if(msg.address=="/metronome") {
  62. metronome.mute(msg.getInt(0));
  63. }
  64. else if(msg.address=="/clear") {
  65. msg.getInt(0) => int channel;
  66. pedals[channel].clear();
  67. }
  68. else if(msg.address=="/fx") {
  69. (100+msg.getFloat(0)*10000) => lpf.freq;
  70. (100+msg.getFloat(1)*10000) => hpf.freq;
  71. msg.getFloat(2) => reverb.mix;
  72. }
  73. else if(msg.address=="/master") {
  74. msg.getFloat(0) => mainOutput.gain;
  75. }
  76. }
  77. }
  78. class LoopPedal
  79. {
  80. // We are wrapping a live sampler, LiSa
  81. LiSa sample;
  82. sample => Gain wet;
  83. sample => Gain dry;
  84. dur loopTime;
  85. // Setup
  86. 10::second => sample.duration; // Allocate max 10 secs of memory
  87. 0::second => sample.recPos => sample.playPos;
  88. 1.0 => sample.feedback;
  89. 1 => sample.loop;
  90. /*.5 => sample.rate;*/
  91. setLoopPoint(1::second);
  92. setWet(0.5);
  93. public void setLoopPoint( dur length ) { length => loopTime => sample.loopEnd => sample.loopEndRec; }
  94. public void setFeedback( float fb ) { fb => sample.feedback; }
  95. public void setGain( float gain ) { gain => sample.gain; }
  96. public void setPan( float pan ) { } //pan => panner.pan; }
  97. public void setWet( float ratio ) { ratio => wet.gain; 1-ratio => dry.gain;}
  98. public void clear() { sample.clear(); }
  99. public void recordFrom(UGen ugen) { ugen => sample; }
  100. public dur remaining() { return loopTime - sample.playPos(); }
  101. public void outputTo(UGen wetSink, UGen drySink) {
  102. 1 => sample.play;
  103. wet => wetSink;
  104. dry => drySink;
  105. }
  106. public void arm(int value) {
  107. sample.playPos() => sample.recPos;
  108. value => sample.record;
  109. }
  110. }
  111. class Metronome
  112. {
  113. // A simple metronome
  114. SinOsc s => ADSR a;
  115. 0.5 => s.gain;
  116. a.set(0.001, .1, .5, .13);
  117. 10::ms => dur plipTime;
  118. fun void mute(int value) {
  119. if (value){ a => dac; } else { a =< dac; }
  120. }
  121. fun void run() {
  122. while(true) {
  123. // Compute the beat time
  124. pedals[0].loopTime/4. - plipTime => dur beatTime;
  125. // Beep four times
  126. 50 => s.freq;
  127. a.keyOn(); plipTime => now; a.keyOff();
  128. beatTime => now;
  129. 50 => s.freq;
  130. a.keyOn(); plipTime => now; a.keyOff();
  131. beatTime => now;
  132. a.keyOn(); plipTime => now; a.keyOff();
  133. beatTime => now;
  134. a.keyOn(); plipTime => now; a.keyOff();
  135. pedals[0].remaining() => now; // Sync
  136. }
  137. }
  138. }