Oracle interMedia Annotator User's Guide
Release 9.0.1

Part Number A88784-01
Go To Documentation Library
Home
Go To Product List
Book List
Go To Table Of Contents
Contents
Go To Index
Index

Master Index

Feedback

Go to previous page Go to next page

8
interMedia Annotator Custom Parser Example

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.


Note:

This chapter contains examples of Java code. Some of the code examples display boldface numbers enclosed in brackets; these indicate that further explanation of that code will be in the numbered list immediately following the example. 


8.1 Parser Creation Overview

To define a new parser, perform the following operations:

  1. Create a new Java class that inherits from oracle.ord.media.annotator.parsers.Parser. In this example, the Java class is defined in AuParser.java.

    Your Java class must implement the following methods:

    • parse( ): parses the content from the InputStream object

    • saveToAnnotation( ): saves the results of the parsing as an annotation named m_annInst

    • extractSamples( ): extracts samples from the media source file. You must implement this method whether or not you want to support sample extraction.

    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.

  2. Write a parser descriptor XML file and add it to the <ORACLE_HOME>/ord/Annotator/lib/descriptors/parsers directory. For an example of a parser descriptor XML file, see <ORACLE_HOME>/ord/Annotator/lib/descriptors/parsers/AuParser.xml.

  3. Optionally, modify the following file to set your parser to be used for a specific MIME type:

    <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.

8.2 AU File Structure

Example 8-1 shows the basic structure of an AU file.

Example 8-1 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.

8.3 Package and Import Statements

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.

Example 8-2 Package and Import Statements

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.*;

8.4 Class Definition and Instance Variables

Example 8-3 shows the class definition and instance variables for AuParser.java.

Example 8-3 Class Definition and Instance Variables

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:

8.5 FormatInfo Class

Example 8-4 shows the contents of the FormatInfo class, which is used to encapsulate information related to a specific data format.

Example 8-4 FormatInfo Class

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:

  1. Two instance variables that store values for the format string and format code.

  2. A constructor with two parameters that set the format string and the format code.

  3. A method that returns the format string to the caller.

  4. A method that returns the format code to the caller.

8.6 AuParser( ) Method

Example 8-5 shows the contents of the AuParser( ) method, which is the constructor of this class.

Example 8-5 AuParser( ) Method

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:

  1. Instantiates the m_htFormatInfo variable.

  2. Populates m_htFormatInfo with data by calling the FillFormatHashTable( ) method. See Example 8-9 for more information.

8.7 parse( ) Method

Example 8-6 shows the parse( ) method, which parses an AU file and extracts some of its metadata.

Example 8-6 parse( ) Method

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:

  1. Reads the first integer in the AU file (the magic number) and sets it to iMagicNumber.

    m_madisResource is the MADataInputStream that contains the AU file to be processed. See Section 9.4 for more information.

  2. Tests to see if the magic number that was just read matches the magic number of an AU file. If it does not, then the file is not an AU file and an exception is thrown.

  3. Reads the next integer in m_madisResource, which is the offset from the beginning of the stream where the media data begins, and sets it to iDataLocation.

  4. Sets a counter. Because 2 integers (8 bytes total) have already been read, the counter is set to 2.

  5. Sets the start and end value of the AnnTaskMonitor object. The end value is the value of iDataLocation, which is where the media data begins. This value also represents the length of the header information.

  6. Sets the current task in the AnnTaskMonitor object. The current value is set to 8 (the number of bytes read), and the message is set to "Parsing AU Header..."

  7. Reads the next integer in m_madisResource, which is the number of bytes of media data in the file. Sets the value to iDataSize. Sets the task progress monitor to reflect the 4 bytes that were read.

  8. Reads the next integer in m_madisResource, which is the data format code. Sets the value to iDataFormat. Sets the task progress monitor to reflect the 4 bytes that were read.

  9. Reads the next integer in m_madisResource, which is the sampling rate of the media data in the file. Sets the value to iSampleRate. Sets the task progress monitor to reflect the 4 bytes that were read.

  10. Reads the next integer in m_madisResource, which is the number of channels in the media data in the file. Sets the value to iChannelCount. Sets the task progress monitor to reflect the 4 bytes that were read.

  11. Reads the rest of the header information and sets the value to m_szUserData.

    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.

  12. Sets the value of the task progress monitor to show that all header information has been read.

  13. Ends the current task in the AnnTaskManager object.

  14. Sets the value of m_fiFormatInfo by getting the appropriate value from the Hashtable object named m_htFormatInfo.

  15. Sets the value of m_iBitsPerSample to 0 as a default.

  16. Checks the value of iDataFormat against a series of values in the m_htFormatInfo Hashtable object and sets the value of m_iBitsPerSample to the appropriate value.

  17. Catches any errors or exceptions that may have been raised in the previous steps.

  18. Calls the saveToAnnotation( ) method to save the annotation. See Section 8.8 for more information. This method should be called at the end of any implementation of the parse( ) method.

8.8 saveToAnnotation( ) Method

Example 8-7 shows the saveToAnnotation( ) method. This method should be called after the parse( ) method has successfully finished.

Example 8-7 saveToAnnotation( ) Method

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:

  1. Sets the MEDIA_SOURCE_FILE_FORMAT_CODE and MEDIA_SOURCE_FILE_FORMAT attributes in the annotation to the values for an AU file.

  2. If m_fiFileFormat has a value, sets its format string and format code to the MEDIA_FORMAT_ENCODING and MEDIA_FORMAT_ENCODING_CODE attributes in the annotation, respectively.

  3. If m_szUserData has a value, sets it to the MEDIA_USER_DATA attribute in the annotation.

  4. Sets the values of m_iBitsPerSample, m_iSampleRate, and m_iChannelCount to the AUDIO_BITS_PER_SAMPLE, AUDIO_SAMPLE_RATE, and AUDIO_NUM_CHANNELS attributes in the annotation, respectively.

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.

8.9 extractSamples( ) Method

Example 8-8 shows the extractSamples( ) method. This method is invoked by AnnotationHandler.extractMedia( ).

Example 8-8 extractSamples( ) Method

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:

  1. Uses the Status object to print a message stating that AuParser.java does not support sample extraction. See Section 6.10 for more information.

  2. Ends the current task with the AnnTaskManager.done( ) method. See Section 9.1 for more information.

See the QuickTime parser for an example of a parser that does support sample extraction.

8.10 FillFormatHashTable( ) Method

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.

Example 8-9 FillFormatHashTable( ) Method

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"));
}


Go to previous page Go to next page
Oracle
Copyright © 1996-2001, Oracle Corporation.

All Rights Reserved.
Go To Documentation Library
Home
Go To Product List
Book List
Go To Table Of Contents
Contents
Go To Index
Index

Master Index

Feedback