📄 signalviewer.java
字号:
Math.abs(samp.getPossibleMinSample())); if (samp.getWavHeader().getNumberOfChannels() == 1) { channelMode = MONO; } else if (samp.getWavHeader().getNumberOfChannels() == 2) { channelMode = STEREO_SEPARATE; } } int w = Toolkit.getDefaultToolkit().getScreenSize().width; //start with loading twice the screenwidth into the WavePart //loadData(0L, SCREEN_BUFFER * w * msPerPixel, w); loadData(0L, msPerPixel, w); } /** * Loads the wave data for the specified interval into the WavePart object.<br> * The WaveSampler is requested to read all bytes for the interval in one * turn. This method then takes care of the extraction of the values per * pixel. * * @param fromTime the interval starttime in ms * @param toTime the interval stoptime in ms * @param width DOCUMENT ME! * * @return true if loading was successful, false otherwise * * @see WAVSampler#readInterval(int, int) */ private boolean loadData(long fromTime, long toTime, final int width) { //long start = System.currentTimeMillis(); if (samp == null) { return false; } fromTime += mediaOffset; toTime += mediaOffset; if ((fromTime > samp.getDuration()) || (fromTime > toTime) || (toTime < 0)) { return false; } long to = (toTime > (long) samp.getDuration()) ? (long) samp.getDuration() : toTime; long from = (fromTime < mediaOffset) ? mediaOffset : fromTime; long startSample = from / msPerPixel; long stopSample = to / msPerPixel; int extent = (int) (stopSample - startSample) + 1; int size = (extent > width) ? extent : width; // HS apr 04: in order to achieve more precision in the calculation of // the sample to seek, the samplesPerPixel value isn't used here anymore double firstSeeksample = (from * samp.getSampleFrequency()) / 1000; //samp.seekSample(startSample * samplesPerPixel); // old samp.seekSample((long) firstSeeksample); int samplesRead = 0; int startSampleInt = (int) startSample; int min; int max; switch (channelMode) { case MONO: //fallthrough, same as STEREO_MERGED //break; case STEREO_MERGED: currentPart.reset(); currentPart.setInterval(from, to, startSampleInt, size, extent); samplesRead = samp.readInterval(extent * samplesPerPixel, 1); // don't read more than the number of samples returned by readInterval for (int i = 0, p = startSampleInt; (i < (samplesRead - samplesPerPixel)) && (p < (startSampleInt + size)); i += samplesPerPixel, p++) { int sample; min = 0; max = 0; for (int j = 0; j < samplesPerPixel; j++) { sample = samp.getFirstChannelArray()[i + j]; if (sample < min) { min = sample; } else if (sample > max) { max = sample; } } currentPart.addLineToFirstChannel(p, -max, -min); } break; case STEREO_BLENDED: //fallthrough case STEREO_SEPARATE: currentPart.reset(); currentPart.setInterval(from, to, startSampleInt, size, extent); samplesRead = samp.readInterval(extent * samplesPerPixel, 2); int min2; int max2; // don't read more than the number of samples returned by readInterval // the existence of two int arrays is guaranteed, even if there is no // second channel in the sound file (0 values will be read in that case). for (int i = 0, p = startSampleInt; (i < (samplesRead - samplesPerPixel)) && (p < (startSampleInt + size)); i += samplesPerPixel, p++) { int sample; int sample2; min = 0; max = 0; min2 = 0; max2 = 0; for (int j = 0; j < samplesPerPixel; j++) { sample = samp.getFirstChannelArray()[i + j]; if (sample < min) { min = sample; } else if (sample > max) { max = sample; } sample2 = samp.getSecondChannelArray()[i + j]; if (sample2 < min2) { min2 = sample2; } else if (sample2 > max2) { max2 = sample2; } } currentPart.addLineToFirstChannel(p, -max, -min); currentPart.addLineToRightChannel(p, -max2, -min2); } break; default: break; } //System.out.println("SignalViewer: samples read: " + samplesRead); //System.out.println("Load time: " + (System.currentTimeMillis() - start) + " ms"); return true; } /** * Paint to the BufferedImage. This is necessary in the following situations:<br> * - the viewer has been resized<br> * - the timeline cursor has (been) moved out of the current interval<br> * - the msPerPixel has been changed<br> * - the media source has been changed??<br> * - the timeline cursor has (been) moved out of the loaded samples<br> * - the MONO - STEREO mode has been changed */ private void paintBuffer() { if ((getWidth() <= 0) || (getHeight() <= 0)) { return; } if ((getWidth() != imageWidth) || (getHeight() != imageHeight)) { imageWidth = getWidth(); imageHeight = getHeight(); if (intervalEndTime == 0) { intervalEndTime = intervalBeginTime + (imageWidth * msPerPixel); if (timeScaleConnected) { setGlobalTimeScaleIntervalEndTime(intervalEndTime); } } } synchronized (paintlock) { if ((bi == null) || (bi.getWidth() < imageWidth) || (bi.getHeight() < imageHeight)) { bi = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB); big2d = bi.createGraphics(); } //check whether we have to load a new interval if (!currentPart.contains(intervalBeginTime, intervalEndTime)) { boolean loaded = loadData(intervalBeginTime, intervalBeginTime + (SCREEN_BUFFER * imageWidth * msPerPixel), imageWidth); // loadData only returns false in case of a severe error /* if (!loaded) { //return; currentPart.reset(); currentPart.setStartTime(0L); currentPart.setStopTime(0L); } */ } int channelHeight; int intervalX1 = (int) (intervalBeginTime / msPerPixel); //int intervalX2 = (int)(intervalEndTime / msPerPixel); // since there can be a media offset (i.e. the global begin time and the media begin // time are not the same) we need different translations for the ruler etc // and the wave part(s) int waveIntervalX1 = (int) ((intervalBeginTime + mediaOffset) / msPerPixel); int waveIntervalX2 = (int) ((intervalEndTime + mediaOffset) / msPerPixel); AffineTransform at = new AffineTransform(); //paint the background color big2d.setComposite(AlphaComposite.Src); big2d.setColor(Constants.DEFAULTBACKGROUNDCOLOR); big2d.fillRect(0, 0, imageWidth, imageHeight); // mark the area beyond the media time if (intervalEndTime > getMediaDuration()) { int xx = xAt(getMediaDuration()); big2d.setColor(UIManager.getColor("Panel.background")); big2d.fillRect(xx, 0, imageWidth - xx, bi.getHeight()); } /*paint time ruler */ big2d.setColor(Constants.DEFAULTFOREGROUNDCOLOR); big2d.translate(-intervalX1, 0.0); ruler.paint(big2d, intervalBeginTime, imageWidth, msPerPixel, SwingConstants.TOP); big2d.translate(intervalX1 - waveIntervalX1, 0.0); ///end ruler // paint the wave(s) switch (channelMode) { case MONO: //fallthrough case STEREO_MERGED: //one merged channel for the wave stored in WavePart.firstPath channelHeight = imageHeight - rulerHeight; int channelMid = rulerHeight + Math.round(channelHeight / 2f); big2d.translate(0.0, channelMid); big2d.drawLine(waveIntervalX1, 0, waveIntervalX2, 0); at.setToScale(1.0, ((((float) channelHeight) / maxAmplitude) / 2) * (vertZoom / 100f)); /* Graphics2D.draw(Shape.createTransformedShape(AffineTransform)) seems to be faster */ //big2d.transform(at); //big2d.draw(currentPart.getFirstPath().createTransformedShape(at)); currentPart.paintLeftChannelLimit(big2d, at, channelHeight / 2); big2d.translate(0.0, -channelMid); break; case STEREO_SEPARATE: channelHeight = (imageHeight - rulerHeight - GAP) / 2; int leftChannelMid = rulerHeight + (int) (Math.ceil(channelHeight / 2f)); int rightChannelMid = imageHeight - (int) (Math.ceil(channelHeight / 2f)); // decoration big2d.setColor(Constants.SIGNALCHANNELCOLOR); big2d.fillRect(waveIntervalX1, rulerHeight, imageWidth + 2, channelHeight); big2d.fillRect(waveIntervalX1, imageHeight - channelHeight, imageWidth + 2, channelHeight); big2d.setColor(Constants.DEFAULTFOREGROUNDCOLOR); // big2d.translate(0.0, leftChannelMid); big2d.drawLine(waveIntervalX1, 0, waveIntervalX2, 0); at.setToScale(1.0, ((((float) channelHeight) / maxAmplitude) / 2) * (vertZoom / 100f)); //big2d.draw(currentPart.getFirstPath().createTransformedShape(at));//expensive?? // big2d.setClip(0, -leftChannelMid + rulerHeight, imageWidth + 2, channelHeight); currentPart.paintLeftChannelLimit(big2d, at, channelHeight / 2); // big2d.setClip(null); big2d.translate(0.0, rightChannelMid - leftChannelMid); big2d.drawLine(waveIntervalX1, 0, waveIntervalX2, 0); //big2d.draw(currentPart.getSecondPath().createTransformedShape(at)); // big2d.setClip(0, -leftChannelMid + rulerHeight, imageWidth + 2, channelHeight); currentPart.paintRightChannelLimit(big2d, at, channelHeight / 2); big2d.translate(0.0, -rightChannelMid); // big2d.setClip(null); break; case STEREO_BLENDED: channelHeight = imageHeight - rulerHeight; int chMid = rulerHeight + Math.round(channelHeight / 2f); big2d.translate(0.0, chMid); big2d.drawLine(waveIntervalX1, 0, waveIntervalX2, 0); at.setToScale(1.0, ((((float) channelHeight) / maxAmplitude) / 2) * (vertZoom / 100f)); big2d.setColor(Constants.SIGNALSTEREOBLENDEDCOLOR1); //big2d.draw(currentPart.getFirstPath().createTransformedShape(at)); currentPart.paintLeftChannelLimit(big2d, at, channelHeight / 2); big2d.setColor(Constants.SIGNALSTEREOBLENDEDCOLOR2); big2d.setComposite(alpha04); //big2d.draw(currentPart.getSecondPath().createTransformedShape(at)); currentPart.paintRightChannelLimit(big2d, at, channelHeight / 2); big2d.setComposite(AlphaComposite.Src); big2d.translate(0.0, -chMid); break; default: ; } drawCuePoints(big2d); big2d.setTransform(new AffineTransform()); //reset transform } // end synchronized block repaint(); } /** * Draws cue points if there are present in wav file * * @param big2g */ private void drawCuePoints(Graphics2D big2g) { if (samp == null) { return; } WAVCuePoint[] cuePoints = samp.getWavHeader().getCuePoints(); if (cuePoints.length > 0) { big2d.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f, new float[] { 4.0f }, 0.0f)); big2d.setColor(Color.darkGray); for (int i = 0; i < cuePoints.length; i++) { int time = (int) samp.getTimeAtSample(cuePoints[i].getSampleOffset()); int x = time / msPerPixel; if ((intervalBeginTime <= time) && (time < intervalEndTime)) { big2d.drawLine(x, rulerHeight, x, imageHeight); String label = cuePoints[i].getLabel(); String note = cuePoints[i].getNote(); if ((label != null) && (note != null)) { label += " : "; } big2d.drawString(((label != null) ? label : new Integer(i).toString()) + ((note != null) ? note : ""), x + 1, imageHeight - 1); } } big2d.setStroke(new BasicStroke()); } } /** * Override <code>JComponent</code>'s paintComponent to paint:<br> * - a BufferedImage with a ruler and the waveform<br> * - the current selection<br> * - the cursor / crosshair * * @param g DOCUMENT ME! */ public void paintComponent(Graphics g) { super.paintComponent(g);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -