Skip to content
Permalink
Browse files

Java Sound SPI

  • Loading branch information...
kc7bfi
kc7bfi committed Jun 26, 2004
1 parent 0c8c656 commit 4c5a9e20a0b594b636932c3b40ab04ca610e90c7
@@ -2,3 +2,6 @@ eclipse
bak
classes
target
*.log

pack.flac
@@ -0,0 +1,2 @@
META-INF/services/javax.sound.sampled.spi.AudioFileReader:UTF-8
META-INF/services/javax.sound.sampled.spi.FormatConversionProvider:UTF-8
@@ -0,0 +1,2 @@
# Providers of Speex sound file-reading services
org.kc7bfi.jflac.sound.spi.FlacAudioFileReader
@@ -0,0 +1,2 @@
# Providers of Speex sound conversion services
org.kc7bfi.jflac.sound.spi.FlacFormatConvertionProvider
@@ -4,5 +4,14 @@
<preGoal name="xdoc:jelly-transform">
<attainGoal name="faq"/>
</preGoal>

<preGoal name="jar:jar">
<copy todir="${maven.build.dest}/META-INF">
<fileset dir="${basedir}/META-INF"/>
</copy>
<copy todir="${maven.build.dest}/meta-inf">
<fileset dir="${basedir}/META-INF"/>
</copy>
</preGoal>

</project>
@@ -84,13 +84,19 @@ on SourceForge</p>
<include>**/*Test.java</include>
</includes>
<resources>
<resource>
<resource>
<directory>testdata</directory>
<includes>
<include>*.flac</include>
</includes>
</resource>
</resources>
</resource>
<resource>
<directory>META-INF</directory>
<includes>
<include>**/javax.*</include>
</includes>
</resource>
</resources>
</unitTest>
</build>

@@ -312,6 +312,34 @@ public void decode() throws IOException {
}
}

public void decodeFrames() throws IOException {
state = STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
while (true) {
switch (state) {
case STREAM_DECODER_SEARCH_FOR_METADATA :
findMetadata();
break;
case STREAM_DECODER_READ_METADATA :
Metadata metadata = readMetadata();
if (metadata == null) break;
break;
case STREAM_DECODER_SEARCH_FOR_FRAME_SYNC :
frameSync();
break;
case STREAM_DECODER_READ_FRAME :
if (!readFrame()) break;
callFrameListeners(frame);
callPCMProcessors(frame);
break;
case STREAM_DECODER_END_OF_STREAM :
case STREAM_DECODER_ABORTED :
return;
default :
throw new IOException("Unknown state: " + state);
}
}
}

public void decode(SeekPoint from, SeekPoint to) throws IOException {
// position random access file
if (!(inputStream instanceof RandomFileInputStream)) throw new IOException("Not a RandomFileInputStream: " + inputStream.getClass().getName());
@@ -525,6 +553,7 @@ private void skipID3v2Tag() throws IOException {
}

private void frameSync() throws IOException {
System.out.println("frameSync "+streamInfo);
boolean first = true;
int cnt=0;

@@ -564,6 +593,7 @@ private void frameSync() throws IOException {
}
}
} catch (EOFException e) {
System.out.println("EOF");
if (!first) callErrorListeners("FindSync LOST_SYNC: Left over data in file");
state = STREAM_DECODER_END_OF_STREAM;
}
@@ -0,0 +1,138 @@
package org.kc7bfi.jflac.apps;
import java.io.File;
import java.io.IOException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;

