float[] sPeakP;
float offX, scaleX, scaleY, f1;
long start = info.span.start;
long totalLength = info.getTotalLength();
Span chunkSpan;
long fullLen, fullStop;
int chunkLen, decimLen;
Rectangle r;
try {
drawBusyList.clear(); // "must be called in the event thread"
if( logAmp ) {
maxY = view.getAmpLogMax();
minY = view.getAmpLogMin();
minInpY = (float) Math.exp( minY / TWENTYBYLOG10 );
} else {
maxY = view.getAmpLinMax();
minY = view.getAmpLinMin();
minInpY = 0; // not used
}
deltaY = maxY - minY;
deltaYN = -4 / deltaY;
offY = maxY / deltaY;
//System.out.println( "deltaY " + deltaY + "; deltaYN " + deltaYN + "; offY " + offY );
synchronized( bufSync ) {
createBuffers();
while( totalLength > 0 ) {
fullLen = Math.min( maxLen, totalLength );
chunkLen = (int) (fromPCM ? fullLen : decimHelps[ info.idx ].fullrateToSubsample( fullLen ));
decimLen = chunkLen / info.inlineDecim;
chunkLen = decimLen * info.inlineDecim;
fullLen = (long) chunkLen << info.shift;
// chunkSpan = new Span( start, start + fullLen );
if( fromPCM ) {
fullStop = fullScale.getSpan().stop;
chunkSpan = new Span( start, Math.min( fullStop, start + fullLen ));
fullScale.readFrames( tmpBuf, 0, chunkSpan );
final long chunkStop = chunkSpan.getLength();
if( (chunkStop < fullLen) && (chunkStop > 0) ) {
// duplicate last frames
for( int i = (int) chunkStop, j = i - 1; i < (int) fullLen; i++ ) {
for( int ch = 0; ch < fullChannels; ch++ ) {
sPeakP = tmpBuf[ ch ];
sPeakP[ i ] = sPeakP[ j ];
}
}
}
if( !toPCM ) decimator.decimatePCM( tmpBuf, tmpBuf2, 0, decimLen, info.inlineDecim );
} else {
chunkSpan = new Span( start, start + fullLen );
readFrames( info.idx, tmpBuf2, 0, drawBusyList, chunkSpan, null);
if( info.inlineDecim > 1 ) decimator.decimate( tmpBuf2, tmpBuf2, 0, decimLen, info.inlineDecim );
}
if( toPCM ) {
if( logAmp ) {
for( int ch = 0; ch < fullChannels; ch++ ) {
sPeakP = tmpBuf[ ch ];
for( int i = 0; i < decimLen; i++ ) {
f1 = Math.abs( sPeakP[ i ]);
if( f1 > minInpY ) {
sPeakP[ i ] = (float) (Math.log( f1 ) * TWENTYBYLOG10);
} else {
sPeakP[ i ] = minY;
}
}
}
}
for( int ch = 0; ch < fullChannels; ch++ ) {
sPeakP = tmpBuf[ ch ];
r = view.rectForChannel( ch );
scaleX = 4 * r.width / (float) (info.sublength - 1);
scaleY = r.height * deltaYN;
offX = scaleX * off[ ch ];
sampleAndHold[ch] = scaleX > 16;
off[ch] = drawPCM( sPeakP, decimLen, peakPolyX[ ch ],
peakPolyY[ ch ], off[ ch ], offX, scaleX, scaleY, sampleAndHold[ ch ]);
}
} else {
if( logAmp ) {
for( int ch = 0; ch < fullChannels; ch++ ) {
off[ ch ] = decimator.drawLog( info, ch, peakPolyX, peakPolyY, rmsPolyX, rmsPolyY, decimLen, view.rectForChannel( ch ), deltaYN, off[ ch ], minY, minInpY );
}
} else {
for( int ch = 0; ch < fullChannels; ch++ ) {
off[ ch ] = decimator.draw( info, ch, peakPolyX, peakPolyY, rmsPolyX, rmsPolyY, decimLen, view.rectForChannel( ch ), deltaYN, off[ ch ]);
}
}
}
start += fullLen;
totalLength -= fullLen;
}
} // synchronized( bufSync )
// System.err.println( "busyList.size() = "+busyList.size() );
if( toPCM ) {
final Stroke strkOrig = g2.getStroke();
g2.setStroke( strkLine );
g2.setPaint( pntLine );
for( int ch = 0; ch < fullChannels; ch++ ) {
r = view.rectForChannel( ch );
g2.clipRect( r.x, r.y, r.width, r.height );
g2.translate( r.x, r.y + r.height * offY );
g2.scale( 0.25f, 0.25f );
g2.drawPolyline( peakPolyX[ ch ], peakPolyY[ ch ], off[ ch ]);
g2.setTransform( atOrig );
g2.setClip( clipOrig );
}
g2.setStroke( strkOrig );
} else {
// g2.setPaint( pntArea );
for( int ch = 0; ch < fullChannels; ch++ ) {
r = view.rectForChannel( ch );
g2.clipRect( r.x, r.y, r.width, r.height );
if( !drawBusyList.isEmpty() ) {
// g2.setColor( Color.red );
g2.setPaint( pntBusy );
for( int i = 0; i < drawBusyList.size(); i++ ) {
chunkSpan = (Span) drawBusyList.get( i );
scaleX = r.width / (float) info.getTotalLength(); // (info.sublength - 1);
g2.fillRect( (int) ((chunkSpan.start - info.span.start) * scaleX) + r.x, r.y,
(int) (chunkSpan.getLength() * scaleX), r.height );
}
}
g2.translate( r.x, r.y + r.height * offY );
g2.scale( 0.25f, 0.25f );
g2.setColor( Color.gray );