diff --git a/src/avtk/clipselector.cxx b/src/avtk/clipselector.cxx index 33ee6d2..b9f1127 100644 --- a/src/avtk/clipselector.cxx +++ b/src/avtk/clipselector.cxx @@ -93,7 +93,8 @@ void ClipSelector::clipName(int clip, std::string name) void ClipSelector::setClipBeats(int scene, int beats, bool isBeatsToRecord) { - clips[scene].setBeats(beats, isBeatsToRecord); + clips[scene].setBeats(beats, isBeatsToRecord); + redraw(); } double getCairoTextWith(cairo_t * cr, const char * str) @@ -286,10 +287,9 @@ void setRecordBarsCb(Fl_Widget *w, void* data) long bars = (long)data; if(bars == -2){ const char* answer = fl_input("Enter a custom number: "); - bars = atoi(answer); - if(!answer || bars <= 0|| bars > MAX_BARS) { + if(!answer || atoi(bars) <= 0|| atoi(bars) > MAX_BARS) { bars = -1; - fl_message("Invalid Input. You may enter a number smaller than %i!", MAX_BARS); + fl_message("Please enter value between 1 and %.", MAX_BARS); } else bars = atoi(answer); } @@ -367,7 +367,7 @@ int ClipSelector::handle(int event) RECORD_BARS_MENU_ITEM(4), RECORD_BARS_MENU_ITEM(6), RECORD_BARS_MENU_ITEM(8), - {"Endless", 0, setRecordBarsCb, (void*)-1, FL_MENU_DIVIDER | (clips[clipNum].getBeatsToRecord() <= 0) ? FL_ACTIVATE : 0 + {"Endless", 0, setRecordBarsCb, (void*)-1, FL_MENU_DIVIDER | FL_MENU_RADIO | ((clips[clipNum].getBeatsToRecord() <= 0) ? FL_ACTIVATE : 0) | empty ? 0 : FL_MENU_INACTIVE}, {"Custom", 0, setRecordBarsCb, (void*)-2, empty ? 0 : FL_MENU_INACTIVE}, {0}, diff --git a/src/config.hxx b/src/config.hxx index 30bb35d..c091e21 100644 --- a/src/config.hxx +++ b/src/config.hxx @@ -65,7 +65,7 @@ #define LUPPP_RETURN_WARNING 1 #define LUPPP_RETURN_ERROR 2 -#define MAX_BARS 100 +#define MAX_BARS 64 /// debug.hxx for printing convienience #include "debug.hxx" diff --git a/src/looper.cxx b/src/looper.cxx index 92fb8aa..bdb49ea 100644 --- a/src/looper.cxx +++ b/src/looper.cxx @@ -31,50 +31,50 @@ extern Jack* jack; Looper::Looper(int t) : - AudioProcessor(), - TimeObserver(), - track(t) + AudioProcessor(), + TimeObserver(), + track(t) { - uiUpdateConstant= jack->getSamplerate() / 30.f; - uiUpdateCounter = jack->getSamplerate() / 30.f; + uiUpdateConstant= jack->getSamplerate() / 30.f; + uiUpdateCounter = jack->getSamplerate() / 30.f; - // pre-zero the internal sample - //tmpRecordBuffer = (float*)malloc( sizeof(float) * MAX_BUFFER_SIZE ); - //memset( tmpRecordBuffer, 0, sizeof(float) * MAX_BUFFER_SIZE ); + // pre-zero the internal sample + //tmpRecordBuffer = (float*)malloc( sizeof(float) * MAX_BUFFER_SIZE ); + //memset( tmpRecordBuffer, 0, sizeof(float) * MAX_BUFFER_SIZE ); - for(int i = 0; i < NSCENES; i++ ) { - clips[i] = new LooperClip(track, i); - } + for(int i = 0; i < NSCENES; i++ ) { + clips[i] = new LooperClip(track, i); + } - tmpBuffer.resize( MAX_BUFFER_SIZE ); + tmpBuffer.resize( MAX_BUFFER_SIZE ); - fpb = 22050; + fpb = 22050; - // init faust pitch shift variables - fSamplingFreq = jack->getSamplerate(); - IOTA = 0; + // init faust pitch shift variables + fSamplingFreq = jack->getSamplerate(); + IOTA = 0; - //tmpRecordBuffer.resize(MAX_BUFFER_SIZE); + //tmpRecordBuffer.resize(MAX_BUFFER_SIZE); - for (int i=0; i<65536; i++) - fVec0[i] = 0; - for (int i=0; i<2; i++) - fRec0[i] = 0; - semitoneShift = 0.0f; - windowSize = 1000; - crossfadeSize = 1000; + for (int i=0; i<65536; i++) + fVec0[i] = 0; + for (int i=0; i<2; i++) + fRec0[i] = 0; + semitoneShift = 0.0f; + windowSize = 1000; + crossfadeSize = 1000; } LooperClip* Looper::getClip(int scene) { - return clips[scene]; + return clips[scene]; } void Looper::beat() { - //TODO needed? - //FIXME: Need to keep looperClips in sync when there exists no int N - // such that playSpeed*N==1 + //TODO needed? + //FIXME: Need to keep looperClips in sync when there exists no int N + // such that playSpeed*N==1 // for(int i=0;igetPlayhead()+1.0; @@ -94,119 +94,115 @@ void Looper::beat() void Looper::setRequestedBuffer(int s, AudioBuffer* ab) { - clips[s]->setRequestedBuffer( ab ); + clips[s]->setRequestedBuffer( ab ); } void Looper::setFpb(int f) { - fpb = f; + fpb = f; } void Looper::process(unsigned int nframes, Buffers* buffers) { - // process each clip individually: this allows for playback of one clip, - // while another clip records. - for ( int clip = 0; clip < NSCENES; clip++ ) { - // handle state of clip, and do what needs doing: - // record into buffer, play from buffer, etc - if ( clips[clip]->recording() ) { - if(clips[clip]->getBeatsToRecord() > 0 && clips[clip]->getBeats() >= clips[clip]->getBeatsToRecord() - 4) - clips[clip]->queuePlay(true); + // process each clip individually: this allows for playback of one clip, + // while another clip records. + for ( int clip = 0; clip < NSCENES; clip++ ) { + // handle state of clip, and do what needs doing: + // record into buffer, play from buffer, etc + if ( clips[clip]->recording() ) { + if ( clips[clip]->recordSpaceAvailable() < LOOPER_SAMPLES_BEFORE_REQUEST && + !clips[clip]->newBufferInTransit() ) { + EventLooperClipRequestBuffer e( track, clip, clips[clip]->audioBufferSize() + LOOPER_SAMPLES_UPDATE_SIZE); + writeToGuiRingbuffer( &e ); + clips[clip]->newBufferInTransit(true); + } + // copy data from input buffer to recording buffer + float* inputL = buffers->audio[Buffers::MASTER_INPUT_L]; + float* inputR = buffers->audio[Buffers::MASTER_INPUT_R]; + clips[clip]->record( nframes, inputL, inputR); + } else if ( clips[clip]->playing() ) { + // copy data into tmpBuffer, then pitch-stretch into track buffer + long targetFrames = clips[clip]->getBeats() * fpb; + long actualFrames = clips[clip]->getActualAudioLength();//getBufferLenght(); + float playSpeed = 1.0; - if ( clips[clip]->recordSpaceAvailable() < LOOPER_SAMPLES_BEFORE_REQUEST && - !clips[clip]->newBufferInTransit() ) { - EventLooperClipRequestBuffer e( track, clip, clips[clip]->audioBufferSize() + LOOPER_SAMPLES_UPDATE_SIZE); - writeToGuiRingbuffer( &e ); - clips[clip]->newBufferInTransit(true); - } + if ( targetFrames != 0 && actualFrames != 0 ) { + playSpeed = float(actualFrames) / targetFrames; + } - // copy data from input buffer to recording buffer - float* inputL = buffers->audio[Buffers::MASTER_INPUT_L]; - float* inputR = buffers->audio[Buffers::MASTER_INPUT_R]; - clips[clip]->record( nframes, inputL, inputR); - } else if ( clips[clip]->playing() ) { - // copy data into tmpBuffer, then pitch-stretch into track buffer - long targetFrames = clips[clip]->getBeats() * fpb; - long actualFrames = clips[clip]->getActualAudioLength();//getBufferLenght(); - float playSpeed = 1.0; + float* outL = buffers->audio[Buffers::SEND_TRACK_0_L + track]; + float* outR = buffers->audio[Buffers::SEND_TRACK_0_R + track]; - if ( targetFrames != 0 && actualFrames != 0 ) { - playSpeed = float(actualFrames) / targetFrames; - } + for(unsigned int i = 0; i < nframes; i++ ) { + // REFACTOR into system that is better than per sample function calls + float tmpL = 0; + float tmpR = 0; + clips[clip]->getSample(playSpeed, &tmpL, &tmpR); - float* outL = buffers->audio[Buffers::SEND_TRACK_0_L + track]; - float* outR = buffers->audio[Buffers::SEND_TRACK_0_R + track]; + float deltaPitch = 12 * log ( playSpeed ) / log (2); + semitoneShift = -deltaPitch; - for(unsigned int i = 0; i < nframes; i++ ) { - // REFACTOR into system that is better than per sample function calls - float tmpL = 0; - float tmpR = 0; - clips[clip]->getSample(playSpeed, &tmpL, &tmpR); + // write the pitch-shifted signal to the track buffer + //FIXME: pitchShift adds delay even for playSpeed = 1.0!! + //we should use something better (e.g librubberband) + if(0) { //playSpeed!=1.0f) { + pitchShift( 1, &tmpL, &outL[i] ); + pitchShift( 1, &tmpR, &outR[i] ); + } else { + outL[i]+=tmpL; + outR[i]+=tmpR; + } + } - float deltaPitch = 12 * log ( playSpeed ) / log (2); - semitoneShift = -deltaPitch; + //printf("Looper %i playing(), speed = %f\n", track, playSpeed ); - // write the pitch-shifted signal to the track buffer - //FIXME: pitchShift adds delay even for playSpeed = 1.0!! - //we should use something better (e.g librubberband) - if(0) { //playSpeed!=1.0f) { - pitchShift( 1, &tmpL, &outL[i] ); - pitchShift( 1, &tmpR, &outR[i] ); - } else { - outL[i]+=tmpL; - outR[i]+=tmpR; - } - } + if ( uiUpdateCounter > uiUpdateConstant ) { + jack->getControllerUpdater()->setTrackSceneProgress(track, clip, clips[clip]->getProgress() ); + uiUpdateCounter = 0; + } + uiUpdateCounter += nframes; + } - //printf("Looper %i playing(), speed = %f\n", track, playSpeed ); - - if ( uiUpdateCounter > uiUpdateConstant ) { - jack->getControllerUpdater()->setTrackSceneProgress(track, clip, clips[clip]->getProgress() ); - uiUpdateCounter = 0; - } - uiUpdateCounter += nframes; - } - - } + } } void Looper::resetTimeState() { - for(int i=0; isetPlayHead(0.0); + for(int i=0; isetPlayHead(0.0); } void Looper::pitchShift(int count, float* input, float* output) { - float fSlow0 = windowSize; - float fSlow1 = ((1 + fSlow0) - powf(2,(0.08333333333333333f * semitoneShift))); - float fSlow2 = (1.0f / crossfadeSize); - float fSlow3 = (fSlow0 - 1); - float* input0 = &input[0]; - //float* output0 = &output[0]; + float fSlow0 = windowSize; + float fSlow1 = ((1 + fSlow0) - powf(2,(0.08333333333333333f * semitoneShift))); + float fSlow2 = (1.0f / crossfadeSize); + float fSlow3 = (fSlow0 - 1); + float* input0 = &input[0]; + //float* output0 = &output[0]; - for (int i=0; i