След: Звук
Синтезирование Звука
Домашняя страница > Звук

Синтезирование Звука

Большинство программ, которые пользуются пакетом MIDI API Звука Java, делает так, чтобы синтезировать звук. У всего аппарата файлов MIDI, событий, последовательностей, и секвенсеров, который был ранее обсужден, почти всегда есть цель в конечном счете отправки музыкальных данных к синтезатору, чтобы преобразовать в аудио. (Возможные исключения включают программы, которые преобразовывают MIDI в музыкальную нотацию, которая может быть считана музыкантом, и программами, которые отправляют сообщения внешним УПРАВЛЯЕМЫМ MIDI устройствам, таким как микшерные пульты.)

Synthesizer интерфейс является поэтому основным принципом к пакету MIDI. Эта страница показывает, как управлять синтезатором, чтобы играть звук. Много программ будут просто использовать секвенсер, чтобы отправить данные файла MIDI синтезатору, и не должны будут вызвать многих Synthesizer методы непосредственно. Однако, возможно управлять синтезатором непосредственно, не используя секвенсеры или даже MidiMessage объекты, как объяснено около конца этой страницы.

Архитектура синтеза могла бы казаться сложной для читателей, которые незнакомы с MIDI. Его API включает три интерфейса:

и четыре класса:

Как ориентация для всего этого API, следующий раздел объясняет некоторые из основ синтеза MIDI и как они отражаются в API Звука Java. Последующие разделы дают более подробный взгляд на API.

Понимание Синтеза MIDI

Как синтезатор генерирует звук? В зависимости от его реализации это может использовать один или методы более синтеза звука. Например, много синтезаторов используют wavetable синтез. wavetable синтезатор читает сохраненные отрывки аудио из памяти, играя их на различных демонстрационных уровнях и цикличном выполнении их, чтобы создать примечания различных передач и продолжительностей. Например, чтобы синтезировать звук саксофона, играя примечание C#4 (примечание MIDI номер 61), синтезатор мог бы получить доступ к очень короткому отрывку от записи саксофона, играя Середину примечания C (примечание MIDI номер 60), и затем цикл неоднократно через этот отрывок на немного более быстром демонстрационном уровне, чем это было записано в, который создает длинное примечание немного более высокой подачи. Другие синтезаторы используют методы, такие как модуляция частоты (FM), аддитивный синтез, или физическое моделирование, которое не использует сохраненное аудио, но вместо этого генерирует аудио, с нуля используя различные алгоритмы.

Инструменты

Что имеют все методы синтеза, вместе возможность создать много видов звуков. Различные алгоритмы, или различные настройки параметров в пределах того же самого алгоритма, создают различно звучащие результаты. Инструмент является спецификацией для того, чтобы синтезировать определенный тип звука. Тот звук может эмулировать традиционный музыкальный инструмент, такой как фортепьяно или скрипка; это может эмулировать некоторый другой вид звукового источника, например, телефона или вертолета; или это не может эмулировать "реальный" звук вообще. Спецификация под названием Общий MIDI определяет стандартный список 128 инструментов, но большинство синтезаторов позволяет другие инструменты также. Много синтезаторов обеспечивают набор встроенных инструментов, которые всегда доступны для использования; некоторые синтезаторы также поддерживают механизмы для того, чтобы загрузить дополнительные инструменты.

Инструмент может быть поставщиком-specific⠀” другими словами, применимый только к одному синтезатору или нескольким моделям от того же самого поставщика. Эта несовместимость заканчивается, когда два различных синтезатора используют различные методы синтеза звука, или различные внутренние алгоритмы и параметры, даже если фундаментальный метод является тем же самым. Поскольку детали метода синтеза являются часто собственными, несовместимость распространена. API Звука Java включает способы обнаружить, поддерживает ли данный синтезатор данный инструмент.

Инструмент можно обычно считать предварительной установкой; Вы ничего не должны знать о деталях метода синтеза, который производит его звук. Однако, можно все еще изменить аспекты его звука. Каждое Примечание По сообщению определяет подачу и объем отдельного примечания. Можно также изменить звук посредством других команд MIDI, таких как сообщения контроллера или монопольные системой сообщения.

Каналы

