Oracle interMedia Annotator User's Guide Release 9.0.1 Part Number A88784-01 |
|
This chapter provides a description of AuParser.java, which is an example of a user-developed parser for a custom content format that was written using the interMedia Annotator parser APIs. AuParser.java contains user-defined methods that use Java and interMedia Annotator APIs to define a parser for the Next/Sun AU file format. The purpose of the parser is to extract the format encoding information and the associated user data from the file.
The contents of AuParser.java are included in a zip file at the following location:
<
ORACLE_HOME>/ord/Annotator/src/parsers.zip
This chapter provides an example of creating a new parser for a custom content format.
This code will not necessarily match the code shipped as AuParser.java with the interMedia Annotator installation. If you want to run this example on your system, use the file provided with the interMedia Annotator installation; do not attempt to compile and run the code presented in this chapter.
To define a new parser, perform the following operations:
Your Java class must implement the following methods:
Additionally, you can add other methods depending on the operations that you want your parser to perform.
Section 8.3 through Section 8.10 provide examples of the contents of AuParser.java.
<ORACLE_HOME>
/ord/Annotator/lib/conf/Annotator.mime
You can also set a parser for a specific MIME type with the Annotator GUI. See Section 2.2.5 for more information.
Example 8-1 shows the basic structure of an AU file.
<pre><code> typedef struct { int magic; // magic number SND_MAGIC int dataLocation; // offset or pointer to the data int dataSize; // number of bytes of data int dataFormat; // the data format code int samplingRate; // the sampling rate int channelCount; // the number of channels char info[4]; // optional text information } SNDSoundStruct; </code></pre>
The magic number is equal to ((int)0x2e736e64), which is a representation of .snd". The info parameter will be associated with the user data attribute of the annotation.
Example 8-2 shows the import statements that must be included to properly run an Annotator parser, and the package statements that set the package of this class.
package oracle.ord.media.annotator.parsers.au; import java.io.*; import java.util.*; import java.net.*; import oracle.ord.media.annotator.parsers.*; import oracle.ord.media.annotator.annotations.*; import oracle.ord.media.annotator.utils.*;
Example 8-3 shows the class definition and instance variables for AuParser.java.
public class AuParser extends Parser{ private static final Integer SND_FORMAT_UNSPECIFIED = new Integer(0); private static final Integer SND_FORMAT_MULAW_8 = new Integer(1); private static final Integer SND_FORMAT_LINEAR_8 = new Integer(2); private static final Integer SND_FORMAT_LINEAR_16 = new Integer(3); private static final Integer SND_FORMAT_LINEAR_24 = new Integer(4); private static final Integer SND_FORMAT_LINEAR_32 = new Integer(5); private static final Integer SND_FORMAT_FLOAT = new Integer(6); private static final Integer SND_FORMAT_DOUBLE = new Integer(7); private static final Integer SND_FORMAT_INDIRECT = new Integer(8); private static final Integer SND_FORMAT_NESTED = new Integer(9); private static final Integer SND_FORMAT_DSP_CORE = new Integer(10); private static final Integer SND_FORMAT_DSP_DATA_8 = new Integer(11); private static final Integer SND_FORMAT_DSP_DATA_16 = new Integer(12); private static final Integer SND_FORMAT_DSP_DATA_24 = new Integer(13); private static final Integer SND_FORMAT_DSP_DATA_32 = new Integer(14); private static final Integer SND_FORMAT_UNKNOWN = new Integer(15); private static final Integer SND_FORMAT_DISPLAY = new Integer(16); private static final Integer SND_FORMAT_MULAW_SQUELCH = new Integer(17); private static final Integer SND_FORMAT_EMPHASIZED = new Integer(18); private static final Integer SND_FORMAT_COMPRESSED = new Integer(19); private static final Integer SND_FORMAT_COMPRESSED_EMPHASIZED = new Integer(20); private static final Integer SND_FORMAT_DSP_COMMANDS = new Integer(21); private static final Integer SND_FORMAT_DSP_COMMANDS_SAMPLES = new Integer(22); private static final Integer SND_FORMAT_ADPCM_G721 = new Integer(23); private static final Integer SND_FORMAT_ADPCM_G722 = new Integer(24); private static final Integer SND_FORMAT_ADPCM_G723_3 = new Integer(25); private static final Integer SND_FORMAT_ADPCM_G723_5 = new Integer(26); private static final Integer SND_FORMAT_ALAW_8 = new Integer(27); private Hashtable m_htFormatInfo; private int m_iBitsPerSample; private int m_iSampleRate; private int m_iChannelCount; private String m_szUserData; private FormatInfo m_fiFormatInfo;
A parser must extend the Parser class. See Section 9.3 for more information on the fields and methods of the Parser class.
The AU parser contains a Hashtable object named m_htFormatInfo, which will map keys to values. The keys are instantiated as private static Integer objects and given sequential values. These are specific to AuParser.java and may not be necessary for your parser.
AuParser.java contains a FormatInfo object named m_fiFormatInfo, which is used to encapsulate information related to a specific data format. See Section 8.5 for more information. These are specific to AuParser.java and may not be necessary for your parser.
AuParser.java also contains the following instance variables:
Example 8-4 shows the contents of the FormatInfo class, which is used to encapsulate information related to a specific data format.
private class FormatInfo{ [1] private String m_szFormatString; private String m_szFormatCode; [2] public FormatInfo(String szFormatString, String szFormatCode){ m_szFormatString = szFormatString; m_szFormatCode = szFormatCode; } [3] public String getFormatString( ){ return m_szFormatString; } [4] public String getFormatCode( ){ return m_szFormatCode; } }
The FormatInfo class contains the following code:
Example 8-5 shows the contents of the AuParser( ) method, which is the constructor of this class.
public AuParser( ){ [1] m_htFormatInfo = new Hashtable( ); [2] FillFormatHashTable( ); }
A parser must have a constructor with no parameters.
The code in the AuParser( ) method performs the following operations:
Example 8-6 shows the parse( ) method, which parses an AU file and extracts some of its metadata.
public void parse( ) throws ParserException{ try { [1] int iMagicNumber = m_madisResource.readInt( ); [2] if(iMagicNumber != ((int)0x2e736e64)) throw new ParserException("Format Exception. Expecting a Next/Sun au formatted file"); [3] int iDataLocation = m_madisResource.readInt( ); [4] int iIntCounter = 2; [5] m_annTaskMan.setTask(0, iDataLocation); [6] m_annTaskMan.setTaskCurrent(iIntCounter*4, "Parsing AU Header..."); [7] int iDataSize = m_madisResource.readInt( ); m_annTaskMan.setTaskCurrent((++iIntCounter)*4); [8] int iDataFormat = m_madisResource.readInt( ); m_annTaskMan.setTaskCurrent((++iIntCounter)*4); [9] m_iSampleRate = m_madisResource.readInt( ); m_annTaskMan.setTaskCurrent((++iIntCounter)*4); [10] m_iChannelCount = m_madisResource.readInt( ); m_annTaskMan.setTaskCurrent((++iIntCounter)*4); [11] int iInfoLength = iDataLocation - 24; m_szUserData = m_madisResource.readString(iInfoLength); [12] m_annTaskMan.setTaskCurrent(iDataLocation); [13] m_annTaskMan.done( ); [14] m_fiFormatInfo = (FormatInfo) m_htFormatInfo.get (new Integer(iDataFormat)); [15] m_iBitsPerSample = 0; [16] if((iDataFormat == SND_FORMAT_MULAW_8.intValue( )) || (iDataFormat == SND_FORMAT_LINEAR_8.intValue( )) || (iDataFormat == SND_FORMAT_DSP_DATA_8.intValue( )) || (iDataFormat == SND_FORMAT_ALAW_8.intValue( ))) m_iBitsPerSample = 8; else if((iDataFormat == SND_FORMAT_LINEAR_16.intValue( )) || (iDataFormat == SND_FORMAT_DSP_DATA_16.intValue( )) || (iDataFormat == SND_FORMAT_EMPHASIZED.intValue( )) || (iDataFormat == SND_FORMAT_COMPRESSED.intValue( )) || (iDataFormat == SND_FORMAT_COMPRESSED_EMPHASIZED.intValue( ))) m_iBitsPerSample = 16; else if((iDataFormat == SND_FORMAT_LINEAR_24.intValue( )) || (iDataFormat == SND_FORMAT_DSP_DATA_24.intValue( ))) m_iBitsPerSample = 24; else if((iDataFormat == SND_FORMAT_LINEAR_32.intValue( )) || (iDataFormat == SND_FORMAT_DSP_DATA_32.intValue( )) || (iDataFormat == SND_FORMAT_FLOAT.intValue( )) || (iDataFormat == SND_FORMAT_DOUBLE.intValue( ))) m_iBitsPerSample = 32; else m_iBitsPerSample = -1; } [17] catch(IOException ioExc) { throw new ParserException("IOException raised while reading from input stream"); } [18] saveToAnnotation( ); }
The code in the parse( ) method performs the following operations:
m_madisResource is the MADataInputStream that contains the AU file to be processed. See Section 9.4 for more information.
The length of the rest of the header information is determined by subtracting the number of bytes already read (24) from the total length of the header information.
Example 8-7 shows the saveToAnnotation( ) method. This method should be called after the parse( ) method has successfully finished.
public void saveToAnnotation( ){ [1] m_annInst.setAttribute("MEDIA_SOURCE_FILE_FORMAT_CODE", "AUFF"); m_annInst.setAttribute("MEDIA_SOURCE_FILE_FORMAT", "Next/Sun audio file format"); [2] if (m_fiFormatInfo != null) { m_annInst.setAttribute("MEDIA_FORMAT_ENCODING", m_fiFormatInfo.getFormatString( )); m_annInst.setAttribute("MEDIA_FORMAT_ENCODING_CODE", m_fiFormatInfo.getFormatCode( )); } [3] if(m_szUserData.trim( ).length( ) != 0) m_annInst.setAttribute("MEDIA_USER_DATA", m_szUserData); [4] m_annInst.setAttribute("AUDIO_BITS_PER_SAMPLE", new Integer(m_iBitsPerSample)); m_annInst.setAttribute("AUDIO_SAMPLE_RATE", new Integer(m_iSampleRate)); m_annInst.setAttribute("AUDIO_NUM_CHANNELS", new Integer(m_iChannelCount)); }
The code in the saveToAnnotation( ) method performs the following operations:
To create a sub-annotation, a parser uses the AnnotationFactory to create a sub-annotation and attach it to m_annInst. However, AuParser does not create sub-annotations. See QtParser.java, which is the QuickTime parser included with Annotator (located in <ORACLE_HOME>/ord/Annotator/src/parsers.zip) for an example of a parser that creates sub-annotations.
Example 8-8 shows the extractSamples( ) method. This method is invoked by AnnotationHandler.extractMedia( ).
public void extractSamples( ) throws ParserException{ [1] m_sStatus.Report(Status.OUTPUT_MODE_STATUS, "AuParser does not support any sample extraction."); [2] m_annTaskMan.done( ); }
Annotator does not support sample extraction from an AU file. Instead of throwing an error or exception, this method performs the following operations:
See the QuickTime parser for an example of a parser that does support sample extraction.
Example 8-9 shows the FillFormatHashTable( ) method, which uses the Hashtable.put( ) method to assign a value to each key in the m_htFormatString Hashtable object. See the Java 1.2 Javadoc for more information. This method is specific to AuParser.java and may not be needed for your parser.
private void FillFormatHashTable( ){ m_htFormatInfo.put(SND_FORMAT_UNSPECIFIED, new FormatInfo("unspecified format", "UNSPECIFIED")); m_htFormatInfo.put(SND_FORMAT_MULAW_8, new FormatInfo("8-bit mu-law samples", "MULAW")); m_htFormatInfo.put(SND_FORMAT_LINEAR_8, new FormatInfo("8-bit linear samples", "LINEAR")); m_htFormatInfo.put(SND_FORMAT_LINEAR_16, new FormatInfo("16-bit linear samples", "LINEAR")); m_htFormatInfo.put(SND_FORMAT_LINEAR_24, new FormatInfo("24-bit linear samples", "LINEAR")); m_htFormatInfo.put(SND_FORMAT_LINEAR_32, new FormatInfo("32-bit linear samples", "LINEAR")); m_htFormatInfo.put(SND_FORMAT_FLOAT, new FormatInfo("floating-point samples", "FLOAT")); m_htFormatInfo.put(SND_FORMAT_DOUBLE, new FormatInfo("double-precision float samples", "DOUBLE")); m_htFormatInfo.put(SND_FORMAT_INDIRECT, new FormatInfo("fragmented sampled data", "FRAGMENTED")); m_htFormatInfo.put(SND_FORMAT_NESTED, new FormatInfo("nested format", "NESTED")); m_htFormatInfo.put(SND_FORMAT_DSP_CORE, new FormatInfo("DSP program", "DSP_ CORE")); m_htFormatInfo.put(SND_FORMAT_DSP_DATA_8, new FormatInfo("8-bit fixed-point samples", "DSP_DATA")); m_htFormatInfo.put(SND_FORMAT_DSP_DATA_16, new FormatInfo("16-bit fixed-point samples", "DSP_DATA")); m_htFormatInfo.put(SND_FORMAT_DSP_DATA_24, new FormatInfo("24-bit fixed-point samples", "DSP_DATA")); m_htFormatInfo.put(SND_FORMAT_DSP_DATA_32, new FormatInfo("32-bit fixed-point samples", "DSP_DATA")); m_htFormatInfo.put(SND_FORMAT_UNKNOWN, new FormatInfo("unknown au format", "UNKNOWN")); m_htFormatInfo.put(SND_FORMAT_DISPLAY, new FormatInfo("non-audio display data", "DISPLAY")); m_htFormatInfo.put(SND_FORMAT_MULAW_SQUELCH, new FormatInfo("squelch format", "MULAW_SQUELCH")); m_htFormatInfo.put(SND_FORMAT_EMPHASIZED, new FormatInfo("16-bit linear with emphasis", "EMPHASIZED")); m_htFormatInfo.put(SND_FORMAT_COMPRESSED, new FormatInfo("16-bit linear with compression", "COMPRESSED")); m_htFormatInfo.put(SND_FORMAT_COMPRESSED_EMPHASIZED, new FormatInfo("16-bit linear with emphasis and compression", "COMPRESSED_EMPHASIZED")); m_htFormatInfo.put(SND_FORMAT_DSP_COMMANDS, new FormatInfo("Music Kit DSP commands", "DSP_COMMANDS")); m_htFormatInfo.put(SND_FORMAT_DSP_COMMANDS_SAMPLES, new FormatInfo("DSP commands samples", "DSP_COMMANDS_SAMPLES")); m_htFormatInfo.put(SND_FORMAT_ADPCM_G721, new FormatInfo("adpcm G721", "ADPCM_G721")); m_htFormatInfo.put(SND_FORMAT_ADPCM_G722, new FormatInfo("adpcm G722", "ADPCM_G722")); m_htFormatInfo.put(SND_FORMAT_ADPCM_G723_3, new FormatInfo("adpcm G723_3", "ADPCM_G723_3")); m_htFormatInfo.put(SND_FORMAT_ADPCM_G723_5, new FormatInfo("adpcm G723_5", "ADPCM_G723_5")); m_htFormatInfo.put(SND_FORMAT_ALAW_8, new FormatInfo("8-bit a-law samples", "ALAW")); }
|
Copyright © 1996-2001, Oracle Corporation. All Rights Reserved. |
|