Ключевые знаки для тональности в Пианоле

Дмитрий Маштаков
   В программе «Пианола» знаки альтерации, то есть, знаки диезов и бемолей, следуют сразу за обозначениями нот. Например, F# означает фа диез, а B- означает си бемоль. Во второй октаве это будет выглядеть так f# и b-.  Поскольку знаками обозначается индивидуально каждая нота, то знаки бекар в такой записи не нужны.

   Для большинства музыкальных записей индивидуальный принцип расстановки диезов и бемолей вполне годится, но есть и произведения с большим количеством знаков в своём ключе, такие, как прелюдии и фуги И.С.Баха, например. Поэтому я и решил добавить в программу «Пианола» такую возможность.
   Об этом я сейчас вам и расскажу. Тут интересен не только сам результат, но и способ добавления новых возможностей в уже готовую программу. Главный принцип состоит в том, чтобы не переделывать программу существенно, а поискать в ней такие элементы и места, небольшие изменения в которых придадут программе новые качества.

   По части внешнего интерфейса дело обстояло просто – на панели с кнопками имелось пустое место, на котором я размесил новую кнопку. Называется эта кнопка «Тональность».
   Подсказка, которая возникает, когда наводишь указатель на эту кнопку, подсказывает, что клик по левой стороне этой кнопки создаёт бемольные тональности, а клик по правой стороне кнопки создаёт мажорные тональности. Кликая по кнопке мы можем увеличивать или уменьшать количество знаков в ключе, число знаков показывается на кнопке так, как вы можете видеть это на иллюстрации.
   Соответственно числу выставленных на кнопке знаков меняется глобальная переменная K4T, она принимает значения от -6 до 6. Минус для бемолей и плюс для диезов. Значение 0 показывает, что никаких знаков в ключе не выставлено, и программа тогда будет работать по своим прежним алгоритмам.

   Итак, знаки в ключе мы устанавливать научились, но как заставить программу понимать это? Как я уже говорил, давайте поищем в программе то место, в которое мы могли бы внедрить это новшество.
   Проигрыванием нотной строки звуками и определением частот звучания в «Пианоле» занимается отдельная подпрограмма – Интерпретатор нотной строки. Как это следует из названия, подпрограмма эта занимается следующем – она идёт по строке от её начала к её концу, читает поочерёдно символы, написанные в строке и интерпретирует их, то есть, совершает те или иные действия.

   В частности, увидев символ ноты C,D,E… c,d,e,f… интерпретатор понимает, что это нота первой или второй октавы и для неё нужно найти, а точнее – извлечь из заранее приготовленного массива, частоту её звучания.
   Однако интерпретатор знает, что вслед за обозначением ноты в строке может идти минус – знак бемоля, или решётка # - знак диеза. Интерпретатор смотрит на следующую позицию в строке и если этот знак он там находит, то он понижает или повышает индекс считывания из массива и извлекает оттуда соседнюю частоту.
   Если же минус или решётка после знака ноты отсутствуют, то индекс, соответствующий этой ноте не меняется, и извлекается частота в точности ей соответствующая.

   Вот перед этим самым местом как раз и можно сделать развилку с тем, чтобы внести в программу новые возможности.
   Не будем сразу извлекать частоту в точности соответствующую частоте ноты, а сначала проверим, а не входит ли эта нота в список нот, отмеченных знаком альтерации в нотном ключе, и если обнаружим, что это именно так, то тогда понизим или повысим индекс извлечения частоты без прямых на то указаний.
   Как такую проверку сделать?
   Да очень просто. Приготовим заранее две строки:
ST1 = "FfCcGgDdAaEe"  для диезных тональностей и
ST2 = "BbEeAaDdGgCc"  для бемольных тональностей

   В соответствии с выставленным количеством диезов или бемолей выделим в одной из этих строк начальный фрагмент удвоенной длины. И поищем символ нашей ноты в этом фрагменте.

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

   При тональности в ключе нам понадобится символ знака бекар. Символ стоящий сразу после обозначения ноты. Опять же, не будем ничего выдумывать. Возьмём для бекара знак ноль.
   Этот знак 0 после ноты до сих пор не означал ничего.
   Поясню – сочетания F5 f6 D7 b8 C9 означали удлинения звучания указанных нот, а сочетания F4 f3 D2 b1 – укорочение звука. А сочетание F0 длительности звука не меняло. То есть, так можно было бы написать, но смысла в этой записи не было никакого. Интерпретатор цифру 0 после ноты не отслеживал.
   Теперь мы заставим его это сделать. Он же читает следующий за нотой знак, пусть теперь знает, что 0 это бекар. Не обнаружив знак решётки и знак минус, но найдя знак бекар, он обойдёт предусмотренное тональностью в ключе повышение или понижение тона и не изменит индекс извлечения частоты.

   Кстати, в записи с бекаром F09 изменение длительности звука точно также происходит, как и при обычной записи F9 или F#9. В примере, приведённом в иллюстрации, вы увидите несколько бекаров. В отличие от обычных правил, действие бекаров, а также явно указываемых диезов и бемолей, не распространяется на последующие ноты такта. Эти указания ставятся индивидуально для каждой ноты.

   Последняя нерешённая проблема – как указывать на тональность не нажимая на кнопку, а делать это непосредственно из нотной записи? И тут решение очень простое – нужно поискать в программе такую конструкцию, такое сочетание символов, которое можно было бы приспособить к тому, чтобы с помощью него можно было бы устанавливать кнопку «Тональность» в нужное положение.
   Такая подходящая конструкция в программе «Пианола» имеется – запись вида Z1.25) трактуется интерпретатором строки как пауза произвольной длительности, число после буквы Z задаёт число четвертей в этой паузе.
   Конструкция эта используется не часто, практически всегда вполне хватает обычных пауз, но её нетрудно приспособить и для наших целей – число, указывающее на длительность паузы, не может содержать в своей второй позиции знак минус или знак решётки. Поставим там эти знаки, и тогда эта конструкция будет указывать нам на тональность, точь в точь, как на кнопке.

   Цифра между буквой Z и знаком альтерации укажет на число диезов или на число бемолей (вы видите эту конструкцию в строке на иллюстрации), а если эта цифра будет 0, то интерпретатор отменит тональность в ключе и поставит на кнопке значки --.
   Опять же, чувствуете, какая красота получается в программировании? Как одно другому может соответствовать. Ничуть не меньше, чем рифмы в стихах. ))
   К тому же и мнемоника понятная, чисто человеческая – видим надпись 4- читаем: четыре бемоля, видим надпись 6# читаем: шесть диезов.

__________
19.03.2024