Много синтезаторов являются multimbral (иногда названный политембральным), означая, что они могут играть примечания различных инструментов одновременно. (Тембр является характерным качеством звука, которое позволяет слушателю отличить один вид музыкального инструмента от других видов.) Синтезаторы Multimbral могут эмулировать весь ансамбль реальных инструментов вместо только одного инструмента за один раз. Синтезаторы MIDI обычно реализуют эту опцию, используя в своих интересах различные каналы MIDI, на которых спецификация MIDI позволяет данным быть переданными. В этом случае синтезатор является фактически набором звуковых электростанций, каждый эмулирующий различный инструмент и отвечающий независимо обменивается сообщениями, которые получаются на различном канале MIDI. Так как спецификация MIDI обеспечивает только 16 каналов, типичный синтезатор MIDI может играть до 16 различных инструментов сразу. Синтезатор получает поток команд MIDI, многие из которых являются командами канала. (Команды канала предназначаются к определенному каналу MIDI; для получения дополнительной информации см. спецификацию MIDI.) Если синтезатор является мультитембральным, он направляет каждую команду канала к корректной звуковой электростанции согласно номеру канала, обозначенному в команде.

В API Звука Java эти звуковые электростанции являются экземплярами классов, которые реализуют MidiChannel интерфейс. A synthesizer у объекта есть по крайней мере один MidiChannel объект. Если синтезатор является multimbral, у него есть больше чем один, обычно 16. Каждый MidiChannel представляет независимую звуковую электростанцию.

Поскольку синтезатор MidiChannel объекты более или менее независимы, присвоение инструментов к каналам не должно быть уникальным. Например, все 16 каналов могли играть тембр фортепьяно, как если бы был ансамбль 16 фортепьяно. Любая группировка является possible⠀” например, каналы 1, 5, и 8 могли играть звуки гитары, в то время как у каналов, 2 и 3 удара игры и образовывают канал 12, есть басовый тембр. Инструмент, играемый на данном канале MIDI, может быть изменен динамически; это известно как изменение программы.

Даже при том, что большинство синтезаторов позволяет только 16 или меньшему количеству инструментов быть активным в установленный срок, эти инструменты могут обычно быть выбраны из намного большего выбора и присвоены определенным каналам как требуется.

Soundbanks и Patches

Инструменты организуются иерархически в синтезаторе числом банка и числом программы. Банки и программы могут считаться строками и столбцами в двумерной таблице инструментов. Банк является набором программ. Спецификация MIDI позволяет до 128 программ в банке, и до 128 банков. Однако, определенный синтезатор мог бы поддерживать только один банк, или несколько банков, и мог бы поддерживать меньше чем 128 программ на банк.

В API Звука Java есть более высокий уровень к иерархии: soundbank. Soundbanks может содержать до 128 банков, каждый содержащий до 128 инструментов. Некоторые синтезаторы могут загрузить весь soundbank в память.

Чтобы выбрать инструмент из тока soundbank, Вы определяете число банка и число программы. Спецификация MIDI выполняет это с двумя командами MIDI: избранный банк и изменение программы. В API Звука Java комбинация числа банка и числа программы инкапсулируется в a Patch объект. Вы изменяете текущий инструмент канала MIDI, определяя новый патч. Патч можно рассмотреть, двумерные индексируют инструментов в токе soundbank.

Вы могли бы задаваться вопросом, индексируются ли soundbanks, также, в цифровой форме. Ответ нет; спецификация MIDI не предусматривает это. В API Звука Java, a Soundbank объект может быть получен, читая soundbank файл. Если soundbank поддерживается синтезатором, его инструменты могут быть загружены в синтезатор индивидуально как требующийся, или внезапно. У многих синтезаторов есть встроенное или значение по умолчанию soundbank; инструменты, содержавшиеся в этом soundbank, всегда доступны синтезатору.

Речь

Важно различить число тембров, которые синтезатор может играть одновременно и число примечаний, которые это может играть одновременно. Прежний был описан выше под "Каналами". Возможность играть многократные примечания сразу упоминается как полифония. Даже синтезатор, который не является мультитембральным, может обычно играть больше чем одно примечание за один раз (все имеющие тот же самый тембр, но различные передачи). Например, играя любой аккорд, такой как соль-мажорная триада или си-минорный седьмой аккорд, требует полифонии. У любого синтезатора, который генерирует звук в режиме реального времени, есть ограничение на число примечаний, которые это может синтезировать сразу. В API Звука Java синтезатор сообщает об этом ограничении через getMaxPolyphony метод.

Речь является последовательностью единственных примечаний, таких как мелодия, которую может спеть человек. Полифония состоит из многократной речи, такой как части, спетые хором. 32 синтезатора речи, например, могут играть 32 примечания одновременно. (Однако, немного литературы MIDI использует слово "речь" в различном смысле, подобном значению "инструмента" или "тембра.")

