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.

110 lines
2.9KB

  1. // TODO: turn off adcThru when recording
  2. // Effects chain
  3. adc => Gain adcThru => dac; // Monitor input through a mixer
  4. SampleChan channels[4];
  5. // Levels
  6. //0 => adc.gain;
  7. .5 => adcThru.gain;
  8. // Global loop time
  9. 1::second => dur loopTime;
  10. // Each channel should output to the mixer
  11. for( 0 => int i; i < channels.cap(); i++ ) { channels[i].outputTo(dac); }
  12. // Listen to OSC messages
  13. OscIn oin; 9000 => oin.port;
  14. oin.listenAll();
  15. OscMsg msg;
  16. // Start the metronome
  17. 0 => int metronomeLevel;
  18. spork ~plip();
  19. // Event loop
  20. while (true) {
  21. oin => now;
  22. while (oin.recv(msg)) {
  23. if (msg.address=="/input") {
  24. msg.getFloat(0) => adc.gain;
  25. msg.getFloat(1) => adcThru.gain;
  26. }
  27. else if(msg.address=="/delay") {
  28. msg.getFloat(0)::second => loopTime;
  29. msg.getFloat(1) => float feedback;
  30. for( 0 => int i; i < channels.cap(); i++ ) {
  31. channels[i].setLoopPoint(loopTime);
  32. channels[i].setFeedback(feedback);
  33. }
  34. }
  35. else if(msg.address=="/channel") {
  36. msg.getInt(0) => int i;
  37. channels[i].setGain(msg.getFloat(1));
  38. channels[i].setPan(msg.getFloat(2));
  39. }
  40. else if(msg.address=="/arm") {
  41. msg.getInt(0) => int channel;
  42. for( 0 => int i; i < channels.cap(); i++ ) { channels[i].arm(i==channel); }
  43. }
  44. else if(msg.address=="/metronome") {
  45. msg.getInt(0) => metronomeLevel;
  46. }
  47. else if(msg.address=="/clear") {
  48. msg.getInt(0) => int channel;
  49. channels[channel].clear();
  50. }
  51. }
  52. }
  53. public class SampleChan
  54. {
  55. // Chain
  56. adc => LiSa sample => LPF filter => Pan2 panner;
  57. // Setup
  58. 10::second => sample.duration; //This is the max duration
  59. 0::second => sample.recPos => sample.playPos;
  60. 1.0 => sample.feedback;
  61. 1 => sample.loop;
  62. 1 => filter.Q;
  63. setLoopPoint(1::second);
  64. setFilter(10000);
  65. public void setLoopPoint( dur length ) { length => sample.loopEnd => sample.loopEndRec; }
  66. public void setFeedback( float fb ) { fb => sample.feedback; }
  67. public void setFilter( float freq ) { freq => filter.freq; }
  68. public void setGain( float gain ) { gain => filter.gain; }
  69. public void setPan( float pan ) { pan => panner.pan; }
  70. public void clear() { sample.clear(); }
  71. public void outputTo(UGen ugen) {
  72. 1 => sample.play;
  73. panner => ugen;
  74. }
  75. public void arm(int value) {
  76. sample.playPos() => sample.recPos;
  77. value => sample.record;
  78. }
  79. }
  80. // TODO timing here should be done using events
  81. fun void plip()
  82. {
  83. SinOsc s => dac;
  84. 0.01::second => dur plipTime;
  85. while(true){
  86. for( 0 => int i; i < 4; i++ ) {
  87. if (i==0){2000 => s.freq;} else {1000 => s.freq;}
  88. .1*metronomeLevel => s.gain;
  89. plipTime => now;
  90. 0 => s.gain;
  91. loopTime/4 - plipTime => now;
  92. }
  93. }
  94. }