⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 voicespeakeroutput.java

📁 jxta官方例程
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
    }    /**     * Return the call control object     */    protected VoJxtaCallControl getCallControl() {        return this.callControl;    }    /**     * Retrieves the command (as String) from this DialogMessage.     *     * @param msg DialogMessage containing the command string     * @return String command     */    private String getMessageSessionCommand(DialogMessage msg) {        String command = null;        MessageElement commandMessageElement = msg.getMessageElement(VoJxtaCallControl.TAG_SESSION_COMMAND);        if (commandMessageElement != null) {            if (true || commandMessageElement instanceof ByteArrayMessageElement) {                command = commandMessageElement.toString();            } else {                if (LOG.isEnabledFor(Level.INFO)) {                    LOG.info("getMessageSessionCommand is not instanceof ByteArrayMessageElement");                }            }        } else {            if (LOG.isEnabledFor(Level.INFO)) {                LOG.info("sessionMessageCommandElement is null");            }        }        return command;    }    /**     * Retrieves the data element from this DialogMessage and returns the speex     * encoded bytes.     *     * @param msg The DialogMessage containing voice data     * @return voiceData actual speex encoded bytes     */    private byte[] getMessageVoiceBytes(DialogMessage msg) {        byte[] voiceData = null;        MessageElement voiceMessageElement = msg.getMessageElement(VoJxtaCallControl.TAG_VOICE_DATA);        if (voiceMessageElement != null) {            if (voiceMessageElement instanceof ByteArrayMessageElement) {                ByteArrayMessageElement voiceDataElelment =                        (ByteArrayMessageElement) voiceMessageElement;                voiceData = voiceDataElelment.getBytes();            } else {                if (LOG.isEnabledFor(Level.INFO)) {                    LOG.info("getMessageVoiceBytes VOICE DATA Element is not instanceof ByteMessageElement");                }            }        } else {            if (LOG.isEnabledFor(Level.INFO)) {                LOG.info("voiceMessageElement is null");            }        }        return voiceData;    }    /**     * Decode and write decoded bytes to pcmBuffer. we pull a chunk of     * speex bytes of speexMessageSize into this method then block it out     * to its basic block size (determined by speex quality) and write the     * raw pcm to the pcmBuffer. the decoded block size is 640 bytes at the     * current sample rate.     * ie     * speexMessageSize = 75 bytes (5 chunks of 15bytes)     * break the message up into 5 chunks and decode each     * put it all together and write to pcmBufer     * <p/>     * SourceLine writes do large chunks better than rapid small chunks (640)     * so we put a message back together and write it to the pcmBuffer     */    protected void decodeAndPlay(byte[] buf) {        if (getSpeakerState() != this.STATE_OFF ||                getSpeakerState() != this.STATE_PAUSE) {            int chunks = buf.length / speexChunkSize;            byte[] decodedBuff = new byte[chunks * rawChunkSize];            int[] encodedStartPos = new int[chunks];            int[] decodedStartPos = new int[chunks];            for (int j = 0; j < chunks; j++) {                encodedStartPos[j] = j * speexChunkSize;                decodedStartPos[j] = j * rawChunkSize;            }            for (int i = 0; i < chunks; i++) {                byte[] preDecodeBuff = new byte[speexChunkSize];                System.arraycopy(buf, encodedStartPos[i], preDecodeBuff, 0, speexChunkSize);                long in = System.currentTimeMillis();                byte[] postDecodeBuff = decoder.decode(preDecodeBuff);                long out = System.currentTimeMillis();                long roundTrip = (out - in);                if (averageDecodeTime != 0) {                    averageDecodeTime = (long) (averageDecodeTime + roundTrip) / 2;                } else {                    averageDecodeTime = roundTrip;                }                System.arraycopy(postDecodeBuff, 0, decodedBuff, decodedStartPos[i], rawChunkSize);            }            boolean sourceLineWaiting = false;            synchronized (sourceLineThreadWaiting) {                sourceLineWaiting = sourceLineThreadWaiting.booleanValue();            }            if (sourceLineWaiting && sourceLineThread.getBufferSize() >= sourceLineThread.getWriteBlockSize()) {                messageThreadWaiting = new Boolean(false);                synchronized (sourceLineThreadLock) {                    sourceLineThreadLock.notify();                }            }            sourceLineThread.put(decodedBuff);            //sourceLine.write (decodedBuff, 0, decodedBuff.length);        } else {            LOG.info("Unable to play audio, line closed!");        }    }    /**     * Statistical accessor     */    public int getPCMBufferSize() {        return sourceLineThread != null ? sourceLineThread.getBufferSize() : -1;    }    /**     * Statistical accessor     */    public int getSourceLineAvailable() {        return sourceLine.available();    }    /**     * This thread holds a dynamic buffer from which decoded bytes are written.     * Largish chunks (multiples of rawPCMBlockSize) are read and written to     * the source line when source line buffer has room and there are ample     * bytes in the pcmBuffer. This Thread does the actual Playing to the     * speaker.     * TODO:     * The pause state is recognized in this thread which will halt the     * playing of sound but a signal needs to be sent to the main VoiceSpekaerOutput     * run() or else hte buffers will continue to fill.     */    class WriteToSourceLineThread extends Thread {        private VoiceDataBuffer pcmBuffer = null;        private int writeBlockSize = rawChunkSize * 30;        private int pcmBufferSize = rawBufferSize * 60;        WriteToSourceLineThread() {            pcmBuffer = new VoiceDataBuffer(pcmBufferSize,                    VoiceSpeakerOutput.this, "WriteToSourceLineThread");            setPriority(Thread.NORM_PRIORITY);        }        public int getWriteBlockSize() {            return writeBlockSize;        }        public int getBufferSize() {            return pcmBuffer.size();        }        public void put(byte[] buff) {            pcmBuffer.append(buff);        }        public void run() {            if (LOG.isEnabledFor(Level.INFO)) {                LOG.info("WriteToSourceLineThread : run begin");            }            while (true) {                try {                    if (getSpeakerState() == VoiceSpeakerOutput.this.STATE_PAUSE) {                        if (LOG.isEnabledFor(Level.INFO)) {                            LOG.info("WriteToSourceLineThread run : is paused");                        }                        synchronized (pauseLock) {                            pauseLock.wait();                        }                    }                    if (getSpeakerState() == VoiceSpeakerOutput.this.STATE_OFF) {                        if (LOG.isEnabledFor(Level.INFO)) {                            LOG.info("WriteToSourceLineThread run : is off");                        }                        //we should send any remaining data in buffer first                        break;                    }                    //if( sourceLine.available () >= writeBlockSize &&                    //      pcmBuffer.size () > writeBlockSize) {                    if (pcmBuffer.size() > (640)) {                        int l = pcmBuffer.size();                        sourceLine.write(pcmBuffer.get(l), 0, l);                        //sourceLine.write (pcmBuffer.get (writeBlockSize), 0, writeBlockSize);                    } else {                        synchronized (sourceLineThreadWaiting) {                            sourceLineThreadWaiting = new Boolean(true);                        }                        synchronized (sourceLineThreadLock) {                            if (LOG.isEnabledFor(Level.INFO)) {                                //LOG.info ("Waiting for new PCM Blocks..");                            }                            sourceLineThreadLock.wait();                        }                    }                } catch (InterruptedException ix) {                    ix.printStackTrace();                }            }            if (LOG.isEnabledFor(Level.INFO)) {                LOG.info("WriteToSourceLineThread : run end");            }        }    }    private int getSpeakerState() {        return this.speakerState;    }    /**     * halts writing to the source line (speaker). race condition exists. fix     */    public void pauseSpeaker() {        setSpeakerState(this.STATE_PAUSE);        sourceLine.stop();    }    /**     * Resumes writing to the sourceLine and starts the line     */    public void resumeSpeaker() {        sourceLine.start();        setSpeakerState(this.STATE_ON);        synchronized (pauseLock) {            pauseLock.notify();        }    }    /**     * Accessor for incoming speex buffer size     */    public int getEncodedBufferSize() {        return speexBufferSize;    }    /**     * Accessor for incoming speex buffer size     */    public void setEncodedBufferSize(int encodedBufferSize) {        // at the momment the buffer is not resizeable        //this.speexBufferSize = encodedBufferSize;    }    /**     * statistical accessor     */    public long getNumberOfMessagesReceived() {        return this.receivedMessages;    }    /**     * statistical accessor     */    public long getNumberOfBytesReceived() {        return this.receivedBytes;    }    /**     * statistical accessor     */    public long getAverageDecodeTime() {        return averageDecodeTime;    }    /**     * statistical accessor     */    public int getEncodedMessageSize() {        return speexMessageSize;    }    /**     * statistical accessor     */    public void setEncodedMessageSize(int encodedMessageSize) {        this.speexMessageSize = encodedMessageSize;    }    /**     * statistical accessor     */    public boolean isGainControlSupported() {        return gainControl != null;    }    /**     * Sets the gain on this source Line     */    public void adjustGainValue(float gainValue) {        if (gainControl != null) {            gainControl.setValue(gainValue);        }    }    /**     * Returns the current gain value.     */    public float getGainValue() {        return (gainControl != null) ? gainControl.getValue() : 0.0f;    }    /**     * Returns the max gain value for this sourceline     */    public float getMaxGainValue() {        return (gainControl != null) ? gainControl.getMaximum() : 0.0f;    }    /**     * Returns the min gain value for this sourceline     */    public float getMinGainValue() {        return (gainControl != null) ? gainControl.getMinimum() : 0.0f;    }    /**     * Returns a string representing the units this gain control uses     */    public String getGainUnits() {        return (gainControl != null) ? gainControl.getUnits() : "";    }    /**     * Returns a string representing the max value as a label     */    public String getMaxGainLabel() {        return (gainControl != null) ? gainControl.getMaxLabel() : "";    }    /**     * Returns a string representing the min value as a label     */    public String getMinGainLabel() {        return (gainControl != null) ? gainControl.getMinLabel() : "";    }    /**     * Querys control state     */    public boolean isMuteControlSupported() {        return muteControl != null;    }    /**     * Querys control state     */    public boolean isMute() {        return muteControl.getValue();    }    /**     * sets control state     */    public void setMute(boolean mute) {        muteControl.setValue(mute);    }    /**     * Querys control unit string     */    public String getMuteStateLabel() {        return muteControl.getStateLabel(muteControl.getValue());    }    private void printMixers() {        System.out.println("\n\rSpeakerMixers : ");        Mixer.Info[] info = AudioSystem.getMixerInfo();        for (int i = 0; i < info.length; i++) {            System.out.println("\tName: " + info[i].getName() + " Description: " + info[i].getDescription());        }    }    private void printControls() {        System.out.println("\n\rSpeakerControls : ");        Control[] controls = sourceLine.getControls();        for (int i = 0; i < controls.length; i++) {            System.out.println("\tName: " + controls[i].toString());        }    }    /**     * debugging     */    private void printSpeakerState() {        String s = null;        if (this.speakerState == STATE_PAUSE) {            s = "PAUSE  ";        }        if (this.speakerState == STATE_ON) {            s = "ON  ";        }        if (this.speakerState == STATE_OFF) {            s = "OFF  ";        }        if (LOG.isEnabledFor(Level.INFO)) {            LOG.info("printMicState = " + s);        }    }    protected void printSupportedControls() {        LOG.info("Speaker SupportedControls");        LOG.info("mute " + sourceLine.isControlSupported(BooleanControl.Type.MUTE));        LOG.info("Balance " + sourceLine.isControlSupported(FloatControl.Type.BALANCE));        LOG.info("MasterGain " + sourceLine.isControlSupported(FloatControl.Type.MASTER_GAIN));        LOG.info("Pan " + sourceLine.isControlSupported(FloatControl.Type.PAN));        LOG.info("SampleRate " + sourceLine.isControlSupported(FloatControl.Type.SAMPLE_RATE));        LOG.info("Volume " + sourceLine.isControlSupported(FloatControl.Type.VOLUME));        Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();        for (int i = 0; i < mixerInfo.length; i++) {            speakerMixer = AudioSystem.getMixer(mixerInfo[i]);            LOG.info("speakerMixer SupportedControls for mixer" + mixerInfo[i].toString());            LOG.info("mute " + speakerMixer.isControlSupported(BooleanControl.Type.MUTE));            LOG.info("Balance " + speakerMixer.isControlSupported(FloatControl.Type.BALANCE));            LOG.info("MasterGain " + speakerMixer.isControlSupported(FloatControl.Type.MASTER_GAIN));            LOG.info("Pan " + speakerMixer.isControlSupported(FloatControl.Type.PAN));            LOG.info("SampleRate " + speakerMixer.isControlSupported(FloatControl.Type.SAMPLE_RATE));            LOG.info("Volume " + speakerMixer.isControlSupported(FloatControl.Type.VOLUME));        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -