Любителям всего старого, но безумно интересного, добрый вечер!
Помните такой телефон — Nokia 3310? Разумеется, помните! А такую штуку как синтезатор мелодий в нем? Тоже помните, отлично. А по старым, теплым и ламповым мелодиям скучаете? Вот и я скучаю. А еще мне на глаза попался сайтик с более чем сотней нотных листов для этого редактора. И что я должен был оставить эту прелесть без внимания? Нет уж. Что я сделал? Правильно! Взял и написал точно такой же генератор мелодий, который позволяет на выходе получить Wave — файл с мелодией. Интересно, что из этого получилось? Тогда прошу под кат.
Nokia Composer был встроен в целую кучу телефонов, подобных Nokia 3310. Кроме 7 нот, он позволял записать 5 диезов, указать октаву и длительность в частях. А еще были ноты, которые не звучали — паузы. То есть «нота» в Composer’e была действительно нотой.
Сама запись ноты для Composer’a выглядела так:
То есть, в начале идет длительность (в частях от целой), затем могла присутствовать точка, удлиняющая звучание в полтора раза, сама нота в буквенном обозначении, и октава. При этом после паузы октава не указывается (логично?), а длительность указывается ровно так же, как и для нормальной ноты.
Давайте напишем скрипт, который будет принимать ноту, как она есть и возвращать кортеж параметров.
(пишем на Python 2.7, да)
Во! То есть, сначала мы переводим ее в ВЕРХНИЙ РЕГИСТР, а затем — с помощью регулярных выражений разбираем на составляющие. Отдельно проверяем наличие точки (увеличиваем в 1.5 раза) и учитываем паузу.
Готото!
Теперь если передать функции, например, 16C2, на выходе получим (2, C, 2) то есть длительность в долях, ноту и октаву.
Что? Откуда взялось число 32? Это просто
Оригинальный Nokia Composer позволял установить длительность ноты как 1/32 «полной» ноты. При этом для него существуют еще и 1/16, 1/8, 1 / 4, 1 /2 и 1 длительности. То есть каждая следующая длительность отличается от предыдущей ровно в 2 раза. Тогда мы можем сделать вот что:
Возьмем 1/32 ноты как «единичную ноту». Тогда 1/16 — это уже 2 единичных ноты, 1/8 — 4 и так далее. Тогда мы можем взять и поделить 32 на полученную длительность.
С этим разобрались. Теперь осталось понять, как мы будем все это дело превращать в Wav — файл.
Если очень грубо — в Wave файле, кроме заголовка записаны напряжения, которые подаются на динамик. Если чуть точнее — части напряжений от максимального. То есть, если в двухбайтовом фрейме записано число 32765 — это означает, что нужно подать максимальное напряжение. Изменяя уровни напряжений с течением времени, мы можем добиться колебаний мембраны динамика. А если эти колебания будут в нужном нам диапазоне… Правильно! Мы услышим звук определенной частоты.
Теперь, о том, как это сделать.
Давайте напряжем память и… вспомним школьный курс физики! Примерно ту часть, в которой говорится о гармонических колебаниях.
Если очень просто: гармонические колебания — тип колебаний, колеблющаяся величина которых изменяется по закону синуса (ну или косинуса, как хотите)
Общая формула этого безобразия выглядит как:
При этом циклическая частота это
Вспомнили? Отлично! Теперь надо понять — зачем.
Раз уж звук мы решили задавать как изменение напряжения на динамике, то изменения это будем задавать как синусоиду с нужной нам циклической частотой (кстати, самый наглядный способ формирования звука). При этом формула для расчета амплитуды текущего фрейма будет выглядеть как
32765 — Фрейм у нас двухбайтовый, поэтому максимальное значение амплитуды ровно 32765. VOL — переменная, задающая громкость. Изменяется в диапазоне от 0 (полная тишина) до 1 (орет как на площади)
6.28 — это всего-навсего 2*Pi. Можно каждый раз высчитывать, но мы ж не звери.
FREQ — А это то, ради чего все и затевалось — нужная нам частота.
i/44100 — время, относительно начала отсчета. Почему мы делим на 44100? А потому что это частота дискретизации выходного файла (ну это я так придумал. Можно и меньше. Качество будет ниже). За секунду проходит 44100 отсчетов, поэтому и делим. Надеюсь, получилось объяснить
Ну вот. Один фрейм мы задавать научились. Теперь нужно сделать так, чтобы это все работало. То есть, помимо частоты задать еще и длительность.
А раз уж частота фиксированная… Ага! Обернем в цикл.
Опять непонятности. Откуда взялось TIME/10*441? Из моего воображения. Нет, серьезно. Это я так решил, что минимальное время звучания — 0.001 секунда. Как я уже говорил — один отсчет (при данной частоте дискретизации) это 1/44100 секунды. Соответственно, 0.001 секунда это 44.1 отсчета. А 44.1 = 441/10. А если надо задать N миллисекунд… домножим, ага. Вот мы и получаем то, что написали (TIME — это как раз таки время в миллисекундах, да)
Так ну и обернем все это дело функцию, надеюсь никто не против?
Во! Теперь мы можем генерировать звук абсолютно любой частоты.
Осталось записать то, что получилось в wave — файл.
Для работы с Wave в Python (по крайней мере в 2.7) есть прелестный модуль с незабываемым названием — Wave. А для работы со всяческими структурами — struct (вообще, до определенного момента, Python — безумно логичный язык).
После некоторых плясок с бубном и прочих извращений получилась вот такая функция:
(про нее рассказывать не буду, потому как во — первых все понятно, а во — вторых — не будем отдаляться от темы)
Ну вот. Теперь можно сгенерировать звук!
Пробуем.
Полная громкость, 4 килогерца, 5 секунд.
Посмотрим что получилось?
Вот так это звучит:
А вот так выглядит:
Ну, в общем — то, что хотели, то и получили. Звук, правда довольно неприятный.
Кстати, если мне не изменяет память, что в старой библиотеке для Turbo Pascal звук задавался не синусоидой, а меандром. На самом деле достаточно просто изменять напряжение на динамике. Просто синусоида симпатичнее, чем меандр или пила.
Ну вот. Теперь у нас есть функция генерирующая звук нужной частоты и длительности и функция, записывающая то, что мы наделали в настоящий файл.
Теперь нужно научиться записывать ноты.
Чистая (инструментально не окрашенная) нота — это звук определенной частоты.
Диез чистой ноты — звук, с частотой на полтона выше чистой ноты
Бе — моль — звук с частотой на полтона ниже чистой ноты. Бе — моли оригинальный Composer (еще помните, что мы там хотели написать? Отлично!) задавать не дает, поэтому с бе — молями работать не будем. Ну их.
Октава — если упрощенно, это множитель частоты ноты. То есть частота Ре второй октавы вдвое выше той же Ре первой октавы.
Найдем на просторах интернета таблицу нот и их частот
И сделаем из нее словарь.
(Вообще, наверно, правильнее писать C#, а не #C, но как правило все мелодии для Composer’a указывались именно в таком формате)
А теперь напишем еще одну функцию, генерирующую звук определенной ноты
Так, тут надо еще кое — что дорассказать.
С первой частью все понятно — значение нужной частоты берется из словаря, домножается на октаву и пишется в список.
Зачем нужна вторая?
Очень просто. Если желаемая длительность не кратна периоду синусоиды, то в момент времени T1 на динамик может подаваться большое напряжение, а в T1+1 уже ничего подаваться не будет. На мой медвежий слух, это звучит как внезапно оборвавшаяся фраза убитого товарища — неприятно. Поэтому мы доводим нашу синусоиду до ближайшего нуля. При высокой частоте дискретизации заметно это будет мало, а на слух будет выглядеть как та же обрывающаяся фраза товарища, если на глазах мертвеющий (но вопящий) товарищ падает в колодец. Тоже не Бог весть что, но для генерации Нокиевских мелодий сгодится.
Теперь осталось написать функцию, которая будет принимать список нот и поэлементно скармливать его генератору.
Приблизительно вот так.
Снова что — то непонятно? Это нормально,
я тоже ничего не понимаю, сейчас разберемся.
BPM — это количество ударов в минуту. Грубо говоря, это «скорость игры». Это самое BPM равно количеству четвертных нот за одну минуту. То есть одна четвертная нота должна играться 60/BPM секунд. А поскольку, мы решили, что длительность единичной ноты у нас это 1/32 — это значение равно 60/32*4/BPM = 7.5/BPM. Звучит одна четвертная нота ровно 1000 миллисекунд (композиторы почему — то так придумали), а потом этот результат домножается еще и на количество таких 1/32 нот.
Когда функция отработает в списке Frame окажется готовый файл, который останется только записать.
Ну и поскольку мне лень писать GUI я люблю консольные интерфейсы, напишем обработчик последовательности нот, который принимает эту последовательность, BPM и имя выходного файла в списке аргументов и скармливает функции Append_Notes()
Теперь осталось только передать программе исходные данные и забрать готовую мелодию.
Вгоняем в генератор…
И забираем результат:
По — моему неплохо.
Еще примеров? Легко!
Хотите сами писать? Попробуйте!
Пропустите через генератор и посмотрите что получится (А кто-то может и на глаз узнает).
Надеюсь, вам понравилось!
Искренне Ваш, слушающий монофонического Моцарта, GrakovNe
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Страница 73
Внимание! Текст в этом документе был распознан автоматически. Для просмотра оригинальной страницы Вы можете воспользоваться режимом "Оригинал".
При выборе значения Откл. звуковые сигналы телефона отключаются, и на дисплее появляется
■ Синтезатор мелодий (меню 5-4)
Телефон позволяет создавать собственные мелодии сигнала вызова. Созданные пользователем 3
мелодии помещаются в конец списка сигналов вызова.
П. Примечание. Для того, чтобы использовать эту функцию, телефон должен быть
включен. Не включайте телефон в таких местах, где его использование запрещено либо о
он может являться источником опасности или создавать помехи.
Создание нового сигнала вызова
1. Прокрутите список до сигнала, который требуется изменить, и нажмите
2. Введите требуемые ноты. Например, нажмите для ноты фа
(отображается как /). Телефон воспроизводит каждую ноту после ее
ввода (если тональные сигналы телефона не выключены).
3. Для изменения характеристик ноты:
• Длительность ноты: нажмите или для уменьшения (-) или увеличения (+)
длительности ноты или паузы. Длительность по умолчанию равна 1 /4. Длительность
отображается перед обозначением ноты, например, 16d задает ноту ре длительностью 1/
удерживая нажатой клавишу ноты, можно увеличить ее длительность
наполовину (на дисплее это отображается точкой, например, 8.а).
©2001 Nokia Mobile Phones. All rights reserved.
Помните такой олдскульный телефон Nokia 3310 и приложение Синтезатор мелодий (Nokia Composer)? Правда было здорово? И вот в 2017 году вы опять можете сочинять и прослушивать любимые Nokia-мелодии на своем Android устройстве.
Что умеет приложение:
— проигрывать рингтоны, в том числе есть более 800 предустановленных мелодий
— редактировать рингтоны
— сохранять рингтоны
— устанавливать рингтоны на звонок, уведомление и будильник
— обмениваться рингтонами с друзьями.
Реклама.
Требуется Android: 4.0+