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.AudioPlayer;
053import org.openimaj.audio.SampleChunk;
054import org.openimaj.audio.conversion.BitDepthConverter;
055import org.openimaj.audio.conversion.BitDepthConverter.BitDepthConversionAlgorithm;
056import org.openimaj.audio.generation.Synthesizer;
057import org.openimaj.audio.samples.SampleBuffer;
058
059
060/**
061 *  @author David Dupplaw (dpd@ecs.soton.ac.uk)
062 *
063 *      @created 18 Jun 2012
064 */
065public class AudioBitDepthConversionTest
066{
067        /**
068         *  @param args
069         */
070        public static void main( final String[] args )
071    {
072                try
073        {
074                // ============================================================== //
075                // This is what we'll convert from
076                final AudioFormat inputFormat  = new AudioFormat( 16, 22.05, 1 );
077
078                // This is what we'll convert to
079                final AudioFormat outputFormat1 = new AudioFormat( 8, 22.05, 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 BitDepthConverter bdc1 = new BitDepthConverter( synth,
090                                BitDepthConversionAlgorithm.NEAREST,
091                                outputFormat1 );
092
093                // ============================================================== //
094                // Add the synth's chunks to the display
095                final ArrayList<SampleChunk> chunks = new ArrayList<SampleChunk>();
096                for( int n = 0; n < 3; n++ )
097                        chunks.add( synth.nextSampleChunk().clone() );
098                final DefaultXYDataset ds1 = AudioBitDepthConversionTest.getDataSet( chunks );
099
100                // ============================================================== //
101                // Now add the resampled chunks to the display
102                final ArrayList<SampleChunk> resampledChunks1 = new ArrayList<SampleChunk>();
103                for( int n = 0; n < chunks.size(); n++ )
104                        resampledChunks1.add( bdc1.process( chunks.get(n) ).clone() );
105                final DefaultXYDataset ds2 = AudioBitDepthConversionTest.getDataSet( resampledChunks1 );
106
107                // ============================================================== //
108                // Set up the display
109                final JPanel p = new JPanel( new GridBagLayout() );
110                final GridBagConstraints gbc = new GridBagConstraints();
111                gbc.gridx = gbc.gridy = 0;
112                gbc.fill = GridBagConstraints.BOTH;
113                gbc.weightx = gbc.weighty = 1;
114
115                // ============================================================== //
116                // Add a chart of the original samples
117                JFreeChart c = ChartFactory.createXYLineChart( "Samples @ "+inputFormat, "Amplitude",
118                        "Samples", ds1, PlotOrientation.HORIZONTAL, false, false,
119                        false );
120                ChartPanel chartPanel = new ChartPanel( c, false );
121                chartPanel.setPreferredSize( new Dimension( 1500, 300 ) );
122
123                gbc.gridy++;
124                p.add( chartPanel, gbc );
125
126                // ============================================================== //
127                // Add a chart of the resampled samples
128                c = ChartFactory.createXYLineChart( "Samples @ "+outputFormat1, "Amplitude",
129                        "Samples", ds2, PlotOrientation.HORIZONTAL, false, false,
130                        false );
131                chartPanel = new ChartPanel( c, false );
132                chartPanel.setPreferredSize( new Dimension( 1500, 300 ) );
133
134                gbc.gridy++;
135                p.add( chartPanel, gbc );
136
137                // ============================================================== //
138                // Display
139                final JFrame f = new JFrame();
140                f.add( p, BorderLayout.CENTER );
141                f.pack();
142                f.setVisible( true );
143
144                // Play the sample (minus the first three chunks ;)
145                final AudioPlayer ap = new AudioPlayer( bdc1 );
146                ap.run();
147
148        }
149        catch( final HeadlessException e )
150        {
151                e.printStackTrace();
152        }
153        catch( final Exception e )
154        {
155                e.printStackTrace();
156        }
157    }
158
159        /**
160         *      Returns a data set that displays the sample chunks.
161         *
162         *  @param chunks
163         *  @return a dataset
164         */
165        public static DefaultXYDataset getDataSet( final List<SampleChunk> chunks )
166        {
167                final DefaultXYDataset ds = new DefaultXYDataset();
168
169                int x = 0, y = 0;
170                for( int n = 0; n < chunks.size(); n++ )
171                {
172                        final SampleChunk sc = chunks.get(n);
173                        final SampleBuffer b = sc.getSampleBuffer();
174
175                        // Convert sample to a XY data plot
176                        final double[][] data = new double[2][];
177                        data[0] = new double[b.size()]; // x
178                        data[1] = new double[b.size()]; // y
179
180                        for( x = 0; x < b.size(); x++ )
181                        {
182                                data[0][x] = b.get(x);
183                                data[1][x] = x+y;
184                        }
185
186                        y += x;
187
188                        ds.addSeries( "samples "+n, data );
189                }
190
191                return ds;
192        }
193}