001/* A simple application that demonstrates the use of LiveSound by performing 002 soft clipping in real-time. 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.SoftClip; 030 031import ptolemy.actor.injection.ActorModuleInitializer; 032import ptolemy.media.javasound.LiveSound; 033 034//////////////////////////////////////////////////// 035 036/** 037 A simple application that demonstrates the use of LiveSound by 038 performing soft clipping in real-time. This application performs 039 real-time capture, processing, and playback of audio data. Sound 040 samples are captured from the computer's audio input port. The 041 processing consists of a simple soft-clipping function (the arc 042 tangent is used). The soft-clipped audio data is then played out 043 the speaker. 044 045 @author Brian K. Vogel 046 @version $Id$ 047 @since Ptolemy II 1.0 048 @Pt.ProposedRating Red (vogel) 049 @Pt.AcceptedRating Red (vogel) 050 */ 051public class SoftClip { 052 /** Perform real-time capture, processing and playback of audio data. 053 * @param args Not used. 054 */ 055 public static void main(String[] args) { 056 ActorModuleInitializer.initializeInjector(); 057 058 // Create a sound capture object that captures audio 059 // from the computer's audio input port (mic or 060 // line-in). 061 int sampleRate = 44100; // in Hz 062 int sampleSizeInBits = 16; 063 int channels = 2; // stereo. 064 int inBufferSize = 4096; // Internal buffer size for capture. 065 int outBufferSize = 4096; // Internal buffer size for playback. 066 067 // the object that has access to the sound capture device. 068 Object consumer = new Object(); 069 070 // the object that has access to the sound playback device. 071 Object producer = new Object(); 072 073 // Amount of data to read or write from/to the internal buffer 074 // at a time. This should be set smaller than the internal buffer 075 // size! 076 int getSamplesSize = 256; 077 078 /* 079 SoundCapture soundCapture = 080 new SoundCapture(sampleRate, sampleSizeInBits, 081 channels, inBufferSize, 082 getSamplesSize); 083 */ 084 085 // Construct a sound playback object that plays audio 086 //through the computer's speaker. 087 /* 088 SoundPlayback soundPlayback = new SoundPlayback(sampleRate, 089 sampleSizeInBits, 090 channels, 091 outBufferSize, 092 putSamplesSize); 093 */ 094 095 // Initialize and begin real-time capture and playback. 096 try { 097 //soundCapture.startCapture(); 098 // Set up LiveSound parameters for capture/playback 099 LiveSound.setSampleRate(sampleRate); 100 LiveSound.setBitsPerSample(sampleSizeInBits); 101 LiveSound.setChannels(channels); 102 LiveSound.setBufferSize(inBufferSize); 103 System.out.println("Attempting to set both buffer sizes: " 104 + outBufferSize + " samples."); 105 LiveSound.setTransferSize(getSamplesSize); 106 107 LiveSound.startCapture(consumer); 108 109 LiveSound.startPlayback(producer); 110 111 //soundPlayback.startPlayback(); 112 } catch (Exception ex) { 113 System.err.println(ex); 114 } 115 116 double[][] capturedSamplesArray = new double[channels][getSamplesSize]; 117 118 System.out.println(" Actual audio capture buffer size: " 119 + LiveSound.getBufferSizeCapture() + " samples."); 120 System.out.println(" Actual audio playback buffer size: " 121 + LiveSound.getBufferSizePlayback() + " samples."); 122 123 try { 124 // Loop forever. 125 System.out.println("starting"); 126 127 int count = 0; 128 129 while (count < 1000) { 130 count++; 131 132 // Read in some captured audio. 133 //capturedSamplesArray = soundCapture.getSamples(); 134 capturedSamplesArray = LiveSound.getSamples(consumer); 135 136 // Do some simple processing on the 137 // captured audio. 138 for (int j = 0; j < channels; j++) { 139 for (int i = 0; i < getSamplesSize; i++) { 140 // ********** PROCESSING CODE HERE ********** 141 // Perform soft clipping using the arc tangent. 142 capturedSamplesArray[j][i] = java.lang.Math 143 .atan(capturedSamplesArray[j][i]) * 0.6; 144 } 145 } 146 147 // Play the processed audio samples. 148 //soundPlayback.putSamples(capturedSamplesArray); 149 LiveSound.putSamples(producer, capturedSamplesArray); 150 } 151 152 // Stop capture. 153 LiveSound.stopCapture(consumer); 154 155 // Stop playback. 156 //soundPlayback.stopPlayback(); 157 LiveSound.stopPlayback(producer); 158 System.out.println("stopping"); 159 } catch (Exception ex) { 160 System.err.println(ex); 161 } 162 } 163}