marytts.server.http.AudioStreamNHttpEntity.java Source code

Java tutorial

Introduction

Here is the source code for marytts.server.http.AudioStreamNHttpEntity.java

Source

/**
 * Copyright 2009 DFKI GmbH.
 * All Rights Reserved.  Use is subject to license terms.
 *
 * This file is part of MARY TTS.
 *
 * MARY TTS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package marytts.server.http;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;

import marytts.server.Request;
import marytts.util.MaryUtils;

import org.apache.http.entity.AbstractHttpEntity;
import org.apache.http.nio.ContentEncoder;
import org.apache.http.nio.IOControl;
import org.apache.http.nio.entity.ContentOutputStream;
import org.apache.http.nio.entity.ProducingNHttpEntity;
import org.apache.http.nio.util.HeapByteBufferAllocator;
import org.apache.http.nio.util.SharedOutputBuffer;
import org.apache.log4j.Logger;

/**
 * @author marc
 *
 */
public class AudioStreamNHttpEntity extends AbstractHttpEntity implements ProducingNHttpEntity, Runnable {
    private Request maryRequest;
    private AudioInputStream audio;
    private AudioFileFormat.Type audioType;
    private Logger logger;
    private Object mutex;
    private SharedOutputBuffer out;

    public AudioStreamNHttpEntity(Request maryRequest) {
        this.maryRequest = maryRequest;
        this.audio = maryRequest.getAudio();
        this.audioType = maryRequest.getAudioFileFormat().getType();
        setContentType(MaryHttpServerUtils.getMimeType(audioType));
        this.mutex = new Object();
    }

    public void finish() {
        assert logger != null : "we should never be able to write if run() is not called";
        logger.info("Completed sending streaming audio");
        maryRequest = null;
        audio = null;
        audioType = null;
        logger = null;
    }

    public void produceContent(ContentEncoder encoder, IOControl ioctrl) throws IOException {
        if (out == null) {
            synchronized (mutex) {
                out = new SharedOutputBuffer(8192, ioctrl, new HeapByteBufferAllocator());
                mutex.notify();
            }
        }
        while (!encoder.isCompleted())
            out.produceContent(encoder);
    }

    public long getContentLength() {
        return -1;
    }

    public boolean isRepeatable() {
        return false;
    }

    public boolean isStreaming() {
        return true;
    }

    public InputStream getContent() {
        return null;
    }

    public void writeTo(final OutputStream outstream) throws IOException {
        throw new RuntimeException("Should not be called");
    }

    /**
     * Wait for the SharedOutputBuffer to become available, write audio data to it.
     */
    public void run() {
        this.logger = MaryUtils.getLogger(Thread.currentThread().getName());
        // We must wait until produceContent() is called:
        while (out == null) {
            synchronized (mutex) {
                try {
                    mutex.wait();
                } catch (InterruptedException e) {
                }
            }
        }
        assert out != null;
        ContentOutputStream outStream = new ContentOutputStream(out);
        try {
            AudioSystem.write(audio, audioType, outStream);
            outStream.flush();
            outStream.close();
            logger.info("Finished writing output");
        } catch (IOException ioe) {
            logger.info("Cannot write output, client seems to have disconnected. ", ioe);
            maryRequest.abort();
        }
    }

}