Процесс присвоения входящих примечаний MIDI к определенной речи известен как речевое выделение. Синтезатор поддерживает список речи, отслеживание того, которые являются активными (подразумевать, что у них в настоящий момент есть звучание примечаний). Когда примечание прекращает звучать, речь становится неактивной, означая, что это теперь свободно принять следующее примечание - по запросу, который получает синтезатор. Входящий поток команд MIDI может легко запросить больше одновременных примечаний, чем синтезатор способен к генерированию. Когда речь всего синтезатора является активной, как следующее должно Отметить По запросу быть обработанным? Синтезаторы могут реализовать различные стратегии: последний раз требуемое примечание может быть проигнорировано; или это может играться, прекращая другое примечание, такое как наименее недавно запущенный.

Хотя спецификация MIDI не требует этого, синтезатор может обнародовать содержание каждой его речи. API Звука Java включает a VoiceStatus class с этой целью.

A VoiceStatus отчеты относительно текущего активного или неактивного состояния речи, канала MIDI, банка и числа программы, числа примечания MIDI, и объема MIDI.

С этим фоном давайте исследуем специфические особенности API Звука Java для синтеза.

Управление Instruments и Soundbanks

Во многих случаях программа может использовать a Synthesizer объект, явно не вызывая почти ни одного API синтеза. Например, предположите, что Вы играете стандартный файл MIDI. Вы загружаете это в a Sequence объект, который Вы играете при наличии секвенсера, отправляет данные синтезатору значения по умолчанию. Данные в управлении последовательностью синтезатор как предназначено, играя все правильные примечания в правильные времена.

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

MIDI, который 1.0 Спецификации предусматривают избранный банком и команды изменения программы, которые влияют, какой инструмент в настоящий момент играет на каждом канале MIDI. Однако, спецификация не определяет, какой инструмент должен находиться в каждом расположении патча (банк и число программы). Более свежая Общая спецификация MIDI рассматривает эту проблему, определяя банк, содержащий 128 программ, которые соответствуют определенным инструментальным звукам. Общий синтезатор MIDI использует 128 инструментов, которые соответствуют этот указанный набор. Различные Общие синтезаторы MIDI могут звучать очень отличающимися, играя, что, как предполагается, является тем же самым инструментом. Однако, файл MIDI должен по большей части звучать подобным (даже если не идентичный), независимо от того какой Общий синтезатор MIDI играет его.

Тем не менее, не все создатели файлов MIDI хотят быть ограниченными набором 128 тембров, определенных Общим MIDI. Этот раздел показывает, как изменить инструменты от набора значения по умолчанию, с которым идет синтезатор. (Если нет никакого значения по умолчанию, означая, что никакие инструменты не загружаются, когда Вы получаете доступ к синтезатору, необходимо использовать этот API, чтобы запустить с в любом случае.)

Изучение, Какие Инструменты Загружаются

Чтобы учиться, являются ли инструменты, в настоящий момент загруженные в синтезатор, теми, Вы хотите, можно вызвать это Synthesizer метод:

Instrument[] getLoadedInstruments() 

и выполните итерации по возвращенному массиву, чтобы видеть точно, какие инструменты в настоящий момент загружаются. Наиболее вероятно Вы вывели бы на экран имена инструментов в пользовательском интерфейсе (использующий getName метод Instrument), и позвольте пользователю решать, использовать ли те инструменты или загрузить других. Instrument API включает метод, который сообщает, какому soundbank инструмент принадлежит. Имя soundbank могло бы помочь Вашей программе, или пользователь устанавливают точно, каков инструмент.

Это Synthesizer метод:

Soundbank getDefaultSoundbank() 

дает Вам значение по умолчанию soundbank. Soundbank API включает методы, чтобы получить имя soundbank, поставщика, и номер версии, которым программа или пользователь могут проверить идентификационные данные банка. Однако, невозможно принять, когда Вы сначала получаете синтезатор, что инструменты от значения по умолчанию soundbank были загружены в синтезатор. Например, синтезатор мог бы иметь большой выбор в наличии встроенных инструментов для использования, но из-за его ограниченной памяти это не могло бы загрузить их автоматически.

Загрузка Различных Инструментов

Пользователь мог бы решить загрузить инструменты, которые отличаются от текущих (или Вы могли бы принять то решение программно). Следующий метод говорит Вам который инструменты, с которыми идут синтезатор (против необходимости быть загруженным из soundbank файлов):

Instrument[] getAvailableInstruments()

