Mercurial > hg > cmdp
view test/uk/ac/qmul/eecs/depic/daw/test/SoundWaveChunkTest.java @ 0:3074a84ef81e
first import
author | Fiore Martin <f.martin@qmul.ac.uk> |
---|---|
date | Wed, 26 Aug 2015 16:16:53 +0100 |
parents | |
children |
line wrap: on
line source
/* Cross-Modal DAW Prototype - Prototype of a simple Cross-Modal Digital Audio Workstation. Copyright (C) 2015 Queen Mary University of London (http://depic.eecs.qmul.ac.uk/) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package uk.ac.qmul.eecs.depic.daw.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.net.URI; import java.net.URISyntaxException; import javax.swing.SwingUtilities; import org.junit.Before; import org.junit.Test; import uk.ac.qmul.eecs.depic.daw.SoundWave; import uk.ac.qmul.eecs.depic.daw.beads.BeadsSoundEngineFactory; @SuppressWarnings("unused") public class SoundWaveChunkTest { BeadsSoundEngineFactory factory; SoundWave wave; boolean swingIsDone; @Before public void setUp() throws Exception { swingIsDone = false; factory = new BeadsSoundEngineFactory(); } @Test public void testConstructor(){ int[] scaleFactors = new int[] {-1,0}; for(int scaleFactor : scaleFactors) try { SoundWave w1 = factory .setSoundWaveParameters(SoundWave.MIN_SUPPORTED_CHUNK_SIZE,scaleFactor,scaleFactor) .createSoundWave(); fail(); }catch(RuntimeException e){ assertTrue(true); } /* test chunks size < MIN_SUPPORTED_CHUNK_SIZE and not a power of 2*/ int[] chunkSizes = new int[] {-1,-16,0,10,100,SoundWave.MIN_SUPPORTED_CHUNK_SIZE+2}; for(int size : chunkSizes) try { SoundWave w2 = factory .setSoundWaveParameters(size,1,1) .createSoundWave(); fail("Size "+size+" allowed"); }catch(RuntimeException e){ assertTrue(true); } /* check correct chunk size > MIN_SUPPORTED_CHUNK_SIZE and power of 2*/ chunkSizes = new int[] {SoundWave.MIN_SUPPORTED_CHUNK_SIZE, SoundWave.MIN_SUPPORTED_CHUNK_SIZE*2, SoundWave.MIN_SUPPORTED_CHUNK_SIZE*4}; for(int size : chunkSizes) try { factory.setSoundWaveParameters(size,1,1).createSoundWave(); }catch(RuntimeException e){ e.printStackTrace(); assertTrue(false); } } @Test public void testGetFrameAtChunk() { /* 128 samples per chunk, scale factor = 1 and 2 */ wave = factory.setSoundWaveParameters(128,3,1).createSoundWave(); /* by-pass the final constrain using an array */ final AssertionError [] swingError = {null}; try { SwingUtilities.invokeAndWait(new Runnable(){ @Override public void run() { URI fileURI = null; try { fileURI = getClass().getResource("./audio/sound1.wav").toURI(); } catch (URISyntaxException e) { new RuntimeException(e.getMessage()).printStackTrace(); System.exit(-1); } wave.loadAudioData(new File(fileURI), new PropertyChangeListener(){ @Override public void propertyChange(PropertyChangeEvent evt) { if("progress".equals(evt.getPropertyName())){ /* only test when the file is fully loaded */ if((Integer)evt.getNewValue() == SoundWave.FILE_LOAD_TOTAL_PROGRESS){ try { /* sound1.wav file is 44100Hz, 2 bytes per frame, mono * * 0-1 and 7-8 seconds are silenced */ byte[] audioData = AudioFileLoader.getAudioBuffer(getClass().getResource("./audio/sound1.wav")); /* first second @ 8000Hz is silence */ for(int i = 0; i * 128 < 8000; i++){ assertEquals("chunk "+i,0,audioData[(int)wave.getFramesPositionAt(i).get(0)]); assertEquals("chunk "+i+" (scale = 2)",0,audioData[(int)wave.getFramesPositionAt(i).get(0)/2]); assertEquals("chunk "+i+" (scale = 2)",0,audioData[(int)wave.getFramesPositionAt(i).get(0)/4]); } /* (16min *44100)/128 = 5512.5 */ /* 1min * 44100 = 344 chunks and 68 frames */ /* 7th seconds @ 8000Hz is at (7 * 8000)/128 = 437 chunks + 64 frames */ /* check a neighbourhood of 10 samples */ for(int i=10; i<20;i++){ wave.setScaleFactor(1); assertEquals("chunk at second 7",0,audioData[(int)wave.getFramesPositionAt(437).get(0)+64+i]); wave.setScaleFactor(2); assertEquals("chunk at second 7 (scale = 2)",0,audioData[((int)wave.getFramesPositionAt(437).get(0)+64+i)/2]); wave.setScaleFactor(3); assertEquals("chunk at second 7 (scale = 3)",0,audioData[((int)wave.getFramesPositionAt(437).get(0)+64+i)/4]); } }catch(AssertionError e){ swingError[0] = e; }finally{ //System.out.println("just after assert Equals"); synchronized(wave){ swingIsDone = true; wave.notify(); } } } }else if(SoundWave.FILE_ERROR_PROPERTY.equals(evt.getPropertyName())){ new RuntimeException("could not open file:"+evt.getNewValue()).printStackTrace(); System.exit(-1); } } }); } }); } catch (InvocationTargetException | InterruptedException e) { e.printStackTrace(); System.exit(-1); } /* wait for the swing thread to finish. The swing thread will be finished when propertyChange with progress = * * SoundWave.FILE_LOAD_TOTAL_PROGRESS will be scheduled for execution in the EDT, by the swing worker */ synchronized(wave){ while(!swingIsDone) try { wave.wait(); /* throw the error in the JUnit thread so that it's counted */ if(swingError[0] != null){ assertTrue(swingError[0].getMessage(),false); } } catch (InterruptedException e) { e.printStackTrace(); System.exit(-1); } } } }