Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
src/SoundMemRecord.java
/* |
* QuickTime for Java SDK Sample Code |
Usage subject to restrictions in SDK License Agreement |
* Copyright: © 1996-1999 Apple Computer, Inc. |
*/ |
import java.awt.*; |
import java.awt.event.*; |
import quicktime.*; |
import quicktime.sound.*; |
import quicktime.util.*; |
public class SoundMemRecord extends Frame { |
private static int |
kOSType = 1 << 1; |
private static int sndBufferSize = 327680; |
public static void main (String args[]) { |
System.out.println ("Make sure you have connected an Input device or have a built in audio input device."); |
SoundMemRecord sr = new SoundMemRecord ("Sound Recording"); |
sr.show(); |
sr.toFront(); |
} |
// the sndHndl is kept around as it must be cached while we're using it |
SndHandle sndHndl; |
SPBDevice sndDevice; |
SPB recorder; |
SoundMemRecord (String title) { |
super (title); |
try { |
QTSession.open(); |
sndDevice = new SPBDevice (null, SoundConstants.siWritePermission); |
System.out.println ("OptionsDialog==" + sndDevice.hasOptionsDialog()); |
System.out.println ("NumChannels=" + sndDevice.getChannelAvailable()); |
System.out.println ("SampleSize=" + sndDevice.getSampleSize()); |
System.out.println ("SampleRate=" + sndDevice.getSampleRate()); |
printArray ("Names", sndDevice.getInputSourceNames()); |
printArray("Compression", sndDevice.getCompressionAvailable(), kOSType); |
printArray("SampleSize", sndDevice.getSampleSizeAvailable(), 0); |
printArray("SampleRate", sndDevice.getSampleRateAvailable()); |
sndDevice.setPlayThruOnOff (0); |
sndHndl = new SndHandle (sndDevice.getNumberChannels(), |
sndDevice.getSampleRate(), |
sndDevice.getSampleSize(), |
sndDevice.getCompressionType(), |
60); |
sndHndl.appendSoundBuffer (sndBufferSize); //this is the size of our sound buffer |
// Set up recording to reuse object for multiple recordings |
// we hold onto this variable so that it isn't finalized before we |
// finish recording |
// we also need to remove the completion proc as we shut this down - see closingWindow |
System.out.println ("Will Record:" + sndDevice.bytesToMilliseconds(sndBufferSize) + " msecs"); |
recorder = new SPB(sndDevice, 0, sndDevice.bytesToMilliseconds(sndBufferSize), sndHndl.getSoundData()); |
// We're going to record this block ASynchronously |
// and we're installing a completion proc to notify us when |
// the recording is finished |
recorder.setCompletionProc (new SICompletion () { |
final SndHandle soundHdl = sndHndl; |
final SPBDevice device = sndDevice; |
public void execute (SPB paramBlock) { |
System.out.println ("FinishedRecording"); |
try{ |
// set up sndHndl after recording is finished so we cam play it |
soundHdl.setupHeader (device.getNumberChannels(), |
device.getSampleRate(), |
device.getSampleSize(), |
device.getCompressionType(), |
60, |
paramBlock.getCount()); |
} catch (QTException ee){ |
ee.printStackTrace(); |
} |
} |
}); |
} catch (Exception ee) { |
ee.printStackTrace(); |
QTSession.close(); |
} |
setLayout(new GridLayout(1, 3, 2, 2)); |
startButton.addActionListener (new ActionListener () { |
public void actionPerformed (ActionEvent event) { |
try{ |
System.out.println ("StartRecording"); |
recorder.record (true); |
} catch (QTException ee){ |
ee.printStackTrace(); |
} |
} |
}); |
add (startButton); |
playRecordedButton.addActionListener (new ActionListener () { |
public void actionPerformed (ActionEvent event) { |
try{ |
if (sndHndl != null) { |
// As with all other callbacks the application is reponsible for |
// disposing of the callback - in this case that means disposing the sound channel. |
// So if using a callback the last thing you should do |
// is install a callback command on the channel and dispose it when that guy fires |
// see SoundAction .... |
SndChannel sndChan1 = new SndChannel (new SoundCallBack () { |
SndHandle theSnd = sndHndl; |
public void execute (SndChannel sc) { |
try { |
System.out.println ("In Execute:" + sc); |
if (theSnd != null) { |
SndInfo info = theSnd.parseSndHeader (); |
SoundComponentData data = info.sndData; |
//shows use of buffer command |
// this call will LOCK the handle - it must stay locked whilst the buffer command is active |
QTPointerRef sndData = theSnd.getSoundData(); |
ExtScheduledSoundHeader buffer = new ExtScheduledSoundHeader (sndData,//data.getBuffer(), |
data.getNumChannels(), |
data.getSampleRate(), |
data.getSampleSize(), |
data.getFormat()); |
SndCommand bufferCmd = new SndCommand (SoundConstants.bufferCmd); |
bufferCmd.setBuffer (buffer); |
sc.doCommand (bufferCmd); |
theSnd = null; |
// reschedule callback to dispose the SndChannel |
// do it this way so that we don't have to wait |
// until the sound is finished playing |
sc.doCommand (new SndCommand (SoundConstants.callBackCmd)); |
System.out.println ("Replay the sound just for fun:" + sc); |
} else { |
System.out.println ("Finished Playing:" + sc); |
sc.disposeQTObject();//finished with SndChannel so we MUST dispose it |
} |
} catch (Exception e) { |
e.printStackTrace(); |
} |
} |
}); |
// this plays asynchronously |
// we issue a callback on the SndChannel which will |
// fire AFTER the snd play has completed |
sndChan1.play (sndHndl); |
sndChan1.doCommand (new SndCommand (SoundConstants.callBackCmd)); |
System.out.println ("finished scheduling play and callback:" + sndChan1); |
} |
} catch (Exception ee){ |
ee.printStackTrace(); |
} |
} |
}); |
add (playRecordedButton); |
playMyDataButton.addActionListener (new ActionListener () { |
public void actionPerformed (ActionEvent event) { |
try{ |
System.out.println ("Play constructed data"); |
Thread.yield(); // make sure we get print feedback!!! |
// CONSTRUCT a Sound in memory and play it |
//use this constructor then do setup header with data size |
SndHandle tempSndHndl = new SndHandle (); |
byte[] media = new byte[64000]; |
short val = -32768; |
for (int i = 0; i < media.length; i+=2) { |
if (val > 32750) |
val = -32768; |
val+=16; |
media[i] = (byte)((val | 0xFF00) >>> 8); |
media[i + 1] = (byte)val; |
} |
// MUST do this first |
tempSndHndl.setupHeader (1, 11050, 16, SoundConstants.k16BitBigEndianFormat, 0, media.length); |
// either way works |
if (false) { |
// allocates the extra memory for the sound buffer in the SndHandle |
tempSndHndl.appendSoundBuffer (media.length); |
QTPointerRef qtpr=tempSndHndl.getSoundData(); |
qtpr.copyFromArray (0,media,0,media.length); |
} else { |
QTPointerRef qtpr= new QTPointer (media.length, true); |
qtpr.copyFromArray (0,media,0,media.length); |
// sets the data directly |
tempSndHndl.setSoundData (qtpr); |
} |
Sound.play(tempSndHndl); |
System.out.println ("Finished Playing"); |
} catch (Exception ee){ |
ee.printStackTrace(); |
} |
} |
}); |
add (playMyDataButton); |
pack(); |
addWindowListener (new WindowAdapter () { |
public void windowClosing (WindowEvent e) { |
recorder.removeCompletionProc(); //clean this up as we installed it |
QTSession.close(); |
dispose(); |
} |
public void windowClosed (WindowEvent e) { |
System.exit(0); |
} |
}); |
} |
private static void printArray (String prefix, int[] array, int printTypeFlag) { |
System.out.print (prefix + "=["); |
if (array.length == 0) { |
System.out.println ("]"); |
return; |
} |
for (int i = 0; i < array.length - 1; i++) { |
if ((printTypeFlag & kOSType) != 0) |
System.out.print (QTUtils.fromOSType(array[i]) + ","); |
else |
System.out.print (array[i] + ","); |
} |
if ((printTypeFlag & kOSType) != 0) |
System.out.println (QTUtils.fromOSType(array[array.length-1]) + "]"); |
else |
System.out.println (array[array.length-1] + "]"); |
} |
private static void printArray (String prefix, float[] array) { |
System.out.print (prefix + "=["); |
if (array.length == 0) { |
System.out.println ("]"); |
return; |
} |
for (int i = 0; i < array.length - 1; i++) { |
System.out.print (array[i] + "F,"); |
} |
System.out.println (array[array.length-1] + "F]"); |
} |
private static void printArray (String prefix, String[] array) { |
System.out.print (prefix + "=["); |
if (array.length == 0) { |
System.out.println ("]"); |
return; |
} |
for (int i = 0; i < array.length - 1; i++) { |
System.out.print (array[i] + ","); |
} |
System.out.println (array[array.length-1] + "]"); |
} |
private Button startButton = new Button("Record"); |
private Button playRecordedButton = new Button("Play Recorded Data"); |
private Button playMyDataButton = new Button("Play My Data"); |
private boolean recording = false; |
} |
Copyright © 2006 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2006-05-05