/**
* Play.java
* <p>
* A simple class that plays audio from given file names.
* <p>
* Uses the Java Sound SourceDataLine interface to stream the sound.
* Converts compressed encodings (ALAW, ULAW, MP3) to PCM.
* @author Dan Becker, beckerdo@io.com
*/
public class SndPlayer {
/** Plays audio from given file names. */
public static void main( String [] args ) {
// Check for given sound file names.
if (args.length < 1) {
System.out.println( "SndPlayer usage:" );
System.out.println( "\tjava SndPlayer <sound file names>*" );
System.exit( 0 );
}

// Process arguments.
for (int i = 0; i < args.length; i++ )
playAudioFile( args[ i ] );

// Must exit explicitly since audio creates non-daemon threads.
System.exit( 0 );
} // main

/** Play audio from the given file name. */
public static void playAudioFile( String fileName ) {
File soundFile = new File( fileName );

try {
// Create a stream from the given file.
// Throws IOException or UnsupportedAudioFileException
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream( soundFile );
// AudioSystem.getAudioInputStream( inputStream ); // alternate audio stream from inputstream
playAudioStream( audioInputStream );
} catch ( Exception e ) {
System.out.println( "Problem with file " + fileName + ":" );
e.printStackTrace();
}
} // playAudioFile

/** Plays audio from the given audio input stream. */
public static void playAudioStream( AudioInputStream audioInputStream ) {
// Audio format provides information like sample rate, size, channels.
AudioFormat audioFormat = audioInputStream.getFormat();
System.out.println( "Play input audio format=" + audioFormat );

// Convert compressed audio data to uncompressed PCM format.
if ( audioFormat.getEncoding() != AudioFormat.Encoding.PCM_SIGNED ) {
// if ((audioFormat.getEncoding() != AudioFormat.Encoding.PCM) ||
// (audioFormat.getEncoding() == AudioFormat.Encoding.ALAW) ||
// (audioFormat.getEncoding() == AudioFormat.Encoding.MP3)) {
AudioFormat newFormat = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
audioFormat.getSampleRate(),
16,
audioFormat.getChannels(),
audioFormat.getChannels() * 2,
audioFormat.getSampleRate(),
false );
System.out.println( "Converting audio format to " + newFormat );
AudioInputStream newStream = AudioSystem.getAudioInputStream( newFormat, audioInputStream );
audioFormat = newFormat;
audioInputStream = newStream;
}

// Open a data line to play our type of sampled audio.
// Use SourceDataLine for play and TargetDataLine for record.
DataLine.Info info = new DataLine.Info( SourceDataLine.class, audioFormat );
if ( !AudioSystem.isLineSupported( info ) ) {
System.out.println( "Play.playAudioStream does not handle this type of audio on this system." );
return;
}

try {
// Create a SourceDataLine for play back (throws LineUnavailableException).
SourceDataLine dataLine = (SourceDataLine) AudioSystem.getLine( info );
// System.out.println( "SourceDataLine class=" + dataLine.getClass() );

// The line acquires system resources (throws LineAvailableException).
dataLine.open( audioFormat );

// Adjust the volume on the output line.
if( dataLine.isControlSupported( FloatControl.Type.MASTER_GAIN ) ) {
FloatControl volume = (FloatControl) dataLine.getControl( FloatControl.Type.MASTER_GAIN );
volume.setValue( 100.0F );
}

// Allows the line to move data in and out to a port.
dataLine.start();

// Create a buffer for moving data from the audio stream to the line.
int bufferSize = (int) audioFormat.getSampleRate() * audioFormat.getFrameSize();
byte [] buffer = new byte[ bufferSize ];

// Move the data until done or there is an error.
try {
int bytesRead = 0;
while ( bytesRead >= 0 ) {
bytesRead = audioInputStream.read( buffer, 0, buffer.length );
if ( bytesRead >= 0 ) {
// System.out.println( "Play.playAudioStream bytes read=" + bytesRead +
// ", frame size=" + audioFormat.getFrameSize() + ", frames read=" + bytesRead / audioFormat.getFrameSize() );
// Odd sized sounds throw an exception if we don't write the same amount.
int framesWritten = dataLine.write( buffer, 0, bytesRead );
}
} // while
} catch ( IOException e ) {
e.printStackTrace();
}

System.out.println( "Play.playAudioStream draining line." );
// Continues data line I/O until its buffer is drained.
dataLine.drain();

System.out.println( "Play.playAudioStream closing line." );
// Closes the data line, freeing any resources such as the audio device.
dataLine.close();
} catch ( LineUnavailableException e ) {
e.printStackTrace();
}
} // playAudioStream
} // Play


0 comments on commit 4c5a9e2

Please sign in to comment.
You can’t perform that action at this time.