001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030/** 031 * 032 */ 033package org.openimaj.demos.sandbox.audio; 034 035import java.awt.BorderLayout; 036import java.awt.Dimension; 037import java.awt.GridBagConstraints; 038import java.awt.GridBagLayout; 039import java.awt.HeadlessException; 040import java.util.ArrayList; 041import java.util.List; 042 043import javax.swing.JFrame; 044import javax.swing.JPanel; 045 046import org.jfree.chart.ChartFactory; 047import org.jfree.chart.ChartPanel; 048import org.jfree.chart.JFreeChart; 049import org.jfree.chart.plot.PlotOrientation; 050import org.jfree.data.xy.DefaultXYDataset; 051import org.openimaj.audio.AudioFormat; 052import org.openimaj.audio.SampleChunk; 053import org.openimaj.audio.conversion.SampleRateConverter; 054import org.openimaj.audio.conversion.SampleRateConverter.SampleRateConversionAlgorithm; 055import org.openimaj.audio.generation.Synthesizer; 056import org.openimaj.audio.samples.SampleBuffer; 057 058 059/** 060 * @author David Dupplaw (dpd@ecs.soton.ac.uk) 061 * 062 * @created 18 Jun 2012 063 */ 064public class AudioSampleRateConversionTest 065{ 066 /** 067 * @param args 068 */ 069 public static void main( final String[] args ) 070 { 071 try 072 { 073 // ============================================================== // 074 // This is what we'll convert from 075 final AudioFormat inputFormat = new AudioFormat( 16, 22.05, 1 ); 076 077 // This is what we'll convert to 078 final AudioFormat outputFormat1 = new AudioFormat( 16, 11.025, 1 ); 079 final AudioFormat outputFormat2 = new AudioFormat( 16, 44.1, 1 ); 080 081 // Create a synthesiser to output stuff 082 final Synthesizer synth = new Synthesizer(); 083 synth.setFrequency( 500 ); 084 synth.setFormat( inputFormat ); 085// XuggleAudio xa = new XuggleAudio( new File( "videoplayback.3gp" ) ); 086// MultichannelToMonoProcessor synth = new MultichannelToMonoProcessor(xa); 087 088 // The sample rate converter we're testing 089 final SampleRateConverter src1 = new SampleRateConverter( 090 SampleRateConversionAlgorithm.LINEAR_INTERPOLATION, 091 outputFormat1 ); 092 final SampleRateConverter src2 = new SampleRateConverter( 093 SampleRateConversionAlgorithm.LINEAR_INTERPOLATION, 094 outputFormat2 ); 095 096 // ============================================================== // 097 // Add the synth's chunks to the display 098 final ArrayList<SampleChunk> chunks = new ArrayList<SampleChunk>(); 099 for( int n = 0; n < 10; n++ ) 100 chunks.add( synth.nextSampleChunk().clone() ); 101 final DefaultXYDataset ds1 = AudioSampleRateConversionTest.getDataSet( chunks ); 102 103 for( int n = 0; n < chunks.size(); n++ ) 104 System.out.println( "Chunk "+n+" format: "+chunks.get(n).getFormat() ); 105 106 // ============================================================== // 107 // Now add the resampled chunks to the display 108 final ArrayList<SampleChunk> resampledChunks1 = new ArrayList<SampleChunk>(); 109 for( int n = 0; n < chunks.size(); n++ ) 110 resampledChunks1.add( src1.process( chunks.get(n) ).clone() ); 111 final DefaultXYDataset ds2 = AudioSampleRateConversionTest.getDataSet( resampledChunks1 ); 112 for( int n = 0; n < resampledChunks1.size(); n++ ) 113 System.out.println( "1: Resampled Chunk "+n+" format: "+resampledChunks1.get(n).getFormat() ); 114 // ============================================================== // 115 final ArrayList<SampleChunk> resampledChunks2 = new ArrayList<SampleChunk>(); 116 for( int n = 0; n < chunks.size(); n++ ) 117 resampledChunks2.add( src2.process( chunks.get(n) ).clone() ); 118 final DefaultXYDataset ds3 = AudioSampleRateConversionTest.getDataSet( resampledChunks2 ); 119 for( int n = 0; n < resampledChunks2.size(); n++ ) 120 System.out.println( "2: Resampled Chunk "+n+" format: "+resampledChunks2.get(n).getFormat() ); 121 122 // ============================================================== // 123 // Set up the display 124 final JPanel p = new JPanel( new GridBagLayout() ); 125 final GridBagConstraints gbc = new GridBagConstraints(); 126 gbc.gridx = gbc.gridy = 0; 127 gbc.fill = GridBagConstraints.BOTH; 128 gbc.weightx = gbc.weighty = 1; 129 130 // ============================================================== // 131 // Add a chart of the original samples 132 JFreeChart c = ChartFactory.createXYLineChart( "Original Samples", "Amplitude", 133 "Samples", ds1, PlotOrientation.HORIZONTAL, false, false, 134 false ); 135 ChartPanel chartPanel = new ChartPanel( c, false ); 136 chartPanel.setPreferredSize( new Dimension( 1500, 300 ) ); 137 138 gbc.gridy++; 139 p.add( chartPanel, gbc ); 140 141 // ============================================================== // 142 // Add a chart of the resampled samples 143 c = ChartFactory.createXYLineChart( "Downsampled Samples", "Amplitude", 144 "Samples", ds2, PlotOrientation.HORIZONTAL, false, false, 145 false ); 146 chartPanel = new ChartPanel( c, false ); 147 chartPanel.setPreferredSize( new Dimension( 1500, 300 ) ); 148 149 gbc.gridy++; 150 p.add( chartPanel, gbc ); 151 152 // ============================================================== // 153 // Add a chart of the resampled samples 154 c = ChartFactory.createXYLineChart( "Upsampled Samples", "Amplitude", 155 "Samples", ds3, PlotOrientation.HORIZONTAL, false, false, 156 false ); 157 chartPanel = new ChartPanel( c, false ); 158 chartPanel.setPreferredSize( new Dimension( 1500, 300 ) ); 159 160 gbc.gridy++; 161 p.add( chartPanel, gbc ); 162 163 // ============================================================== // 164 // Display 165 final JFrame f = new JFrame(); 166 f.add( p, BorderLayout.CENTER ); 167 f.pack(); 168 f.setVisible( true ); 169 } 170 catch( final HeadlessException e ) 171 { 172 e.printStackTrace(); 173 } 174 catch( final Exception e ) 175 { 176 e.printStackTrace(); 177 } 178 } 179 180 /** 181 * Returns a data set that displays the sample chunks. 182 * 183 * @param chunks 184 * @return a dataset 185 */ 186 public static DefaultXYDataset getDataSet( final List<SampleChunk> chunks ) 187 { 188 final DefaultXYDataset ds = new DefaultXYDataset(); 189 190 int x = 0, y = 0; 191 for( int n = 0; n < chunks.size(); n++ ) 192 { 193 final SampleChunk sc = chunks.get(n); 194 final SampleBuffer b = sc.getSampleBuffer(); 195 196 // Convert sample to a XY data plot 197 final double[][] data = new double[2][]; 198 data[0] = new double[b.size()]; // x 199 data[1] = new double[b.size()]; // y 200 201 for( x = 0; x < b.size(); x++ ) 202 { 203 data[0][x] = b.get(x); 204 data[1][x] = x+y; 205 } 206 207 y += x; 208 209 ds.addSeries( "samples "+n, data ); 210 } 211 212 return ds; 213 } 214}