Первая переменная введена, чтобы упростить использование константы ToneControl.C4. Оставшиеся переменные – это ноты различных октав, которые рассчитаны относительно средней C4. Переменная C5 очень интересна, поскольку она на одну октаву выше, чем C4. Поскольку в октаве 12 нот, то, чтобы из C4 получить C5, можно к первой прибавить 12. Аналогично, чтобы из C5 получить C4, необходимо из C5 вычесть 12. Чтобы лучше понять операции с нотами, посмотрите таблицу 8.1. Теперь, когда вы знаете, как определить высоту ноты, вам остается лишь передать ее в метод Manager.playTone() и воспроизвести ее:
try {
// воспроизвести среднее C (C4) в течение двух секунд (2000ms)
при максимальной громкости (100)
Manager.playTone(ToneControl.C4, 2000, 100);
}
catch(MediaException me) {
}Этот код воспроизводит ноту C4 средней октавы, все очень просто, для этого даже не надо рассчитывать смещений. Обратите внимание, что эта функция принимает два дополнительных параметра, которые устанавливают длительность воспроизведения звука (2 секунды) и громкость (100 %). Вы, вероятно, обратили внимание, что метод playTone() вызывается внутри конструкции try-catch. Это необходимо, поскольку этот метод может вызвать исключение MediaException, если произойдет какой-нибудь сбой во время воспроизведения тона. В данном примере код ничего не выполняет, но вы можете, например, вывести соответствующее предупреждение или учесть это в коде.
Воспроизведение последовательности тонов
Тоновая последовательность – это набор звуков, воспроизводимых в определенном порядке. Такие последовательности очень часто применяются при создании игр. Используя последовательности тонов, вы можете программировать музыку, а это не такая простая задача. Ниже приведены основные шаги, которые необходимо выполнить, чтобы воспроизвести звуковую последовательность средствами MIDP 2.0 Media API:
1. создать проигрыватель;
2. реализовать проигрыватель;
3. получить тональное управление проигрывателя;
4. установить тональную последовательность;
5. использовать проигрыватель для воспроизведения последовательности;
6. закрыть проигрыватель.
Создается впечатление, что это не такая уж простая задача, но не все так плохо. Самая хитрая часть кода – это создание структуры данных, представляющей тоновую последовательность. После того как последовательность создана, ее установка и воспроизведение выполняются парой строк.
Тоновая последовательность хранится внутри массива типа byte, каждый байт массива имеет свое особое значение. Как только вы научитесь создавать такие массивы, размещая информацию в нужных местах, вы увидите, что это не так уж и сложно. Чтобы задать тоновую последовательность как массив типа byte, необходимо использовать ряд констант, определенных в интерфейсе ToneControl. Ниже приведен список наиболее важных констант:
► VERSION – версия тоновой последовательности (обычно равно 1 для новой последовательности);
► TEMPO – темп тоновой последовательности (скорость воспроизведения);
► BLOCK_START – начальный блок тонов;
► BLOCK_END – конец блока тонов;
► PLAY_BLOCK – воспроизводимые ноты, включая блоки.
Блок в тоновой последовательности – это фрагмент тоновой последовательности. Например, если у вас есть музыкальный фрагмент, который повторяется несколько раз во время звучания музыки, то вы можете поместить его ноты в блок, а затем, вместо того чтобы записывать ноты вновь, просто сослаться на блок нот. Константа PLAY_BLOCK ставится в том месте, где следует воспроизвести блок. Вы можете указать отдельные ноты или их последовательность, используя константу PLAY_BLOCK.
Я понимаю, что это рассуждение, вероятно, не так легко воспринять, поскольку сложно представить, как константа может символизировать блок тонов. Поэтому давайте рассмотрим пример. Ниже приведен код тоновой последовательности песни, которая, вероятно, вам знакома:
byte[] marylambSequence = {
ToneControl.VERSION, 1,
ToneControl.Tempo, 30,
ToneControl.BLOCK_START, 0, //Секция А песни
E4, 8, D4, 8, C4, 8, D4, 8,
E4, 8, E4, 8, E4, 8, rest, 8,
ToneControl.BLOCK_END, 0,
ToneControl.PLAY_BLOCK, 0, //Этот код воспроизводит секцию А
D4, 8, D4, 8, D4, 8, rest, 8 //Воспроизвести секцию В
E4, 8, G4, 8, G4, 8, rest, 8,
ToneControl.PLAY_BLOCK, 0, //Воспроизвести секцию А снова
D4, 8, D4, 8, E4, 8, D4, 8, C4, 8 //воспроизвести секцию С
};