Program: 54996
Project: 54996
Buggy source:
@Override public boolean onScroll(MotionEvent e1,MotionEvent e2,float distanceX,float distanceY){
  if (source != null) {
    float hzPerPx=virtualSampleRate / (float)width;
switch (this.scrollType) {
case SCROLLTYPE_NORMAL:
      virtualFrequency=Math.min(Math.max(virtualFrequency + (long)(hzPerPx * distanceX),source.getMinFrequency() - source.getSampleRate() / 2),source.getMaxFrequency() + source.getSampleRate() / 2);
    if (virtualFrequency <= 0)     virtualFrequency=1;
  if (demodulationEnabled && channelFrequency < virtualFrequency - virtualSampleRate / 2) {
    channelFrequency=virtualFrequency - virtualSampleRate / 2;
    callbackHandler.onUpdateChannelFrequency(channelFrequency);
  }
if (demodulationEnabled && channelFrequency > virtualFrequency + virtualSampleRate / 2) {
  channelFrequency=virtualFrequency + virtualSampleRate / 2;
  callbackHandler.onUpdateChannelFrequency(channelFrequency);
}
break;
case SCROLLTYPE_CHANNEL_FREQUENCY:
channelFrequency-=distanceX * hzPerPx;
callbackHandler.onUpdateChannelFrequency(channelFrequency);
break;
case SCROLLTYPE_CHANNEL_WIDTH_LEFT:
case SCROLLTYPE_CHANNEL_WIDTH_RIGHT:
int tmpChannelWidth=scrollType == SCROLLTYPE_CHANNEL_WIDTH_LEFT ? (int)(channelWidth + distanceX * hzPerPx) : (int)(channelWidth - distanceX * hzPerPx);
if (callbackHandler.onUpdateChannelWidth(tmpChannelWidth)) channelWidth=tmpChannelWidth;
break;
case SCROLLTYPE_SQUELCH:
float dbPerPx=(maxDB - minDB) / (float)getFftHeight();
squelch=squelch + distanceY * dbPerPx;
callbackHandler.onUpdateSquelch(squelch);
break;
default :
Log.e(LOGTAG,"String_Node_Str" + scrollType);
}
if (verticalScrollEnabled && scrollType != SCROLLTYPE_SQUELCH) {
float yDiff=(maxDB - minDB) * (distanceY / (float)getFftHeight());
if (maxDB - yDiff > MAX_DB) yDiff=MAX_DB - maxDB;
if (minDB - yDiff < MIN_DB) yDiff=MIN_DB - minDB;
this.setDBScale(minDB - yDiff,maxDB - yDiff);
}
if (source.getFrequency() + source.getSampleRate() / 2 < virtualFrequency + virtualSampleRate / 2 || source.getFrequency() - source.getSampleRate() / 2 > virtualFrequency - virtualSampleRate / 2) {
if (virtualFrequency >= source.getMinFrequency() && virtualFrequency <= source.getMaxFrequency()) source.setFrequency(virtualFrequency);
}
}
return true;
}

Fixed version (ground truth):
@Override public boolean onScroll(MotionEvent e1,MotionEvent e2,float distanceX,float distanceY){
  if (source != null) {
    float hzPerPx=virtualSampleRate / (float)width;
switch (this.scrollType) {
case SCROLLTYPE_NORMAL:
      virtualFrequency=Math.min(Math.max(virtualFrequency + (long)(hzPerPx * distanceX),source.getMinFrequency() - source.getSampleRate() / 2),source.getMaxFrequency() + source.getSampleRate() / 2);
    if (virtualFrequency <= 0)     virtualFrequency=1;
  if (demodulationEnabled && channelFrequency < virtualFrequency - virtualSampleRate / 2) {
    channelFrequency=virtualFrequency - virtualSampleRate / 2;
    callbackHandler.onUpdateChannelFrequency(channelFrequency);
  }
if (demodulationEnabled && channelFrequency > virtualFrequency + virtualSampleRate / 2) {
  channelFrequency=virtualFrequency + virtualSampleRate / 2;
  callbackHandler.onUpdateChannelFrequency(channelFrequency);
}
break;
case SCROLLTYPE_CHANNEL_FREQUENCY:
channelFrequency-=distanceX * hzPerPx;
callbackHandler.onUpdateChannelFrequency(channelFrequency);
break;
case SCROLLTYPE_CHANNEL_WIDTH_LEFT:
case SCROLLTYPE_CHANNEL_WIDTH_RIGHT:
int tmpChannelWidth=scrollType == SCROLLTYPE_CHANNEL_WIDTH_LEFT ? (int)(channelWidth + distanceX * hzPerPx) : (int)(channelWidth - distanceX * hzPerPx);
if (callbackHandler.onUpdateChannelWidth(tmpChannelWidth)) channelWidth=tmpChannelWidth;
break;
case SCROLLTYPE_SQUELCH:
float dbPerPx=(maxDB - minDB) / (float)getFftHeight();
squelch=squelch + distanceY * dbPerPx;
if (squelch < minDB) squelch=minDB;
break;
default :
Log.e(LOGTAG,"String_Node_Str" + scrollType);
}
if (verticalScrollEnabled && scrollType != SCROLLTYPE_SQUELCH) {
float yDiff=(maxDB - minDB) * (distanceY / (float)getFftHeight());
if (maxDB - yDiff > MAX_DB) yDiff=MAX_DB - maxDB;
if (minDB - yDiff < MIN_DB) yDiff=MIN_DB - minDB;
this.setDBScale(minDB - yDiff,maxDB - yDiff);
if (squelch < minDB) squelch=minDB;
if (squelch > maxDB) squelch=maxDB;
}
if (source.getFrequency() + source.getSampleRate() / 2 < virtualFrequency + virtualSampleRate / 2 || source.getFrequency() - source.getSampleRate() / 2 > virtualFrequency - virtualSampleRate / 2) {
if (virtualFrequency >= source.getMinFrequency() && virtualFrequency <= source.getMaxFrequency()) source.setFrequency(virtualFrequency);
}
}
return true;
}