Whole document tree Chapter 14Providing Sampled-Audio Services
As discussed in Chapter 13, "Introduction to the Service Provider Interfaces," the JavaTM Sound API includes two packages, This chapter can be safely skipped by applications programmers who merely wish to use existing audio services in their programs. For the use of the installed audio services in an application program, see Part I, "Sampled Audio," of this Programmer's Guide. This chapter assumes that the reader is familiar with the JavaTM Sound API methods that application programs invoke to access installed audio services. Introduction
There are four abstract classes in the
In essence there is a double isolation of the service instances from the application developer. An application program never directly creates instances of the service objects, such as mixers or format converters, that it needs for its audio processing tasks. Nor does the program even directly request these objects from the SPI classes that administer them. The application program makes requests to the
The existence of new audio services might be completely transparent to both the user and the application programmer. All application references are through standard objects of the
In this chapter, we'll continue the previous chapter's convention of referring to new SPI subclasses by names like Providing Audio File-Writing Services
Let's start with
A subclass that implements the methods of
The first of these methods informs the caller whether this file writer can write sound files of the specified type. This method is a general inquiry, it will returnboolean isFileTypeSupported(AudioFileFormat.Type fileType) boolean isFileTypeSupported(AudioFileFormat.Type fileType, AudioInputStream stream) true if the file writer can write that kind of file, assuming the file writer is handed appropriate audio data. However, the ability to write a file can depend on the format of the specific audio data that's handed to the file writer. A file writer might not support every audio data format, or the constraint might be imposed by the file format itself. (Not all kinds of audio data can be written to all kinds of sound files.) The second method is more specific, then, asking whether a particular AudioInputStream can be written to a particular type of file.
Generally, you won't need to override these two concrete methods. Each is simply a wrapper that invokes one of two other query methods and iterates over the results returned. These other two query methods are abstract and therefore need to be implemented in the subclass: These methods correspond directly to the previous two. Each returns an array of all the supported file types-all that are supported in general, in the case of the first method, and all that are supported for a specific audio stream, in the case of the second method. A typical implementation of the first method might simply return an array that the file writer's constructor initializes. An implementation of the second method might test the stream'sabstract AudioFileFormat.Type[] getAudioFileTypes() abstract AudioFileFormat.Type[] getAudioFileTypes(AudioInputStream stream) AudioFormat object to see whether it's a data format that the requested type of file supports.
The final two methods of These methods write a stream of bytes representing the audio data to the stream or file specified by the third argument. The details of how this is done depend on the structure of the specified type of file. Theabstract int write(AudioInputStream stream, AudioFileFormat.Type fileType, java.io.File out) abstract int write(AudioInputStream stream, AudioFileFormat.Type fileType, java.io.OutputStream out) write method must write the file's header and the audio data in the manner prescribed for sound files of this format (whether it's a standard type of sound file or a new, possibly proprietary one).
Providing Audio File-Reading Services
The A typical implementation ofabstract AudioFileFormat getAudioFileFormat( java.io.File file) abstract AudioFileFormat getAudioFileFormat( java.io.InputStream stream) abstract AudioFileFormat getAudioFileFormat( java.net.URL url) getAudioFileFormat method reads and parses the sound file's header to ascertain its file format. See the description of the AudioFileFormat class to see what fields need to be read from the header, and refer to the specification for the particular file type to figure out how to parse the header.
Because the caller providing a stream as an argument to this method expects the stream to be unaltered by the method, the file reader should generally start by marking the stream. After reading to the end of the header, it should reset the stream to its original position.
The other overloaded Typically, an implementation ofabstract AudioInputStream getAudioInputStream( java.io.File file) abstract AudioInputStream getAudioInputStream( java.io.InputStream stream) abstract AudioInputStream getAudioInputStream( java.net.URL url) getAudioInputStream returns an AudioInputStream wound to the beginning of the file's data chunk (after the header), ready for reading. It would be conceivable, though, for a file reader to return an AudioInputStream whose audio format represents a stream of data that is in some way decoded from what is contained in the file. The important thing is that the method return a formatted stream from which the audio data contained in the file can be read. The AudioFormat encapsulated in the returned AudioInputStream object will inform the caller about the stream's data format, which is usually, but not necessarily, the same as the data format in the file itself.
Generally, the returned stream is an instance of Providing Format-Conversion Services
A
The work of conversion is performed in the overloaded abstract method of
The two variants of andabstract AudioInputStream getAudioInputStream( AudioFormat.Encoding targetEncoding, AudioInputStream sourceStream) These differ in the first argument, according to whether the caller is specifying a complete target format or just the format's encoding.abstract AudioInputStream getAudioInputStream( AudioFormat targetFormat, AudioInputStream sourceStream)
A typical implementation of
The implementation of The actual format conversion takes place in newpublic AudioInputStream getAudioInputStream (AudioFormat outputFormat, AudioInputStream stream) { AudioInputStream cs = null; AudioFormat inputFormat = stream.getFormat(); if (inputFormat.matches(outputFormat) ) { cs = stream; } else { cs = (AudioInputStream) (new AcmeCodecStream(stream, outputFormat)); tempBuffer = new byte[tempBufferSize]; } return cs; } read methods of the returned AcmeCodecStream , a subclass of AudioInputStream . Again, application programs that access this returned AcmeCodecStream simply operate on it as an AudioInputStream , and don't need to know the details of its implementation.
The other methods of a As in the query methods of theabstract AudioFormat.Encoding[] getSourceEncodings() abstract AudioFormat.Encoding[] getTargetEncodings() abstract AudioFormat.Encoding[] getTargetEncodings( AudioFormat sourceFormat) abstract AudioFormat[] getTargetFormats( AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat) AudioFileReader class discussed above, these queries are typically handled by checking private data of the object, comparing them against the argument, if the method takes one.
The remaining four As withboolean isConversionSupported( AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat) boolean isConversionSupported(AudioFormat targetFormat, AudioFormat sourceFormat) boolean isSourceEncodingSupported( AudioFormat.Encoding sourceEncoding) boolean isTargetEncodingSupported( AudioFormat.Encoding targetEncoding) AudioFileWriter .isFileTypeSupported,the default implementation of each of these methods is essentially a wrapper that invokes one of the other query methods and iterates over the results returned.
Providing New Types of Mixers
As its name implies, a
Since
The other two methods of andabstract Mixer.Info[] getMixerInfo() These methods allow the audio system to determine whether this particular provider class can produce a device that an application program needs. In other words, theboolean isMixerSupported(Mixer.Info info) AudioSystem object can iterate over all the installed MixerProviders to see which ones, if any, can supply the device that the application program has requested of the AudioSystem . (See the discussion under "Getting a Mixer" in Chapter 3, "Accessing Audio System Resources.") The getMixerInfo method returns an array of objects containing information about the kinds of mixer available from this provider object. The system can pass these information objects, along with those from other providers, to an application program.
A single
Your subclass needs to implement [Top] [Prev] [Next] [Bottom] Copyright © 2000, Sun Microsystems Inc. All rights reserved. |