public void draw(Canvas canvas) { if (waveformBytes == null || width == 0) { return; } float totalBarsCount = width / AndroidUtilities.dp(3); if (totalBarsCount <= 0.1f) { return; } byte value; int samplesCount = (waveformBytes.length * 8 / 5); float samplesPerBar = samplesCount / totalBarsCount; float barCounter = 0; int nextBarNum = 0; paintInner.setColor( messageObject != null && !messageObject.isOutOwner() && messageObject.isContentUnread() && messageObject.messageOwner.to_id.channel_id == 0 ? outerColor : (selected ? selectedColor : innerColor)); paintOuter.setColor(outerColor); int y = (height - AndroidUtilities.dp(14)) / 2; int barNum = 0; int lastBarNum; int drawBarCount; for (int a = 0; a < samplesCount; a++) { if (a != nextBarNum) { continue; } drawBarCount = 0; lastBarNum = nextBarNum; while (lastBarNum == nextBarNum) { barCounter += samplesPerBar; nextBarNum = (int) barCounter; drawBarCount++; } int bitPointer = a * 5; int byteNum = bitPointer / 8; int byteBitOffset = bitPointer - byteNum * 8; int currentByteCount = 8 - byteBitOffset; int nextByteRest = 5 - currentByteCount; value = (byte) ((waveformBytes[byteNum] >> byteBitOffset) & ((2 << (Math.min(5, currentByteCount) - 1)) - 1)); if (nextByteRest > 0) { value <<= nextByteRest; value |= waveformBytes[byteNum + 1] & ((2 << (nextByteRest - 1)) - 1); } for (int b = 0; b < drawBarCount; b++) { int x = barNum * AndroidUtilities.dp(3); if (x < thumbX && x + AndroidUtilities.dp(2) < thumbX) { canvas.drawRect( x, y + AndroidUtilities.dp(14 - Math.max(1, 14.0f * value / 31.0f)), x + AndroidUtilities.dp(2), y + AndroidUtilities.dp(14), paintOuter); } else { canvas.drawRect( x, y + AndroidUtilities.dp(14 - Math.max(1, 14.0f * value / 31.0f)), x + AndroidUtilities.dp(2), y + AndroidUtilities.dp(14), paintInner); if (x < thumbX) { canvas.drawRect( x, y + AndroidUtilities.dp(14 - Math.max(1, 14.0f * value / 31.0f)), thumbX, y + AndroidUtilities.dp(14), paintOuter); } } barNum++; } } }