Можно загрузить любой из этих инструментов, вызывая:

boolean loadInstrument(Instrument instrument) 

Инструмент загружается в синтезатор в расположении, определенном инструментом Patch объект (который может быть получен, используя getPatch метод Instrument).

Чтобы загрузить инструменты из другого soundbanks, сначала вызовите Synthesizer's isSupportedSoundbank метод, чтобы удостовериться, что soundbank является совместимым с этим синтезатором (если это не, можно выполнить итерации по синтезаторам системы, чтобы попытаться найти тот, который поддерживает soundbank). Можно тогда вызвать один из этих методов, чтобы загрузить инструменты из soundbank:

boolean loadAllInstruments(Soundbank soundbank) 
boolean loadInstruments(Soundbank soundbank, 
  Patch[] patchList) 

Поскольку имена предлагают, первая из этих загрузок весь набор инструментов от данного soundbank, и вторые загрузки выбранные инструменты от soundbank. Вы могли также использовать Soundbank's getInstruments метод, чтобы получить доступ ко всем инструментам, затем выполните итерации по ним и загрузке выбранных инструментов, по одному используя loadInstrument.

Это не необходимо для всех инструментов, которые Вы загружаете, чтобы быть от того же самого soundbank. Вы могли использовать loadInstrument или loadInstruments загрузить определенные инструменты из одного soundbank, другой набор от различного soundbank, и так далее.

У каждого инструмента есть свое собственное Patch объект, который определяет расположение на синтезаторе, где инструмент должен быть загружен. Расположение определяется числом банка и числом программы. Нет никакого API, чтобы изменить расположение, изменяя банк патча или число программы.

Однако, возможно загрузить инструмент в расположение кроме того, определенного его патчем, используя следующий метод Synthesizer:

boolean remapInstrument(Instrument from, Instrument to) 

Этот метод разгружает свой первый параметр от синтезатора, и помещает его второй параметр в любое расположение патча синтезатора, был занят первым параметром.

Разгрузка Инструментов

Загрузка инструмента в расположение программы автоматически разгружается, любой инструмент уже был в том расположении, если любой. Можно также явно разгрузить инструменты, обязательно не заменяя их новыми. Synthesizer включает три разгружающихся метода, которые соответствуют трем загружающимся методам. Если синтезатор получает сообщение изменения программы, которое выбирает расположение программы, где никакой инструмент в настоящий момент не загружается, не будет никакого звука от канала MIDI, на котором было отправлено сообщение изменения программы.

Доступ Ресурсы Soundbank

Некоторые синтезаторы хранят другую информацию помимо инструментов в их soundbanks. Например, wavetable синтезатор хранит аудиосэмплы, к которым могут получить доступ один или более инструментов. Поскольку выборки могли бы быть совместно использованы многократными инструментами, они сохранены в soundbank независимо от любого инструмента. Оба Soundbank взаимодействуйте через интерфейс и Instrument class обеспечивает вызов метода getSoundbankResources, который возвращает список SoundbankResource объекты. Детали этих объектов являются определенными для синтезатора, для которого разрабатывается soundbank. В случае wavetable синтеза ресурс мог бы быть объектом, который инкапсулирует серию аудиосэмплов, взятых от одного отрывка звукозаписи. Синтезаторы, которые используют другие методы синтеза, могли бы сохранить другие виды объектов в синтезаторе SoundbankResources массив.

Запросы Возможностей Синтезатора и текущего состояния

Synthesizer интерфейс включает методы, которые возвращают информацию о возможностях синтезатора:

    public long getLatency()
    public int getMaxPolyphony()

Задержка измеряет задержку худшего случая между временем, сообщение MIDI передается к синтезатору и время, когда синтезатор фактически приводит к соответствующему результату. Например, синтезатору могли бы потребоваться несколько миллисекунд, чтобы начать генерировать аудио после получения примечания - на событии.

getMaxPolyphony метод указывает, сколько примечаний синтезатор может звучать одновременно, как обсуждено ранее под Речью. Как упомянуто в том же самом обсуждении, синтезатор может предоставить информацию о своей речи. Это выполняется через следующий метод:

public VoiceStatus[] getVoiceStatus()

Каждый VoiceStatus в возвращенном массиве сообщает о текущем активном или неактивном состоянии речи, канале MIDI, банке и числе программы, числе примечания MIDI, и объеме MIDI. Длина массива должна обычно быть тем же самым числом, возвращенным getMaxPolyphony. Если синтезатор не играет, все VoiceStatus объектам установили их активное поле в false.

