Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Тональный звук в MMID 2.0 API


Автор: bncom 7.3.2010, 17:35
День добрый!

По заданию необходимо создать мидлет, который воспроизводит тональную последовательность заданной музыкальной композиции (в моем случае, это "5 симфония Бетховена"). Муз. композиция задана в формате RTTL, и чтобы ее вопроизвести в мидлете, необходимо коды RTTL перегнать в массив нот.

Вот сама RTTL последовательность:

Код

d=16, 0=5, b=100:
g,g,g,4d#,4p,f,f,f,4d,4p,g,g,g,d#,g#,g#,g#,g,d#6,d#6,d#6,4c6,8p,g,g,g,g#,g#,g#,g,f6,f6,f6,4d6,8p,g6,g6,f6,4d#6,8p,g6,g6,f6,4d#6


Скажу сразу, что я не знаю, как формировать октаву =( (это то, что идет после знака решетки). Нашел следующее:

Код

"0" | Нота A = 440 Герц (самая низкая октава)
"1" | Нота A = 880 Герц
"2" | Нота A = 1.76 КилоГерц
"3" | Нота A = 3.52 КилоГерц (самая высокая октава)
"4" | Нота A = 440 Герц (самая низкая октава)
"5" | Нота A = 880 Герц
"6" | Нота A = 1.76 КилоГерц
"7" | Нота A = 3.52 КилоГерц (самая высокая октава)


но как это применить, не знаю. Ведь нота в массиве определяется парой значений, которые задают высоту и длительность звучания. Но про октаву ничего не сказано.

И так, вот что у меня получилось:

Код

private void playMusic()
    {
        byte p = ToneControl.SILENCE;
        byte C4 = ToneControl.C4; // до
        byte C4d = (byte)(C4 + 1); // до-диез
        byte D4 = (byte)(C4 + 2); // ре
        byte D4d = (byte)(C4 + 3); // ре-диез
        byte E4 = (byte)(C4 + 4); // ми
        byte F4 = (byte)(C4 + 5); // фа
        byte F4d = (byte)(C4 + 6); // фа-диез
        byte G4 = (byte)(C4 + 7); // соль
        byte G4d = (byte)(C4 + 8); // соль-диез
        byte A4 = (byte)(C4 + 9); // ля
        byte A4d = (byte)(C4 + 10); // ля-диез
        byte B4 = (byte)(C4 + 11); //си
        byte C5 = (byte)(C4 + 12); // до

        byte[] nots = {
            ToneControl.VERSION, 1,
            ToneControl.TEMPO, 100,
           
            ToneControl.BLOCK_START, 0,
            G4,1,G4,1,G4,1,
            ToneControl.BLOCK_END, 0,
            ToneControl.PLAY_BLOCK, 0,
            D4d,4,p,4,F4,1,F4,1,F4,1,D4,4,p,4,
            ToneControl.PLAY_BLOCK, 0,
            D4d,1,
            ToneControl.BLOCK_START, 1,
            G4d,1,G4d,1,G4d,1,
            ToneControl.BLOCK_END, 1,
            ToneControl.PLAY_BLOCK, 1,
            G4,1,
            ToneControl.BLOCK_START, 2,
            D4d,6,D4d,6,D4d,6,
            ToneControl.BLOCK_END, 2,
            ToneControl.PLAY_BLOCK, 2,
            C4,4,p,8,
            ToneControl.PLAY_BLOCK, 0,
            D4,1,
            ToneControl.PLAY_BLOCK, 1,
            G4,1,F4,1,F4,1,F4,1,D4,4,p,8,G4,1,G4,1,F4,1,D4d,4,p,8,G4,1,G4,1,F4,1,D4d,4
        };

        try
        {
            player = Manager.createPlayer(Manager.TONE_DEVICE_LOCATOR);
            player.realize();
            tone_control = (ToneControl)
            player.getControl("ToneControl");
            tone_control.setSequence(nots);
            player.start();
        }
        catch(java.io.IOException ioe) {System.out.println(ioe.getMessage());}
        catch(MediaException me){}
    }


При попытки запустить мидлет, выскакивает следующее исключение:

Код

TRACE: <at java.lang.IllegalArgumentException: Tone sequence check failed at offset 34: invalid sequence event '-5'>, Exception caught in Display class java.lang.IllegalArgumentException: Tone sequence check failed at offset 34: invalid sequence event '-5'


Начал тестировать и искать место, от куда начинает появляться исключение, и в итоге определил, что с места ToneControl.BLOCK_START, 1,. До этого места мелодия худо бедно проигрывается.

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

Автор: MaxPayneC 7.3.2010, 20:03
Что такое "d=16, 0=5, b=100:"?

Автор: bncom 7.3.2010, 20:42
Цитата(MaxPayneC @ 7.3.2010,  20:03)
Что такое "d=16, 0=5, b=100:"?

Код

d = - (duration) длительность принимаемая в коде по умолчанию. Допустим если d=8, то в коде мелодии можно писать не 8d1, а d1 Если параметр d не указан, то он телефоном берётся по умолчанию равным 4.

  o = - (scale) шкала, а проще говоря, октава принимаемая по умолчанию, т.е. в этом случае для сокращения кода, если в нём много нот октавы 2, можно задать o=2, и не указывать их в коде мелодии. Тогда 4e2 будет выглядеть как 4e, а если ещё и указать d=4, тогда просто как 'e'. По умолчанию, в случае если параметр o= не указывается, телефоном берётся значение o=5.

  b = - (beats per minute) проще говоря темп мелодии, или, как любят говорить продвинутые музыканты 'BPM' число ударов в минуту. В случае если не указывать параметр b= то телефоном он будет воспринят как b=63, что для любой современной мелодии является уж очень низким темпом, поэтому во многих рингтонах в RTTTL он указывается в два раза большим, т.е. примерно b=125. Поэтому все мелодии для Nokia написанные в кодах RTTTL и Nokring (коды которые отображаются на дисплее телефона при забивке мелодии вручную с клавиатуры) сейчас по умолчанию подразумевают игру в темпе 125. Если мелодия требует другого темпа, то это надо указывать явно. Диапазон параметра 'b' лежит в пределах 25 ... 900. Сверхвысокий темп может пригодиться для реализации специальных звуковых эффектов, например pitch'а (плавного изменения тона), или для реализации например эффекта щебетания птичек :).


 

Автор: bncom 8.3.2010, 19:53
Ну, ребята, кто поможет?

Действительно требуется подсказка или анализ ошибки...

Автор: toreo 9.3.2010, 17:37
Извини за дурацкий ответ (но всякое же бывает).
А ты уверен, что надо именно byte[] передать в setSequence?
По вбиваемым в этот массив данным, думаю, лучше будет использовать какой-нибудь set в виде (ключ, значение).

Автор: bncom 11.3.2010, 20:27
Проблема решена.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)