Chris Lacy's Software Engineering Blog

Saturday Jun 26, 2010

music test

package net.chrislacy.music.test;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;

public class MusicTest {
	
	
	private static final double[] NOTES = { 261.626, 293.665, 329.628, 349.228, 391.995, 440.000, 493.883, 523.251 };
	private static final Set<Integer> INCLUDE = new HashSet<Integer>();
	private static final double VOLUME = 0.03;
	private static final long LENGTH_MS = 1500;
	
	static {
		
		INCLUDE.add(1);
		INCLUDE.add(3);
		//INCLUDE.add(4);
		INCLUDE.add(5);
		//INCLUDE.add(8);
	}

	public static void main(String[] args) throws Throwable {
		
		// TODO add fails to "more often test" list
		// print solution after x (3) wrong guesses
		
		while(true) {
			
			List<Integer> notes = playRandomPhrase(3, VOLUME);
			InputStreamReader converter = new InputStreamReader(System.in);
			BufferedReader in = new BufferedReader(converter);
			
			boolean shouldRepeat = true;
			
			while(shouldRepeat) {
				
				String line = in.readLine();
				int index = 0;
				boolean passed = true;
				
				inner:
				for(Integer n : notes) {
					
					if(line.length() != notes.size() || Integer.parseInt(line.charAt(index++) + "") != n) {
						
						System.out.println("nope");
						playPhrase(VOLUME, createSimilarNotes(LENGTH_MS, 100, hertzFromOneBased(notes)));
						passed = false;
						break inner;
					}
				}
				
				shouldRepeat = !passed;
			}
		}
	}
	
	private static double[] hertzFromOneBased(List<Integer> oneBased) {
		
		double[] hertzs = new double[oneBased.size()];
		int index = 0;
		
		for(Integer oneB : oneBased) {
			
			hertzs[index++] = NOTES[oneB - 1];
		}
		
		return hertzs;
	}
	
	private static List<Integer> playRandomPhrase(int length, double volume) {

		List<Integer> result = new LinkedList<Integer>();
		double[] hertzs = new double[length];
		
		result.add(1);
		hertzs[0] = NOTES[0];
		
		for(int ii=1; ii<length; ii++) {
			
			int cur = randomIntLessThan(NOTES.length);
			int oneBasedCur = cur + 1;
			
			while(!INCLUDE.contains(oneBasedCur)) {
				
				cur = randomIntLessThan(NOTES.length);
				oneBasedCur = cur + 1;
			}
			
			result.add(oneBasedCur);
			hertzs[ii] = NOTES[cur];
		}
		
		playPhrase(volume, createSimilarNotes(LENGTH_MS, 100, hertzs));
		
		return result;
	}
	
	private static int randomIntLessThan(int max) {
		
		double r = Math.random();
		
		return (int) Math.round(r * max);
	}
	
	private static ComplexNote[] createSimilarNotes(long length, int relativeVolume, double... hertz) {
		
		ComplexNote[] result = new ComplexNote[hertz.length];
		
		for(int ii=0; ii<hertz.length; ii++) {
			
			result[ii] = new ComplexNote(hertz[ii], length, relativeVolume);
		}
		
		return result;
	}
	
	private static byte[] createOneWave(int numberOfBytes, double maxHeight) {
		
		byte[] oneWave = new byte[numberOfBytes];
		
		for(int i=0; i<numberOfBytes; i++) {
			
			double fractionalPos = ((double)i*2) / numberOfBytes;
			double angle = fractionalPos * Math.PI;
			double sineVal = Math.sin(angle);
			Double volSine = sineVal * maxHeight;
			byte b = volSine.byteValue();
			oneWave[i] = b;
		}
		
		return oneWave;
	}
	
	private static byte[] makeWaveTwoChannel(byte[] oneWave) {
		
		byte[] stereoWave = new byte[oneWave.length * 2];
		
		for(int i=0; i<oneWave.length; i++) {
			
			int stereoPos = i*2;
			stereoWave[stereoPos] = stereoWave[stereoPos+1] = oneWave[i];
		}
		
		return stereoWave;
	}
	
	private static byte[] repeatWave(byte[] original, int numberOfWaves) {
		
		byte[] multipleStereoWaves = new byte[original.length * numberOfWaves];
		
		for(int i=0; i < numberOfWaves; i++) {
			
			System.arraycopy(original, 0, multipleStereoWaves, original.length * i, original.length);
		}
		
		return multipleStereoWaves;
	}
	
	private static byte[] createMultipleStereoWaves(int bytesPerWave, double volume, int numberOfWaves) {
		
		byte[] oneWave = createOneWave(bytesPerWave, volume);
		byte[] stereoWave = makeWaveTwoChannel(oneWave);
		
		return repeatWave(stereoWave, numberOfWaves);
	}
	
	private static Clip createClip(AudioInputStream ais) {
		
		Clip clip;
		
		try {
			
			clip = AudioSystem.getClip();
			clip.open(ais);
			clip.setFramePosition(0);
		}
		catch (Exception e) {

			throw new RuntimeException(e);
		}
		
		return clip;
	}
	