Можно изучить дополнительную информацию о текущем статусе синтезатора, получая MidiChannel объекты и запросы их состояния. Это обсуждается больше в следующем разделе.

Используя Каналы

Иногда это полезно или необходимо получить доступ к синтезатору MidiChannel объекты непосредственно. Этот раздел обсуждает такие ситуации.

Управление Синтезатором без Использования Секвенсера

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

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

Есть по крайней мере два способа отправить сообщение MIDI синтезатору, не используя секвенсер. Первое должно создать a MidiMessage и передайте это к синтезатору, используя отправить метод Receiver. Например, чтобы произвести Середину C (примечание MIDI номер 60) на MIDI образовывают канал 5 (на основе одно) сразу, Вы могли сделать следующее:

    ShortMessage myMsg = new ShortMessage();
    // Play the note Middle C (60) moderately loud
    // (velocity = 93)on channel 4 (zero-based).
    myMsg.setMessage(ShortMessage.NOTE_ON, 4, 60, 93); 
    Synthesizer synth = MidiSystem.getSynthesizer();
    Receiver synthRcvr = synth.getReceiver();
    synthRcvr.send(myMsg, -1); // -1 means no time stamp

Второй путь состоит в том, чтобы обойти уровень передачи сообщений (то есть, MidiMessage и Receiver API), в целом, и взаимодействуют с синтезатором MidiChannel объекты непосредственно. Вы сначала должны получить синтезатор MidiChannel объекты, используя следующий Synthesizer метод:

public MidiChannel[] getChannels()

после которого можно вызвать требуемый MidiChannel методы непосредственно. Это - более непосредственный маршрут чем отправка соответствия MidiMessages к синтезатору Receiver и позволяя синтезатору обработать передачу с его собственным MidiChannels. Например, код, соответствующий предыдущему примеру, был бы:

    Synthesizer synth = MidiSystem.getSynthesizer();
    MidiChannel chan[] = synth.getChannels(); 
    // Check for null; maybe not all 16 channels exist.
    if (chan[4] != null) {
         chan[4].noteOn(60, 93); 
    }

Получение текущего состояния Канала

MidiChannel интерфейс обеспечивает методы, которые соответствуют непосредственные каждой "речи канала" или "сообщениям" режима канала, определенным спецификацией MIDI. Мы видели один случай с использованием noteOn метода в предыдущем примере. Однако, в дополнение к этим каноническим методам, API Звука Java MidiChannel интерфейс добавляет, что некоторые "заставляют" методы получать значение, последний раз установленное соответствующей речью или методами "набора" режима:

    int       getChannelPressure()
    int       getController(int controller)
    boolean   getMono()
    boolean   getOmni() 
    int       getPitchBend() 
    int       getPolyPressure(int noteNumber)
    int       getProgram()

Эти методы могли бы быть полезными для отображения состояния канала пользователю, или для того, чтобы решить что значения передаться впоследствии к каналу.

Muting и Soloing Канал

API Звука Java добавляет понятия соло на канал и бесшумный, которые не требуются спецификацией MIDI. Они являются подобными соло и бесшумными на дорожках последовательности MIDI.

Если отключено звук идет, этот канал не будет звучать, но другие каналы незатронуты. Если соло будет идти, то этот канал, и любой другой канал soloed, будут звучать (если это не будет отключено звук), но никакие другие каналы не будут звучать. Канал, который является и soloed и отключенный звук, не будет звучать. MidiChannel API включает четыре метода:

    boolean      getMute() 
    boolean      getSolo()
    void         setMute(boolean muteState) 
    void         setSolo(boolean soloState)

Разрешение, чтобы Играть Синтезируемый Звук

Аудио, произведенное любым установленным синтезатором MIDI, обычно направляется через выбранную аудиосистему. Если у Вашей программы не будет разрешения, чтобы играть аудио, то звук синтезатора не услышат, и исключение безопасности будет выдано. Для получения дополнительной информации по аудио полномочиям см. предыдущее обсуждение Разрешения, чтобы Использовать Аудио Разрешение Ресурсов, чтобы Использовать Аудио Ресурсы.


Проблемы с примерами? Попытайтесь Компилировать и Выполнить Примеры: FAQ.
Жалобы? Поздравление? Предложения? Дайте нам свою обратную связь.

Предыдущая страница: Использование Усовершенствованных Функций Секвенсера
Следующая страница: Введение в Интерфейсы Поставщика услуг



Spec-Zone.ru - all specs in one place