Spec-Zone .ru
спецификации, руководства, описания, API
Содержание документации

<Содержание

Глава 14: Предоставление Услуг Выбранного аудио

Как обсуждено в Главе 13, "Введение в Интерфейсы Поставщика услуг," API Звука Java включает два пакета, javax.sound.sampled.spi и javax.sound.midi.spi, это определяет абстрактные классы, которые будут использоваться разработчиками звуковых служб. Реализовывая и устанавливая подкласс одного из этих абстрактных классов, поставщик услуг регистрирует новую службу, расширяя функциональность системы времени выполнения. Существующая глава говорит Вам, как пойти об использовании javax.sound.sampled.spi пакет, чтобы предоставить новые услуги для того, чтобы обработать выбранное аудио.

Эта глава может быть безопасно пропущена прикладными программистами, которые просто хотят использовать существующие аудио службы в их программах. Для использования установленных аудио служб в прикладной программе см. Первую часть, "Выбранное Аудио," из Руководства этого Программиста. Эта глава предполагает, что читатель знаком с методами API Звука JavaTM, которые прикладные программы вызывают, чтобы получить доступ к установленным аудио службам.

Введение

Есть четыре абстрактных класса в javax.sound.sampled.spi пакет, представляя четыре различных типов служб, что можно предусмотреть выбранную аудиосистему:

Чтобы резюмировать обсуждение в Главе 13, поставщики услуг могут расширить функциональность системы времени выполнения. У типичного класса SPI есть два типа методов: которые отвечают на запросы о типах служб, доступных от определенного провайдера, и, которые или выполняют новую службу непосредственно, или экземпляры возврата объектов, которые фактически предоставляют услугу. Механизм поставщика услуг среды выполнения обеспечивает регистрацию установленных служб с аудиосистемой, и управление новыми классами поставщика услуг.

В основном есть двойная изоляция экземпляров службы от разработчика приложений. Прикладная программа никогда непосредственно создает экземпляры объектов службы, таких как микшеры или преобразователи формата, в которых она нуждается для его задач обработки аудиоданных. И при этом программа даже непосредственно не запрашивает эти объекты от классов SPI, которые администрируют их. Прикладная программа обращается с просьбами к AudioSystem объект в javax.sound.sampled пакет, и AudioSystem поочередно использует объекты SPI обработать эти запросы и запросы на обслуживание.

Существование новых аудио служб могло бы быть абсолютно прозрачным и пользователю и прикладному программисту. Все ссылки приложения через стандартные объекты javax.sound.sampled пакет, прежде всего AudioSystem, и специальная обработка, которую могли бы обеспечивать новые службы, часто полностью скрывается.

В этой главе мы будем продолжать соглашение предыдущей главы обращения к новым подклассам SPI именами как AcmeMixer и AcmeMixerProvider.

Предоставление Пишущих аудиофайл Услуг

Давайте запустим с AudioFileWriter, один из более простых классов SPI.

Подкласс, который реализует методы AudioFileWriter должен обеспечить реализации ряда методов, чтобы обработать запросы о форматах файлов и типах файлов, поддерживаемых классом, так же как обеспечить методы, которые фактически выписывают предоставленный поток аудиоданных к a File или OutputStream.

AudioFileWriter включает два метода, у которых есть конкретные реализации в базовом классе:

boolean isFileTypeSupported(AudioFileFormat.Type fileType) 
boolean isFileTypeSupported(AudioFileFormat.Type fileType, 
    AudioInputStream stream) 
Первый из этих методов сообщает вызывающей стороне, может ли этот писатель файла записать звуковые файлы указанного типа. Этот метод является справкой по общим вопросам, он возвратится true если писатель файла может записать такой файл, предполагая, что писателю файла вручают соответствующие аудиоданные. Однако, возможность записать файл может зависеть от формата определенных аудиоданных, которые это вручается писателю файла. Писатель файла не мог бы поддерживать каждый формат аудиоданных, или ограничение могло бы быть наложено форматом файла непосредственно. (Не все виды аудиоданных могут быть записаны всем видам звуковых файлов.) Второй метод является более определенным, тогда, спрашивая ли деталь AudioInputStream может быть записан определенному типу файла.

Обычно, Вы не должны будете переопределить эти два конкретных метода. Каждый - просто обертка, которая вызывает один из двух других методов запроса и выполняет итерации по возвращенным результатам. Эти другие два метода запроса абстрактны и поэтому должны быть реализованы в подклассе:

abstract AudioFileFormat.Type[] getAudioFileTypes() 
abstract AudioFileFormat.Type[]
    getAudioFileTypes(AudioInputStream stream) 
Эти методы соответствуют непосредственно предыдущим двум. Каждый возвращает массив всех поддерживаемых типов файлов - все, что поддерживается вообще, в случае первого метода, и все, что поддерживается для определенного аудиопотока, в случае второго метода. Типичная реализация первого метода могла бы просто возвратить массив, который инициализирует конструктор писателя файла. Реализация второго метода могла бы протестировать поток AudioFormat объект видеть, является ли это форматом данных, который поддерживает требуемый тип файла.

