view src/HumanEchoServlet.java @ 67:b8f8ed1ef8dd tip

Provide .wav suffix in delivered filename
author Chris Cannam
date Tue, 30 Sep 2014 16:52:50 +0100
parents 21bab43ae2c1
children
line wrap: on
line source
/*
 * HumanEchoServlet
 *
 * Version information
 *
 * 3 December 2013
 *
 * Copyright notice
 */

import java.util.Properties;
import java.io.IOException;

import java.io.FileInputStream;
import java.io.BufferedInputStream;
import java.io.File;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;

import org.apache.log4j.Logger;

import javax.servlet.*;
import javax.servlet.http.*;

import com.mathworks.toolbox.javabuilder.MWJavaObjectRef;
import com.mathworks.toolbox.javabuilder.MWNumericArray;
import com.mathworks.toolbox.javabuilder.MWStructArray;
import com.mathworks.toolbox.javabuilder.MWException;
import com.mathworks.toolbox.javabuilder.internal.MCRConfiguration;

import uk.ac.soton.isvr.*;

public class HumanEchoServlet extends HttpServlet {

    private HumanEcho echo;
    private static Logger logger = Logger.getLogger(HumanEchoServlet.class);

    private String outdir = "";
    private String indir = "";

    private static Integer dirId = 0;

    public void init(ServletConfig config) throws ServletException {
        super.init(config);

	logger.info("In init");

	logger.info("java.library.path is " + 
		     System.getProperty("java.library.path"));

        try {
            Properties properties = new Properties();
            properties.load
		(Thread.currentThread().getContextClassLoader().
		 getResourceAsStream("HumanEcho.properties"));

            outdir = properties.getProperty("outdir");
            indir = properties.getProperty("indir");

	    logger.info("WAV file directory is " + outdir);

        } catch (Exception e) {
	    logger.error("Failed to load app properties: " + e.getMessage());
            e.printStackTrace();
        }

        try {
	    // Test that we can construct one of the MATLAB objects
	    
	    long before = System.currentTimeMillis();
            echo = new HumanEcho();
	    long after = System.currentTimeMillis();
	    logger.info("Created a HumanEcho object: it took " + (after - before) + " ms");
        } catch (MWException e) {
	    logger.error("Failed to construct HumanEcho object: " + e.getMessage());
            e.printStackTrace();
        }

	logger.info("Init completed");
    }

    public void destroy() {
        super.destroy();

        if (echo != null) {
            echo.dispose();
        }
    }

    protected synchronized String getDirToken() {
	dirId = dirId + 1;
	return dirId.toString();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	logger.info("In doGet");

        logger.info("Distance (as string) is: " + request.getParameter("dist"));

        // todo: validate/normalise distance
        Double dist = Double.parseDouble(request.getParameter("dist"));
	Double azim = Double.parseDouble(request.getParameter("azim"));
	String orientation = request.getParameter("orient");
	Double dirweight = Double.parseDouble(request.getParameter("dirweight"));

	logger.info("Got parameters");

        MWStructArray Input = null;

        String outputfname = new String();

	// this needs to be distinct for the parameters
	StringBuilder sb = new StringBuilder();

	sb.append("e_d");
	sb.append(dist);
	sb.append("_a");
	sb.append(azim);

	if (orientation.equals("horz")) {
	    sb.append("_H");
	} else if (orientation.equals("angled")) {
	    sb.append("_A");
	}

	sb.append("_w");
	sb.append(dirweight);

	outputfname = sb.toString();

	String target = outdir + File.separator + outputfname + ".wav";
	File targetFile = new File(target);
	targetFile.deleteOnExit();

	if (!targetFile.exists()) {

	    try {
		logger.info("Property catalina.base is " + System.getProperty("catalina.base"));

		String tempDir = outdir + File.separator + getDirToken();
		File tempDirFilePath = new File(tempDir);
		tempDirFilePath.mkdirs();

		// Matlab structure:
		// 
		// Input = struct('dist', 0.9, 'azim', 0, 'orient',
		// 'horz', 'dirweight', 0.2, 'outdir', '/tmp/wav',
		// 'outname', 'foo.wav', 'indir', '/path/to/hrir')

		String[] InputStructFields = {
		    "dist", "azim", "orient", "dirweight",
		    "outdir", "outname", "indir" 
		};

		Input = new MWStructArray(1, 1, InputStructFields);
		Input.set("dist", 1, Double.valueOf(dist));
		Input.set("azim", 1, Double.valueOf(azim));
		Input.set("orient", 1, orientation);
		Input.set("dirweight", 1, Double.valueOf(dirweight));
		Input.set("outdir", 1, tempDir);
		Input.set("indir", 1, indir);

		Input.set("outname", 1, outputfname);

		Object[] result = echo.simulateBinauralSignals(Input);

		File createdFile = new File(tempDir + File.separator + outputfname + ".wav");
		if (!createdFile.exists()) {
		    String err = "The simulateBinauralSignals call failed to create expected output file \"" + createdFile + "\"";
		    logger.error(err);
		    throw new ServletException(err);
		}

		Files.move(createdFile.toPath(),
			   targetFile.toPath(),
			   StandardCopyOption.ATOMIC_MOVE);

		tempDirFilePath.delete();

	    } catch (MWException e) {
		logger.error("Failed to calculate simulateBinauralSignals: " + e.getMessage());
		e.printStackTrace();
		throw new ServletException(e.getMessage());
	    }
	}

        // Creating the stream
        ServletOutputStream stream = null;
        BufferedInputStream buf = null;

        try{
            stream = response.getOutputStream();

	    logger.info("About to read WAV data from \"" + target + "\"");

            //set response headers
            response.setContentType("audio/x-wav");
            response.addHeader("Content-Disposition","attachment; filename=" + outputfname + ".wav");
            response.setContentLength( (int) targetFile.length( ) );

            FileInputStream input = new FileInputStream(targetFile);
            buf = new BufferedInputStream(input);

            int b = 0;
	    int total = 0;

            // read from the file; write to the ServletOutputStream
            while ((b = buf.read()) != -1) {
                stream.write(b);
		total += 1;
	    }

	    logger.info("Successfully wrote " + total + " byte(s) to client");

        } catch (IOException ioe){
	    logger.error("Failed to read wav data: " + ioe.getMessage());
            throw new ServletException(ioe.getMessage( ));
        } finally {
            if (stream != null) stream.close();
            if (buf != null) buf.close();
	}
    }
}