001/* A simple application that demonstrates the use of SoundReader 002 and SoundWriter by performing soft clipping on an input sound file. 003 004 Copyright (c) 2000-2012 The Regents of the University of California. 005 All rights reserved. 006 Permission is hereby granted, without written agreement and without 007 license or royalty fees, to use, copy, modify, and distribute this 008 software and its documentation for any purpose, provided that the above 009 copyright notice and the following two paragraphs appear in all copies 010 of this software. 011 012 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 013 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 014 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 015 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 016 SUCH DAMAGE. 017 018 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 020 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 021 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 022 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 023 ENHANCEMENTS, OR MODIFICATIONS. 024 025 PT_COPYRIGHT_VERSION_2 026 COPYRIGHTENDKEY 027 028 */ 029package ptolemy.media.javasound.demo.ReaderProcessWriter; 030 031import ptolemy.media.javasound.SoundReader; 032import ptolemy.media.javasound.SoundWriter; 033 034//////////////////////////////////////////////////// 035 036/** A simple application that demonstrates the use of SoundReader and 037 * SoundWriter by performing soft clipping on an input sound file. 038 * 039 * <p>Samples are read from a sound file specified as a URL, simple 040 * processing is performed on the audio data, and the processed data 041 * is written to a sound file. For this application, the processing 042 * consists of a simple soft clipping operation.</p> 043 * @author Brian K. Vogel 044 * @version $Id$ 045 * @since Ptolemy II 2.0 046 * @Pt.ProposedRating Red (vogel) 047 * @Pt.AcceptedRating Red (vogel) 048 */ 049public class ReaderProcessWriter { 050 /** Read samples from a sound file, process the data using a soft 051 * clipping algorithm and write the results. 052 * @param args Not used. 053 */ 054 public static void main(String[] args) { 055 // Set this to "true" to turn on debugging information. 056 boolean _debug = true; 057 058 // URL path to the input sound file, which is stored in a relative 059 //directory in the ptolemy tree 060 String sourceURL = "file:../../../../actor/lib/javasound/voice.wav"; 061 062 // File name of the output file to create. 063 String writeFile = "demoOutput.wav"; 064 065 // Amount of data to read or write from/to the internal buffer 066 // at a time. This should be set smaller than the internal buffer 067 // size. 068 int getSamplesSize = 256; 069 070 try { 071 // Construct a SoundReader object that is used to read 072 // sound samples from an audio file. 073 SoundReader soundReader = new SoundReader(sourceURL, 074 getSamplesSize); 075 076 // The sample rate to playback at, in Hz. 077 // Set the playback sample rate to the sample rate of the 078 // input sound file. 079 float sampleRate = soundReader.getSampleRate(); 080 081 if (_debug) { 082 System.out.println("Sample rate of the input file is " 083 + sampleRate + " Hz."); 084 } 085 086 // Number of bits per sample. 087 int bitsPerSample = soundReader.getBitsPerSample(); 088 089 if (_debug) { 090 System.out.println("Bits per sample for the input file is " 091 + bitsPerSample); 092 } 093 094 // 1 for mono, 2 for stereo, etc. 095 int channels = soundReader.getChannels(); 096 097 if (_debug) { 098 System.out.println( 099 "Number of channels for the input file is " + channels); 100 } 101 102 int putSamplesSize = getSamplesSize; 103 104 // Construct a sound writer object that is used to write 105 // audio samples to a sound file. 106 SoundWriter soundWriter = new SoundWriter(writeFile, sampleRate, 107 bitsPerSample, channels, putSamplesSize); 108 109 boolean done = false; 110 111 // The main loop. 112 while (!done) { 113 // Read in some audio samples. 114 double[][] capturedSamplesArray = soundReader.getSamples(); 115 116 if (_debug) { 117 System.out.println("Read some samples..."); 118 } 119 120 if (capturedSamplesArray == null) { 121 // reached end of file. 122 done = true; 123 System.out.println("Reached end of file."); 124 } else { 125 // Do some simple processing on the 126 // captured audio. 127 for (int j = 0; j < channels; j++) { 128 for (int i = 0; i < getSamplesSize; i++) { 129 // ********** INSERT PROCESSING CODE HERE **** 130 // Perform soft clipping using the arc tangent. 131 capturedSamplesArray[j][i] = java.lang.Math 132 .atan(capturedSamplesArray[j][i]) * 0.6; 133 } 134 } 135 136 // Write the processed audio samples. 137 soundWriter.putSamples(capturedSamplesArray); 138 } 139 } 140 141 // Close the input sound file, because we are done with it. 142 soundReader.closeFile(); 143 144 // Close the output sound file, because we are done with it. 145 soundWriter.closeFile(); 146 } catch (Exception ex) { 147 System.err.println(ex); 148 } 149 150 System.out.println("Done."); 151 } 152}