Заключительные два метода AudioFileWriter сделайте фактическую пишущую файл работу:

abstract  int write(AudioInputStream stream, 
    AudioFileFormat.Type fileType, java.io.File out) 
 abstract  int write(AudioInputStream stream, 
    AudioFileFormat.Type fileType, java.io.OutputStream out) 
Эти методы пишут поток байтов, представляющих аудиоданные потоку или файлу, определенному третьим параметром. Детали того, как это делается, зависят от структуры указанного типа файла. write метод должен записать заголовок файла и аудиоданные, таким образом предписанные для звуковых файлов этого формата (является ли это стандартным типом звукового файла или нового, возможно собственный).

Предоставление Читающих аудиофайл Услуг

AudioFileReader класс состоит из шести абстрактных методов, которые Ваш подкласс должен реализовать фактически, два различных перегруженных метода, каждый из которых может взять a File, URL, или InputStream параметр. Первый из этих перегруженных методов принимает запросы о формате файла указанного файла:

abstract AudioFileFormat getAudioFileFormat(
    java.io.File file) 
abstract AudioFileFormat getAudioFileFormat(
    java.io.InputStream stream) 
abstract AudioFileFormat getAudioFileFormat(
    java.net.URL url) 
Типичная реализация getAudioFileFormat метод читает и анализирует заголовок звукового файла, чтобы установить его формат файла. См. описание класса AudioFileFormat, чтобы видеть то, что поля должны быть считаны из заголовка, и отсылать к спецификации для определенного типа файла, чтобы выяснить, как проанализировать заголовок.

Поскольку вызывающая сторона, обеспечивающая поток как параметр этому методу, ожидает, что поток будет неизменен методом, средство чтения файлов должно обычно запуститься, отмечая поток. После чтения до конца заголовка, это должно сбросить поток к своей исходной позиции.

Другой перегруженный AudioFileReader метод предоставляет читающие файл услуги, возвращая AudioInputStream, из которого могут быть считаны аудиоданные файла:

abstract AudioInputStream getAudioInputStream(
    java.io.File file) 
abstract AudioInputStream getAudioInputStream(
     java.io.InputStream stream) 
abstract AudioInputStream getAudioInputStream(
     java.net.URL url) 
Как правило, реализация getAudioInputStream возвраты AudioInputStream раньте к началу блока данных файла (после заголовка), готовый к чтению. Это было бы мыслимо, тем не менее, для средства чтения файлов, чтобы возвратиться AudioInputStream чей аудиоформат представляет поток данных, которые в некотором роде декодируются от того, что содержится в файле. Важная вещь состоит в том, что метод возвращает отформатированный поток, из которого могут быть считаны аудиоданные, содержавшиеся в файле. AudioFormat инкапсулировавший в возвращенном AudioInputStream объект сообщит вызывающей стороне о формате данных потока, который обычно является, но не обязательно, то же самое как формат данных в файле непосредственно.

Обычно, возвращенный поток является экземпляром AudioInputStream; маловероятно, что Вы должны были бы когда-либо разделять на подклассы AudioInputStream.

Предоставление Услуг Преобразования формата

A FormatConversionProvider подкласс преобразовывает AudioInputStream у этого есть один формат аудиоданных в тот, у которого есть другой формат. Прежний (ввод) поток упоминается как исходный поток, и последний (вывод), поток упоминается как целевой поток. Вспомните из Главы 2, "Краткий обзор Выбранного Пакета," это AudioInputStream содержит AudioFormat, и AudioFormat поочередно содержит определенный тип кодирования данных, представленного AudioFormat.Encoding объект. Формат и кодирующий в исходном потоке вызывают исходным форматом и исходным кодированием, и тех в целевом потоке аналогично вызывают целевым форматом и целевым кодированием.

Работа преобразования выполняется в перегруженном абстрактном методе FormatConversionProvider вызванный getAudioInputStream. У класса также есть абстрактные методы запроса для того, чтобы узнать обо всей поддерживаемой цели и исходных форматах и кодировках. Есть конкретные методы обертки для того, чтобы запросить об определенном преобразовании.

Две разновидности getAudioInputStream :

abstract AudioInputStream getAudioInputStream(
    AudioFormat.Encoding targetEncoding, 
    AudioInputStream sourceStream) 
        
и
abstract AudioInputStream getAudioInputStream(
    AudioFormat targetFormat,
    AudioInputStream sourceStream) 
Они отличаются по первому параметру, согласно тому, определяет ли вызывающая сторона полный целевой формат или только кодирование формата.

Типичная реализация getAudioInputStream работы, возвращая новый подкласс AudioInputStream это переносит оригинал (источник) AudioInputStream и применяет преобразование формата данных в его данные всякий раз, когда a read метод вызывается. Например, рассмотрите случай нового FormatConversionProvider подкласс вызывают AcmeCodec, который работает с новым AudioInputStream подкласс вызывают AcmeCodecStream.

