(495) 240-82-80ПН-СБ с 10:00 до 18:00
We speak English

Урок 2.3. Цикл в работе со звуком

В данном уроке вы научитесь воспроизводить мелодию с помощью микроконтроллера TI-Innovator Hub.

Вы научитесь

  • Использовать цикл с оператором for в работе с определенными частотами
  • Использовать цикл со списком музыкальных нот
  • Писать программу, которая воспроизводит мелодию

Немного из теории музыки

Музыкальные ноты определяются частотой вибрирующих объектов, таких как динамик, мембрана барабана или струна (на гитаре или пианино). Как ни странно, ноты в гамме имеют прямое отношение к математике. В каждой октаве 12 шагов. Если частота определенной ноты равна F, то частоту следующей ноты можно вычислить по формуле F × 12√2.

Умножение частоты ноты на 12√2 или 21/12 (корень в степени 12 из 2) двенадцать раз приводит к удвоению исходной частоты, поэтому последняя нота октавы (или первая нота следующей октавы) имеет частоту равную F × (21/12)12 = 2 × F. Например, если частота ноты равна 440 Гц, то у ноты такого же названия на октаву выше, частота будет составлять 880 Гц, а та же самая нота октавой ниже будет иметь частоту 220 Гц.

Человеческое ухо в целом воспринимает две ноты на расстоянии одной октавы как "одинаковые" из-за родственной гармонии. По этой причине в Западной нотации ноты, находящиеся на расстоянии одной октавы друг от друга, называются одинаково - нота "до" (С) через одну октаву тоже будет называться "до". 12 интервалов между этими двумя нотами называются "полутонами".

В данном проекте мы воспользуемся принципом умножения на 21/12, чтобы смоделировать в программе проигрывание 12 нот одной октавы (натурального звукоряда и бемольные/диезные) и первой ноты следующей октавы.

Нота "до" (C) 1-ой октавы (самая нижняя нота на нотных линейках на рисунке выше) имеет частоту 261.64 Гц. Нота "до" 2-ой октавы имеет частоту 2 × 261.64 Гц, то есть 523.28 Гц. Между этими двумя нотами 12 шагов (полутонов), и каждый полутон в 21/12 раз больше предыдущего.

1. Как показано на рисунке ниже введите 261.64 в приложении Калькулятор (Calculator). Затем в следующей строке сначала нажмите кнопку умножения х. Калькулятор подставит переменную Ans в начале строки (в примере не показано), потому что перед знаком умножения должен стоять какой-то множитель.

Умножьте переменную Ans на 2^(1/12) и нажмите enter. Затем еще несколько раз нажмите на enter, чтобы отобразить последовательность ответов, как показано на рисунке.

Этот принцип повтора можно легко внедрить в свою программу. Если вы продолжите нажимать на enter, то 12-ый ответ будет равен 523.28, то есть значению в два раза больше первого введенного вами значения, что соответствует упомянутой выше формуле F × (21/12)12 = 2 × F.

Примечание для учителя: Числа, которые были использованы, являются реальными значениями частот нот. Процесс вычисления в программе удваивает первое введенное вами значение вне зависимости от того, чему оно было равно.

2. Начните с создания нового проекта Python Hub. Сначала присвойте переменной freq число 261.64.

freq = 261.64

3. Затем запишите цикл с оператором for, который позволит выполнить операцию умножения 12 раз:

for i in range(12):

4. В блоке (block) цикла с оператором for введите следующие функции:

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

sound.tone(freq,1)

Затем увеличить частоту в 2**(1/12) (корень в 12 степени из 2).

freq = freq * 2 ** (1/12)

Знак ** в языке Python является оператором "возведения в степень" или "экспоненты".

Примечание для учителя: Вы не можете использовать символ ^ на калькуляторе TI-Nspire CX II-Т в языке программирования Python.

5. Если вы запустите программу сейчас (и при условии, что ошибок в коде нет), вы услышите только последний тон. Программа работает слишком быстро, чтобы успеть воспроизвести все ноты по порядку. Задержка в одну секунду в функции работы со звуком происходит именно в микроконтроллере TI-Innovator Hub, а не на калькуляторе. Программа посылает запрос на выполнение следующего сигнала слишком быстро. Вам нужно сделать так, чтобы она "дождалась", пока микроконтроллер проиграет каждую ноту. Для этого вам понадобится функция sleep(1), добавленная в цикл после проигрывания звука.

Вы также можете использовать выражение отображения print(), чтобы смотреть, какие частоты воспроизводятся в момент звучания нот.

Примечание для учителя: Расположение функции sleep() не важно, главное, чтобы она находилась в пределах цикла (то есть, структурирована) и ниже функции sound.tone().

6. Существует еще один способ воспроизведения музыкальных нот на микроконтроллере TI-Innovator Hub. Для этого добавьте следующий фрагмент кода в свою программу:

sleep(2)
for note in ["c4","d4","e4","f4","g4","a4","b4","c5"]:
  sound.note(note,1)
  sleep(1)

Кнопка с квадратными скобками [ ] находится на клавиатуре. Нажмите на ctrl+(mслева от кнопки 0.

Пояснение:

Функция sleep(2) задает 2-секундную паузу между первой частью программы и второй.

Функция for note in - это начало стандартного выражения цикла с оператором for. Такую форму выражения с оператором for можно найти в меню: menu > Built-ins > Control > for index in list:.

["c4","d4","e4","f4","g4","a4","b4","c5"] - это список музыкальных нот, каждая из которых прописана в кавычках (формат строки)."c4" - это нота "до" (C) 4-ой октавы (нота "до" 1-ой октавы имеет частоту равную 261.64 Гц).

Цикл sound.note(noteName ,time) проигрывает знакомую всем последовательность до-ре-ми-фа-соль-ля-си-до. Все бемольные и диезные ноты в октаве не проигрываются.

Можете ли вы изменить список таким образом, чтобы получилась мелодия?

Примечание для учителя: В строках с нотами можно использовать как заглавные, так и прописные буквы. В качестве бемолей и диезов используйте обозначения F и S после названия самой ноты. Например: CS4 - это нота между C4 и D4, и это та же самая нота, что и DF4.

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

song=["c4", "d4", "e4", "f4", "g4", "a4", "b4", "c5"]
time=[  1  ,  2  ,  1  ,  2  ,  1  ,  2  ,  1  ,  2 ]
for note in song:
  t=time [song.index(note)]
  sound.note(note,t)
  sleep(t)

Но эта тема не входит в программу данного курса.