/*
* saint.java
*
* Standalone program to demonstrate the usage of the Saint class.
*/
import java.io.InputStream;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.LineUnavailableException;
import gnu.getopt.Getopt;
import org.tritonus.lowlevel.saint.Saint;
public class saint
{
private static class SupportedFormat
{
private String m_strName;
private int m_nNumber;
private AudioFormat.Encoding m_encoding;
private int m_nSampleSize;
private boolean m_bBigEndian;
// sample size is in bits
public SupportedFormat(String strName,
int nNumber,
AudioFormat.Encoding encoding,
int nSampleSize,
boolean bBigEndian)
{
m_strName = strName;
m_nNumber = nNumber;
m_encoding = encoding;
m_nSampleSize = nSampleSize;
}
public String getName()
{
return m_strName;
}
public int getNumber()
{
return m_nNumber;
}
public AudioFormat.Encoding getEncoding()
{
return m_encoding;
}
public int getSampleSize()
{
return m_nSampleSize;
}
public boolean getBigEndian()
{
return m_bBigEndian;
}
}
private static final SupportedFormat[] SUPPORTED_FORMATS =
{
new SupportedFormat("s8", Saint.SND_PCM_SFMT_S8,
AudioFormat.Encoding.PCM_SIGNED, 8, true),
new SupportedFormat("u8", Saint.SND_PCM_SFMT_U8,
AudioFormat.Encoding.PCM_UNSIGNED, 8, true),
new SupportedFormat("s16l", Saint.SND_PCM_SFMT_S16_LE,
AudioFormat.Encoding.PCM_SIGNED, 16, false),
new SupportedFormat("s16b", Saint.SND_PCM_SFMT_S16_BE,
AudioFormat.Encoding.PCM_SIGNED, 16, true),
new SupportedFormat("u16l", Saint.SND_PCM_SFMT_U16_LE,
AudioFormat.Encoding.PCM_UNSIGNED, 16, false),
new SupportedFormat("u16b", Saint.SND_PCM_SFMT_U16_BE,
AudioFormat.Encoding.PCM_UNSIGNED, 16, true),
new SupportedFormat("s24l", Saint.SND_PCM_SFMT_S24_LE,
AudioFormat.Encoding.PCM_SIGNED, 24, false),
new SupportedFormat("s24b", Saint.SND_PCM_SFMT_S24_BE,
AudioFormat.Encoding.PCM_SIGNED, 24, true),
new SupportedFormat("u24l", Saint.SND_PCM_SFMT_U24_LE,
AudioFormat.Encoding.PCM_UNSIGNED, 24, false),
new SupportedFormat("u24b", Saint.SND_PCM_SFMT_U24_BE,
AudioFormat.Encoding.PCM_UNSIGNED, 24, true),
new SupportedFormat("s32l", Saint.SND_PCM_SFMT_S32_LE,
AudioFormat.Encoding.PCM_SIGNED, 32, false),
new SupportedFormat("s32b", Saint.SND_PCM_SFMT_S32_BE,
AudioFormat.Encoding.PCM_SIGNED, 32, true),
new SupportedFormat("u32l", Saint.SND_PCM_SFMT_U32_LE,
AudioFormat.Encoding.PCM_UNSIGNED, 32, false),
new SupportedFormat("u32b", Saint.SND_PCM_SFMT_U32_BE,
AudioFormat.Encoding.PCM_UNSIGNED, 32, true),
new SupportedFormat("f32l", Saint.SND_PCM_SFMT_S32_LE,
AudioFormat.Encoding.PCM_SIGNED /* obviously wrong */, 32, false),
new SupportedFormat("f32b", Saint.SND_PCM_SFMT_S32_BE,
AudioFormat.Encoding.PCM_SIGNED /* obviously wrong */, 32, true),
};
private static final int DEFAULT_FORMAT = 2;
public static void main(String[] args)
throws IOException
{
InputStream bitstream = null;
InputStream orchestra = null;
InputStream score = null;
OutputStream output = null;
int nOutputFormatIndex = DEFAULT_FORMAT;
boolean bLineOutput = false;
int c;
Getopt g = new Getopt("saint", args, "hVb:c:s:o:f:");
while ((c = g.getopt()) != -1)
{
switch (c)
{
case 'h':
printUsageAndExit();
case 'V':
printVersionAndExit();
case 'b':
bitstream = new FileInputStream(g.getOptarg());
break;
case 'c':
orchestra = new FileInputStream(g.getOptarg());
break;
case 's':
score = new FileInputStream(g.getOptarg());
break;
case 'o':
if (g.getOptarg().equals("-"))
{
output = System.out;
}
if (g.getOptarg().equals("+"))
{
bLineOutput = true;
}
else
{
output = new FileOutputStream(g.getOptarg());
}
break;
case 'f':
int nNewOutputFormatIndex = -1;
for (int i = 0; i < SUPPORTED_FORMATS.length; i++)
{
if (SUPPORTED_FORMATS[i].getName().equals(g.getOptarg()))
{
nNewOutputFormatIndex = i;
// nNewOutputFormat = SUPPORTED_FORMATS[i].getNumber();
}
}
if (nNewOutputFormatIndex != -1)
{
nOutputFormatIndex = nNewOutputFormatIndex;
}
else
{
System.err.println("warning: output format " + g.getOptarg() + "not supported; using default output format");
}
break;
}
}
if (output == null && ! bLineOutput)
{
System.out.println("no output specified!");
printUsageAndExit();
}
Saint saint = null;
// specifying a bitstream overrides specifying orchestra & score files.
if (bitstream != null)
{
saint = new Saint(bitstream);
}
else if (orchestra != null)
{
if (score != null)
{
saint = new Saint(orchestra, score);
}
else
{
System.out.println("no score file specified!");
printUsageAndExit();
}
}
else
{
System.out.println("neither bitstream nor orchestra specified!");
printUsageAndExit();
}
System.err.println("output will be produces with " + saint.getChannelCount() + " channel(s) at " + saint.getSamplingRate() + " Hz\n");
if (bLineOutput)
{
AudioFormat format = new AudioFormat(
SUPPORTED_FORMATS[nOutputFormatIndex].getEncoding(),
saint.getSamplingRate(),
SUPPORTED_FORMATS[nOutputFormatIndex].getSampleSize(),
saint.getChannelCount(),
// TODO: 24 bit is not handled correctely!!!
saint.getChannelCount() * SUPPORTED_FORMATS[nOutputFormatIndex].getSampleSize() / 8,
saint.getSamplingRate(),
SUPPORTED_FORMATS[nOutputFormatIndex].getBigEndian());
DataLine.Info info = new DataLine.Info(
SourceDataLine.class, format);
SourceDataLine line = null;
try
{
line = (SourceDataLine) AudioSystem.getLine(info);
// TODO: (Tritonus) check if calling without arguments should work
line.open(format);
line.start();
}
catch (LineUnavailableException e)
{
}
output = new SourceDataLineOutputStream(line);
}
saint.setOutput(output, SUPPORTED_FORMATS[nOutputFormatIndex].getNumber());
saint.run();
try
{
output.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static void
printUsageAndExit()
{
System.out.println("usage:");
System.out.println("\t[TODO]:");
System.exit(1);
}
public static void
printVersionAndExit()
{
System.out.println("saint (new) version 0.1");
System.exit(0);
}
}
/*** saint.java ***/