Реализация AcmeCodec's второй getAudioInputStream метод мог бы быть:

public 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 методы возвращенного AcmeCodecStream, подкласс AudioInputStream. Снова, прикладные программы, которые получают доступ к этому, возвратились AcmeCodecStream просто работайте на этом как AudioInputStream, и не должны знать детали о его реализации.

Другие методы a FormatConversionProvider все разрешение запрашивает о кодировках входа и выхода и форматах, которые поддерживает объект. Следующие четыре метода, будучи абстрактным, должны быть реализованы:

abstract AudioFormat.Encoding[] getSourceEncodings() 
abstract AudioFormat.Encoding[] getTargetEncodings() 
abstract AudioFormat.Encoding[] getTargetEncodings(
    AudioFormat sourceFormat) 
abstract  AudioFormat[] getTargetFormats(
    AudioFormat.Encoding targetEncoding, 
    AudioFormat sourceFormat) 

Как в методах запроса AudioFileReader класс, обсужденный выше, эти запросы обычно обрабатываются, проверяя частные данные объекта и, для последних двух методов, сравнивая их против параметра (ов).

Оставление четыре FormatConversionProvider методы конкретны и обычно не должны быть переопределены:

boolean isConversionSupported(
    AudioFormat.Encoding targetEncoding,
    AudioFormat sourceFormat) 
boolean isConversionSupported(AudioFormat targetFormat, 
    AudioFormat sourceFormat) 
boolean isSourceEncodingSupported(
    AudioFormat.Encoding sourceEncoding) 
boolean isTargetEncodingSupported(
    AudioFormat.Encoding targetEncoding) 
Как с AudioFileWriter.isFileTypeSupported(), реализация по умолчанию каждого из этих методов является по существу оберткой, которая вызывает один из других методов запроса и выполняет итерации по возвращенным результатам.

Обеспечение Новых Типов Микшеров

Поскольку его имя подразумевает, a MixerProvider экземпляры предоставлений микшеров. Каждый бетон MixerProvider разделите действия на подклассы как фабрику для Mixer объекты используются прикладной программой. Конечно, определение нового MixerProvider только имеет смысл если один или более новые реализации Mixer интерфейс также определяется. Как в FormatConversionProvider пример выше, где наш getAudioInputStream метод, возвращенный подкласс AudioInputStream это выполняло преобразование, наш новый класс AcmeMixerProvider имеет метод getMixer это возвращает экземпляр другого нового класса, который реализует Mixer интерфейс. Мы вызовем последний класс AcmeMixer. Особенно, если микшер реализуется в аппаратных средствах, провайдер мог бы поддерживать только один статический экземпляр требуемого устройства. Если так, это должно возвратить этот статический экземпляр в ответ на каждый вызов getMixer.

С тех пор AcmeMixer поддерживает Mixer интерфейс, прикладные программы не требуют, чтобы никакая дополнительная информация получила доступ к своей основной функциональности. Однако, если AcmeMixer поддерживает функциональность, не определенную в Mixer интерфейс, и поставщик хотят сделать эту расширенную функциональность доступной для прикладных программ, микшер должен, конечно, быть определен как общедоступный класс с дополнительными, хорошо задокументированными открытыми методами, так, чтобы программа, которая хочет использовать эту расширенную функциональность, могла импортировать AcmeMixer и бросок объект, возвращенный getMixer к этому типу.

Другие два метода MixerProvider :

abstract Mixer.Info[] getMixerInfo() 
и
boolean isMixerSupported(Mixer.Info info) 
Эти методы позволяют аудиосистеме определять, может ли этот определенный класс провайдера произвести устройство, в котором нуждается прикладная программа. Другими словами, AudioSystem объект может выполнить итерации по всему установленному MixerProviders видеть, которые, если таковые вообще имеются, могут предоставить устройство, которое прикладная программа запросила AudioSystem. (См. обсуждение при "Получении Микшера" в Главе 3, "Получая доступ к Ресурсам Аудиосистемы.") getMixerInfo метод возвращает массив объектов, содержащих информацию о видах микшера, доступного от этого объекта провайдера. Система может передать эти информационные объекты, наряду с теми от других провайдеров, к прикладной программе.

Сингл MixerProvider может обеспечить больше чем один вид микшера. Когда система вызывает MixerProvider's getMixerInfo метод, это получает список информационных объектов, идентифицирующих различные виды микшера, который поддерживает этот провайдер. Система может тогда вызвать MixerProvider.getMixer(Mixer.Info) получить каждый микшер интереса.

Ваш подкласс должен реализовать getMixerInfo, поскольку это абстрактно. isMixerSupported метод конкретен и не должен обычно быть переопределен. Реализация по умолчанию просто сравнивает обеспеченный Mixer.Info каждому в массиве, возвращенном getMixerInfo.

 


Oracle и/или его филиалы Авторское право © 1993, 2011, Oracle и/или его филиалы. Все права защищены.
Свяжитесь с Нами