	/**
	 * @param volume 1.000104 min vol headphones @ 220 hz
	 */
	private static AudioInputStream createAudioInputStream(double volume, ComplexNote... notes) {
		
		float bytesPerSecond = 48000f;
		
		AudioFormat af = new AudioFormat(bytesPerSecond, 
				8, // sample size in bits
				2, // channels
				true, // signed
				false // bigendian
		);
		
		List<byte[]> waveList = new LinkedList<byte[]>();
		int finalLength = 0;
		
		for(ComplexNote note : notes) {
		
			Double bpw = bytesPerSecond/note.getHertz();
			int bytesPerWave = bpw.intValue();
			int numberOfWaves = 800/bpw.intValue() + 5; // 763
			byte[] multipleStereoWaves = createMultipleStereoWaves(bytesPerWave, note.getRelativeVolume() * volume, numberOfWaves);
			
			int numBytesNeeded = ((Float) (bytesPerSecond * (note.getLength()/1000))).intValue();
			byte[] noteBuffer = new byte[numBytesNeeded];
			int repeatNum = numBytesNeeded / multipleStereoWaves.length;
			int ii=0;
			
			for(; ii<repeatNum; ii++) {
				
				System.arraycopy(multipleStereoWaves, 0, noteBuffer, multipleStereoWaves.length * ii, multipleStereoWaves.length);
			}
			
			System.arraycopy(multipleStereoWaves, 0, noteBuffer, multipleStereoWaves.length * ii, numBytesNeeded % multipleStereoWaves.length);
			
			waveList.add(noteBuffer);
			finalLength += noteBuffer.length;
		}
		
		byte[] finalBa = new byte[finalLength];
		int index = 0;
		
		for(byte[] cur : waveList) {
			
			System.arraycopy(cur, 0, finalBa, index, cur.length);
			index = index + cur.length;;
		}
			
		return new AudioInputStream(new ByteArrayInputStream(finalBa), af, finalBa.length/2);
	}
	
	private static void playPhrase(double volume, ComplexNote... notes) {
		
		Clip clip = createClip(createAudioInputStream(volume, notes));
		clip.loop(0);
		clip.drain();
		clip.flush();
		clip.close();
	}

}

Wednesday Jun 23, 2010

SingleResourceResolver

I don't know what others are doing for this, but try this for your rest implementations:

package net.chrislacy.webapp.util;

import java.util.Locale;

import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;

public class SingleViewResolver implements ViewResolver {

	
	private View view;
	
	
	public SingleViewResolver(View view) {
		
		this.view = view;
	}
	
	@Override
	public View resolveViewName(String viewName, Locale locale) throws Exception {
		
		return view;
	}

}

for example:
	<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
		<property name="mediaTypes">
			<map>
				<entry key="json" value="application/json" />
				<entry key="xml" value="application/xml" />
				<entry key="html" value="text/html" />
			</map>
		</property>
		<property name="viewResolvers">
			<list>
				<bean class="net.chrislacy.webapp.util.SingleViewResolver">
					<constructor-arg name="view">
						<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
					</constructor-arg>
				</bean>
				<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
					p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />
			</list>
		</property>
	</bean>

Tuesday Jun 22, 2010

Integration Testing Spring Web Applications through DispatcherServlet

import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.*;
import static org.springframework.web.util.WebUtils.*;

import java.util.Enumeration;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.chrislacy.utils.c.EasyEnumeration;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

public class DispatcherTestHelper {

	
	private DispatcherTestHelper() {}
	
	
	@SuppressWarnings("unchecked")
	public static HttpServletResponse test(String configLocation, String method, String path) throws Throwable {
		
		DispatcherServlet ds = new DispatcherServlet();
		ds.setContextConfigLocation(configLocation);
		
		ServletConfig sc = mock(ServletConfig.class);
		Enumeration e = mock(Enumeration.class);
			
		when(sc.getInitParameterNames()).thenReturn(e);
		ServletContext scon = mock(ServletContext.class);
		when(scon.getInitParameterNames()).thenReturn(e);
		when(scon.getAttributeNames()).thenReturn(e);
		when(sc.getServletContext()).thenReturn(scon);
		
		ds.init(sc);
		
		WebApplicationContext wac = ds.getWebApplicationContext();
		when(scon.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE)).thenReturn(wac);
		
		HttpServletRequest hsr = mock(HttpServletRequest.class);
		when(hsr.getMethod()).thenReturn(method);
		
		when(hsr.getAttribute(INCLUDE_REQUEST_URI_ATTRIBUTE)).thenReturn(path);
		when(hsr.getAttribute(INCLUDE_CONTEXT_PATH_ATTRIBUTE)).thenReturn(path);
		when(hsr.getAttribute(INCLUDE_SERVLET_PATH_ATTRIBUTE)).thenReturn(path);
		when(hsr.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE)).thenReturn(wac);
		when(hsr.getAttributeNames()).thenReturn(new EasyEnumeration(INCLUDE_REQUEST_URI_ATTRIBUTE, 
INCLUDE_CONTEXT_PATH_ATTRIBUTE, INCLUDE_SERVLET_PATH_ATTRIBUTE, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE));
		when(hsr.getRequestURI()).thenReturn(path);
		RequestDispatcher rd = mock(RequestDispatcher.class);
		when(hsr.getRequestDispatcher(anyString())).thenReturn(rd);
		HttpServletResponse hsres = mock(HttpServletResponse.class);
		ds.service(hsr, hsres);
		
		verify(rd).include(hsr, hsres);
		
		return hsres;
	}
}


	@Test
	public void test() throws Throwable {
		HttpServletResponse hsres = DispatcherTestHelper.test("file:src/main/webapp/WEB-INF/spring/*-config.xml", "GET", "/welcome");
		System.out.println(hsres);
	}

Calendar

Feeds

Search

Links

Navigation

Referrers